]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
45449974209a150ecc106185658b1bbbaa1a5363
[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 "common.h"
57 #include <util/atomic.h>
58 #include "debug.h"
59 #include "z80-if.h"
60
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_HALT PORTA
81 //#define HALT 12
82 #define P_IOCS1 PORTE
83 #define IOCS1 5
84 #define DDR_IOCS1 DDRE
85 //#define P_NMI PORTB
86 //#define NMI 7
87 #define P_RST PORTD
88 #define DDR_RST DDRD
89 #define RST 5
90
91
92 #define P_DB PORTF
93 #define PIN_DB PINF
94 #define DDR_DB DDRF
95
96 #define P_ADL PORTA
97 #define P_ADH PORTC
98 #define P_ADB PORTE
99 #define PIN_ADB PINE
100 #define DDR_ADL DDRA
101 #define DDR_ADH DDRC
102 #define DDR_ADB DDRE
103
104 #define ADB_WIDTH 3
105 #define ADB_SHIFT 2
106 //#define ADB_PORT PORTE
107
108
109 //#define Z80_O_ZCLK SBIT(P_ZCLK, 5)
110 #define Z80_O_MREQ SBIT(P_MREQ, 4)
111 #define Z80_O_RD SBIT(P_RD, 3)
112 #define Z80_O_WR SBIT(P_WR, 2)
113 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
114 //#define Z80_O_NMI SBIT(P_NMI, )
115 #define Z80_O_RST SBIT(P_RST, 5)
116 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
117 //#define Z80_I_HALT SBIT(P_HALT, )
118
119
120 #define MASK(n) ((1<<(n))-1)
121 #define SMASK(w,s) (MASK(w) << (s))
122
123
124 typedef union {
125 uint32_t l;
126 uint16_t w[2];
127 uint8_t b[4];
128 } addr_t;
129
130
131 static zstate_t zstate;
132
133 /*--------------------------------------------------------------------------*/
134
135
136 static void z80_addrbus_set_tristate(void)
137 {
138 /* /MREQ, /RD, /WR: Input, no pullup */
139 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
140 Z80_O_MREQ = 0;
141 Z80_O_RD = 0;
142 Z80_O_WR = 0;
143
144 P_ADL = 0;
145 DDR_ADL = 0;
146 P_ADH = 0;
147 DDR_ADH = 0;
148 PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
149 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
150 }
151
152
153 static void z80_addrbus_set_active(void)
154 {
155 /* /MREQ, /RD, /WR: Output and high */
156 Z80_O_MREQ = 1;
157 Z80_O_RD = 1;
158 Z80_O_WR = 1;
159 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
160
161 DDR_ADL = 0xff;
162 DDR_ADH = 0xff;
163 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
164 }
165
166
167 static void z80_dbus_set_in(void)
168 {
169 DDR_DB = 0;
170 P_DB = 0;
171 }
172
173
174 static void z80_dbus_set_out(void)
175 {
176 DDR_DB = 0xff;
177 }
178
179
180 static void z80_reset_pulse(void)
181 {
182 Z80_O_RST = 0;
183 _delay_us(10);
184 Z80_O_RST = 1;
185 }
186
187
188 void z80_setup_bus(void)
189 {
190 /* /ZRESET: Output and low */
191 Z80_O_RST = 0;
192 DDR_RST |= _BV(RST);
193
194 /* /BUSREQ: Output and high */
195 Z80_O_BUSREQ = 1;
196 DDR_BUSREQ |= _BV(BUSREQ);
197
198 /* /BUSACK: Input, no pullup */
199 DDR_BUSACK &= ~_BV(BUSACK);
200 P_BUSACK &= ~_BV(BUSACK);
201
202 /* /IOCS1: Input, no pullup */
203 DDR_IOCS1 &= ~_BV(IOCS1);
204 P_IOCS1 &= ~_BV(IOCS1);
205
206 z80_addrbus_set_tristate();
207 z80_dbus_set_in();
208
209 zstate = RESET;
210 }
211
212
213 zstate_t z80_bus_state(void)
214 {
215 return zstate;
216 }
217
218
219 static void z80_busreq_hpulse(void)
220 {
221 z80_dbus_set_in();
222 z80_addrbus_set_tristate();
223
224 ATOMIC_BLOCK(ATOMIC_FORCEON) {
225 Z80_O_BUSREQ = 1;
226 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
227 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
228 }
229
230 if (zstate & ZST_ACQUIRED) {
231 while(Z80_I_BUSACK == 1)
232 ;
233 z80_addrbus_set_active();
234 }
235 }
236
237
238 /*
239
240 + | | | | |
241 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
242 + | | | | |
243 + | 0 | 1 | 2 | 3 |
244 Event + | | | | |
245 ----------------+---------------+---------------+---------------+---------------+
246 | | | | |
247 Reset | 0 | 0 | 0 | 0 |
248 | | | | |
249 | | | | |
250 Request | 1 | | 3 | |
251 | | | | |
252 | | | | |
253 Release | | 0 | | 2 |
254 | | | | |
255 | | | | |
256 Run | 2 | 3 | | |
257 | | | | |
258 | | | | |
259 Restart | | | 2 | 3 |
260 | | | | |
261 | | | | |
262 M_Cycle | | | | 3 |
263 | | | | |
264 | | | | |
265 */
266
267 zstate_t z80_bus_cmd(bus_cmd_t cmd)
268 {
269 switch (cmd) {
270
271 case Reset:
272 z80_dbus_set_in();
273 z80_addrbus_set_tristate();
274 Z80_O_RST = 0;
275 Z80_O_BUSREQ = 1;
276 zstate = RESET;
277 break;
278
279 case Request:
280 switch (zstate) {
281 case RESET:
282 Z80_O_BUSREQ = 0;
283 Z80_O_RST = 1;
284 while(Z80_I_BUSACK == 1)
285 ;
286 z80_addrbus_set_active();
287 zstate = RESET_AQRD;
288 break;
289
290 case RUNNING:
291 Z80_O_BUSREQ = 0;
292 while(Z80_I_BUSACK == 1)
293 ;
294 z80_addrbus_set_active();
295 zstate = RUNNING_AQRD;
296 break;
297
298 default:
299 break;
300 }
301 break;
302
303 case Release:
304 switch (zstate) {
305 case RESET_AQRD:
306 z80_dbus_set_in();
307 z80_addrbus_set_tristate();
308 Z80_O_RST = 0;
309 Z80_O_BUSREQ = 1;
310 zstate = RESET;
311 break;
312 case RUNNING_AQRD:
313 z80_dbus_set_in();
314 z80_addrbus_set_tristate();
315 Z80_O_BUSREQ = 1;
316 zstate = RUNNING;
317 break;
318 default:
319 break;
320 }
321 break;
322
323 case Run:
324 switch (zstate) {
325 case RESET:
326 Z80_O_RST = 1;
327 zstate = RUNNING;
328 break;
329
330 case RESET_AQRD:
331 z80_dbus_set_in();
332 z80_addrbus_set_tristate();
333 z80_reset_pulse();
334 z80_addrbus_set_active();
335 zstate = RUNNING_AQRD;
336 break;
337 default:
338 break;
339 }
340 break;
341
342 case Restart:
343 switch (zstate) {
344 case RUNNING:
345 case RUNNING_AQRD:
346 z80_reset_pulse();
347 break;
348 default:
349 break;
350 }
351 break;
352
353 case M_Cycle:
354 switch (zstate) {
355 case RUNNING_AQRD:
356 z80_busreq_hpulse();
357 break;
358 default:
359 break;
360 }
361 }
362 return zstate;
363 }
364
365
366 /*--------------------------------------------------------------------------*/
367
368 static
369 //inline __attribute__ ((always_inline))
370 void z80_setaddress(uint32_t addr)
371 {
372 addr_t x; x.l = addr;
373
374 P_ADL = x.b[0];
375 P_ADH = x.b[1];
376 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
377 }
378
379 void z80_write(uint32_t addr, uint8_t data)
380 {
381 z80_setaddress(addr);
382 Z80_O_MREQ = 0;
383 z80_dbus_set_out();
384 P_DB = data;
385 P_DB = data;
386 Z80_O_WR = 0;
387 Z80_O_WR = 0;
388 Z80_O_WR = 1;
389 Z80_O_MREQ = 1;
390 }
391
392 uint8_t z80_read(uint32_t addr)
393 {
394 uint8_t data;
395
396 z80_setaddress(addr);
397 Z80_O_MREQ = 0;
398 z80_dbus_set_in();
399 Z80_O_RD = 0;
400 Z80_O_RD = 0;
401 Z80_O_RD = 0;
402 data = PIN_DB;
403 Z80_O_RD = 1;
404 Z80_O_MREQ = 1;
405
406 return data;
407 }
408
409
410 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
411 {
412 z80_dbus_set_out();
413 Z80_O_MREQ = 0;
414 while(length--) {
415 z80_setaddress(addr++);
416 P_DB = data;
417 P_DB = data;
418 Z80_O_WR = 0;
419 Z80_O_WR = 0;
420 Z80_O_WR = 1;
421 }
422 Z80_O_MREQ = 1;
423 }
424
425 void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
426 {
427 uint8_t data;
428
429 z80_dbus_set_out();
430 Z80_O_MREQ = 0;
431 while(length--) {
432 z80_setaddress(dest++);
433 data = *src++;
434 P_DB = data;
435 P_DB = data;
436 Z80_O_WR = 0;
437 Z80_O_WR = 0;
438 Z80_O_WR = 1;
439 }
440 Z80_O_MREQ = 1;
441 }
442
443 /*
444 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
445 017A' rx.in_idx: ds 1 ;
446 017B' rx.out_idx: ds 1 ;
447 017C' rx.buf: ds rx.buf_len ;
448 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
449
450 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
451 018D' tx.in_idx: ds 1 ;
452 018E' tx.out_idx: ds 1 ;
453 018F' tx.buf: ds tx.buf_len ;
454 019E' tx.buf_end equ $-1 ; last byte
455 */
456
457
458 typedef struct __attribute__((packed)) {
459 uint8_t mask;
460 uint8_t in_idx;
461 uint8_t out_idx;
462 uint8_t buf[];
463 } zfifo_t;
464
465
466
467 #define FIFO_BUFSIZE_MASK -3
468 #define FIFO_INDEX_IN -2
469 #define FIFO_INDEX_OUT -1
470
471
472 static struct {
473 uint32_t base;
474 uint8_t idx_out,
475 idx_in,
476 mask;
477 } fifo_dsc[NUM_FIFOS];
478
479
480 void z80_memfifo_init(const fifo_t f, uint32_t addr)
481 {
482 fifo_dsc[f].base = addr;
483
484 if (addr != 0) {
485
486 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, addr);
487
488 z80_bus_cmd(Request);
489 fifo_dsc[f].mask = z80_read(addr + FIFO_BUFSIZE_MASK);
490 fifo_dsc[f].idx_in = z80_read(addr + FIFO_INDEX_IN);
491 fifo_dsc[f].idx_out = z80_read(addr + FIFO_INDEX_OUT);
492 z80_bus_cmd(Release);
493 }
494 }
495
496
497 int z80_memfifo_is_empty(const fifo_t f)
498 {
499 int rc = 1;
500
501 if (fifo_dsc[f].base != 0) {
502
503 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
504 uint8_t idx;
505
506 z80_bus_cmd(Request);
507 idx = z80_read(adr);
508 z80_bus_cmd(Release);
509 rc = idx == fifo_dsc[f].idx_out;
510 }
511
512 return rc;
513 }
514
515 int z80_memfifo_is_full(const fifo_t f)
516 {
517 int rc = 1;
518
519 if (fifo_dsc[f].base != 0) {
520 z80_bus_cmd(Request);
521 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
522 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
523 z80_bus_cmd(Release);
524 }
525 return rc;
526 }
527
528
529 uint8_t z80_memfifo_getc_wait(const fifo_t f)
530 {
531 uint8_t rc, idx;
532
533 while (z80_memfifo_is_empty(f))
534 ;
535
536 z80_bus_cmd(Request);
537 idx = fifo_dsc[f].idx_out;
538 rc = z80_read(fifo_dsc[f].base+idx);
539 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
540 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
541 z80_bus_cmd(Release);
542
543 return rc;
544 }
545
546 int z80_memfifo_getc(const fifo_t f)
547 {
548 int rc = -1;
549
550 if (fifo_dsc[f].base != 0) {
551 uint8_t idx = fifo_dsc[f].idx_out;
552 z80_bus_cmd(Request);
553 if (idx != z80_read(fifo_dsc[f].base + FIFO_INDEX_IN)) {
554 rc = z80_read(fifo_dsc[f].base+idx);
555 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
556 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
557 }
558 z80_bus_cmd(Release);
559 }
560
561 return rc;
562 }
563
564
565 void z80_memfifo_putc(fifo_t f, uint8_t val)
566 {
567 int idx;
568
569 while (z80_memfifo_is_full(f))
570 ;
571
572 z80_bus_cmd(Request);
573 idx = fifo_dsc[f].idx_in;
574 z80_write(fifo_dsc[f].base+idx, val);
575 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
576 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
577 z80_bus_cmd(Release);
578 }