]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
wildcards for ls command (*, ?)
[z180-stamp.git] / avr / z80-if.c
1 /*
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7 /**
8 *
9 * Pin assignments
10 *
11 * | Z180-Sig | AVR-Port | Dir |
12 * +------------+---------------+-------+
13 * | A0 | PA 0 | O |
14 * | A1 | PA 1 | O |
15 * | A2 | PA 2 | O |
16 * | A3 | PA 3 | O |
17 * | A4 | PA 4 | O |
18 * | A5 | PA 5 | O |
19 * | A6 | PA 6 | O |
20 * | A7 | PA 7 | O |
21 * | A8 | PC 0 | O |
22 * | A9 | PC 1 | O |
23 * | A10 | PC 2 | O |
24 * | A11 | PC 3 | O |
25 * | A12 | PC 4 | O |
26 * | A13 | PC 5 | O |
27 * | A14 | PC 6 | O |
28 * | A15 | PC 7 | O |
29 * | A16 | PE 2 | O |
30 * | A17 | PE 3 | O |
31 * | A18 | PE 4 | O |
32 * | D0 | PF 0 | I/O |
33 * | D1 | PF 1 | I/O |
34 * | D2 | PF 2 | I/O |
35 * | D3 | PF 3 | I/O |
36 * | D4 | PF 4 | I/O |
37 * | D5 | PF 5 | I/O |
38 * | D6 | PF 6 | I/O |
39 * | D7 | PF 7 | I/O |
40 * | RD | PD 3 | O |
41 * | WR | PD 2 | O |
42 * | MREQ | PD 4 | O |
43 * | RST | PD 5 | O |
44 * | BUSREQ | PD 7 | O |
45 * | BUSACK | PD 6 | I |
46 * |
47 * | Optional
48 * +------------------------------------+
49 * | STEP | PG 0 | O |
50 * | RUN | PG 1 | O |
51 * | WAIT | PG 2 | I |
52
53 */
54
55
56 #include "z80-if.h"
57 #include <util/atomic.h>
58 #include "debug.h"
59 #include "config.h"
60 #include "env.h"
61
62
63 //#define P_ZCLK PORTB
64 //#define ZCLK 5
65 //#define DDR_ZCLK DDRB
66 #define P_MREQ PORTD
67 #define MREQ 4
68 #define DDR_MREQ DDRD
69 #define P_RD PORTD
70 #define RD 3
71 #define P_WR PORTD
72 #define WR 2
73 #define P_BUSREQ PORTD
74 #define BUSREQ 7
75 #define PIN_BUSREQ PIND
76 #define DDR_BUSREQ DDRD
77 #define P_BUSACK PORTD
78 #define PIN_BUSACK PIND
79 #define BUSACK 6
80 #define DDR_BUSACK DDRD
81 #define P_RST PORTD
82 #define PIN_RST PIND
83 #define DDR_RST DDRD
84 #define RST 5
85
86
87 #define P_DB PORTF
88 #define PIN_DB PINF
89 #define DDR_DB DDRF
90
91 #define P_ADL PORTA
92 #define P_ADH PORTC
93 #define P_ADB PORTE
94 #define PIN_ADB PINE
95 #define DDR_ADL DDRA
96 #define DDR_ADH DDRC
97 #define DDR_ADB DDRE
98
99 #define ADB_WIDTH 3
100 #define ADB_SHIFT 2
101 //#define ADB_PORT PORTE
102
103
104 //#define Z80_O_ZCLK SBIT(P_ZCLK, 5)
105 #define Z80_O_MREQ SBIT(P_MREQ, 4)
106 #define Z80_O_RD SBIT(P_RD, 3)
107 #define Z80_O_WR SBIT(P_WR, 2)
108 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
109 #define Z80_I_BUSREQ SBIT(PIN_BUSREQ, 7)
110 //#define Z80_O_NMI SBIT(P_NMI, )
111 #define Z80_O_RST SBIT(P_RST, 5)
112 #define Z80_I_RST SBIT(PIN_RST, 5)
113 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
114 //#define Z80_I_HALT SBIT(P_HALT, )
115
116 /* Optional */
117 #define P_RUN PORTG
118 #define RUN 1
119 #define DDR_RUN DDRG
120 #define P_STEP PORTG
121 #define STEP 0
122 #define DDR_STEP DDRG
123 #define P_WAIT PORTG
124 #define WAIT 2
125 #define DDR_WAIT DDRG
126 /* All three signals are on the same Port (PortG) */
127 #define PORT_SS PORTG
128 #define DDR_SS DDRG
129 #define PIN_SS PING
130 #define Z80_O_RUN SBIT(PORT_SS, RUN)
131 #define Z80_O_STEP SBIT(PORT_SS, STEP)
132 #define Z80_I_WAIT SBIT(PORT_SS, WAIT)
133
134
135 #define BUS_TO 20
136
137
138 #define MASK(n) ((1<<(n))-1)
139 #define SMASK(w,s) (MASK(w) << (s))
140
141 void z80_bus_request_or_exit(void)
142 {
143 if (!(z80_bus_cmd(Request) & ZST_ACQUIRED))
144 cmd_error(CMD_RET_FAILURE, EBUSTO, NULL);
145 }
146
147 static zstate_t zstate;
148 static volatile uint8_t timer; /* used for bus timeout */
149
150
151 static volatile uint16_t busack_cycles_ovl;
152
153 static uint32_t busack_cycles;
154
155 ISR(TIMER4_COMPB_vect)
156 {
157 busack_cycles_ovl++;
158 }
159
160 /*---------------------------------------------------------*/
161 /* 10Hz timer interrupt generated by OC5A */
162 /*---------------------------------------------------------*/
163
164 ISR(TIMER5_COMPA_vect)
165 {
166 uint8_t i = timer;
167
168 if (i)
169 timer = i - 1;
170 }
171
172 /*--------------------------------------------------------------------------*/
173
174
175 static void z80_addrbus_set_in(void)
176 {
177 /* /MREQ, /RD, /WR: Input, no pullup */
178 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
179 Z80_O_MREQ = 0;
180 Z80_O_RD = 0;
181 Z80_O_WR = 0;
182
183 P_ADL = 0;
184 DDR_ADL = 0;
185 P_ADH = 0;
186 DDR_ADH = 0;
187 PIN_ADB = P_ADB & (MASK(ADB_WIDTH) << ADB_SHIFT);
188 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
189 }
190
191
192 static void z80_addrbus_set_out(void)
193 {
194 /* /MREQ, /RD, /WR: Output and high */
195 Z80_O_MREQ = 1;
196 Z80_O_RD = 1;
197 Z80_O_WR = 1;
198 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
199
200 DDR_ADL = 0xff;
201 DDR_ADH = 0xff;
202 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
203 }
204
205
206 static void z80_dbus_set_in(void)
207 {
208 DDR_DB = 0;
209 P_DB = 0;
210 }
211
212
213 static void z80_dbus_set_out(void)
214 {
215 DDR_DB = 0xff;
216 }
217
218 static void z80_reset_active(void)
219 {
220 if (Stat & S_RESET_POLARITY)
221 Z80_O_RST = 1;
222 else
223 Z80_O_RST = 0;
224 }
225
226 static void z80_reset_inactive(void)
227 {
228 if (Stat & S_RESET_POLARITY)
229 Z80_O_RST = 0;
230 else
231 Z80_O_RST = 1;
232 }
233
234 static void z80_reset_pulse(void)
235 {
236 z80_reset_active();
237 _delay_us(10);
238 z80_reset_inactive();
239 }
240
241
242 void z80_setup_bus(void)
243 {
244 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
245
246 /* /ZRESET: Input, no pullup */
247 DDR_RST &= ~_BV(RST);
248 Z80_O_RST = 0;
249
250 /* /BUSREQ: Output and high */
251 Z80_O_BUSREQ = 1;
252 DDR_BUSREQ |= _BV(BUSREQ);
253
254 /* /BUSACK: Input, no pullup */
255 DDR_BUSACK &= ~_BV(BUSACK);
256 P_BUSACK &= ~_BV(BUSACK);
257
258 z80_addrbus_set_in();
259 z80_dbus_set_in();
260
261 if (getenv_yesno(PSTR(ENV_SINGLESTEP))) {
262 /* /RUN & /STEP: output, /WAIT: input */
263
264 PORT_SS = (PORT_SS & ~_BV(RUN)) | _BV(STEP);
265 DDR_SS = (DDR_SS & ~_BV(WAIT)) | _BV(RUN) | _BV(STEP);
266 }
267
268 if (Z80_I_RST)
269 Stat |= S_RESET_POLARITY;
270 else
271 Stat &= ~S_RESET_POLARITY;
272 z80_reset_active();
273 DDR_RST |= _BV(RST);
274
275 zstate = RESET;
276 }
277
278 /* Timer 5 */
279 PRR1 &= ~_BV(PRTIM5);
280 OCR5A = F_CPU / 1024 / 10 - 1; /* Timer: 10Hz interval (OC4A) */
281 TCCR5B = (0b01<<WGM52)|(0b101<<CS40); /* CTC Mode, Prescaler 1024 */
282 TIMSK5 = _BV(OCIE5A); /* Enable oca interrupt */
283
284 }
285
286
287 uint32_t z80_get_busreq_cycles(void)
288 {
289 return busack_cycles;
290 }
291
292 zstate_t z80_bus_state(void)
293 {
294 return zstate;
295 }
296
297 void z80_toggle_reset(void)
298 {
299 Z80_I_RST = 1;
300 }
301
302 void z80_toggle_busreq(void)
303 {
304 Z80_I_BUSREQ = 1;
305 }
306
307
308 static void z80_busreq_hpulse(void)
309 {
310 z80_dbus_set_in();
311 z80_addrbus_set_in();
312
313 #if 0
314 ATOMIC_BLOCK(ATOMIC_FORCEON) {
315 Z80_O_BUSREQ = 1;
316 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
317 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
318 }
319 #endif
320
321 #if 1
322 ATOMIC_BLOCK(ATOMIC_FORCEON) {
323 Z80_O_BUSREQ = 1;
324
325 do {
326 if (Z80_I_BUSACK == 1) {
327 Z80_O_BUSREQ = 0;
328 break;
329 }
330 } while (1);
331 }
332 #endif
333
334 if (zstate & ZST_ACQUIRED) {
335 timer = BUS_TO;
336 while (Z80_I_BUSACK == 1 && timer)
337 ;
338 if (Z80_I_BUSACK == 0)
339 z80_addrbus_set_out();
340 }
341 }
342
343
344 /*
345
346 + | | | | |
347 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
348 + | | | | |
349 + | 0 | 1 | 2 | 3 |
350 Event + | | | | |
351 ----------------+---------------+---------------+---------------+---------------+
352 | | | | |
353 Reset | 0 | 0 | 0 | 0 |
354 | | | | |
355 | | | | |
356 Request | 1 | | 3 | |
357 | | | | |
358 | | | | |
359 Release | | 0 | | 2 |
360 | | | | |
361 | | | | |
362 Run | 2 | 3 | | |
363 | | | | |
364 | | | | |
365 Restart | | | 2 | 3 |
366 | | | | |
367 | | | | |
368 M_Cycle | | | | 3 |
369 | | | | |
370 | | | | |
371 */
372
373 zstate_t z80_bus_cmd(bus_cmd_t cmd)
374 {
375 switch (cmd) {
376
377 case Reset:
378 z80_dbus_set_in();
379 z80_addrbus_set_in();
380 z80_reset_active();
381 _delay_us(10);
382 Z80_O_BUSREQ = 1;
383 timer = BUS_TO;
384 while (Z80_I_BUSACK == 0 && timer)
385 ;
386 zstate = RESET;
387 break;
388
389 case Request:
390 switch (zstate) {
391 case RESET:
392 Z80_O_BUSREQ = 0;
393 timer = 255; //BUS_TO;
394
395 uint16_t tcnt;
396 uint16_t ovl_cnt;
397 uint8_t ifr;
398 busack_cycles = 0;
399 busack_cycles_ovl = 0;
400 ATOMIC_BLOCK(ATOMIC_FORCEON) {
401 Z80_I_RST = 1; /* Toggle RESET --> inactive */
402 OCR4B = TCNT4;
403 TIFR4 = _BV(OCF4B); /* Clear compare match flag */
404 // TIMSK4 &= ~_BV(OCIE4A); /* Disable Output Compare A interrupt */
405 }
406 TIMSK4 |= _BV(OCIE4B); /* Enable compare match interrupt */
407
408 while (Z80_I_BUSACK == 1 && timer)
409 ;
410
411 ATOMIC_BLOCK(ATOMIC_FORCEON) {
412 tcnt = TCNT4 - OCR4B;
413 ovl_cnt = busack_cycles_ovl;
414 ifr = TIFR4;
415 TIMSK4 &= ~_BV(OCIE4B); /* Disable compare match interrupt */
416 // TIMSK4 |= _BV(OCIE4A); /* Enable Output Compare A interrupt */
417 }
418 if (Z80_I_BUSACK == 0) {
419 if ((ifr & _BV(OCF4B)) && !(tcnt & (1<<15)))
420 ovl_cnt++;
421 busack_cycles = tcnt + ((uint32_t) ovl_cnt << 16);
422 z80_addrbus_set_out();
423 zstate = RESET_AQRD;
424 // debug("### ovl: %u, ifr: %u, beg: %u, end: %u\n", ovl_cnt,
425 // (ifr & _BV(OCF4B)) != 0, OCR4B, tcnt);
426 } else {
427 z80_reset_active();
428 Z80_O_BUSREQ = 1;
429 }
430 break;
431
432 case RUNNING:
433 Z80_O_BUSREQ = 0;
434 timer = BUS_TO;
435 while (Z80_I_BUSACK == 1 && timer)
436 ;
437 if (Z80_I_BUSACK == 0) {
438 z80_addrbus_set_out();
439 zstate = RUNNING_AQRD;
440 } else {
441 Z80_O_BUSREQ = 1;
442 }
443 break;
444
445 default:
446 break;
447 }
448 break;
449
450 case Release:
451 switch (zstate) {
452 case RESET_AQRD:
453 z80_dbus_set_in();
454 z80_addrbus_set_in();
455 z80_reset_active();
456 _delay_us(10);
457 Z80_O_BUSREQ = 1;
458 timer = BUS_TO;
459 while (Z80_I_BUSACK == 0 && timer)
460 ;
461 zstate = RESET;
462 break;
463 case RUNNING_AQRD:
464 z80_dbus_set_in();
465 z80_addrbus_set_in();
466 Z80_O_BUSREQ = 1;
467 timer = BUS_TO;
468 while (Z80_I_BUSACK == 0 && timer)
469 ;
470 zstate = RUNNING;
471 break;
472 default:
473 break;
474 }
475 break;
476
477 case Run:
478 switch (zstate) {
479 case RESET:
480 _delay_ms(20); /* TODO: */
481 z80_reset_inactive();
482 zstate = RUNNING;
483 break;
484
485 case RESET_AQRD:
486 z80_dbus_set_in();
487 z80_addrbus_set_in();
488 z80_reset_pulse();
489 z80_addrbus_set_out();
490 zstate = RUNNING_AQRD;
491 break;
492 default:
493 break;
494 }
495 break;
496
497 case Restart:
498 switch (zstate) {
499 case RUNNING:
500 case RUNNING_AQRD:
501 z80_reset_pulse();
502 break;
503 default:
504 break;
505 }
506 break;
507
508 case M_Cycle:
509 switch (zstate) {
510 case RUNNING_AQRD:
511 z80_busreq_hpulse(); /* TODO: */
512 break;
513 default:
514 break;
515 }
516 }
517 return zstate;
518 }
519
520 /*--------------------------------------------------------------------------*/
521
522 #define DEBUG_FREQ 0 /* set to 1 to debug */
523
524 #define debug_cpu(fmt, args...) \
525 debug_cond(DEBUG_FREQ, fmt, ##args)
526
527 #if 0
528 static
529 char * ulltoa (uint64_t val, char *s)
530 {
531 char *p = s;
532
533 while (val >= 10) {
534 *p++ = (val % 10) + '0';
535 val = val / 10;
536 }
537 *p++ = val + '0';
538 *p = '\0';
539
540 return strrev(s);
541 }
542 #endif
543
544 uint32_t z80_measure_phi(uint_fast8_t cycles)
545 {
546 uint16_t ref_stop;
547 uint16_t ref_ovfl;
548 uint8_t x_ovfl;
549 uint32_t x_freq;
550
551
552 PRR1 &= ~_BV(PRTIM3);
553 TCCR3A = 0;
554 TCCR3B = 0b000<<CS30; /* stop counter */
555 TCNT3 = 0;
556 x_ovfl = 0;
557 TIFR3 = _BV(TOV3);
558 ref_ovfl = 0;
559
560 ATOMIC_BLOCK(ATOMIC_FORCEON) {
561 EIFR = _BV(INTF6); /* Reset pending int */
562 while ((EIFR & _BV(INTF6)) == 0) /* Wait for falling edge */
563 ;
564 OCR4B = TCNT4;
565 TCCR3B = 0b110<<CS30; /* Count falling edges on T3 (==INT6) */
566 TIFR4 = _BV(OCF4B); /* clear compare match flag */
567
568 while (ref_ovfl < 60) {
569 if ((TIFR4 & _BV(OCF4B)) != 0) {
570 TIFR4 = _BV(OCF4B);
571 ++ref_ovfl;
572 }
573 if ((TIFR3 & _BV(TOV3)) != 0) {
574 TIFR3 = _BV(TOV3);
575 ++x_ovfl;
576 }
577 }
578
579 EIFR = _BV(INTF6);
580 for (;;) {
581 if (EIFR & _BV(INTF6)) {
582 TCCR3B = 0b000<<CS30; /* stop counter */
583 ref_stop = TCNT4;
584 break;
585 }
586 if ((TIFR4 & _BV(OCF4B)) != 0) {
587 TIFR4 = _BV(OCF4B);
588 ++ref_ovfl;
589 }
590 }
591 }
592
593 if ((TIFR3 & _BV(TOV3)) != 0) {
594 TIFR3 = _BV(TOV3);
595 x_ovfl++;
596 }
597
598 uint32_t ref_cnt = (ref_stop - OCR4B) + ((uint32_t)ref_ovfl << 16);
599 uint32_t x_cnt = TCNT3 + ((uint32_t) x_ovfl << 16);
600 uint64_t x_tmp = (uint64_t) 100000 * (x_cnt * cycles);
601
602 /* Stop Timer */
603 TCCR3B = 0;
604 PRR1 |= _BV(PRTIM3);
605
606 debug_cpu("\nx_ovfl: %6u, TCNT3: %6u, cycles: %3u\n", x_ovfl, TCNT3, cycles);
607 debug_cpu("ref_ovfl: %6u, ref_...: %6u\n", ref_ovfl, ref_stop-OCR4B);
608 debug_cpu("x_cnt: %9lu, ref_cnt: %9lu\n", x_cnt, ref_cnt);
609
610 x_tmp = (x_tmp * getenv_ulong(PSTR(ENV_FMON), 10, F_CPU) + (ref_cnt / 2)) / ref_cnt;
611
612 /* round to 5 decimal digits */
613 int_fast8_t sc = 5;
614 for ( ; sc > 0 || x_tmp >= 100000; sc--) x_tmp = (x_tmp + 5)/10;
615 x_freq = x_tmp;
616 for ( ; sc < 0; sc++) x_freq *= 10;
617
618 return x_freq;
619 }
620
621 /*--------------------------------------------------------------------------*/
622
623 static
624 //inline __attribute__ ((always_inline))
625 void z80_setaddress(uint32_t addr)
626 {
627 P_ADL = addr;
628 P_ADH = (addr & 0xff00) >> 8;
629 PIN_ADB = (((addr >> 16) << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT;
630 }
631
632 int32_t z80_memsize_detect(void)
633 {
634 const uint8_t PATTERN_1 = 0x55;
635 const uint8_t PATTERN_2 = ~PATTERN_1;
636 uint32_t addr;
637
638 if (!(z80_bus_cmd(Request) & ZST_ACQUIRED))
639 return -EBUSTO;
640
641 uint8_t ram_0 = z80_read(0);
642 uint8_t ram_1 = z80_read(1);
643
644 z80_write(0, ram_0 ^ 0xff);
645 z80_write(1, ram_1);
646 if ((z80_read(0) ^ ram_0) != 0xff) {
647 addr = 0;
648 } else {
649 z80_write(0, PATTERN_1);
650 for (addr=1; addr < CONFIG_SYS_RAMSIZE_MAX; addr <<= 1) {
651 uint8_t ram_i = z80_read(addr);
652 z80_write(addr, PATTERN_2);
653 if (z80_read(0) != PATTERN_1 || z80_read(addr) != PATTERN_2)
654 break;
655 z80_write(addr, ram_i);
656 }
657 }
658
659 z80_write(0, ram_0);
660 z80_bus_cmd(Release);
661
662 return addr;
663 }
664
665 /*--------------------------------------------------------------------------*/
666
667 void z80_write(uint32_t addr, uint8_t data)
668 {
669 z80_setaddress(addr);
670 Z80_O_MREQ = 0;
671 z80_dbus_set_out();
672 P_DB = data;
673 P_DB = data;
674 Z80_O_WR = 0;
675 Z80_O_WR = 0;
676 Z80_O_WR = 1;
677 Z80_O_MREQ = 1;
678 }
679
680 uint8_t z80_read(uint32_t addr)
681 {
682 uint8_t data;
683
684 z80_setaddress(addr);
685 Z80_O_MREQ = 0;
686 z80_dbus_set_in();
687 Z80_O_RD = 0;
688 Z80_O_RD = 0;
689 Z80_O_RD = 0;
690 data = PIN_DB;
691 Z80_O_RD = 1;
692 Z80_O_MREQ = 1;
693
694 return data;
695 }
696
697
698 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
699 {
700 z80_dbus_set_out();
701 Z80_O_MREQ = 0;
702 P_DB = data;
703 while(length--) {
704 z80_setaddress(addr++);
705 Z80_O_WR = 0;
706 Z80_O_WR = 0;
707 Z80_O_WR = 1;
708 }
709 Z80_O_MREQ = 1;
710 }
711
712 void z80_write_block_P(const FLASH uint8_t *src, uint32_t dest, uint32_t length)
713 {
714 uint8_t data;
715
716 z80_dbus_set_out();
717 Z80_O_MREQ = 0;
718 while(length--) {
719 z80_setaddress(dest++);
720 data = *src++;
721 P_DB = data;
722 P_DB = data;
723 Z80_O_WR = 0;
724 Z80_O_WR = 0;
725 Z80_O_WR = 1;
726 }
727 Z80_O_MREQ = 1;
728 }
729
730 void z80_write_block(const uint8_t *src, uint32_t dest, uint32_t length)
731 {
732 uint8_t data;
733
734 z80_dbus_set_out();
735 Z80_O_MREQ = 0;
736 while(length--) {
737 z80_setaddress(dest++);
738 data = *src++;
739 P_DB = data;
740 P_DB = data;
741 Z80_O_WR = 0;
742 Z80_O_WR = 0;
743 Z80_O_WR = 1;
744 }
745 Z80_O_MREQ = 1;
746 }
747
748 void z80_read_block (uint8_t *dest, uint32_t src, size_t length)
749 {
750 uint8_t data;
751
752 Z80_O_MREQ = 0;
753 z80_dbus_set_in();
754 while(length--) {
755 z80_setaddress(src++);
756 Z80_O_RD = 0;
757 Z80_O_RD = 0;
758 Z80_O_RD = 0;
759 data = PIN_DB;
760 Z80_O_RD = 1;
761 *dest++ = data;
762 }
763 Z80_O_MREQ = 1;
764 }
765
766 /*--------------------------------------------------------------------------*/
767
768 /*
769 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
770 017A' rx.in_idx: ds 1 ;
771 017B' rx.out_idx: ds 1 ;
772 017C' rx.buf: ds rx.buf_len ;
773 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
774
775 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
776 018D' tx.in_idx: ds 1 ;
777 018E' tx.out_idx: ds 1 ;
778 018F' tx.buf: ds tx.buf_len ;
779 019E' tx.buf_end equ $-1 ; last byte
780 */
781
782
783 typedef struct __attribute__((packed)) {
784 uint8_t mask;
785 uint8_t in_idx;
786 uint8_t out_idx;
787 uint8_t buf[];
788 } zfifo_t;
789
790
791
792 #define FIFO_BUFSIZE_MASK -3
793 #define FIFO_INDEX_IN -2
794 #define FIFO_INDEX_OUT -1
795
796
797 static struct {
798 uint32_t base;
799 uint8_t idx_out,
800 idx_in,
801 mask;
802 } fifo_dsc[NUM_FIFOS];
803
804
805 void z80_memfifo_init(const fifo_t f, uint32_t addr)
806 {
807 fifo_dsc[f].base = addr;
808
809
810 if (addr != 0) {
811 z80_bus_cmd(Request);
812 fifo_dsc[f].mask = z80_read(addr + FIFO_BUFSIZE_MASK);
813 fifo_dsc[f].idx_in = z80_read(addr + FIFO_INDEX_IN);
814 fifo_dsc[f].idx_out = z80_read(addr + FIFO_INDEX_OUT);
815 z80_bus_cmd(Release);
816
817 if (fifo_dsc[f].idx_in != 0 || fifo_dsc[f].idx_out != 0) {
818 DBG_P(1, "## z80_memfifo_init: %i, %lx, in: %.2x, out: %.2x, mask: %.2x\n",
819 f, addr, fifo_dsc[f].idx_in, fifo_dsc[f].idx_out, fifo_dsc[f].mask);
820 }
821 }
822 }
823
824
825 int z80_memfifo_is_empty(const fifo_t f)
826 {
827 int rc = 1;
828
829 if (fifo_dsc[f].base != 0) {
830
831 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
832 uint8_t idx;
833
834 z80_bus_cmd(Request);
835 idx = z80_read(adr);
836 z80_bus_cmd(Release);
837 rc = idx == fifo_dsc[f].idx_out;
838 }
839
840 return rc;
841 }
842
843 int z80_memfifo_is_full(const fifo_t f)
844 {
845 int rc = 0;
846
847 if (fifo_dsc[f].base != 0) {
848 z80_bus_cmd(Request);
849 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
850 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
851 z80_bus_cmd(Release);
852 }
853 return rc;
854 }
855
856
857 uint8_t z80_memfifo_getc_wait(const fifo_t f)
858 {
859 uint8_t rc, idx;
860
861 while (z80_memfifo_is_empty(f))
862 ;
863
864 z80_bus_cmd(Request);
865 idx = fifo_dsc[f].idx_out;
866 rc = z80_read(fifo_dsc[f].base+idx);
867 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
868 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
869 z80_bus_cmd(Release);
870
871 return rc;
872 }
873
874 int z80_memfifo_getc(const fifo_t f)
875 {
876 int rc = -1;
877
878 if (fifo_dsc[f].base != 0) {
879 uint8_t idx = fifo_dsc[f].idx_out;
880 z80_bus_cmd(Request);
881 if (idx != z80_read(fifo_dsc[f].base + FIFO_INDEX_IN)) {
882 rc = z80_read(fifo_dsc[f].base+idx);
883 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
884 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
885 }
886 z80_bus_cmd(Release);
887 }
888
889 return rc;
890 }
891
892
893 void z80_memfifo_putc(fifo_t f, uint8_t val)
894 {
895 int idx;
896
897 while (z80_memfifo_is_full(f))
898 ;
899
900 z80_bus_cmd(Request);
901 idx = fifo_dsc[f].idx_in;
902 z80_write(fifo_dsc[f].base+idx, val);
903 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
904 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
905 z80_bus_cmd(Release);
906 }
907
908 /*--------------------------------------------------------------------------*/
909
910 void z80_load_mem(int_fast8_t verbosity,
911 const FLASH unsigned char data[],
912 const FLASH unsigned long *sections,
913 const FLASH unsigned long address[],
914 const FLASH unsigned long length_of_sections[])
915 {
916 uint32_t sec_base = 0;
917
918 if (verbosity > 1)
919 printf_P(PSTR("Loading Z180 memory... \n"));
920
921 for (unsigned sec = 0; sec < *sections; sec++) {
922 if (verbosity > 0) {
923 printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"),
924 address[sec],
925 address[sec]+length_of_sections[sec] - 1,
926 length_of_sections[sec]);
927 }
928
929 z80_write_block_P((const FLASH unsigned char *) &data[sec_base], /* src */
930 address[sec], /* dest */
931 length_of_sections[sec]); /* len */
932 sec_base += length_of_sections[sec];
933 }
934 }