]>
Commit | Line | Data |
---|---|---|
e64eba00 L |
1 | /* |
2 | */ | |
3 | ||
4 | #include <errno.h> | |
5 | #include <stdio.h> | |
6 | #include <unistd.h> | |
7 | ||
8 | #include <libopencmsis/core_cm3.h> | |
9 | #include <libopencm3/cm3/nvic.h> | |
10 | #include <libopencm3/cm3/systick.h> | |
11 | #include <libopencm3/stm32/rtc.h> | |
12 | #include <libopencm3/stm32/usart.h> | |
13 | #include <libopencm3/stm32/rcc.h> | |
14 | #include <libopencm3/stm32/gpio.h> | |
15 | #include <libopencm3/stm32/timer.h> | |
16 | ||
17 | #define ODR 0x0c | |
18 | #define IDR 0x08 | |
19 | ||
20 | ||
21 | /* | |
22 | #define __ASM __asm | |
23 | #define __STATIC_INLINE static inline | |
24 | ||
25 | __attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) | |
26 | { | |
27 | __ASM volatile ("cpsie i"); | |
28 | } | |
29 | ||
30 | __attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void) | |
31 | { | |
32 | __ASM volatile ("cpsid i"); | |
33 | } | |
34 | */ | |
35 | ||
36 | ||
37 | ||
38 | #include "z80-if.h" | |
39 | #include "hdrom.h" | |
40 | ||
41 | #define USART_CONSOLE USART1 | |
42 | ||
43 | int _write(int fd, char *ptr, int len) __attribute__((used)); | |
44 | ||
45 | #define S_10MS_TO (1<<0) | |
46 | ||
47 | /* | |
48 | * LED Connections | |
49 | */ | |
50 | ||
51 | #define LED_PORT GPIOC | |
52 | #define LED_BLUE_PIN GPIO8 | |
53 | #define BLUE 8 | |
54 | #define LED_GREEN_PIN GPIO9 | |
55 | #define GREEN 9 | |
56 | ||
57 | ||
58 | #define LED_BLUE_ON() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 1 | |
59 | #define LED_BLUE_OFF() BBIO_PERIPH(LED_PORT+ODR, BLUE) = 0 | |
60 | #define LED_BLUE_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, BLUE) = !BBIO_PERIPH(LED_PORT+ODR, BLUE) | |
61 | ||
62 | #define LED_GREEN_ON() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 1 | |
63 | #define LED_GREEN_OFF() BBIO_PERIPH(LED_PORT+ODR, GREEN) = 0 | |
64 | #define LED_GREEN_TOGGLE() BBIO_PERIPH(LED_PORT+ODR, GREEN) = !BBIO_PERIPH(LED_PORT+ODR, GREEN) | |
65 | ||
66 | ||
67 | /* | |
68 | * Button connections | |
69 | */ | |
70 | ||
71 | //BBIO_PERIPH(GPIOA+IDR, 0); | |
72 | ||
73 | #define KEY_PORT GPIOA_IDR | |
74 | #define KEY0 GPIO0 | |
75 | //#define KEY1 GPIO1 | |
76 | //#define KEY2 GPIO2 | |
77 | ||
78 | #define REPEAT_MASK KEY0 // repeat: key0 | |
79 | #define REPEAT_START 100 // after 1s | |
80 | #define REPEAT_NEXT 20 // every 200ms | |
81 | ||
82 | ||
83 | typedef enum { | |
84 | NOTHING, PULSE, BLINK1, BLINK2 | |
85 | } LED_MODE; | |
86 | ||
87 | typedef struct { | |
88 | uint8_t mode; | |
89 | uint8_t ontime, offtime; | |
90 | } led_stat_t; | |
91 | ||
92 | volatile uint8_t led_timer[2]; | |
93 | led_stat_t led_stat[2]; | |
94 | ||
95 | volatile int timeout_1s; | |
96 | volatile uint32_t Stat; | |
97 | ||
98 | ||
99 | /*--------------------------------------------------------------------------*/ | |
100 | ||
101 | ||
102 | static void clock_setup(void) | |
103 | { | |
104 | rcc_clock_setup_in_hse_8mhz_out_24mhz(); | |
105 | ||
106 | /* Enable clocks for: | |
107 | GPIO port A (for GPIO_USART1_TX and Button) | |
108 | GPIO port C (LEDs) | |
109 | USART1 | |
110 | TIM16 (RST-Pin) | |
111 | TIM1 (IOE) | |
112 | TODO: USART1 --> USART_CONSOLE | |
113 | */ | |
114 | rcc_peripheral_enable_clock(&RCC_APB2ENR, | |
115 | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | |
116 | | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | |
117 | | RCC_APB2ENR_USART1EN | RCC_APB2ENR_AFIOEN | |
118 | | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM16EN); | |
119 | /* Enable clocks for: | |
120 | TIM3 | |
121 | */ | |
122 | rcc_peripheral_enable_clock(&RCC_APB1ENR, | |
123 | RCC_APB1ENR_TIM3EN); | |
124 | ||
125 | /* Enable clocks for: | |
126 | TIM3 | |
127 | */ | |
128 | rcc_peripheral_enable_clock(&RCC_AHBENR, | |
129 | RCC_AHBENR_DMA1EN); | |
130 | } | |
131 | ||
132 | static void systick_setup(void) | |
133 | { | |
134 | /* SysTick interrupt every N clock pulses: set reload to N-1 */ | |
135 | STK_RVR = 24000000/1000 - 1; | |
136 | ||
137 | /* Set source to core clock, enable int and start counting. */ | |
138 | STK_CSR = STK_CSR_CLKSOURCE_AHB | STK_CSR_TICKINT | STK_CSR_ENABLE; | |
139 | } | |
140 | ||
141 | #if 0 | |
142 | static void nvic_setup(void) | |
143 | { | |
144 | // nvic_enable_irq(NVIC_RTC_IRQ); | |
145 | // nvic_set_priority(NVIC_RTC_IRQ, 1); | |
146 | } | |
147 | #endif | |
148 | ||
149 | static void tim3_setup(void) | |
150 | { | |
151 | TIM3_CR1 = TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP; | |
152 | ||
153 | TIM3_CCMR2 = 0 | |
154 | | TIM_CCMR2_OC4M_FORCE_LOW | |
155 | /* | TIM_CCMR2_OC4M_FORCE_HIGH */ | |
156 | /* | TIM_CCMR2_OC4M_PWM2 */ | |
157 | ||
158 | /* | TIM_CCMR2_OC4PE */ | |
159 | /* | TIM_CCMR2_OC4FE */ | |
160 | | TIM_CCMR2_CC4S_OUT; | |
161 | ||
162 | TIM3_CCER = TIM_CCER_CC4E | |
163 | | TIM_CCER_CC4P; | |
164 | ||
165 | TIM3_ARR = 48; /* default */ | |
166 | TIM3_CCR4 = 1; /* */ | |
167 | } | |
168 | ||
169 | static void gpio_setup(void) | |
170 | { | |
171 | ||
172 | /* Disable JTAG-DP, but leave SW-DP Enabled. (free PA15, PB3, PB4) | |
173 | Remap SPI1 to PB3, PB4, PB5 and PA15. | |
174 | Remap TIM3 (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) | |
175 | */ | |
176 | gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, | |
177 | AFIO_MAPR_SPI1_REMAP | AFIO_MAPR_TIM3_REMAP_FULL_REMAP); | |
178 | ||
179 | /* LEDs and User Button. */ | |
180 | gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, | |
181 | GPIO_CNF_OUTPUT_PUSHPULL, LED_BLUE_PIN); | |
182 | gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_10_MHZ, | |
183 | GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, LED_GREEN_PIN); | |
184 | gpio_set_mode(GPIOA, GPIO_MODE_INPUT, | |
185 | GPIO_CNF_INPUT_FLOAT, GPIO0); | |
186 | } | |
187 | ||
188 | ||
189 | static void usart_setup(void) | |
190 | { | |
191 | /* Setup GPIO pin GPIO_USART1_TX/LED_GREEN_PIN on GPIO port A for transmit. */ | |
192 | /* TODO: USART1 --> USART_CONSOLE */ | |
193 | ||
194 | gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, | |
195 | GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX); | |
196 | ||
197 | /* Setup UART parameters. */ | |
198 | // usart_set_baudrate(USART_CONSOLE, 38400); | |
199 | usart_set_baudrate(USART_CONSOLE, 115200); | |
200 | usart_set_databits(USART_CONSOLE, 8); | |
201 | usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1); | |
202 | usart_set_mode(USART_CONSOLE, USART_MODE_TX_RX); | |
203 | usart_set_parity(USART_CONSOLE, USART_PARITY_NONE); | |
204 | usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE); | |
205 | ||
206 | /* Finally enable the USART. */ | |
207 | usart_enable(USART_CONSOLE); | |
208 | } | |
209 | ||
210 | /*--------------------------------------------------------------------------*/ | |
211 | ||
212 | /** | |
213 | * Use USART_CONSOLE as a console. | |
214 | * This is a syscall for newlib | |
215 | * @param fd | |
216 | * @param ptr | |
217 | * @param len | |
218 | * @return | |
219 | */ | |
220 | int _write(int fd, char *ptr, int len) | |
221 | { | |
222 | int i; | |
223 | ||
224 | if (fd == STDOUT_FILENO || fd == STDERR_FILENO) { | |
225 | for (i = 0; i < len; i++) { | |
226 | if (ptr[i] == '\n') { | |
227 | usart_send_blocking(USART_CONSOLE, '\r'); | |
228 | } | |
229 | usart_send_blocking(USART_CONSOLE, ptr[i]); | |
230 | } | |
231 | return i; | |
232 | } | |
233 | errno = EIO; | |
234 | return -1; | |
235 | } | |
236 | ||
237 | ||
238 | /*--------------------------------------------------------------------------*/ | |
239 | ||
240 | void delay_systicks(int ticks) | |
241 | { | |
242 | int start, stop, now; | |
243 | ||
244 | start = STK_CVR; | |
245 | stop = start - ticks; | |
246 | if (stop < 0) { | |
247 | stop += STK_RVR; | |
248 | do { | |
249 | now = STK_CVR; | |
250 | } while ((now > stop) || (now <= start)); | |
251 | } else { | |
252 | do { | |
253 | now = STK_CVR; | |
254 | } while ((now > stop) && (now <= start)); | |
255 | } | |
256 | } | |
257 | ||
258 | ||
259 | /*--------------------------------------------------------------------------*/ | |
260 | ||
261 | static void led_toggle(uint8_t lednr) { | |
262 | if (lednr == 0) | |
263 | LED_BLUE_TOGGLE(); | |
264 | else if (lednr == 1) | |
265 | LED_GREEN_TOGGLE(); | |
266 | } | |
267 | ||
268 | static void led_on(uint8_t lednr) { | |
269 | if (lednr == 0) | |
270 | LED_BLUE_ON(); | |
271 | else if (lednr == 1) | |
272 | LED_GREEN_ON(); | |
273 | } | |
274 | ||
275 | static void led_off(uint8_t lednr) { | |
276 | if (lednr == 0) | |
277 | LED_BLUE_OFF(); | |
278 | else if (lednr == 1) | |
279 | LED_GREEN_OFF(); | |
280 | } | |
281 | ||
282 | static uint8_t led_is_on(uint8_t lednr) { | |
283 | if (lednr == 0) | |
284 | return BBIO_PERIPH(LED_PORT+ODR, BLUE); | |
285 | else if (lednr == 1) | |
286 | return BBIO_PERIPH(LED_PORT+ODR, GREEN); | |
287 | else | |
288 | return 0; | |
289 | } | |
290 | ||
291 | static void ledset(uint8_t lednr, uint8_t what, uint8_t len) { | |
292 | ||
293 | led_stat[lednr].mode = what; | |
294 | switch (what) { | |
295 | case PULSE: | |
296 | led_stat[lednr].ontime = len; | |
297 | led_stat[lednr].offtime = 0; | |
298 | led_timer[lednr] = len; | |
299 | led_on(lednr); | |
300 | break; | |
301 | case BLINK1: | |
302 | case BLINK2: | |
303 | if (what == BLINK1) | |
304 | led_stat[lednr].offtime = 100 - len; | |
305 | else | |
306 | led_stat[lednr].offtime = 200 - len; | |
307 | led_stat[lednr].ontime = len; | |
308 | led_timer[lednr] = len; | |
309 | led_on(lednr); | |
310 | break; | |
311 | default: | |
312 | break; | |
313 | } | |
314 | } | |
315 | ||
316 | /*--------------------------------------------------------------------------*/ | |
317 | ||
318 | static volatile uint16_t key_state, | |
319 | key_press, // key press detect | |
320 | key_rpt; // key long press and repeat | |
321 | ||
322 | ||
323 | static uint16_t get_key_press(uint16_t key_mask) { | |
324 | __disable_irq(); | |
325 | // read and clear atomic ! | |
326 | key_mask &= key_press; // read key(s) | |
327 | key_press ^= key_mask; // clear key(s) | |
328 | __enable_irq(); | |
329 | return key_mask; | |
330 | } | |
331 | ||
332 | static uint16_t get_key_rpt(uint16_t key_mask) { | |
333 | __disable_irq(); | |
334 | // read and clear atomic ! | |
335 | key_mask &= key_rpt; // read key(s) | |
336 | key_rpt ^= key_mask; // clear key(s) | |
337 | __enable_irq(); | |
338 | return key_mask; | |
339 | } | |
340 | ||
341 | static uint16_t get_key_short(uint16_t key_mask) { | |
342 | __disable_irq(); | |
343 | // read key state and key press atomic ! | |
344 | return get_key_press(key_state & key_mask); | |
345 | } | |
346 | ||
347 | /* | |
348 | static uint16_t get_key_long(uint16_t key_mask) { | |
349 | return get_key_press(get_key_rpt(key_mask)); | |
350 | } | |
351 | */ | |
352 | ||
353 | static void key_timerproc() { | |
354 | static uint16_t key_in_last, rpt; | |
355 | uint16_t key_in, c; | |
356 | ||
357 | key_in = KEY_PORT; | |
358 | ||
359 | c = key_in_last & key_in & ~key_state; | |
360 | ||
361 | // key_state = key_state & key_in_last | (key_state | key_in_last) & key_in; | |
362 | // key_state = key_state & key_in | (key_state | key_in) & key_in_last; | |
363 | ||
364 | key_state = c | ((key_in_last | key_in) & key_state); | |
365 | ||
366 | // key_state = (key_state&key_in_last) | (key_state&key_in) | (key_in_last&key_in); | |
367 | ||
368 | key_press |= c; | |
369 | ||
370 | key_in_last = key_in; | |
371 | ||
372 | ||
373 | if ((key_state & REPEAT_MASK) == 0) // check repeat function | |
374 | rpt = REPEAT_START; | |
375 | if (--rpt == 0) { | |
376 | rpt = REPEAT_NEXT; // repeat delay | |
377 | key_rpt |= key_state & REPEAT_MASK; | |
378 | } | |
379 | ||
380 | ||
381 | #if 0 | |
382 | ||
383 | static char ds[30]; | |
384 | int dsi = 0; | |
385 | ||
386 | ds[dsi++] = key_state & 1 ? '1' : '0'; | |
387 | ds[dsi++] = key_in_last & 1 ? '1' : '0'; | |
388 | ds[dsi++] = key_in & 1 ? '1' : '0'; | |
389 | ds[dsi++] = ' '; | |
390 | ||
391 | //ds[dsi++] = key_state & 1 ? '1' : '0'; | |
392 | //ds[dsi++] = key_in_last & 1 ? '1' : '0'; | |
393 | ||
394 | //ds[dsi++] = ' '; | |
395 | //ds[dsi++] = ' '; | |
396 | ds[dsi++] = 0; | |
397 | puts(ds); | |
398 | #endif | |
399 | ||
400 | } | |
401 | ||
402 | /*--------------------------------------------------------------------------*/ | |
403 | ||
404 | void sys_tick_handler(void) | |
405 | { | |
406 | static int tick_10ms = 0; | |
407 | static int count_ms = 0; | |
408 | ||
409 | int i; | |
410 | ||
411 | ++tick_10ms; | |
412 | if (tick_10ms == 10) | |
413 | { | |
414 | Stat |= S_10MS_TO; | |
415 | ||
416 | tick_10ms = 0; | |
417 | ||
418 | i = led_timer[0]; | |
419 | if (i) | |
420 | led_timer[0] = i - 1; | |
421 | i = led_timer[1]; | |
422 | if (i) | |
423 | led_timer[1] = i - 1; | |
424 | ||
425 | key_timerproc(); | |
426 | ||
427 | /* Drive timer procedure of low level disk I/O module */ | |
428 | //disk_timerproc(); | |
429 | } | |
430 | ||
431 | count_ms++; | |
432 | if (count_ms == 1000) { | |
433 | count_ms = 0; | |
434 | ||
435 | if (timeout_1s) | |
436 | --timeout_1s; | |
437 | } | |
438 | } | |
439 | ||
440 | void rtc_isr(void) | |
441 | { | |
442 | /* The interrupt flag isn't cleared by hardware, we have to do it. */ | |
443 | rtc_clear_flag(RTC_SEC); | |
444 | ||
445 | } | |
446 | ||
447 | /*--------------------------------------------------------------------------*/ | |
448 | ||
449 | void tim3_set(int mode) | |
450 | { | |
451 | uint16_t cc_mode; | |
452 | ||
453 | cc_mode = TIM_CCMR2_CC4S_OUT; | |
454 | ||
455 | TIM3_CR1 = TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP | TIM_CR1_OPM; | |
456 | ||
457 | if (mode < 0) | |
458 | cc_mode |= TIM_CCMR2_OC4M_FORCE_LOW; | |
459 | else if (mode == 0) | |
460 | cc_mode |= TIM_CCMR2_OC4M_FORCE_HIGH; | |
461 | else { | |
462 | TIM3_ARR = mode; | |
463 | cc_mode |= TIM_CCMR2_OC4M_PWM2; | |
464 | } | |
465 | ||
466 | TIM3_CCMR2 = cc_mode; | |
467 | ||
468 | if (mode > 0) | |
469 | TIM3_CR1 |= TIM_CR1_CEN; | |
470 | } | |
471 | ||
472 | /*--------------------------------------------------------------------------*/ | |
473 | ||
474 | static uint32_t z80_sram_cmp(uint32_t addr, int length, uint8_t wval, int inc) | |
475 | { | |
476 | uint8_t rval; | |
477 | int errors = 0; | |
478 | ||
479 | printf("SRAM: Check %#.5x byte... ", length); //fflush(stdout); | |
480 | while (length--) { | |
481 | if ((rval = z80_read(addr)) != wval) { | |
482 | if (errors == 0) { | |
483 | printf("\nSRAM: Address W R\n" \ | |
484 | " -------------\n"); | |
485 | // 12345 00 11 | |
486 | } | |
487 | printf(" %.5lx %.2x %.2x\n", addr, wval, rval); | |
488 | ||
489 | if (++errors > 16 ) | |
490 | break; | |
491 | } | |
492 | addr++; | |
493 | wval += inc; | |
494 | } | |
495 | printf("Done.\n"); | |
496 | ||
497 | return addr; | |
498 | } | |
499 | ||
500 | #if 0 | |
501 | static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc) | |
502 | { | |
503 | printf("SRAM: Write %#.5x byte... ", length); //fflush(stdout); | |
504 | while (length--) { | |
505 | z80_write(addr, startval); | |
506 | ++addr; | |
507 | startval += inc; | |
508 | } | |
509 | printf("Done.\n"); | |
510 | } | |
511 | ||
512 | ||
513 | void z80_sram_fill_string(uint32_t addr, int length, const char *text) | |
514 | { | |
515 | char c; | |
516 | const char *p = text; | |
517 | ||
518 | while (length--) { | |
519 | z80_write(addr++, c = *p++); | |
520 | if (c == 0) | |
521 | p = text; | |
522 | } | |
523 | } | |
524 | ||
525 | ||
526 | uint32_t z80_sram_cmp_string(uint32_t addr, int length, const char *text) | |
527 | { | |
528 | char c; | |
529 | const char *p = text; | |
530 | ||
531 | while (length--) { | |
532 | c = *p++; | |
533 | if (z80_read(addr) != c) | |
534 | break; | |
535 | ++addr; | |
536 | if (c == 0) | |
537 | p = text; | |
538 | } | |
539 | return addr; | |
540 | } | |
541 | ||
542 | const char * const qbfox = "Zhe quick brown fox jumps over the lazy dog!"; | |
543 | const char * const qbcat = "Zhe quick brown fox jumps over the lazy cat!"; | |
544 | ||
545 | #endif | |
546 | ||
547 | uint8_t z80_get_byte(uint32_t adr) | |
548 | { | |
549 | uint8_t data; | |
550 | ||
551 | z80_get_bus(); | |
552 | data = z80_read(adr), | |
553 | z80_release_bus(); | |
554 | ||
555 | return data; | |
556 | } | |
557 | ||
558 | ||
559 | /*--------------------------------------------------------------------------*/ | |
560 | ||
561 | static void do_10ms(void) | |
562 | { | |
563 | for (uint8_t i = 0; i < 2; i++) { | |
564 | switch (led_stat[i].mode) { | |
565 | case PULSE: | |
566 | if (led_timer[i] == 0) { | |
567 | led_off(i); | |
568 | led_stat[i].mode = NOTHING; | |
569 | } | |
570 | break; | |
571 | case BLINK1: | |
572 | case BLINK2: | |
573 | if (led_timer[i] == 0) { | |
574 | if (led_is_on(i)) | |
575 | led_timer[i] = led_stat[i].offtime; | |
576 | else | |
577 | led_timer[i] = led_stat[i].ontime; | |
578 | led_toggle(i); | |
579 | } | |
580 | break; | |
581 | default: | |
582 | break; | |
583 | } | |
584 | } | |
585 | } | |
586 | ||
587 | /*--------------------------------------------------------------------------*/ | |
588 | ||
589 | int main(void) | |
590 | { | |
591 | //uint32_t led_state = LED_BLUE_PIN; | |
592 | //uint32_t rc; | |
593 | //uint8_t startval = 0; | |
594 | //int count; | |
595 | int stat, ch; | |
596 | uint8_t c; | |
597 | ||
598 | clock_setup(); | |
599 | gpio_setup(); | |
600 | tim3_setup(); | |
601 | setvbuf(stdout, NULL, _IONBF, 0); | |
602 | usart_setup(); | |
603 | printf("Hello World!\n"); | |
604 | ||
605 | z80_setup_bus(); | |
606 | printf("z80_setup_bus done.\n"); | |
607 | ||
608 | /* | |
609 | * If the RTC is pre-configured just allow access, don't reconfigure. | |
610 | * Otherwise enable it with the LSE as clock source and 0x7fff as | |
611 | * prescale value. | |
612 | */ | |
613 | rtc_auto_awake(LSE, 0x7fff); | |
614 | ||
615 | systick_setup(); | |
616 | ///* Setup the RTC interrupt. */ | |
617 | //nvic_setup(); | |
618 | ||
619 | /* Enable the RTC interrupt to occur off the SEC flag. */ | |
620 | //rtc_interrupt_enable(RTC_SEC); | |
621 | ||
622 | printf("get bus..."); | |
623 | z80_busreq(LOW); | |
624 | z80_reset(HIGH); | |
625 | z80_get_bus(); | |
626 | printf(" got it!\n"); | |
627 | ||
628 | z80_memset(0, 0x76, 0x80000); | |
629 | //z80_sram_fill(0, 512 * 1024, 0x76, 0); | |
630 | z80_sram_cmp(0, 512 * 1024, 0x76, 0); | |
631 | ||
632 | z80_write_block((unsigned char *) hdrom, 0, hdrom_length); | |
633 | z80_reset(LOW); | |
634 | printf("bus released! "); | |
635 | z80_release_bus(); | |
636 | z80_reset(HIGH); | |
637 | printf(" reset released!\n"); | |
638 | ||
639 | timeout_1s = 6; | |
640 | while (timeout_1s) { | |
641 | static int to=0; | |
642 | uint8_t b, rc, tc, m; | |
643 | if (to != timeout_1s) { | |
644 | b = z80_get_byte(tx_fifo-0), | |
645 | rc = z80_get_byte(tx_fifo-1), | |
646 | tc = z80_get_byte(tx_fifo-2), | |
647 | m =z80_get_byte(tx_fifo-3); | |
648 | printf(" %.2x %.2x %.2x %.2x\n", | |
649 | b, rc, tc, m); | |
650 | to = timeout_1s; | |
651 | ||
652 | if ((rc==0) && (m==0x7f)) | |
653 | break; | |
654 | } | |
655 | } | |
656 | ||
657 | z80_fifo_init(); | |
658 | ||
659 | ledset(0, BLINK1, 50); | |
660 | ||
661 | while (1) { | |
662 | // static int tickstat = 0; | |
663 | ||
664 | if (Stat & S_10MS_TO) { | |
665 | Stat &= ~S_10MS_TO; | |
666 | do_10ms(); | |
667 | } | |
668 | ||
669 | ||
670 | // if (get_key_long(KEY0)) | |
671 | // ledset(1, PULSE, 100); | |
672 | ||
673 | if (get_key_short(KEY0)) | |
674 | z80_reset_pulse(); | |
675 | ||
676 | ||
677 | /* | |
678 | switch (tickstat) { | |
679 | ||
680 | case 0: | |
681 | if (BBIO_PERIPH(GPIOA+IDR, 0)) | |
682 | { | |
683 | tickstat = 1; | |
684 | ||
685 | LED_GREEN_ON(); | |
686 | LED_GREEN_OFF(); | |
687 | LED_GREEN_ON(); | |
688 | delay_systicks(12); | |
689 | LED_GREEN_OFF(); | |
690 | } | |
691 | break; | |
692 | default: | |
693 | if (!BBIO_PERIPH(GPIOA+IDR, 0)) | |
694 | tickstat = 0; | |
695 | } | |
696 | */ | |
697 | ||
698 | //BBIO_PERIPH(LED_PORT+0x0C, 9) = BBIO_PERIPH(GPIOA+0x08, 0); | |
699 | ||
700 | //BBIO_PERIPH(LED_PORT+0x0C, 9) = !z80_stat_halt(); | |
701 | ||
702 | //BBIO_PERIPH(LED_PORT+0x0C, 9) = (~key_state & KEY0) != 0; | |
703 | ||
704 | ||
705 | /* | |
706 | stat = z80_fifo_is_not_full(rx_fifo); | |
707 | if(stat) { | |
708 | z80_fifo_putc(rx_fifo, 'y'); | |
709 | if (++count == 154) { | |
710 | putchar('\n'); | |
711 | putchar('\r'); | |
712 | count = 0; | |
713 | } | |
714 | ||
715 | } | |
716 | */ | |
717 | ||
718 | stat = usart_get_flag(USART_CONSOLE, USART_SR_RXNE); | |
719 | if (stat) { | |
720 | c = usart_recv(USART_CONSOLE) & 0xff; | |
721 | switch (c) { | |
722 | case 'H': | |
723 | tim3_set(-1); | |
724 | break; | |
725 | case 'L': | |
726 | tim3_set(0); | |
727 | break; | |
728 | case 'P': | |
729 | tim3_set(24000000/1000000 * 5); /* 5 us */ | |
730 | break; | |
731 | default: | |
732 | z80_fifo_putc(fifo_out, c); | |
733 | } | |
734 | } | |
735 | ||
736 | if (timeout_1s == 0) { | |
737 | ||
738 | while (z80_fifo_is_not_empty(fifo_in)) { | |
739 | // LED_GREEN_ON(); | |
740 | c = z80_fifo_getc(fifo_in); | |
741 | putchar(c); | |
742 | // LED_GREEN_OFF(); | |
743 | } | |
744 | ||
745 | timeout_1s = 1; | |
746 | } | |
747 | ||
748 | while ((ch = z80_inbuf_getc()) >= 0) | |
749 | printf(" 0x%.2X ", ch); | |
750 | } | |
751 | ||
752 | return 0; | |
753 | } | |
754 | ||
755 | #if 0 | |
756 | ||
757 | static char ds[30]; | |
758 | int dsi = 0; | |
759 | ||
760 | ds[dsi++] = key_state1 & 1 ? '1' : '0'; | |
761 | ds[dsi++] = key_in_last & 1 ? '1' : '0'; | |
762 | ds[dsi++] = key_in & 1 ? '1' : '0'; | |
763 | ds[dsi++] = ' '; | |
764 | ds[dsi++] = key_state1 & 1 ? '1' : '0'; | |
765 | ds[dsi++] = key_in_last & 1 ? '1' : '0'; | |
766 | ||
767 | ds[dsi++] = ' '; | |
768 | ds[dsi++] = ' '; | |
769 | ds[dsi++] = key_state & 1 ? '1' : '0'; | |
770 | ds[dsi++] = ct1 & 1 ? '0' : '1'; | |
771 | ds[dsi++] = ct0 & 1 ? '0' : '1'; | |
772 | ds[dsi++] = ' '; | |
773 | ds[dsi++] = key_state & 1 ? '1' : '0'; | |
774 | //ds[dsi++] = '\r'; | |
775 | //ds[dsi++] = '\n'; | |
776 | ds[dsi++] = 0; | |
777 | puts(ds); | |
778 | #endif |