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