]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
Programmable Z180 clock, clock command
[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 static
161 void z80_setup_clock(void)
162 {
163 /* ZCLK: Output and low */
164 DDR_ZCLK |= _BV(ZCLK);
165 Z80_O_ZCLK = 0;
166
167 DDRB |= _BV(6); /* Debug */
168 PORTB |= _BV(6); /* Debug */
169
170 PRR0 &= ~_BV(PRTIM1);
171
172 /* Timer1: CTC: Toggle OC1C on compare match */
173 OCR1A = 0;
174 OCR1C = 0;
175 TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
176 TCCR1B = (0b01 << WGM12) | (0b001 << CS10);
177 }
178
179
180 int z80_clock_set(unsigned long freq)
181 {
182 unsigned long ocrval = F_CPU / freq / 2;
183 uint8_t prescale = 0;
184
185 while (ocrval > (1L<<16)) {
186 prescale++;
187 if (prescale < 3)
188 ocrval = ocrval / 8;
189 else
190 ocrval = ocrval / 4;
191 }
192
193 if ((ocrval == 0) || (prescale > 4))
194 return -1;
195
196 ocrval -= 1;
197
198 PINB |= _BV(6); /* Debug */
199
200 /* Stop Timer */
201 TCCR1B = (0b01 << WGM12) | (0b000 << CS10);
202 TCNT1 = 0;
203
204 OCR1A = ocrval;
205 OCR1CL = ocrval;
206 TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
207 TCCR1B = (0b01 << WGM12) | ((prescale+1) << CS10);
208
209 if (ocrval == 0) {
210 // TCCR1C |= _BV(FOC1C);
211 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
212 TCNT1 = 0xFFFF;
213 }
214 }
215
216 PINB |= _BV(6); /* Debug */
217
218 return 0;
219 }
220
221 uint32_t z80_clock_get(void)
222 {
223 uint32_t count = (OCR1A + 1L) * 2;
224 uint8_t pre = (TCCR1B & 7) - 1;
225
226 while (pre) {
227 if (pre > 2)
228 count *= 4;
229 else
230 count *= 8;
231 pre--;
232
233 }
234
235 return F_CPU/count;
236 }
237
238
239
240 static void z80_addrbus_set_tristate(void)
241 {
242 /* /MREQ, /RD, /WR: Input, no pullup */
243 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
244 Z80_O_MREQ = 0;
245 Z80_O_RD = 0;
246 Z80_O_WR = 0;
247
248 P_ADL = 0;
249 DDR_ADL = 0;
250 P_ADH = 0;
251 DDR_ADH = 0;
252 PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
253 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
254 }
255
256
257 static void z80_addrbus_set_active(void)
258 {
259 /* /MREQ, /RD, /WR: Output and high */
260 Z80_O_MREQ = 1;
261 Z80_O_RD = 1;
262 Z80_O_WR = 1;
263 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
264
265 DDR_ADL = 0xff;
266 DDR_ADH = 0xff;
267 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
268 }
269
270
271 static void z80_dbus_set_in(void)
272 {
273 DDR_DB = 0;
274 P_DB = 0;
275 }
276
277
278 static void z80_dbus_set_out(void)
279 {
280 DDR_DB = 0xff;
281 }
282
283
284 static void z80_reset_pulse(void)
285 {
286 Z80_O_RST = 0;
287 _delay_us(10);
288 Z80_O_RST = 1;
289 }
290
291
292 void z80_setup_bus(void)
293 {
294 z80_setup_clock();
295
296 /* /ZRESET: Output and low */
297 Z80_O_RST = 0;
298 DDR_RST |= _BV(RST);
299
300 /* /BUSREQ: Output and high */
301 Z80_O_BUSREQ = 1;
302 DDR_BUSREQ |= _BV(BUSREQ);
303
304 /* /BUSACK: Input, no pullup */
305 DDR_BUSACK &= ~_BV(BUSACK);
306 P_BUSACK &= ~_BV(BUSACK);
307
308 /* /IOCS1: Input, no pullup */
309 DDR_IOCS1 &= ~_BV(IOCS1);
310 P_IOCS1 &= ~_BV(IOCS1);
311
312 z80_addrbus_set_tristate();
313 z80_dbus_set_in();
314
315 zstate = RESET;
316 }
317
318
319 zstate_t z80_bus_state(void)
320 {
321 return zstate;
322 }
323
324
325 static void z80_busreq_hpulse(void)
326 {
327 z80_dbus_set_in();
328 z80_addrbus_set_tristate();
329
330 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
331 Z80_O_BUSREQ = 1;
332 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
333 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
334 }
335
336 if (zstate & ZST_ACQUIRED) {
337 while(Z80_I_BUSACK == 1)
338 ;
339 z80_addrbus_set_active();
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_tristate();
380 Z80_O_RST = 0;
381 Z80_O_BUSREQ = 1;
382 zstate = RESET;
383 break;
384
385 case Request:
386 switch (zstate) {
387 case RESET:
388 Z80_O_BUSREQ = 0;
389 Z80_O_RST = 1;
390 while(Z80_I_BUSACK == 1)
391 ;
392 z80_addrbus_set_active();
393 zstate = RESET_AQRD;
394 break;
395
396 case RUNNING:
397 Z80_O_BUSREQ = 0;
398 while(Z80_I_BUSACK == 1)
399 ;
400 z80_addrbus_set_active();
401 zstate = RUNNING_AQRD;
402 break;
403
404 default:
405 break;
406 }
407 break;
408
409 case Release:
410 switch (zstate) {
411 case RESET_AQRD:
412 z80_dbus_set_in();
413 z80_addrbus_set_tristate();
414 Z80_O_RST = 0;
415 Z80_O_BUSREQ = 1;
416 zstate = RESET;
417 break;
418 case RUNNING_AQRD:
419 z80_dbus_set_in();
420 z80_addrbus_set_tristate();
421 Z80_O_BUSREQ = 1;
422 zstate = RUNNING;
423 break;
424 default:
425 break;
426 }
427 break;
428
429 case Run:
430 switch (zstate) {
431 case RESET:
432 Z80_O_RST = 1;
433 zstate = RUNNING;
434 break;
435
436 case RESET_AQRD:
437 z80_dbus_set_in();
438 z80_addrbus_set_tristate();
439 z80_reset_pulse();
440 z80_addrbus_set_active();
441 zstate = RUNNING_AQRD;
442 break;
443 default:
444 break;
445 }
446 break;
447
448 case Restart:
449 switch (zstate) {
450 case RUNNING:
451 case RUNNING_AQRD:
452 z80_reset_pulse();
453 break;
454 default:
455 break;
456 }
457 break;
458
459 case M_Cycle:
460 switch (zstate) {
461 case RUNNING_AQRD:
462 z80_busreq_hpulse();
463 break;
464 default:
465 break;
466 }
467 }
468 return zstate;
469 }
470
471
472 /*--------------------------------------------------------------------------*/
473
474 static
475 //inline __attribute__ ((always_inline))
476 void z80_setaddress(uint32_t addr)
477 {
478 addr_t x; x.l = addr;
479
480 P_ADL = x.b[0];
481 P_ADH = x.b[1];
482 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
483 }
484
485 void z80_write(uint32_t addr, uint8_t data)
486 {
487 z80_setaddress(addr);
488 Z80_O_MREQ = 0;
489 z80_dbus_set_out();
490 P_DB = data;
491 P_DB = data;
492 Z80_O_WR = 0;
493 Z80_O_WR = 0;
494 Z80_O_WR = 1;
495 Z80_O_MREQ = 1;
496 }
497
498 uint8_t z80_read(uint32_t addr)
499 {
500 uint8_t data;
501
502 z80_setaddress(addr);
503 Z80_O_MREQ = 0;
504 z80_dbus_set_in();
505 Z80_O_RD = 0;
506 Z80_O_RD = 0;
507 Z80_O_RD = 0;
508 data = PIN_DB;
509 Z80_O_RD = 1;
510 Z80_O_MREQ = 1;
511
512 return data;
513 }
514
515
516 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
517 {
518 z80_dbus_set_out();
519 Z80_O_MREQ = 0;
520 while(length--) {
521 z80_setaddress(addr++);
522 P_DB = data;
523 P_DB = data;
524 Z80_O_WR = 0;
525 Z80_O_WR = 0;
526 Z80_O_WR = 1;
527 }
528 Z80_O_MREQ = 1;
529 }
530
531 void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
532 {
533 uint8_t data;
534
535 z80_dbus_set_out();
536 Z80_O_MREQ = 0;
537 while(length--) {
538 z80_setaddress(dest++);
539 data = *src++;
540 P_DB = data;
541 P_DB = data;
542 Z80_O_WR = 0;
543 Z80_O_WR = 0;
544 Z80_O_WR = 1;
545 }
546 Z80_O_MREQ = 1;
547 }
548
549 /*
550 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
551 017A' rx.in_idx: ds 1 ;
552 017B' rx.out_idx: ds 1 ;
553 017C' rx.buf: ds rx.buf_len ;
554 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
555
556 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
557 018D' tx.in_idx: ds 1 ;
558 018E' tx.out_idx: ds 1 ;
559 018F' tx.buf: ds tx.buf_len ;
560 019E' tx.buf_end equ $-1 ; last byte
561 */
562
563
564 typedef struct __attribute__((packed)) {
565 uint8_t mask;
566 uint8_t in_idx;
567 uint8_t out_idx;
568 uint8_t buf[];
569 } zfifo_t;
570
571
572
573 #define FIFO_BUFSIZE_MASK -3
574 #define FIFO_INDEX_IN -2
575 #define FIFO_INDEX_OUT -1
576
577
578 static struct {
579 uint32_t base;
580 uint8_t idx_out,
581 idx_in,
582 mask;
583 } fifo_dsc[NUM_FIFOS];
584
585
586 void z80_memfifo_init(const fifo_t f, uint32_t adr)
587 {
588
589 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
590
591 fifo_dsc[f].base = adr;
592
593 z80_bus_cmd(Request);
594
595 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
596 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
597 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
598
599 z80_bus_cmd(Release);
600 }
601
602
603 int z80_memfifo_is_empty(const fifo_t f)
604 {
605 int rc = 1;
606
607 if (fifo_dsc[f].base != 0) {
608
609 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
610 uint8_t idx;
611
612 z80_bus_cmd(Request);
613 idx = z80_read(adr);
614 z80_bus_cmd(Release);
615 rc = idx == fifo_dsc[f].idx_out;
616 }
617
618 return rc;
619 }
620
621 int z80_memfifo_is_full(const fifo_t f)
622 {
623 int rc = 1;
624
625 if (fifo_dsc[f].base != 0) {
626 z80_bus_cmd(Request);
627 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
628 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
629 z80_bus_cmd(Release);
630 }
631 return rc;
632 }
633
634 uint8_t z80_memfifo_getc(const fifo_t f)
635 {
636 uint8_t rc, idx;
637
638 while (z80_memfifo_is_empty(f))
639 ;
640
641 z80_bus_cmd(Request);
642 idx = fifo_dsc[f].idx_out;
643 rc = z80_read(fifo_dsc[f].base+idx);
644 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
645 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
646 z80_bus_cmd(Release);
647
648 return rc;
649 }
650
651
652 void z80_memfifo_putc(fifo_t f, uint8_t val)
653 {
654 int idx;
655
656 while (z80_memfifo_is_full(f))
657 ;
658
659 z80_bus_cmd(Request);
660 idx = fifo_dsc[f].idx_in;
661 z80_write(fifo_dsc[f].base+idx, val);
662 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
663 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
664 z80_bus_cmd(Release);
665 }
666
667 /*--------------------------------------------------------------------------*/
668 /*
669 TODO: Rewrite msg_fifo routines for AVR
670 */
671
672 static struct {
673 uint32_t base;
674 //uint8_t idx_out, idx_in;
675 uint16_t count;
676 uint8_t buf[256];
677 } msg_fifo;
678
679 /*--------------------------------------------------------------------------*/
680
681 #if 0
682
683 static void tim1_setup(void)
684 {
685 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
686 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
687
688 TIM1_CR1 = 0;
689
690 TIM1_SMCR = 0
691 /* | TIM_SMCR_ETP */
692 /* | TIM_SMCR_ETF_CK_INT_N_2 */
693 | TIM_SMCR_TS_ETRF
694 | TIM_SMCR_SMS_OFF
695 ;
696
697 TIM1_DIER = TIM_DIER_TDE;
698
699
700 TIM1_CCMR1 = 0
701 | TIM_CCMR1_OC1M_FORCE_LOW
702 | TIM_CCMR1_CC1S_OUT;
703
704 TIM1_SMCR |= TIM_SMCR_SMS_TM;
705 }
706
707 #endif
708
709 /*--------------------------------------------------------------------------*/
710
711 void z80_setup_msg_fifo(void)
712 {
713 // gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
714 // GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
715
716 //...
717
718 // msg_fifo.count = NELEMS(msg_fifo.buf);
719 msg_fifo.count = 0;
720 msg_fifo.base = 0;
721
722 }
723
724
725 void z80_init_msg_fifo(uint32_t addr)
726 {
727
728 DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
729
730 z80_bus_cmd(Request);
731 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
732 z80_bus_cmd(Release);
733 msg_fifo.base = addr;
734 }
735
736
737 int z80_msg_fifo_getc(void)
738 {
739 int c = -1;
740
741 #if 0
742 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
743 c = msg_fifo.buf[msg_fifo.count];
744 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
745 msg_fifo.count = 0;
746
747 if (msg_fifo.base != 0) {
748 z80_bus_cmd(Request);
749 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
750 z80_bus_cmd(Release);
751 }
752 }
753 #endif
754
755 return c;
756 }