]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
User Timer0 as Z180 Clock
[z180-stamp.git] / avr / z80-if.c
1 /**
2 *
3 * Pin assignments
4 *
5 * | Z180-Sig | AVR-Port | Dir | Special Function |
6 * +------------+---------------+-------+-----------------------+
7 * | A0 | PA 0 | O | |
8 * | A1 | PA 1 | O | |
9 * | A2 | PA 2 | O | |
10 * | A3 | PA 3 | O | |
11 * | A4 | PA 4 | O | |
12 * | A5 | PA 5 | O | |
13 * | A6 | PA 6 | O | |
14 * | A7 | PA 7 | O | |
15 * | A8 | PC 0 | O | |
16 * | A9 | PC 1 | O | |
17 * | A10 | PC 2 | O | |
18 * | A11 | PC 3 | O | |
19 * | A12 | PC 4 | O | |
20 * | A13 | PC 5 | O | |
21 * | A14 | PC 6 | O | |
22 * | A15 | PC 7 | O | |
23 * | A16 | PE 2 | O | |
24 * | A17 | PE 3 | O | |
25 * | A18 | PE 4 | O | |
26 * | D0 | PF 0 | I/O | |
27 * | D1 | PF 1 | I/O | |
28 * | D2 | PF 2 | I/O | |
29 * | D3 | PF 3 | I/O | |
30 * | D4 | PF 4 | I/O | |
31 * | D5 | PF 5 | I/O | |
32 * | D6 | PF 6 | I/O | |
33 * | D7 | PF 7 | I/O | |
34 * | RD | PD 3 | O | |
35 * | WR | PD 2 | O | |
36 * | MREQ | PD 4 | O | |
37 * | RST | PD 5 | O | |
38 * | BUSREQ | PD 7 | O | |
39 * | BUSACK | PD 6 | I | |
40 * | IOCS1 | PE 5 | I | |
41 * |* HALT | P | | |
42 * |* NMI | P | | |
43 * | | P | | |
44 * | | P | | af1 USART1_TX |
45 * | | P | | af1 USART1_RX |
46 * | | P |JTDI | remap SPI1_NSS' |
47 * | | P |JTDO | remap SPI1_SCK' |
48 * | | P |JTRST | remap SPI1_MISO' |
49 * | | P | | remap SPI1_MOSI' |
50 * | | P | | af1 OSC32 |
51 * | | P | | af1 OSC32 |
52
53
54 */
55
56 #include <avr/io.h>
57 #include <util/delay.h>
58 #include <util/atomic.h>
59 #include <stdio.h>
60 #include "debug.h"
61 #include "z80-if.h"
62
63
64 /* Number of array elements */
65 #define NELEMS(x) (sizeof x/sizeof *x)
66
67
68 #define CONCAT(x,y) x ## y
69 #define EVALUATOR(x,y) CONCAT(x,y)
70
71 #define GPIO_(X) CONCAT(GPIO, X)
72
73 struct bits {
74 uint8_t b0:1;
75 uint8_t b1:1;
76 uint8_t b2:1;
77 uint8_t b3:1;
78 uint8_t b4:1;
79 uint8_t b5:1;
80 uint8_t b6:1;
81 uint8_t b7:1;
82 } __attribute__((__packed__));
83
84 #define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
85
86
87 #define P_ZCLK PORTB
88 #define ZCLK 7
89 #define DDR_ZCLK DDRB
90 #define P_MREQ PORTD
91 #define MREQ 4
92 #define DDR_MREQ DDRD
93 #define P_RD PORTD
94 #define RD 3
95 #define P_WR PORTD
96 #define WR 2
97 #define P_BUSREQ PORTD
98 #define BUSREQ 7
99 #define DDR_BUSREQ DDRD
100 #define P_BUSACK PORTD
101 #define PIN_BUSACK PIND
102 #define BUSACK 6
103 #define DDR_BUSACK DDRD
104 //#define P_HALT PORTA
105 //#define HALT 12
106 #define P_IOCS1 PORTE
107 #define IOCS1 5
108 #define DDR_IOCS1 DDRE
109 //#define P_NMI PORTB
110 //#define NMI 7
111 #define P_RST PORTD
112 #define DDR_RST DDRD
113 #define RST 5
114
115
116 #define P_DB PORTF
117 #define PIN_DB PINF
118 #define DDR_DB DDRF
119
120 #define P_ADL PORTA
121 #define P_ADH PORTC
122 #define P_ADB PORTE
123 #define PIN_ADB PINE
124 #define DDR_ADL DDRA
125 #define DDR_ADH DDRC
126 #define DDR_ADB DDRE
127
128 #define ADB_WIDTH 3
129 #define ADB_SHIFT 2
130 //#define ADB_PORT PORTE
131
132
133 #define Z80_O_ZCLK SBIT(P_ZCLK, 7)
134 #define Z80_O_MREQ SBIT(P_MREQ, 4)
135 #define Z80_O_RD SBIT(P_RD, 3)
136 #define Z80_O_WR SBIT(P_WR, 2)
137 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
138 //#define Z80_O_NMI SBIT(P_NMI, )
139 #define Z80_O_RST SBIT(P_RST, 5)
140 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
141 //#define Z80_I_HALT SBIT(P_HALT, )
142
143
144 #define MASK(n) ((1<<(n))-1)
145 #define SMASK(w,s) (MASK(w) << (s))
146
147
148
149 typedef union {
150 uint32_t l;
151 uint16_t w[2];
152 uint8_t b[4];
153 } addr_t;
154
155
156 static zstate_t zstate;
157
158 /*--------------------------------------------------------------------------*/
159
160
161 static void z80_setup_addrbus_tristate(void)
162 {
163 /* /MREQ, /RD, /WR: Input, no pullup */
164 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
165 Z80_O_MREQ = 0;
166 Z80_O_RD = 0;
167 Z80_O_WR = 0;
168
169 P_ADL = 0;
170 DDR_ADL = 0;
171 P_ADH = 0;
172 DDR_ADH = 0;
173 PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
174 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
175 }
176
177
178 static void z80_setup_addrbus_active(void)
179 {
180 /* /MREQ, /RD, /WR: Output and high */
181 Z80_O_MREQ = 1;
182 Z80_O_RD = 1;
183 Z80_O_WR = 1;
184 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
185
186 DDR_ADL = 0xff;
187 DDR_ADH = 0xff;
188 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
189 }
190
191
192 static void z80_setup_dbus_in(void)
193 {
194 DDR_DB = 0;
195 P_DB = 0;
196 }
197
198
199 static void z80_setup_dbus_out(void)
200 {
201 DDR_DB = 0xff;
202 }
203
204
205 static void z80_reset_pulse(void)
206 {
207 Z80_O_RST = 0;
208 _delay_us(10);
209 Z80_O_RST = 1;
210 }
211
212 static
213 void z80_setup_clock(void)
214 {
215 /* ZCLK: Output and low */
216 DDR_ZCLK |= _BV(ZCLK);
217 Z80_O_ZCLK = 0;
218
219 /* Timer0: CTC: Toggle OC0A on compare match */
220 PRR0 &= ~_BV(PRTIM0);
221 TCCR0A = _BV(COM0A0) | _BV(WGM01);
222 OCR0A = 0;
223 TCCR0B = (0x01 << CS00);
224 }
225
226 void z80_setup_bus(void)
227 {
228 z80_setup_clock();
229
230 /* /ZRESET: Output and low */
231 Z80_O_RST = 0;
232 DDR_RST |= _BV(RST);
233
234 /* /BUSREQ: Output and high */
235 Z80_O_BUSREQ = 1;
236 DDR_BUSREQ |= _BV(BUSREQ);
237
238 /* /BUSACK: Input, no pullup */
239 DDR_BUSACK &= ~_BV(BUSACK);
240 P_BUSACK &= ~_BV(BUSACK);
241
242 /* /IOCS1: Input, no pullup */
243 DDR_IOCS1 &= ~_BV(IOCS1);
244 P_IOCS1 &= ~_BV(IOCS1);
245
246 z80_setup_addrbus_tristate();
247 z80_setup_dbus_in();
248
249 zstate = RESET;
250 }
251
252
253 zstate_t z80_bus_state(void)
254 {
255 return zstate;
256 }
257
258
259 static void z80_busreq_hpulse(void)
260 {
261 z80_setup_dbus_in();
262 z80_setup_addrbus_tristate();
263
264 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
265 Z80_O_BUSREQ = 1;
266 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
267 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
268 }
269
270 if (zstate & ZST_ACQUIRED) {
271 while(Z80_I_BUSACK == 1)
272 ;
273 z80_setup_addrbus_active();
274 }
275 }
276
277
278 /*
279
280 + | | | | |
281 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
282 + | | | | |
283 + | 0 | 1 | 2 | 3 |
284 Event + | | | | |
285 ----------------+---------------+---------------+---------------+---------------+
286 | | | | |
287 Reset | 0 | 0 | 0 | 0 |
288 | | | | |
289 | | | | |
290 Request | 1 | | 3 | |
291 | | | | |
292 | | | | |
293 Release | | 0 | | 2 |
294 | | | | |
295 | | | | |
296 Run | 2 | 3 | | |
297 | | | | |
298 | | | | |
299 Restart | | | 2 | 3 |
300 | | | | |
301 | | | | |
302 M_Cycle | | | | 3 |
303 | | | | |
304 | | | | |
305 */
306
307 zstate_t z80_bus_cmd(bus_cmd_t cmd)
308 {
309 switch (cmd) {
310
311 case Reset:
312 z80_setup_dbus_in();
313 z80_setup_addrbus_tristate();
314 Z80_O_RST = 0;
315 Z80_O_BUSREQ = 1;
316 zstate = RESET;
317 break;
318
319 case Request:
320 switch (zstate) {
321 case RESET:
322 Z80_O_BUSREQ = 0;
323 Z80_O_RST = 1;
324 while(Z80_I_BUSACK == 1)
325 ;
326 z80_setup_addrbus_active();
327 zstate = RESET_AQRD;
328 break;
329
330 case RUNNING:
331 Z80_O_BUSREQ = 0;
332 while(Z80_I_BUSACK == 1)
333 ;
334 z80_setup_addrbus_active();
335 zstate = RUNNING_AQRD;
336 break;
337
338 default:
339 break;
340 }
341 break;
342
343 case Release:
344 switch (zstate) {
345 case RESET_AQRD:
346 z80_setup_dbus_in();
347 z80_setup_addrbus_tristate();
348 Z80_O_RST = 0;
349 Z80_O_BUSREQ = 1;
350 zstate = RESET;
351 break;
352 case RUNNING_AQRD:
353 z80_setup_dbus_in();
354 z80_setup_addrbus_tristate();
355 Z80_O_BUSREQ = 1;
356 zstate = RUNNING;
357 break;
358 default:
359 break;
360 }
361 break;
362
363 case Run:
364 switch (zstate) {
365 case RESET:
366 Z80_O_RST = 1;
367 zstate = RUNNING;
368 break;
369
370 case RESET_AQRD:
371 z80_setup_dbus_in();
372 z80_setup_addrbus_tristate();
373 z80_reset_pulse();
374 z80_setup_addrbus_active();
375 zstate = RUNNING_AQRD;
376 break;
377 default:
378 break;
379 }
380 break;
381
382 case Restart:
383 switch (zstate) {
384 case RUNNING:
385 case RUNNING_AQRD:
386 z80_reset_pulse();
387 break;
388 default:
389 break;
390 }
391 break;
392
393 case M_Cycle:
394 switch (zstate) {
395 case RUNNING_AQRD:
396 z80_busreq_hpulse();
397 break;
398 default:
399 break;
400 }
401 }
402 return zstate;
403 }
404
405
406 /*--------------------------------------------------------------------------*/
407
408 static
409 //inline __attribute__ ((always_inline))
410 void z80_setaddress(uint32_t addr)
411 {
412 addr_t x; x.l = addr;
413
414 P_ADL = x.b[0];
415 P_ADH = x.b[1];
416 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
417 }
418
419 void z80_write(uint32_t addr, uint8_t data)
420 {
421 z80_setaddress(addr);
422 Z80_O_MREQ = 0;
423 z80_setup_dbus_out();
424 P_DB = data;
425 P_DB = data;
426 Z80_O_WR = 0;
427 Z80_O_WR = 0;
428 Z80_O_WR = 1;
429 Z80_O_MREQ = 1;
430 }
431
432 uint8_t z80_read(uint32_t addr)
433 {
434 uint8_t data;
435
436 z80_setaddress(addr);
437 Z80_O_MREQ = 0;
438 z80_setup_dbus_in();
439 Z80_O_RD = 0;
440 Z80_O_RD = 0;
441 Z80_O_RD = 0;
442 data = PIN_DB;
443 Z80_O_RD = 1;
444 Z80_O_MREQ = 1;
445
446 return data;
447 }
448
449
450 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
451 {
452 z80_setup_dbus_out();
453 Z80_O_MREQ = 0;
454 while(length--) {
455 z80_setaddress(addr++);
456 P_DB = data;
457 P_DB = data;
458 Z80_O_WR = 0;
459 Z80_O_WR = 0;
460 Z80_O_WR = 1;
461 }
462 Z80_O_MREQ = 1;
463 }
464
465 void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
466 {
467 uint8_t data;
468
469 z80_setup_dbus_out();
470 Z80_O_MREQ = 0;
471 while(length--) {
472 z80_setaddress(dest++);
473 data = *src++;
474 P_DB = data;
475 P_DB = data;
476 Z80_O_WR = 0;
477 Z80_O_WR = 0;
478 Z80_O_WR = 1;
479 }
480 Z80_O_MREQ = 1;
481 }
482
483 /*
484 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
485 017A' rx.in_idx: ds 1 ;
486 017B' rx.out_idx: ds 1 ;
487 017C' rx.buf: ds rx.buf_len ;
488 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
489
490 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
491 018D' tx.in_idx: ds 1 ;
492 018E' tx.out_idx: ds 1 ;
493 018F' tx.buf: ds tx.buf_len ;
494 019E' tx.buf_end equ $-1 ; last byte
495 */
496
497
498 typedef struct __attribute__((packed)) {
499 uint8_t mask;
500 uint8_t in_idx;
501 uint8_t out_idx;
502 uint8_t buf[];
503 } zfifo_t;
504
505
506
507 #define FIFO_BUFSIZE_MASK -3
508 #define FIFO_INDEX_IN -2
509 #define FIFO_INDEX_OUT -1
510
511
512 static struct {
513 uint32_t base;
514 uint8_t idx_out,
515 idx_in,
516 mask;
517 } fifo_dsc[NUM_FIFOS];
518
519
520 void z80_memfifo_init(const fifo_t f, uint32_t adr)
521 {
522
523 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
524
525 fifo_dsc[f].base = adr;
526
527 z80_bus_cmd(Request);
528
529 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
530 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
531 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
532
533 z80_bus_cmd(Release);
534 }
535
536
537 int z80_memfifo_is_empty(const fifo_t f)
538 {
539 int rc = 1;
540
541 if (fifo_dsc[f].base != 0) {
542
543 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
544 uint8_t idx;
545
546 z80_bus_cmd(Request);
547 idx = z80_read(adr);
548 z80_bus_cmd(Release);
549 rc = idx == fifo_dsc[f].idx_out;
550 }
551
552 return rc;
553 }
554
555 int z80_memfifo_is_full(const fifo_t f)
556 {
557 int rc = 1;
558
559 if (fifo_dsc[f].base != 0) {
560 z80_bus_cmd(Request);
561 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
562 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
563 z80_bus_cmd(Release);
564 }
565 return rc;
566 }
567
568 uint8_t z80_memfifo_getc(const fifo_t f)
569 {
570 uint8_t rc, idx;
571
572 while (z80_memfifo_is_empty(f))
573 ;
574
575 z80_bus_cmd(Request);
576 idx = fifo_dsc[f].idx_out;
577 rc = z80_read(fifo_dsc[f].base+idx);
578 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
579 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
580 z80_bus_cmd(Release);
581
582 return rc;
583 }
584
585
586 void z80_memfifo_putc(fifo_t f, uint8_t val)
587 {
588 int idx;
589
590 while (z80_memfifo_is_full(f))
591 ;
592
593 z80_bus_cmd(Request);
594 idx = fifo_dsc[f].idx_in;
595 z80_write(fifo_dsc[f].base+idx, val);
596 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
597 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
598 z80_bus_cmd(Release);
599 }
600
601 /*--------------------------------------------------------------------------*/
602 /*
603 TODO: Rewrite msg_fifo routines for AVR
604 */
605
606 static struct {
607 uint32_t base;
608 //uint8_t idx_out, idx_in;
609 uint16_t count;
610 uint8_t buf[256];
611 } msg_fifo;
612
613 /*--------------------------------------------------------------------------*/
614
615 #if 0
616
617 static void tim1_setup(void)
618 {
619 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
620 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
621
622 TIM1_CR1 = 0;
623
624 TIM1_SMCR = 0
625 /* | TIM_SMCR_ETP */
626 /* | TIM_SMCR_ETF_CK_INT_N_2 */
627 | TIM_SMCR_TS_ETRF
628 | TIM_SMCR_SMS_OFF
629 ;
630
631 TIM1_DIER = TIM_DIER_TDE;
632
633
634 TIM1_CCMR1 = 0
635 | TIM_CCMR1_OC1M_FORCE_LOW
636 | TIM_CCMR1_CC1S_OUT;
637
638 TIM1_SMCR |= TIM_SMCR_SMS_TM;
639 }
640
641 #endif
642
643 /*--------------------------------------------------------------------------*/
644
645 void z80_setup_msg_fifo(void)
646 {
647 // gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
648 // GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
649
650 //...
651
652 // msg_fifo.count = NELEMS(msg_fifo.buf);
653 msg_fifo.count = 0;
654 msg_fifo.base = 0;
655
656 }
657
658
659 void z80_init_msg_fifo(uint32_t addr)
660 {
661
662 DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
663
664 z80_bus_cmd(Request);
665 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
666 z80_bus_cmd(Release);
667 msg_fifo.base = addr;
668 }
669
670
671 int z80_msg_fifo_getc(void)
672 {
673 int c = -1;
674
675 #if 0
676 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
677 c = msg_fifo.buf[msg_fifo.count];
678 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
679 msg_fifo.count = 0;
680
681 if (msg_fifo.base != 0) {
682 z80_bus_cmd(Request);
683 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
684 z80_bus_cmd(Release);
685 }
686 }
687 #endif
688
689 return c;
690 }