]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0+
11 * | Z180-Sig | AVR-Port | Dir | Special Function |
12 * +------------+---------------+-------+-----------------------+
23 * | A10 | PC 2 | O | |
24 * | A11 | PC 3 | O | |
25 * | A12 | PC 4 | O | |
26 * | A13 | PC 5 | O | |
27 * | A14 | PC 6 | O | |
28 * | A15 | PC 7 | O | |
29 * | A16 | PE 2 | O | |
30 * | A17 | PE 3 | O | |
31 * | A18 | PE 4 | O | |
32 * | D0 | PF 0 | I/O | |
33 * | D1 | PF 1 | I/O | |
34 * | D2 | PF 2 | I/O | |
35 * | D3 | PF 3 | I/O | |
36 * | D4 | PF 4 | I/O | |
37 * | D5 | PF 5 | I/O | |
38 * | D6 | PF 6 | I/O | |
39 * | D7 | PF 7 | I/O | |
42 * | MREQ | PD 4 | O | |
43 * | RST | PD 5 | O | |
44 * | BUSREQ | PD 7 | O | |
45 * | BUSACK | PD 6 | I | |
46 * | IOCS1 | PE 5 | I | |
50 * | | P | | af1 USART1_TX |
51 * | | P | | af1 USART1_RX |
52 * | | P |JTDI | remap SPI1_NSS' |
53 * | | P |JTDO | remap SPI1_SCK' |
54 * | | P |JTRST | remap SPI1_MISO' |
55 * | | P | | remap SPI1_MOSI' |
56 * | | P | | af1 OSC32 |
57 * | | P | | af1 OSC32 |
63 #include <util/atomic.h>
69 //#define P_ZCLK PORTB
71 //#define DDR_ZCLK DDRB
79 #define P_BUSREQ PORTD
81 #define DDR_BUSREQ DDRD
82 #define P_BUSACK PORTD
83 #define PIN_BUSACK PIND
85 #define DDR_BUSACK DDRD
86 //#define P_HALT PORTA
90 #define DDR_IOCS1 DDRE
112 //#define ADB_PORT PORTE
115 //#define Z80_O_ZCLK SBIT(P_ZCLK, 5)
116 #define Z80_O_MREQ SBIT(P_MREQ, 4)
117 #define Z80_O_RD SBIT(P_RD, 3)
118 #define Z80_O_WR SBIT(P_WR, 2)
119 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
120 //#define Z80_O_NMI SBIT(P_NMI, )
121 #define Z80_O_RST SBIT(P_RST, 5)
122 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
123 //#define Z80_I_HALT SBIT(P_HALT, )
129 #define MASK(n) ((1<<(n))-1)
130 #define SMASK(w,s) (MASK(w) << (s))
140 static zstate_t zstate
;
141 static volatile uint8_t timer
; /* used for bus timeout */
143 /*---------------------------------------------------------*/
144 /* 10Hz timer interrupt generated by OC4A */
145 /*---------------------------------------------------------*/
147 ISR(TIMER4_COMPA_vect
)
156 /*--------------------------------------------------------------------------*/
159 static void z80_addrbus_set_tristate(void)
161 /* /MREQ, /RD, /WR: Input, no pullup */
162 DDR_MREQ
&= ~(_BV(MREQ
) | _BV(RD
) | _BV(WR
));
171 PIN_ADB
= P_ADB
& ~(MASK(ADB_WIDTH
) << ADB_SHIFT
);
172 DDR_ADB
= DDR_ADB
& ~(MASK(ADB_WIDTH
) << ADB_SHIFT
);
176 static void z80_addrbus_set_active(void)
178 /* /MREQ, /RD, /WR: Output and high */
182 DDR_MREQ
|= _BV(MREQ
) | _BV(RD
) | _BV(WR
);
186 DDR_ADB
= DDR_ADB
| (MASK(ADB_WIDTH
) << ADB_SHIFT
);
190 static void z80_dbus_set_in(void)
197 static void z80_dbus_set_out(void)
203 static void z80_reset_pulse(void)
211 void z80_setup_bus(void)
213 /* /ZRESET: Output and low */
217 /* /BUSREQ: Output and high */
219 DDR_BUSREQ
|= _BV(BUSREQ
);
221 /* /BUSACK: Input, no pullup */
222 DDR_BUSACK
&= ~_BV(BUSACK
);
223 P_BUSACK
&= ~_BV(BUSACK
);
225 /* /IOCS1: Input, no pullup */
226 DDR_IOCS1
&= ~_BV(IOCS1
);
227 P_IOCS1
&= ~_BV(IOCS1
);
229 z80_addrbus_set_tristate();
235 PRR1
&= ~_BV(PRTIM4
);
236 OCR4A
= F_CPU
/ 1024 / 10 - 1; /* Timer: 10Hz interval (OC4A) */
237 TCCR4B
= (0b01<<WGM42
)|(0b101<<CS30
); /* CTC Mode, Prescaler 1024 */
238 TIMSK4
= _BV(OCIE4A
); /* Enable oca interrupt */
243 zstate_t
z80_bus_state(void)
249 static void z80_busreq_hpulse(void)
252 z80_addrbus_set_tristate();
254 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
256 Z80_O_BUSREQ
= 1; /* 2 AVR clock cycles */
257 Z80_O_BUSREQ
= 0; /* 2 AVR clock cycles */
260 if (zstate
& ZST_ACQUIRED
) {
262 while (Z80_I_BUSACK
== 1 && timer
)
264 if (Z80_I_BUSACK
== 0)
265 z80_addrbus_set_active();
273 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
277 ----------------+---------------+---------------+---------------+---------------+
279 Reset | 0 | 0 | 0 | 0 |
282 Request | 1 | | 3 | |
285 Release | | 0 | | 2 |
291 Restart | | | 2 | 3 |
299 zstate_t
z80_bus_cmd(bus_cmd_t cmd
)
305 z80_addrbus_set_tristate();
317 while (Z80_I_BUSACK
== 1 && timer
)
319 if (Z80_I_BUSACK
== 0) {
320 z80_addrbus_set_active();
331 while (Z80_I_BUSACK
== 1 && timer
)
333 if (Z80_I_BUSACK
== 0) {
334 z80_addrbus_set_active();
335 zstate
= RUNNING_AQRD
;
350 z80_addrbus_set_tristate();
357 z80_addrbus_set_tristate();
375 z80_addrbus_set_tristate();
377 z80_addrbus_set_active();
378 zstate
= RUNNING_AQRD
;
399 z80_busreq_hpulse(); /* TODO: */
409 /*--------------------------------------------------------------------------*/
412 //inline __attribute__ ((always_inline))
413 void z80_setaddress(uint32_t addr
)
415 addr_t x
; x
.l
= addr
;
419 PIN_ADB
= ((x
.b
[2] << ADB_SHIFT
) ^ P_ADB
) & MASK(ADB_WIDTH
) << ADB_SHIFT
;
422 void z80_write(uint32_t addr
, uint8_t data
)
424 z80_setaddress(addr
);
435 uint8_t z80_read(uint32_t addr
)
439 z80_setaddress(addr
);
453 void z80_memset(uint32_t addr
, uint8_t data
, uint32_t length
)
459 z80_setaddress(addr
++);
467 void z80_write_block_P(const FLASH
uint8_t *src
, uint32_t dest
, uint32_t length
)
474 z80_setaddress(dest
++);
485 void z80_write_block(const uint8_t *src
, uint32_t dest
, uint32_t length
)
492 z80_setaddress(dest
++);
503 void z80_read_block (uint8_t *dest
, uint32_t src
, size_t length
)
510 z80_setaddress(src
++);
523 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
524 017A' rx.in_idx: ds 1 ;
525 017B' rx.out_idx: ds 1 ;
526 017C' rx.buf: ds rx.buf_len ;
527 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
529 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
530 018D' tx.in_idx: ds 1 ;
531 018E' tx.out_idx: ds 1 ;
532 018F' tx.buf: ds tx.buf_len ;
533 019E' tx.buf_end equ $-1 ; last byte
537 typedef struct __attribute__((packed
)) {
546 #define FIFO_BUFSIZE_MASK -3
547 #define FIFO_INDEX_IN -2
548 #define FIFO_INDEX_OUT -1
556 } fifo_dsc
[NUM_FIFOS
];
559 void z80_memfifo_init(const fifo_t f
, uint32_t addr
)
561 fifo_dsc
[f
].base
= addr
;
565 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f
, addr
);
567 z80_bus_cmd(Request
);
568 fifo_dsc
[f
].mask
= z80_read(addr
+ FIFO_BUFSIZE_MASK
);
569 fifo_dsc
[f
].idx_in
= z80_read(addr
+ FIFO_INDEX_IN
);
570 fifo_dsc
[f
].idx_out
= z80_read(addr
+ FIFO_INDEX_OUT
);
571 z80_bus_cmd(Release
);
576 int z80_memfifo_is_empty(const fifo_t f
)
580 if (fifo_dsc
[f
].base
!= 0) {
582 uint32_t adr
= fifo_dsc
[f
].base
+ FIFO_INDEX_IN
;
585 z80_bus_cmd(Request
);
587 z80_bus_cmd(Release
);
588 rc
= idx
== fifo_dsc
[f
].idx_out
;
594 int z80_memfifo_is_full(const fifo_t f
)
598 if (fifo_dsc
[f
].base
!= 0) {
599 z80_bus_cmd(Request
);
600 rc
= ((fifo_dsc
[f
].idx_in
+ 1) & fifo_dsc
[f
].mask
)
601 == z80_read(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
);
602 z80_bus_cmd(Release
);
608 uint8_t z80_memfifo_getc_wait(const fifo_t f
)
612 while (z80_memfifo_is_empty(f
))
615 z80_bus_cmd(Request
);
616 idx
= fifo_dsc
[f
].idx_out
;
617 rc
= z80_read(fifo_dsc
[f
].base
+idx
);
618 fifo_dsc
[f
].idx_out
= ++idx
& fifo_dsc
[f
].mask
;
619 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
, fifo_dsc
[f
].idx_out
);
620 z80_bus_cmd(Release
);
625 int z80_memfifo_getc(const fifo_t f
)
629 if (fifo_dsc
[f
].base
!= 0) {
630 uint8_t idx
= fifo_dsc
[f
].idx_out
;
631 z80_bus_cmd(Request
);
632 if (idx
!= z80_read(fifo_dsc
[f
].base
+ FIFO_INDEX_IN
)) {
633 rc
= z80_read(fifo_dsc
[f
].base
+idx
);
634 fifo_dsc
[f
].idx_out
= ++idx
& fifo_dsc
[f
].mask
;
635 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
, fifo_dsc
[f
].idx_out
);
637 z80_bus_cmd(Release
);
644 void z80_memfifo_putc(fifo_t f
, uint8_t val
)
648 while (z80_memfifo_is_full(f
))
651 z80_bus_cmd(Request
);
652 idx
= fifo_dsc
[f
].idx_in
;
653 z80_write(fifo_dsc
[f
].base
+idx
, val
);
654 fifo_dsc
[f
].idx_in
= ++idx
& fifo_dsc
[f
].mask
;
655 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_IN
, fifo_dsc
[f
].idx_in
);
656 z80_bus_cmd(Release
);