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