]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/z80-if.c
Prompt
[z180-stamp.git] / avr / z80-if.c
CommitLineData
35edb766
L
1/*
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
3 *
a1595a8e 4 * SPDX-License-Identifier: GPL-2.0
35edb766
L
5 */
6
0c5890bb
L
7/**
8 *
9 * Pin assignments
10 *
a1595a8e
L
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 |
0c5890bb 52
0c5890bb
L
53 */
54
ea6971b8 55
a1595a8e 56#include "z80-if.h"
f338df2a 57#include <util/atomic.h>
0c5890bb 58#include "debug.h"
a1595a8e
L
59#include "config.h"
60#include "env.h"
0c5890bb 61
0c5890bb 62
41d36f28
L
63//#define P_ZCLK PORTB
64//#define ZCLK 5
65//#define DDR_ZCLK DDRB
0c5890bb
L
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 DDR_BUSREQ DDRD
76#define P_BUSACK PORTD
9b6b4b31 77#define PIN_BUSACK PIND
0c5890bb
L
78#define BUSACK 6
79#define DDR_BUSACK DDRD
0c5890bb
L
80#define P_RST PORTD
81#define DDR_RST DDRD
82#define RST 5
83
84
85#define P_DB PORTF
86#define PIN_DB PINF
87#define DDR_DB DDRF
88
89#define P_ADL PORTA
90#define P_ADH PORTC
91#define P_ADB PORTE
92#define PIN_ADB PINE
9b6b4b31
L
93#define DDR_ADL DDRA
94#define DDR_ADH DDRC
0c5890bb
L
95#define DDR_ADB DDRE
96
97#define ADB_WIDTH 3
98#define ADB_SHIFT 2
99//#define ADB_PORT PORTE
100
101
41d36f28 102//#define Z80_O_ZCLK SBIT(P_ZCLK, 5)
0c5890bb
L
103#define Z80_O_MREQ SBIT(P_MREQ, 4)
104#define Z80_O_RD SBIT(P_RD, 3)
105#define Z80_O_WR SBIT(P_WR, 2)
106#define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
107//#define Z80_O_NMI SBIT(P_NMI, )
108#define Z80_O_RST SBIT(P_RST, 5)
9b6b4b31 109#define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
0c5890bb
L
110//#define Z80_I_HALT SBIT(P_HALT, )
111
a1595a8e
L
112/* Optional */
113#define P_RUN PORTG
114#define RUN 1
115#define DDR_RUN DDRG
116#define P_STEP PORTG
117#define STEP 0
118#define DDR_STEP DDRG
119#define P_WAIT PORTG
120#define WAIT 2
121#define DDR_WAIT DDRG
122/* All three signals are on the same Port (PortG) */
123#define PORT_SS PORTG
124#define DDR_SS DDRG
125#define PIN_SS PING
126#define Z80_O_RUN SBIT(PORT_SS, RUN)
127#define Z80_O_STEP SBIT(PORT_SS, STEP)
128#define Z80_I_WAIT SBIT(PORT_SS, WAIT)
129
9b6b4b31 130
ea6971b8
L
131#define BUS_TO 20
132
133
0c5890bb
L
134#define MASK(n) ((1<<(n))-1)
135#define SMASK(w,s) (MASK(w) << (s))
136
0c5890bb 137
f338df2a 138static zstate_t zstate;
ea6971b8
L
139static volatile uint8_t timer; /* used for bus timeout */
140
141/*---------------------------------------------------------*/
142/* 10Hz timer interrupt generated by OC4A */
143/*---------------------------------------------------------*/
144
a1595a8e 145ISR(TIMER5_COMPA_vect)
ea6971b8
L
146{
147
148 uint8_t i = timer;
149
150 if (i)
151 timer = i - 1;
152}
eded7ec4 153
0c5890bb
L
154/*--------------------------------------------------------------------------*/
155
6035a17b 156
a1595a8e 157static void z80_addrbus_set_in(void)
0c5890bb 158{
9b6b4b31
L
159 /* /MREQ, /RD, /WR: Input, no pullup */
160 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
161 Z80_O_MREQ = 0;
162 Z80_O_RD = 0;
163 Z80_O_WR = 0;
164
0c5890bb
L
165 P_ADL = 0;
166 DDR_ADL = 0;
167 P_ADH = 0;
168 DDR_ADH = 0;
6353e862 169 PIN_ADB = P_ADB & (MASK(ADB_WIDTH) << ADB_SHIFT);
0c5890bb
L
170 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
171}
172
54678798 173
a1595a8e 174static void z80_addrbus_set_out(void)
0c5890bb 175{
9b6b4b31
L
176 /* /MREQ, /RD, /WR: Output and high */
177 Z80_O_MREQ = 1;
178 Z80_O_RD = 1;
179 Z80_O_WR = 1;
180 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
181
0c5890bb
L
182 DDR_ADL = 0xff;
183 DDR_ADH = 0xff;
184 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
185}
186
187
6035a17b 188static void z80_dbus_set_in(void)
0c5890bb
L
189{
190 DDR_DB = 0;
191 P_DB = 0;
192}
193
62f624d3 194
6035a17b 195static void z80_dbus_set_out(void)
0c5890bb
L
196{
197 DDR_DB = 0xff;
198}
199
62f624d3
L
200
201static void z80_reset_pulse(void)
202{
203 Z80_O_RST = 0;
204 _delay_us(10);
205 Z80_O_RST = 1;
206}
207
208
0c5890bb
L
209void z80_setup_bus(void)
210{
a1595a8e
L
211 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
212
213 /* /ZRESET: Output and low */
214 Z80_O_RST = 0;
215 DDR_RST |= _BV(RST);
0c5890bb 216
a1595a8e
L
217 /* /BUSREQ: Output and high */
218 Z80_O_BUSREQ = 1;
219 DDR_BUSREQ |= _BV(BUSREQ);
0c5890bb 220
a1595a8e
L
221 /* /BUSACK: Input, no pullup */
222 DDR_BUSACK &= ~_BV(BUSACK);
223 P_BUSACK &= ~_BV(BUSACK);
0c5890bb 224
a1595a8e
L
225 z80_addrbus_set_in();
226 z80_dbus_set_in();
0c5890bb 227
a1595a8e
L
228 if (getenv_yesno(PSTR(ENV_SINGLESTEP))) {
229 /* /RUN & /STEP: output, /WAIT: input */
72f58822 230
a1595a8e
L
231 PORT_SS = (PORT_SS & ~_BV(RUN)) | _BV(STEP);
232 DDR_SS = (DDR_SS & ~_BV(WAIT)) | _BV(RUN) | _BV(STEP);
233 }
234
235 zstate = RESET;
236 }
ea6971b8 237
a1595a8e
L
238 /* Timer 5 */
239 PRR1 &= ~_BV(PRTIM5);
240 OCR5A = F_CPU / 1024 / 10 - 1; /* Timer: 10Hz interval (OC4A) */
241 TCCR5B = (0b01<<WGM52)|(0b101<<CS40); /* CTC Mode, Prescaler 1024 */
242 TIMSK5 = _BV(OCIE5A); /* Enable oca interrupt */
ea6971b8 243
0c5890bb
L
244}
245
f338df2a 246
62f624d3 247zstate_t z80_bus_state(void)
f338df2a
L
248{
249 return zstate;
250}
251
62f624d3
L
252
253static void z80_busreq_hpulse(void)
0c5890bb 254{
6035a17b 255 z80_dbus_set_in();
a1595a8e 256 z80_addrbus_set_in();
72f58822 257
a1595a8e 258#if 0
8a7decea 259 ATOMIC_BLOCK(ATOMIC_FORCEON) {
62f624d3
L
260 Z80_O_BUSREQ = 1;
261 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
262 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
f338df2a 263 }
a1595a8e
L
264#endif
265
4b0604a4 266#if 1
a1595a8e
L
267 ATOMIC_BLOCK(ATOMIC_FORCEON) {
268 Z80_O_BUSREQ = 1;
269
270 do {
271 if (Z80_I_BUSACK == 1) {
272 Z80_O_BUSREQ = 0;
273 break;
274 }
275 } while (1);
276 }
4b0604a4 277#endif
72f58822 278
62f624d3 279 if (zstate & ZST_ACQUIRED) {
ea6971b8
L
280 timer = BUS_TO;
281 while (Z80_I_BUSACK == 1 && timer)
f338df2a 282 ;
ea6971b8 283 if (Z80_I_BUSACK == 0)
a1595a8e 284 z80_addrbus_set_out();
f338df2a 285 }
f338df2a
L
286}
287
f338df2a
L
288
289/*
f338df2a 290
ea6971b8 291 + | | | | |
62f624d3 292 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
ea6971b8
L
293 + | | | | |
294 + | 0 | 1 | 2 | 3 |
295Event + | | | | |
62f624d3 296----------------+---------------+---------------+---------------+---------------+
ea6971b8
L
297 | | | | |
298Reset | 0 | 0 | 0 | 0 |
299 | | | | |
300 | | | | |
301Request | 1 | | 3 | |
302 | | | | |
303 | | | | |
304Release | | 0 | | 2 |
305 | | | | |
306 | | | | |
307Run | 2 | 3 | | |
308 | | | | |
309 | | | | |
310Restart | | | 2 | 3 |
311 | | | | |
312 | | | | |
313M_Cycle | | | | 3 |
314 | | | | |
315 | | | | |
62f624d3 316*/
f338df2a 317
62f624d3 318zstate_t z80_bus_cmd(bus_cmd_t cmd)
f338df2a 319{
62f624d3 320 switch (cmd) {
f338df2a 321
62f624d3 322 case Reset:
6035a17b 323 z80_dbus_set_in();
a1595a8e 324 z80_addrbus_set_in();
f338df2a 325 Z80_O_RST = 0;
62f624d3
L
326 Z80_O_BUSREQ = 1;
327 zstate = RESET;
f338df2a
L
328 break;
329
62f624d3
L
330 case Request:
331 switch (zstate) {
332 case RESET:
333 Z80_O_BUSREQ = 0;
334 Z80_O_RST = 1;
ea6971b8
L
335 timer = BUS_TO;
336 while (Z80_I_BUSACK == 1 && timer)
62f624d3 337 ;
ea6971b8 338 if (Z80_I_BUSACK == 0) {
a1595a8e 339 z80_addrbus_set_out();
ea6971b8
L
340 zstate = RESET_AQRD;
341 } else {
342 Z80_O_RST = 0;
343 Z80_O_BUSREQ = 1;
344 }
62f624d3
L
345 break;
346
347 case RUNNING:
348 Z80_O_BUSREQ = 0;
ea6971b8
L
349 timer = BUS_TO;
350 while (Z80_I_BUSACK == 1 && timer)
62f624d3 351 ;
ea6971b8 352 if (Z80_I_BUSACK == 0) {
a1595a8e 353 z80_addrbus_set_out();
ea6971b8
L
354 zstate = RUNNING_AQRD;
355 } else {
356 Z80_O_BUSREQ = 1;
357 }
62f624d3
L
358 break;
359
360 default:
361 break;
362 }
f338df2a 363 break;
f338df2a 364
62f624d3
L
365 case Release:
366 switch (zstate) {
367 case RESET_AQRD:
6035a17b 368 z80_dbus_set_in();
a1595a8e 369 z80_addrbus_set_in();
62f624d3
L
370 Z80_O_RST = 0;
371 Z80_O_BUSREQ = 1;
372 zstate = RESET;
373 break;
374 case RUNNING_AQRD:
6035a17b 375 z80_dbus_set_in();
a1595a8e 376 z80_addrbus_set_in();
62f624d3
L
377 Z80_O_BUSREQ = 1;
378 zstate = RUNNING;
379 break;
380 default:
381 break;
382 }
383 break;
f338df2a 384
62f624d3
L
385 case Run:
386 switch (zstate) {
387 case RESET:
388 Z80_O_RST = 1;
389 zstate = RUNNING;
390 break;
391
392 case RESET_AQRD:
6035a17b 393 z80_dbus_set_in();
a1595a8e 394 z80_addrbus_set_in();
62f624d3 395 z80_reset_pulse();
a1595a8e 396 z80_addrbus_set_out();
62f624d3
L
397 zstate = RUNNING_AQRD;
398 break;
399 default:
400 break;
401 }
402 break;
f338df2a 403
62f624d3
L
404 case Restart:
405 switch (zstate) {
406 case RUNNING:
407 case RUNNING_AQRD:
408 z80_reset_pulse();
409 break;
410 default:
411 break;
412 }
413 break;
f338df2a 414
62f624d3
L
415 case M_Cycle:
416 switch (zstate) {
417 case RUNNING_AQRD:
ea6971b8 418 z80_busreq_hpulse(); /* TODO: */
62f624d3
L
419 break;
420 default:
421 break;
422 }
f338df2a 423 }
62f624d3 424 return zstate;
9b6b4b31
L
425}
426
62f624d3 427
9b6b4b31
L
428/*--------------------------------------------------------------------------*/
429
54678798 430static
9b6b4b31
L
431//inline __attribute__ ((always_inline))
432void z80_setaddress(uint32_t addr)
433{
a1595a8e
L
434 P_ADL = addr;
435 P_ADH = (addr & 0xff00) >> 8;
436 PIN_ADB = (((addr >> 16) << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT;
0c5890bb
L
437}
438
439void z80_write(uint32_t addr, uint8_t data)
440{
441 z80_setaddress(addr);
442 Z80_O_MREQ = 0;
6035a17b 443 z80_dbus_set_out();
9b6b4b31
L
444 P_DB = data;
445 P_DB = data;
446 Z80_O_WR = 0;
0c5890bb
L
447 Z80_O_WR = 0;
448 Z80_O_WR = 1;
449 Z80_O_MREQ = 1;
450}
451
452uint8_t z80_read(uint32_t addr)
453{
454 uint8_t data;
455
456 z80_setaddress(addr);
457 Z80_O_MREQ = 0;
6035a17b 458 z80_dbus_set_in();
0c5890bb
L
459 Z80_O_RD = 0;
460 Z80_O_RD = 0;
9b6b4b31 461 Z80_O_RD = 0;
0c5890bb
L
462 data = PIN_DB;
463 Z80_O_RD = 1;
464 Z80_O_MREQ = 1;
465
466 return data;
467}
468
469
470void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
471{
6035a17b 472 z80_dbus_set_out();
0c5890bb 473 Z80_O_MREQ = 0;
ea6971b8 474 P_DB = data;
0c5890bb
L
475 while(length--) {
476 z80_setaddress(addr++);
ea6971b8
L
477 Z80_O_WR = 0;
478 Z80_O_WR = 0;
479 Z80_O_WR = 1;
480 }
481 Z80_O_MREQ = 1;
482}
483
484void z80_write_block_P(const FLASH uint8_t *src, uint32_t dest, uint32_t length)
485{
486 uint8_t data;
487
488 z80_dbus_set_out();
489 Z80_O_MREQ = 0;
490 while(length--) {
491 z80_setaddress(dest++);
492 data = *src++;
0c5890bb 493 P_DB = data;
9b6b4b31
L
494 P_DB = data;
495 Z80_O_WR = 0;
0c5890bb
L
496 Z80_O_WR = 0;
497 Z80_O_WR = 1;
498 }
499 Z80_O_MREQ = 1;
500}
501
ea6971b8 502void z80_write_block(const uint8_t *src, uint32_t dest, uint32_t length)
0c5890bb
L
503{
504 uint8_t data;
54678798 505
6035a17b 506 z80_dbus_set_out();
0c5890bb
L
507 Z80_O_MREQ = 0;
508 while(length--) {
509 z80_setaddress(dest++);
510 data = *src++;
511 P_DB = data;
9b6b4b31
L
512 P_DB = data;
513 Z80_O_WR = 0;
0c5890bb
L
514 Z80_O_WR = 0;
515 Z80_O_WR = 1;
516 }
517 Z80_O_MREQ = 1;
518}
519
ea6971b8
L
520void z80_read_block (uint8_t *dest, uint32_t src, size_t length)
521{
522 uint8_t data;
523
524 Z80_O_MREQ = 0;
525 z80_dbus_set_in();
526 while(length--) {
527 z80_setaddress(src++);
528 Z80_O_RD = 0;
529 Z80_O_RD = 0;
530 Z80_O_RD = 0;
531 data = PIN_DB;
532 Z80_O_RD = 1;
533 *dest++ = data;
534 }
535 Z80_O_MREQ = 1;
536}
537
538
0c5890bb
L
539/*
540 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
541 017A' rx.in_idx: ds 1 ;
542 017B' rx.out_idx: ds 1 ;
543 017C' rx.buf: ds rx.buf_len ;
544 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
54678798 545
0c5890bb
L
546 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
547 018D' tx.in_idx: ds 1 ;
548 018E' tx.out_idx: ds 1 ;
549 018F' tx.buf: ds tx.buf_len ;
550 019E' tx.buf_end equ $-1 ; last byte
551*/
552
553
554typedef struct __attribute__((packed)) {
555 uint8_t mask;
556 uint8_t in_idx;
557 uint8_t out_idx;
558 uint8_t buf[];
559} zfifo_t;
560
561
562
563#define FIFO_BUFSIZE_MASK -3
564#define FIFO_INDEX_IN -2
565#define FIFO_INDEX_OUT -1
566
567
568static struct {
569 uint32_t base;
570 uint8_t idx_out,
571 idx_in,
572 mask;
573 } fifo_dsc[NUM_FIFOS];
54678798 574
0c5890bb 575
8a7decea 576void z80_memfifo_init(const fifo_t f, uint32_t addr)
0c5890bb 577{
8a7decea 578 fifo_dsc[f].base = addr;
0c5890bb 579
0c5890bb 580
bbd45c46 581 if (addr != 0) {
8a7decea
L
582 z80_bus_cmd(Request);
583 fifo_dsc[f].mask = z80_read(addr + FIFO_BUFSIZE_MASK);
584 fifo_dsc[f].idx_in = z80_read(addr + FIFO_INDEX_IN);
585 fifo_dsc[f].idx_out = z80_read(addr + FIFO_INDEX_OUT);
586 z80_bus_cmd(Release);
910e7206
L
587
588 if (fifo_dsc[f].idx_in != 0 || fifo_dsc[f].idx_out != 0) {
589 DBG_P(1, "## z80_memfifo_init: %i, %lx, in: %.2x, out: %.2x, mask: %.2x\n",
590 f, addr, fifo_dsc[f].idx_in, fifo_dsc[f].idx_out, fifo_dsc[f].mask);
591 }
8a7decea 592 }
0c5890bb
L
593}
594
595
596int z80_memfifo_is_empty(const fifo_t f)
597{
598 int rc = 1;
599
89adce76 600 if (fifo_dsc[f].base != 0) {
0c5890bb
L
601
602 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
603 uint8_t idx;
604
62f624d3 605 z80_bus_cmd(Request);
0c5890bb 606 idx = z80_read(adr);
62f624d3 607 z80_bus_cmd(Release);
0c5890bb
L
608 rc = idx == fifo_dsc[f].idx_out;
609 }
610
611 return rc;
612}
613
614int z80_memfifo_is_full(const fifo_t f)
615{
ce47d431 616 int rc = 0;
54678798 617
0c5890bb 618 if (fifo_dsc[f].base != 0) {
62f624d3 619 z80_bus_cmd(Request);
0c5890bb
L
620 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
621 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
62f624d3 622 z80_bus_cmd(Release);
0c5890bb
L
623 }
624 return rc;
625}
626
89adce76
L
627
628uint8_t z80_memfifo_getc_wait(const fifo_t f)
0c5890bb
L
629{
630 uint8_t rc, idx;
54678798 631
0c5890bb
L
632 while (z80_memfifo_is_empty(f))
633 ;
634
62f624d3 635 z80_bus_cmd(Request);
0c5890bb
L
636 idx = fifo_dsc[f].idx_out;
637 rc = z80_read(fifo_dsc[f].base+idx);
638 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
639 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
62f624d3 640 z80_bus_cmd(Release);
54678798 641
0c5890bb
L
642 return rc;
643}
644
89adce76
L
645int z80_memfifo_getc(const fifo_t f)
646{
647 int rc = -1;
648
649 if (fifo_dsc[f].base != 0) {
650 uint8_t idx = fifo_dsc[f].idx_out;
651 z80_bus_cmd(Request);
652 if (idx != z80_read(fifo_dsc[f].base + FIFO_INDEX_IN)) {
653 rc = z80_read(fifo_dsc[f].base+idx);
654 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
655 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
656 }
657 z80_bus_cmd(Release);
658 }
659
660 return rc;
661}
662
0c5890bb
L
663
664void z80_memfifo_putc(fifo_t f, uint8_t val)
665{
666 int idx;
54678798 667
0c5890bb
L
668 while (z80_memfifo_is_full(f))
669 ;
670
62f624d3 671 z80_bus_cmd(Request);
0c5890bb
L
672 idx = fifo_dsc[f].idx_in;
673 z80_write(fifo_dsc[f].base+idx, val);
674 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
675 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
62f624d3 676 z80_bus_cmd(Release);
0c5890bb 677}