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