]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
z80_measure_phi WIP
[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
167 uint8_t i = timer;
168
169 if (i)
170 timer = i - 1;
171 }
172
173 /*--------------------------------------------------------------------------*/
174
175
176 static void z80_addrbus_set_in(void)
177 {
178 /* /MREQ, /RD, /WR: Input, no pullup */
179 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
180 Z80_O_MREQ = 0;
181 Z80_O_RD = 0;
182 Z80_O_WR = 0;
183
184 P_ADL = 0;
185 DDR_ADL = 0;
186 P_ADH = 0;
187 DDR_ADH = 0;
188 PIN_ADB = P_ADB & (MASK(ADB_WIDTH) << ADB_SHIFT);
189 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
190 }
191
192
193 static void z80_addrbus_set_out(void)
194 {
195 /* /MREQ, /RD, /WR: Output and high */
196 Z80_O_MREQ = 1;
197 Z80_O_RD = 1;
198 Z80_O_WR = 1;
199 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
200
201 DDR_ADL = 0xff;
202 DDR_ADH = 0xff;
203 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
204 }
205
206
207 static void z80_dbus_set_in(void)
208 {
209 DDR_DB = 0;
210 P_DB = 0;
211 }
212
213
214 static void z80_dbus_set_out(void)
215 {
216 DDR_DB = 0xff;
217 }
218
219 static void z80_reset_active(void)
220 {
221 if (Stat & S_RESET_POLARITY)
222 Z80_O_RST = 1;
223 else
224 Z80_O_RST = 0;
225 }
226
227 static void z80_reset_inactive(void)
228 {
229 if (Stat & S_RESET_POLARITY)
230 Z80_O_RST = 0;
231 else
232 Z80_O_RST = 1;
233 }
234
235 static void z80_reset_pulse(void)
236 {
237 z80_reset_active();
238 _delay_us(10);
239 z80_reset_inactive();
240 }
241
242
243 void z80_setup_bus(void)
244 {
245 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
246
247 /* /ZRESET: Input, no pullup */
248 DDR_RST &= ~_BV(RST);
249 Z80_O_RST = 0;
250
251 /* /BUSREQ: Output and high */
252 Z80_O_BUSREQ = 1;
253 DDR_BUSREQ |= _BV(BUSREQ);
254
255 /* /BUSACK: Input, no pullup */
256 DDR_BUSACK &= ~_BV(BUSACK);
257 P_BUSACK &= ~_BV(BUSACK);
258
259 z80_addrbus_set_in();
260 z80_dbus_set_in();
261
262 if (getenv_yesno(PSTR(ENV_SINGLESTEP))) {
263 /* /RUN & /STEP: output, /WAIT: input */
264
265 PORT_SS = (PORT_SS & ~_BV(RUN)) | _BV(STEP);
266 DDR_SS = (DDR_SS & ~_BV(WAIT)) | _BV(RUN) | _BV(STEP);
267 }
268
269 if (Z80_I_RST)
270 Stat |= S_RESET_POLARITY;
271 else
272 Stat &= ~S_RESET_POLARITY;
273 z80_reset_active();
274 DDR_RST |= _BV(RST);
275
276 zstate = RESET;
277 }
278
279 /* Timer 5 */
280 PRR1 &= ~_BV(PRTIM5);
281 OCR5A = F_CPU / 1024 / 10 - 1; /* Timer: 10Hz interval (OC4A) */
282 TCCR5B = (0b01<<WGM52)|(0b101<<CS40); /* CTC Mode, Prescaler 1024 */
283 TIMSK5 = _BV(OCIE5A); /* Enable oca interrupt */
284
285 }
286
287
288 uint32_t z80_get_busreq_cycles(void)
289 {
290 return busack_cycles;
291 }
292
293 zstate_t z80_bus_state(void)
294 {
295 return zstate;
296 }
297
298 void z80_toggle_reset(void)
299 {
300 Z80_I_RST = 1;
301 }
302
303 void z80_toggle_busreq(void)
304 {
305 Z80_I_BUSREQ = 1;
306 }
307
308
309 static void z80_busreq_hpulse(void)
310 {
311 z80_dbus_set_in();
312 z80_addrbus_set_in();
313
314 #if 0
315 ATOMIC_BLOCK(ATOMIC_FORCEON) {
316 Z80_O_BUSREQ = 1;
317 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
318 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
319 }
320 #endif
321
322 #if 1
323 ATOMIC_BLOCK(ATOMIC_FORCEON) {
324 Z80_O_BUSREQ = 1;
325
326 do {
327 if (Z80_I_BUSACK == 1) {
328 Z80_O_BUSREQ = 0;
329 break;
330 }
331 } while (1);
332 }
333 #endif
334
335 if (zstate & ZST_ACQUIRED) {
336 timer = BUS_TO;
337 while (Z80_I_BUSACK == 1 && timer)
338 ;
339 if (Z80_I_BUSACK == 0)
340 z80_addrbus_set_out();
341 }
342 }
343
344
345 /*
346
347 + | | | | |
348 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
349 + | | | | |
350 + | 0 | 1 | 2 | 3 |
351 Event + | | | | |
352 ----------------+---------------+---------------+---------------+---------------+
353 | | | | |
354 Reset | 0 | 0 | 0 | 0 |
355 | | | | |
356 | | | | |
357 Request | 1 | | 3 | |
358 | | | | |
359 | | | | |
360 Release | | 0 | | 2 |
361 | | | | |
362 | | | | |
363 Run | 2 | 3 | | |
364 | | | | |
365 | | | | |
366 Restart | | | 2 | 3 |
367 | | | | |
368 | | | | |
369 M_Cycle | | | | 3 |
370 | | | | |
371 | | | | |
372 */
373
374 zstate_t z80_bus_cmd(bus_cmd_t cmd)
375 {
376 switch (cmd) {
377
378 case Reset:
379 z80_dbus_set_in();
380 z80_addrbus_set_in();
381 z80_reset_active();
382 _delay_us(10);
383 Z80_O_BUSREQ = 1;
384 timer = BUS_TO;
385 while (Z80_I_BUSACK == 0 && timer)
386 ;
387 zstate = RESET;
388 break;
389
390 case Request:
391 switch (zstate) {
392 case RESET:
393 Z80_O_BUSREQ = 0;
394 timer = 255; //BUS_TO;
395
396 uint16_t tcnt;
397 uint16_t ovl_cnt;
398 uint8_t ifr;
399 busack_cycles = 0;
400 busack_cycles_ovl = 0;
401 ATOMIC_BLOCK(ATOMIC_FORCEON) {
402 Z80_I_RST = 1; /* Toggle RESET --> inactive */
403 OCR4B = TCNT4;
404 TIFR4 = _BV(OCF4B); /* Clear compare match flag */
405 /*test*/ TIMSK4 &= ~_BV(OCIE4A); /* Disable Output Compare A interrupt */
406 }
407 TIMSK4 |= _BV(OCIE4B); /* Enable compare match interrupt */
408
409 while (Z80_I_BUSACK == 1 && timer)
410 ;
411
412 ATOMIC_BLOCK(ATOMIC_FORCEON) {
413 tcnt = TCNT4 - OCR4B;
414 ovl_cnt = busack_cycles_ovl;
415 ifr = TIFR4;
416 TIMSK4 &= ~_BV(OCIE4B); /* Disable compare match interrupt */
417 /*test*/ TIMSK4 |= _BV(OCIE4A); /* Enable Output Compare A interrupt */
418 }
419 if (Z80_I_BUSACK == 0) {
420 if ((ifr & _BV(OCF4B)) && !(tcnt & (1<<15)))
421 ovl_cnt++;
422 busack_cycles = tcnt + ((uint32_t) ovl_cnt << 16);
423 z80_addrbus_set_out();
424 zstate = RESET_AQRD;
425 // debug("### ovl: %u, ifr: %u, beg: %u, end: %u\n", ovl_cnt,
426 // (ifr & _BV(OCF4B)) != 0, OCR4B, tcnt);
427 } else {
428 z80_reset_active();
429 Z80_O_BUSREQ = 1;
430 }
431 break;
432
433 case RUNNING:
434 Z80_O_BUSREQ = 0;
435 timer = BUS_TO;
436 while (Z80_I_BUSACK == 1 && timer)
437 ;
438 if (Z80_I_BUSACK == 0) {
439 z80_addrbus_set_out();
440 zstate = RUNNING_AQRD;
441 } else {
442 Z80_O_BUSREQ = 1;
443 }
444 break;
445
446 default:
447 break;
448 }
449 break;
450
451 case Release:
452 switch (zstate) {
453 case RESET_AQRD:
454 z80_dbus_set_in();
455 z80_addrbus_set_in();
456 z80_reset_active();
457 _delay_us(10);
458 Z80_O_BUSREQ = 1;
459 timer = BUS_TO;
460 while (Z80_I_BUSACK == 0 && timer)
461 ;
462 zstate = RESET;
463 break;
464 case RUNNING_AQRD:
465 z80_dbus_set_in();
466 z80_addrbus_set_in();
467 Z80_O_BUSREQ = 1;
468 timer = BUS_TO;
469 while (Z80_I_BUSACK == 0 && timer)
470 ;
471 zstate = RUNNING;
472 break;
473 default:
474 break;
475 }
476 break;
477
478 case Run:
479 switch (zstate) {
480 case RESET:
481 _delay_ms(20); /* TODO: */
482 z80_reset_inactive();
483 zstate = RUNNING;
484 break;
485
486 case RESET_AQRD:
487 z80_dbus_set_in();
488 z80_addrbus_set_in();
489 z80_reset_pulse();
490 z80_addrbus_set_out();
491 zstate = RUNNING_AQRD;
492 break;
493 default:
494 break;
495 }
496 break;
497
498 case Restart:
499 switch (zstate) {
500 case RUNNING:
501 case RUNNING_AQRD:
502 z80_reset_pulse();
503 break;
504 default:
505 break;
506 }
507 break;
508
509 case M_Cycle:
510 switch (zstate) {
511 case RUNNING_AQRD:
512 z80_busreq_hpulse(); /* TODO: */
513 break;
514 default:
515 break;
516 }
517 }
518 return zstate;
519 }
520
521
522 /*--------------------------------------------------------------------------*/
523
524 static
525 //inline __attribute__ ((always_inline))
526 void z80_setaddress(uint32_t addr)
527 {
528 P_ADL = addr;
529 P_ADH = (addr & 0xff00) >> 8;
530 PIN_ADB = (((addr >> 16) << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT;
531 }
532
533 int32_t z80_memsize_detect(void)
534 {
535 const uint8_t PATTERN_1 = 0x55;
536 const uint8_t PATTERN_2 = ~PATTERN_1;
537 uint32_t addr;
538
539 if (!(z80_bus_cmd(Request) & ZST_ACQUIRED))
540 return -EBUSTO;
541
542 uint8_t ram_0 = z80_read(0);
543 uint8_t ram_1 = z80_read(1);
544
545 z80_write(0, ram_0 ^ 0xff);
546 z80_write(1, ram_1);
547 if ((z80_read(0) ^ ram_0) != 0xff) {
548 addr = 0;
549 } else {
550 z80_write(0, PATTERN_1);
551 for (addr=1; addr < CONFIG_SYS_RAMSIZE_MAX; addr <<= 1) {
552 uint8_t ram_i = z80_read(addr);
553 z80_write(addr, PATTERN_2);
554 if (z80_read(0) != PATTERN_1 || z80_read(addr) != PATTERN_2)
555 break;
556 z80_write(addr, ram_i);
557 }
558 }
559
560 z80_write(0, ram_0);
561 z80_bus_cmd(Release);
562
563 return addr;
564 }
565
566 /*--------------------------------------------------------------------------*/
567
568 void z80_write(uint32_t addr, uint8_t data)
569 {
570 z80_setaddress(addr);
571 Z80_O_MREQ = 0;
572 z80_dbus_set_out();
573 P_DB = data;
574 P_DB = data;
575 Z80_O_WR = 0;
576 Z80_O_WR = 0;
577 Z80_O_WR = 1;
578 Z80_O_MREQ = 1;
579 }
580
581 uint8_t z80_read(uint32_t addr)
582 {
583 uint8_t data;
584
585 z80_setaddress(addr);
586 Z80_O_MREQ = 0;
587 z80_dbus_set_in();
588 Z80_O_RD = 0;
589 Z80_O_RD = 0;
590 Z80_O_RD = 0;
591 data = PIN_DB;
592 Z80_O_RD = 1;
593 Z80_O_MREQ = 1;
594
595 return data;
596 }
597
598
599 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
600 {
601 z80_dbus_set_out();
602 Z80_O_MREQ = 0;
603 P_DB = data;
604 while(length--) {
605 z80_setaddress(addr++);
606 Z80_O_WR = 0;
607 Z80_O_WR = 0;
608 Z80_O_WR = 1;
609 }
610 Z80_O_MREQ = 1;
611 }
612
613 void z80_write_block_P(const FLASH uint8_t *src, uint32_t dest, uint32_t length)
614 {
615 uint8_t data;
616
617 z80_dbus_set_out();
618 Z80_O_MREQ = 0;
619 while(length--) {
620 z80_setaddress(dest++);
621 data = *src++;
622 P_DB = data;
623 P_DB = data;
624 Z80_O_WR = 0;
625 Z80_O_WR = 0;
626 Z80_O_WR = 1;
627 }
628 Z80_O_MREQ = 1;
629 }
630
631 void z80_write_block(const uint8_t *src, uint32_t dest, uint32_t length)
632 {
633 uint8_t data;
634
635 z80_dbus_set_out();
636 Z80_O_MREQ = 0;
637 while(length--) {
638 z80_setaddress(dest++);
639 data = *src++;
640 P_DB = data;
641 P_DB = data;
642 Z80_O_WR = 0;
643 Z80_O_WR = 0;
644 Z80_O_WR = 1;
645 }
646 Z80_O_MREQ = 1;
647 }
648
649 void z80_read_block (uint8_t *dest, uint32_t src, size_t length)
650 {
651 uint8_t data;
652
653 Z80_O_MREQ = 0;
654 z80_dbus_set_in();
655 while(length--) {
656 z80_setaddress(src++);
657 Z80_O_RD = 0;
658 Z80_O_RD = 0;
659 Z80_O_RD = 0;
660 data = PIN_DB;
661 Z80_O_RD = 1;
662 *dest++ = data;
663 }
664 Z80_O_MREQ = 1;
665 }
666
667 /*--------------------------------------------------------------------------*/
668
669 /*
670 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
671 017A' rx.in_idx: ds 1 ;
672 017B' rx.out_idx: ds 1 ;
673 017C' rx.buf: ds rx.buf_len ;
674 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
675
676 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
677 018D' tx.in_idx: ds 1 ;
678 018E' tx.out_idx: ds 1 ;
679 018F' tx.buf: ds tx.buf_len ;
680 019E' tx.buf_end equ $-1 ; last byte
681 */
682
683
684 typedef struct __attribute__((packed)) {
685 uint8_t mask;
686 uint8_t in_idx;
687 uint8_t out_idx;
688 uint8_t buf[];
689 } zfifo_t;
690
691
692
693 #define FIFO_BUFSIZE_MASK -3
694 #define FIFO_INDEX_IN -2
695 #define FIFO_INDEX_OUT -1
696
697
698 static struct {
699 uint32_t base;
700 uint8_t idx_out,
701 idx_in,
702 mask;
703 } fifo_dsc[NUM_FIFOS];
704
705
706 void z80_memfifo_init(const fifo_t f, uint32_t addr)
707 {
708 fifo_dsc[f].base = addr;
709
710
711 if (addr != 0) {
712 z80_bus_cmd(Request);
713 fifo_dsc[f].mask = z80_read(addr + FIFO_BUFSIZE_MASK);
714 fifo_dsc[f].idx_in = z80_read(addr + FIFO_INDEX_IN);
715 fifo_dsc[f].idx_out = z80_read(addr + FIFO_INDEX_OUT);
716 z80_bus_cmd(Release);
717
718 if (fifo_dsc[f].idx_in != 0 || fifo_dsc[f].idx_out != 0) {
719 DBG_P(1, "## z80_memfifo_init: %i, %lx, in: %.2x, out: %.2x, mask: %.2x\n",
720 f, addr, fifo_dsc[f].idx_in, fifo_dsc[f].idx_out, fifo_dsc[f].mask);
721 }
722 }
723 }
724
725
726 int z80_memfifo_is_empty(const fifo_t f)
727 {
728 int rc = 1;
729
730 if (fifo_dsc[f].base != 0) {
731
732 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
733 uint8_t idx;
734
735 z80_bus_cmd(Request);
736 idx = z80_read(adr);
737 z80_bus_cmd(Release);
738 rc = idx == fifo_dsc[f].idx_out;
739 }
740
741 return rc;
742 }
743
744 int z80_memfifo_is_full(const fifo_t f)
745 {
746 int rc = 0;
747
748 if (fifo_dsc[f].base != 0) {
749 z80_bus_cmd(Request);
750 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
751 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
752 z80_bus_cmd(Release);
753 }
754 return rc;
755 }
756
757
758 uint8_t z80_memfifo_getc_wait(const fifo_t f)
759 {
760 uint8_t rc, idx;
761
762 while (z80_memfifo_is_empty(f))
763 ;
764
765 z80_bus_cmd(Request);
766 idx = fifo_dsc[f].idx_out;
767 rc = z80_read(fifo_dsc[f].base+idx);
768 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
769 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
770 z80_bus_cmd(Release);
771
772 return rc;
773 }
774
775 int z80_memfifo_getc(const fifo_t f)
776 {
777 int rc = -1;
778
779 if (fifo_dsc[f].base != 0) {
780 uint8_t idx = fifo_dsc[f].idx_out;
781 z80_bus_cmd(Request);
782 if (idx != z80_read(fifo_dsc[f].base + FIFO_INDEX_IN)) {
783 rc = z80_read(fifo_dsc[f].base+idx);
784 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
785 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
786 }
787 z80_bus_cmd(Release);
788 }
789
790 return rc;
791 }
792
793
794 void z80_memfifo_putc(fifo_t f, uint8_t val)
795 {
796 int idx;
797
798 while (z80_memfifo_is_full(f))
799 ;
800
801 z80_bus_cmd(Request);
802 idx = fifo_dsc[f].idx_in;
803 z80_write(fifo_dsc[f].base+idx, val);
804 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
805 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
806 z80_bus_cmd(Release);
807 }
808
809 /*--------------------------------------------------------------------------*/
810
811 void z80_load_mem(int_fast8_t verbosity,
812 const FLASH unsigned char data[],
813 const FLASH unsigned long *sections,
814 const FLASH unsigned long address[],
815 const FLASH unsigned long length_of_sections[])
816 {
817 uint32_t sec_base = 0;
818
819 if (verbosity > 1)
820 printf_P(PSTR("Loading Z180 memory... \n"));
821
822 for (unsigned sec = 0; sec < *sections; sec++) {
823 if (verbosity > 0) {
824 printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"),
825 address[sec],
826 address[sec]+length_of_sections[sec] - 1,
827 length_of_sections[sec]);
828 }
829
830 z80_write_block_P((const FLASH unsigned char *) &data[sec_base], /* src */
831 address[sec], /* dest */
832 length_of_sections[sec]); /* len */
833 sec_base += length_of_sections[sec];
834 }
835 }