]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
env in ram
[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 static void z80_setup_dbus_in(void)
190 {
191 DDR_DB = 0;
192 P_DB = 0;
193 }
194
195
196 static void z80_setup_dbus_out(void)
197 {
198 DDR_DB = 0xff;
199 }
200
201
202 static void z80_reset_pulse(void)
203 {
204 Z80_O_RST = 0;
205 _delay_us(10);
206 Z80_O_RST = 1;
207 }
208
209
210 void z80_setup_bus(void)
211 {
212 /* /ZRESET: Output and low */
213 Z80_O_RST = 0;
214 DDR_RST |= _BV(RST);
215
216 /* /BUSREQ: Output and high */
217 Z80_O_BUSREQ = 1;
218 DDR_BUSREQ |= _BV(BUSREQ);
219
220 /* /BUSACK: Input, no pullup */
221 DDR_BUSACK &= ~_BV(BUSACK);
222 P_BUSACK &= ~_BV(BUSACK);
223
224 /* /IOCS1: Input, no pullup */
225 DDR_IOCS1 &= ~_BV(IOCS1);
226 P_IOCS1 &= ~_BV(IOCS1);
227
228 z80_setup_addrbus_tristate();
229 z80_setup_dbus_in();
230
231 zstate = RESET;
232 }
233
234
235 zstate_t z80_bus_state(void)
236 {
237 return zstate;
238 }
239
240
241 static void z80_busreq_hpulse(void)
242 {
243 z80_setup_dbus_in();
244 z80_setup_addrbus_tristate();
245
246 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
247 Z80_O_BUSREQ = 1;
248 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
249 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
250 }
251
252 if (zstate & ZST_ACQUIRED) {
253 while(Z80_I_BUSACK == 1)
254 ;
255 z80_setup_addrbus_active();
256 }
257 }
258
259
260 /*
261
262 + | | | | |
263 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
264 + | | | | |
265 + | 0 | 1 | 2 | 3 |
266 Event + | | | | |
267 ----------------+---------------+---------------+---------------+---------------+
268 | | | | |
269 Reset | 0 | 0 | 0 | 0 |
270 | | | | |
271 | | | | |
272 Request | 1 | | 3 | |
273 | | | | |
274 | | | | |
275 Release | | 0 | | 2 |
276 | | | | |
277 | | | | |
278 Run | 2 | 3 | | |
279 | | | | |
280 | | | | |
281 Restart | | | 2 | 3 |
282 | | | | |
283 | | | | |
284 M_Cycle | | | | 3 |
285 | | | | |
286 | | | | |
287 */
288
289 zstate_t z80_bus_cmd(bus_cmd_t cmd)
290 {
291 switch (cmd) {
292
293 case Reset:
294 z80_setup_dbus_in();
295 z80_setup_addrbus_tristate();
296 Z80_O_RST = 0;
297 Z80_O_BUSREQ = 1;
298 zstate = RESET;
299 break;
300
301 case Request:
302 switch (zstate) {
303 case RESET:
304 Z80_O_BUSREQ = 0;
305 Z80_O_RST = 1;
306 while(Z80_I_BUSACK == 1)
307 ;
308 z80_setup_addrbus_active();
309 zstate = RESET_AQRD;
310 break;
311
312 case RUNNING:
313 Z80_O_BUSREQ = 0;
314 while(Z80_I_BUSACK == 1)
315 ;
316 z80_setup_addrbus_active();
317 zstate = RUNNING_AQRD;
318 break;
319
320 default:
321 break;
322 }
323 break;
324
325 case Release:
326 switch (zstate) {
327 case RESET_AQRD:
328 z80_setup_dbus_in();
329 z80_setup_addrbus_tristate();
330 Z80_O_RST = 0;
331 Z80_O_BUSREQ = 1;
332 zstate = RESET;
333 break;
334 case RUNNING_AQRD:
335 z80_setup_dbus_in();
336 z80_setup_addrbus_tristate();
337 Z80_O_BUSREQ = 1;
338 zstate = RUNNING;
339 break;
340 default:
341 break;
342 }
343 break;
344
345 case Run:
346 switch (zstate) {
347 case RESET:
348 Z80_O_RST = 1;
349 zstate = RUNNING;
350 break;
351
352 case RESET_AQRD:
353 z80_setup_dbus_in();
354 z80_setup_addrbus_tristate();
355 z80_reset_pulse();
356 z80_setup_addrbus_active();
357 zstate = RUNNING_AQRD;
358 break;
359 default:
360 break;
361 }
362 break;
363
364 case Restart:
365 switch (zstate) {
366 case RUNNING:
367 case RUNNING_AQRD:
368 z80_reset_pulse();
369 break;
370 default:
371 break;
372 }
373 break;
374
375 case M_Cycle:
376 switch (zstate) {
377 case RUNNING_AQRD:
378 z80_busreq_hpulse();
379 break;
380 default:
381 break;
382 }
383 }
384 return zstate;
385 }
386
387
388 /*--------------------------------------------------------------------------*/
389
390 static
391 //inline __attribute__ ((always_inline))
392 void z80_setaddress(uint32_t addr)
393 {
394 addr_t x; x.l = addr;
395
396 P_ADL = x.b[0];
397 P_ADH = x.b[1];
398 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
399 }
400
401 void z80_write(uint32_t addr, uint8_t data)
402 {
403 z80_setaddress(addr);
404 Z80_O_MREQ = 0;
405 z80_setup_dbus_out();
406 P_DB = data;
407 P_DB = data;
408 Z80_O_WR = 0;
409 Z80_O_WR = 0;
410 Z80_O_WR = 1;
411 Z80_O_MREQ = 1;
412 }
413
414 uint8_t z80_read(uint32_t addr)
415 {
416 uint8_t data;
417
418 z80_setaddress(addr);
419 Z80_O_MREQ = 0;
420 z80_setup_dbus_in();
421 Z80_O_RD = 0;
422 Z80_O_RD = 0;
423 Z80_O_RD = 0;
424 data = PIN_DB;
425 Z80_O_RD = 1;
426 Z80_O_MREQ = 1;
427
428 return data;
429 }
430
431
432 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
433 {
434 z80_setup_dbus_out();
435 Z80_O_MREQ = 0;
436 while(length--) {
437 z80_setaddress(addr++);
438 P_DB = data;
439 P_DB = data;
440 Z80_O_WR = 0;
441 Z80_O_WR = 0;
442 Z80_O_WR = 1;
443 }
444 Z80_O_MREQ = 1;
445 }
446
447 void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
448 {
449 uint8_t data;
450
451 z80_setup_dbus_out();
452 Z80_O_MREQ = 0;
453 while(length--) {
454 z80_setaddress(dest++);
455 data = *src++;
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 /*
466 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
467 017A' rx.in_idx: ds 1 ;
468 017B' rx.out_idx: ds 1 ;
469 017C' rx.buf: ds rx.buf_len ;
470 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
471
472 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
473 018D' tx.in_idx: ds 1 ;
474 018E' tx.out_idx: ds 1 ;
475 018F' tx.buf: ds tx.buf_len ;
476 019E' tx.buf_end equ $-1 ; last byte
477 */
478
479
480 typedef struct __attribute__((packed)) {
481 uint8_t mask;
482 uint8_t in_idx;
483 uint8_t out_idx;
484 uint8_t buf[];
485 } zfifo_t;
486
487
488
489 #define FIFO_BUFSIZE_MASK -3
490 #define FIFO_INDEX_IN -2
491 #define FIFO_INDEX_OUT -1
492
493
494 static struct {
495 uint32_t base;
496 uint8_t idx_out,
497 idx_in,
498 mask;
499 } fifo_dsc[NUM_FIFOS];
500
501
502 void z80_memfifo_init(const fifo_t f, uint32_t adr)
503 {
504
505 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
506
507 fifo_dsc[f].base = adr;
508
509 z80_bus_cmd(Request);
510
511 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
512 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
513 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
514
515 z80_bus_cmd(Release);
516 }
517
518
519 int z80_memfifo_is_empty(const fifo_t f)
520 {
521 int rc = 1;
522
523 if (fifo_dsc[f].base != 0) {
524
525 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
526 uint8_t idx;
527
528 z80_bus_cmd(Request);
529 idx = z80_read(adr);
530 z80_bus_cmd(Release);
531 rc = idx == fifo_dsc[f].idx_out;
532 }
533
534 return rc;
535 }
536
537 int z80_memfifo_is_full(const fifo_t f)
538 {
539 int rc = 1;
540
541 if (fifo_dsc[f].base != 0) {
542 z80_bus_cmd(Request);
543 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
544 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
545 z80_bus_cmd(Release);
546 }
547 return rc;
548 }
549
550 uint8_t z80_memfifo_getc(const fifo_t f)
551 {
552 uint8_t rc, idx;
553
554 while (z80_memfifo_is_empty(f))
555 ;
556
557 z80_bus_cmd(Request);
558 idx = fifo_dsc[f].idx_out;
559 rc = z80_read(fifo_dsc[f].base+idx);
560 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
561 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
562 z80_bus_cmd(Release);
563
564 return rc;
565 }
566
567
568 void z80_memfifo_putc(fifo_t f, uint8_t val)
569 {
570 int idx;
571
572 while (z80_memfifo_is_full(f))
573 ;
574
575 z80_bus_cmd(Request);
576 idx = fifo_dsc[f].idx_in;
577 z80_write(fifo_dsc[f].base+idx, val);
578 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
579 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
580 z80_bus_cmd(Release);
581 }
582
583 /*--------------------------------------------------------------------------*/
584 /*
585 TODO: Rewrite msg_fifo routines for AVR
586 */
587
588 static struct {
589 uint32_t base;
590 //uint8_t idx_out, idx_in;
591 uint16_t count;
592 uint8_t buf[256];
593 } msg_fifo;
594
595 /*--------------------------------------------------------------------------*/
596
597 #if 0
598
599 static void tim1_setup(void)
600 {
601 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
602 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
603
604 TIM1_CR1 = 0;
605
606 TIM1_SMCR = 0
607 /* | TIM_SMCR_ETP */
608 /* | TIM_SMCR_ETF_CK_INT_N_2 */
609 | TIM_SMCR_TS_ETRF
610 | TIM_SMCR_SMS_OFF
611 ;
612
613 TIM1_DIER = TIM_DIER_TDE;
614
615
616 TIM1_CCMR1 = 0
617 | TIM_CCMR1_OC1M_FORCE_LOW
618 | TIM_CCMR1_CC1S_OUT;
619
620 TIM1_SMCR |= TIM_SMCR_SMS_TM;
621 }
622
623 #endif
624
625 /*--------------------------------------------------------------------------*/
626
627 void z80_setup_msg_fifo(void)
628 {
629 // gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
630 // GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
631
632 //...
633
634 // msg_fifo.count = NELEMS(msg_fifo.buf);
635 msg_fifo.count = 0;
636 msg_fifo.base = 0;
637
638 }
639
640
641 void z80_init_msg_fifo(uint32_t addr)
642 {
643
644 DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
645
646 z80_bus_cmd(Request);
647 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
648 z80_bus_cmd(Release);
649 msg_fifo.base = addr;
650 }
651
652
653 int z80_msg_fifo_getc(void)
654 {
655 int c = -1;
656
657 #if 0
658 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
659 c = msg_fifo.buf[msg_fifo.count];
660 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
661 msg_fifo.count = 0;
662
663 if (msg_fifo.base != 0) {
664 z80_bus_cmd(Request);
665 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
666 z80_bus_cmd(Release);
667 }
668 }
669 #endif
670
671 return c;
672 }