]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
Command 'go <startaddr>' works now
[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
88 #define P_MREQ PORTD
89 #define MREQ 4
90 #define DDR_MREQ DDRD
91 #define P_RD PORTD
92 #define RD 3
93 #define P_WR PORTD
94 #define WR 2
95 #define P_BUSREQ PORTD
96 #define BUSREQ 7
97 #define DDR_BUSREQ DDRD
98 #define P_BUSACK PORTD
99 #define PIN_BUSACK PIND
100 #define BUSACK 6
101 #define DDR_BUSACK DDRD
102 //#define P_HALT PORTA
103 //#define HALT 12
104 #define P_IOCS1 PORTE
105 #define IOCS1 5
106 #define DDR_IOCS1 DDRE
107 //#define P_NMI PORTB
108 //#define NMI 7
109 #define P_RST PORTD
110 #define DDR_RST DDRD
111 #define RST 5
112
113
114 #define P_DB PORTF
115 #define PIN_DB PINF
116 #define DDR_DB DDRF
117
118 #define P_ADL PORTA
119 #define P_ADH PORTC
120 #define P_ADB PORTE
121 #define PIN_ADB PINE
122 #define DDR_ADL DDRA
123 #define DDR_ADH DDRC
124 #define DDR_ADB DDRE
125
126 #define ADB_WIDTH 3
127 #define ADB_SHIFT 2
128 //#define ADB_PORT PORTE
129
130
131 #define Z80_O_MREQ SBIT(P_MREQ, 4)
132 #define Z80_O_RD SBIT(P_RD, 3)
133 #define Z80_O_WR SBIT(P_WR, 2)
134 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
135 //#define Z80_O_NMI SBIT(P_NMI, )
136 #define Z80_O_RST SBIT(P_RST, 5)
137 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
138 //#define Z80_I_HALT SBIT(P_HALT, )
139
140
141 #define MASK(n) ((1<<(n))-1)
142 #define SMASK(w,s) (MASK(w) << (s))
143
144
145
146 typedef union {
147 uint32_t l;
148 uint16_t w[2];
149 uint8_t b[4];
150 } addr_t;
151
152
153 static zstate_t zstate;
154
155 /*--------------------------------------------------------------------------*/
156
157
158 static void z80_setup_addrbus_tristate(void)
159 {
160 /* /MREQ, /RD, /WR: Input, no pullup */
161 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
162 Z80_O_MREQ = 0;
163 Z80_O_RD = 0;
164 Z80_O_WR = 0;
165
166 P_ADL = 0;
167 DDR_ADL = 0;
168 P_ADH = 0;
169 DDR_ADH = 0;
170 PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
171 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
172 }
173
174
175 static void z80_setup_addrbus_active(void)
176 {
177 /* /MREQ, /RD, /WR: Output and high */
178 Z80_O_MREQ = 1;
179 Z80_O_RD = 1;
180 Z80_O_WR = 1;
181 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
182
183 DDR_ADL = 0xff;
184 DDR_ADH = 0xff;
185 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
186 }
187
188
189
190 static void z80_setup_dbus_in(void)
191 {
192 DDR_DB = 0;
193 P_DB = 0;
194 }
195
196 static void z80_setup_dbus_out(void)
197 {
198 DDR_DB = 0xff;
199 }
200
201 void z80_setup_bus(void)
202 {
203 /* /ZRESET: Output and low */
204 Z80_O_RST = 0;
205 DDR_RST |= _BV(RST);
206
207 /* /BUSREQ: Output and high */
208 Z80_O_BUSREQ = 1;
209 DDR_BUSREQ |= _BV(BUSREQ);
210
211 /* /BUSACK: Input, no pullup */
212 DDR_BUSACK &= ~_BV(BUSACK);
213 P_BUSACK &= ~_BV(BUSACK);
214
215 /* /IOCS1: Input, no pullup */
216 DDR_IOCS1 &= ~_BV(IOCS1);
217 P_IOCS1 &= ~_BV(IOCS1);
218
219 z80_setup_addrbus_tristate();
220 z80_setup_dbus_in();
221
222 zstate = RESET;
223 // Stat &= ~S_Z180_RUNNING;
224 }
225
226 /*--------------------------------------------------------------------------*/
227 #if 0
228 switch (zstate) {
229 case RESET:
230 break;
231 case RESET_AQRD:
232 break;
233 case RUN:
234 break;
235 case RUN_AQRD:
236 break;
237 }
238 #endif
239 /*--------------------------------------------------------------------------*/
240
241 #if 0
242 void z80_busreq(level_t level)
243 {
244 Z80_O_BUSREQ = level;
245 }
246
247 int z80_stat_reset(void)
248 {
249 // return Z80_O_RESET;
250 }
251
252 int z80_stat_halt(void)
253 {
254 return Z80_I_HALT;
255 }
256 #endif
257
258
259 zstate_t z80_runstate(void)
260 {
261 return zstate;
262 }
263
264 void z80_reset(void)
265 {
266 #if DEBUG
267 zstate_t old = zstate;
268 #endif
269 z80_setup_dbus_in();
270 z80_setup_addrbus_tristate();
271 Z80_O_RST = 0;
272 Z80_O_BUSREQ = 1;
273 zstate = RESET;
274
275 debug("z80_reset: state: %02x --> %02x\n", old, zstate);
276 }
277
278 void z80_reset_pulse(void)
279 {
280 #if DEBUG
281 zstate_t old = zstate;
282 #endif
283 switch (zstate) {
284 case RESET:
285 case RESET_AQRD:
286 break;
287
288 case RUN:
289 case RUN_AQRD:
290 Z80_O_RST = 0;
291 _delay_us(10);
292 Z80_O_RST = 1;
293 break;
294 }
295
296 debug("z80_reset_pulse: state: %02x --> %02x\n", old, zstate);
297 }
298
299 void z80_request_bus(void)
300 {
301 #if DEBUG
302 zstate_t old = zstate;
303 #endif
304
305 switch (zstate) {
306 case RESET:
307 Z80_O_BUSREQ = 0;
308 Z80_O_RST = 1;
309 while(Z80_I_BUSACK == 1)
310 ;
311 z80_setup_addrbus_active();
312 zstate = RESET_AQRD;
313 break;
314
315 case RESET_AQRD:
316 break;
317
318 case RUN:
319 Z80_O_BUSREQ = 0;
320 while(Z80_I_BUSACK == 1);
321 z80_setup_addrbus_active();
322 zstate = RUN_AQRD;
323 break;
324
325 case RUN_AQRD:
326 break;
327 }
328 debug("z80_request_bus: state: %02x --> %02x\n", old, zstate);
329 }
330
331 void z80_release_bus(void)
332 {
333 #if DEBUG
334 zstate_t old = zstate;
335 #endif
336 switch (zstate) {
337 case RESET:
338 break;
339 case RESET_AQRD:
340 z80_setup_dbus_in();
341 z80_setup_addrbus_tristate();
342 Z80_O_RST = 0;
343 Z80_O_BUSREQ = 1;
344 zstate = RESET;
345 break;
346 case RUN:
347 break;
348 case RUN_AQRD:
349 z80_setup_dbus_in();
350 z80_setup_addrbus_tristate();
351 Z80_O_BUSREQ = 1;
352 zstate = RUN;
353 break;
354 }
355
356 debug("z80_release_bus: state: %02x --> %02x\n", old, zstate);
357 }
358
359 /*
360 * Do nothing, if we have the bus allready
361 *
362 * return previous state
363 */
364 zstate_t z80_request_bus_save(void)
365 {
366 zstate_t state;
367
368 state = z80_runstate();
369 if (!(state & ZST_ACQUIRED))
370 z80_request_bus();
371
372 return state;
373 }
374
375 /*
376 * Do nothing, if we had the bus before
377 */
378 void z80_release_bus_save(zstate_t prev)
379 {
380 if (!(prev & ZST_ACQUIRED))
381 z80_release_bus();
382 }
383
384 void z80_run(void)
385 {
386 #if DEBUG
387 zstate_t old = zstate;
388 #endif
389 switch (zstate) {
390 case RESET:
391 Z80_O_RST = 1;
392 zstate = RUN;
393 break;
394
395 case RESET_AQRD:
396 z80_setup_dbus_in();
397 z80_setup_addrbus_tristate();
398 Z80_O_RST = 0;
399 _delay_us(10);
400 Z80_O_RST = 1;
401 z80_setup_addrbus_active();
402 zstate = RUN_AQRD;
403 break;
404
405 case RUN:
406 break;
407 case RUN_AQRD:
408 break;
409 }
410
411 debug("z80_run: state: %02x --> %02x\n", old, zstate);
412 }
413
414 void z80_busreq_hpulse(void)
415 {
416 z80_setup_dbus_in();
417 z80_setup_addrbus_tristate();
418
419 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
420 Z80_O_BUSREQ = 1;
421 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
422 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
423 }
424
425 if (zstate & ZST_ACQUIRED) {
426 while(Z80_I_BUSACK == 1)
427 ;
428 z80_setup_addrbus_active();
429 }
430 }
431
432 /*--------------------------------------------------------------------------*/
433
434 static
435 //inline __attribute__ ((always_inline))
436 void z80_setaddress(uint32_t addr)
437 {
438 addr_t x; x.l = addr;
439
440 P_ADL = x.b[0];
441 P_ADH = x.b[1];
442 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
443 }
444
445 void z80_write(uint32_t addr, uint8_t data)
446 {
447 z80_setaddress(addr);
448 Z80_O_MREQ = 0;
449 z80_setup_dbus_out();
450 P_DB = data;
451 P_DB = data;
452 Z80_O_WR = 0;
453 Z80_O_WR = 0;
454 Z80_O_WR = 1;
455 Z80_O_MREQ = 1;
456 }
457
458 uint8_t z80_read(uint32_t addr)
459 {
460 uint8_t data;
461
462 z80_setaddress(addr);
463 Z80_O_MREQ = 0;
464 z80_setup_dbus_in();
465 Z80_O_RD = 0;
466 Z80_O_RD = 0;
467 Z80_O_RD = 0;
468 data = PIN_DB;
469 Z80_O_RD = 1;
470 Z80_O_MREQ = 1;
471
472 return data;
473 }
474
475
476 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
477 {
478 z80_setup_dbus_out();
479 Z80_O_MREQ = 0;
480 while(length--) {
481 z80_setaddress(addr++);
482 P_DB = data;
483 P_DB = data;
484 Z80_O_WR = 0;
485 Z80_O_WR = 0;
486 Z80_O_WR = 1;
487 }
488 Z80_O_MREQ = 1;
489 }
490
491 void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
492 {
493 uint8_t data;
494
495 z80_setup_dbus_out();
496 Z80_O_MREQ = 0;
497 while(length--) {
498 z80_setaddress(dest++);
499 data = *src++;
500 P_DB = data;
501 P_DB = data;
502 Z80_O_WR = 0;
503 Z80_O_WR = 0;
504 Z80_O_WR = 1;
505 }
506 Z80_O_MREQ = 1;
507 }
508
509 /*
510 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
511 017A' rx.in_idx: ds 1 ;
512 017B' rx.out_idx: ds 1 ;
513 017C' rx.buf: ds rx.buf_len ;
514 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
515
516 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
517 018D' tx.in_idx: ds 1 ;
518 018E' tx.out_idx: ds 1 ;
519 018F' tx.buf: ds tx.buf_len ;
520 019E' tx.buf_end equ $-1 ; last byte
521 */
522
523
524 typedef struct __attribute__((packed)) {
525 uint8_t mask;
526 uint8_t in_idx;
527 uint8_t out_idx;
528 uint8_t buf[];
529 } zfifo_t;
530
531
532
533 #define FIFO_BUFSIZE_MASK -3
534 #define FIFO_INDEX_IN -2
535 #define FIFO_INDEX_OUT -1
536
537
538 static struct {
539 uint32_t base;
540 uint8_t idx_out,
541 idx_in,
542 mask;
543 } fifo_dsc[NUM_FIFOS];
544
545
546 void z80_memfifo_init(const fifo_t f, uint32_t adr)
547 {
548
549 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
550
551 fifo_dsc[f].base = adr;
552
553 z80_request_bus();
554
555 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
556 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
557 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
558
559 z80_release_bus();
560 }
561
562
563 int z80_memfifo_is_empty(const fifo_t f)
564 {
565 int rc = 1;
566
567 if (fifo_dsc[f].base != 0) {
568
569 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
570 uint8_t idx;
571
572 z80_request_bus();
573 idx = z80_read(adr);
574 z80_release_bus();
575 rc = idx == fifo_dsc[f].idx_out;
576 }
577
578 return rc;
579 }
580
581 int z80_memfifo_is_full(const fifo_t f)
582 {
583 int rc = 1;
584
585 if (fifo_dsc[f].base != 0) {
586 z80_request_bus();
587 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
588 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
589 z80_release_bus();
590 }
591 return rc;
592 }
593
594 uint8_t z80_memfifo_getc(const fifo_t f)
595 {
596 uint8_t rc, idx;
597
598 while (z80_memfifo_is_empty(f))
599 ;
600
601 z80_request_bus();
602 idx = fifo_dsc[f].idx_out;
603 rc = z80_read(fifo_dsc[f].base+idx);
604 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
605 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
606 z80_release_bus();
607
608 return rc;
609 }
610
611
612 void z80_memfifo_putc(fifo_t f, uint8_t val)
613 {
614 int idx;
615
616 while (z80_memfifo_is_full(f))
617 ;
618
619 z80_request_bus();
620 idx = fifo_dsc[f].idx_in;
621 z80_write(fifo_dsc[f].base+idx, val);
622 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
623 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
624 z80_release_bus();
625 }
626
627 /*--------------------------------------------------------------------------*/
628 /*
629 TODO: Rewrite msg_fifo routines for AVR
630 */
631
632 static struct {
633 uint32_t base;
634 //uint8_t idx_out, idx_in;
635 uint16_t count;
636 uint8_t buf[256];
637 } msg_fifo;
638
639 /*--------------------------------------------------------------------------*/
640
641 #if 0
642
643 static void tim1_setup(void)
644 {
645 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
646 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
647
648 TIM1_CR1 = 0;
649
650 TIM1_SMCR = 0
651 /* | TIM_SMCR_ETP */
652 /* | TIM_SMCR_ETF_CK_INT_N_2 */
653 | TIM_SMCR_TS_ETRF
654 | TIM_SMCR_SMS_OFF
655 ;
656
657 TIM1_DIER = TIM_DIER_TDE;
658
659
660 TIM1_CCMR1 = 0
661 | TIM_CCMR1_OC1M_FORCE_LOW
662 | TIM_CCMR1_CC1S_OUT;
663
664 TIM1_SMCR |= TIM_SMCR_SMS_TM;
665 }
666
667 #endif
668
669 /*--------------------------------------------------------------------------*/
670
671 void z80_setup_msg_fifo(void)
672 {
673 // gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
674 // GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
675
676 //...
677
678 // msg_fifo.count = NELEMS(msg_fifo.buf);
679 msg_fifo.count = 0;
680 msg_fifo.base = 0;
681
682 }
683
684
685 void z80_init_msg_fifo(uint32_t addr)
686 {
687
688 DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
689
690 z80_request_bus();
691 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
692 z80_release_bus();
693 msg_fifo.base = addr;
694 }
695
696
697 int z80_msg_fifo_getc(void)
698 {
699 int c = -1;
700
701 #if 0
702 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
703 c = msg_fifo.buf[msg_fifo.count];
704 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
705 msg_fifo.count = 0;
706
707 if (msg_fifo.base != 0) {
708 z80_request_bus();
709 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
710 z80_release_bus();
711 }
712 }
713 #endif
714
715 return c;
716 }