]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
5 * | Z180-Sig | AVR-Port | Dir | Special Function |
6 * +------------+---------------+-------+-----------------------+
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 | |
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 | |
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 |
57 #include <util/delay.h>
58 #include <util/atomic.h>
64 /* Number of array elements */
65 #define NELEMS(x) (sizeof x/sizeof *x)
68 #define CONCAT(x,y) x ## y
69 #define EVALUATOR(x,y) CONCAT(x,y)
71 #define GPIO_(X) CONCAT(GPIO, X)
82 } __attribute__((__packed__
));
84 #define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
97 #define P_BUSREQ PORTD
99 #define DDR_BUSREQ DDRD
100 #define P_BUSACK PORTD
101 #define PIN_BUSACK PIND
103 #define DDR_BUSACK DDRD
104 //#define P_HALT PORTA
106 #define P_IOCS1 PORTE
108 #define DDR_IOCS1 DDRE
109 //#define P_NMI PORTB
130 //#define ADB_PORT PORTE
133 #define Z80_O_ZCLK SBIT(P_ZCLK, 7)
134 #define Z80_O_MREQ SBIT(P_MREQ, 4)
135 #define Z80_O_RD SBIT(P_RD, 3)
136 #define Z80_O_WR SBIT(P_WR, 2)
137 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
138 //#define Z80_O_NMI SBIT(P_NMI, )
139 #define Z80_O_RST SBIT(P_RST, 5)
140 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
141 //#define Z80_I_HALT SBIT(P_HALT, )
144 #define MASK(n) ((1<<(n))-1)
145 #define SMASK(w,s) (MASK(w) << (s))
147 #define LOWSPEED 50000
157 static zstate_t zstate
;
159 /*--------------------------------------------------------------------------*/
162 uint8_t is_lowspeed()
164 return (TCCR1B
& 7) < 2 &&
165 OCR1A
> (F_CPU
/ 2 / LOWSPEED
);
169 void z80_setup_clock(void)
171 /* ZCLK: Output and low */
172 DDR_ZCLK
|= _BV(ZCLK
);
175 DDRB
|= _BV(6); /* Debug */
176 PORTB
|= _BV(6); /* Debug */
178 PRR0
&= ~_BV(PRTIM1
);
180 /* Timer1: CTC: Toggle OC1C on compare match */
183 TCCR1A
= (0b01 << COM1C0
) | (0b00 << WGM10
);
184 TCCR1B
= (0b01 << WGM12
) | (0b001 << CS10
);
188 int z80_clock_set(unsigned long freq
)
190 unsigned long ocrval
= F_CPU
/ freq
/ 2;
191 uint8_t prescale
= 0;
193 while (ocrval
> (1L<<16)) {
201 if ((ocrval
== 0) || (prescale
> 4))
206 PINB
|= _BV(6); /* Debug */
209 TCCR1B
= (0b01 << WGM12
) | (0b000 << CS10
);
214 TCCR1A
= (0b01 << COM1C0
) | (0b00 << WGM10
);
215 TCCR1B
= (0b01 << WGM12
) | ((prescale
+1) << CS10
);
218 ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) {
222 PINB
|= _BV(6); /* Debug */
227 uint32_t z80_clock_get(void)
229 uint32_t count
= (OCR1A
+ 1L) * 2;
230 uint8_t pre
= (TCCR1B
& 7) - 1;
245 static void z80_addrbus_set_tristate(void)
247 /* /MREQ, /RD, /WR: Input, no pullup */
248 DDR_MREQ
&= ~(_BV(MREQ
) | _BV(RD
) | _BV(WR
));
257 PIN_ADB
= P_ADB
& ~(MASK(ADB_WIDTH
) << ADB_SHIFT
);
258 DDR_ADB
= DDR_ADB
& ~(MASK(ADB_WIDTH
) << ADB_SHIFT
);
262 static void z80_addrbus_set_active(void)
264 /* /MREQ, /RD, /WR: Output and high */
268 DDR_MREQ
|= _BV(MREQ
) | _BV(RD
) | _BV(WR
);
272 DDR_ADB
= DDR_ADB
| (MASK(ADB_WIDTH
) << ADB_SHIFT
);
276 static void z80_dbus_set_in(void)
283 static void z80_dbus_set_out(void)
289 static void z80_reset_pulse(void)
297 void z80_setup_bus(void)
301 /* /ZRESET: Output and low */
305 /* /BUSREQ: Output and high */
307 DDR_BUSREQ
|= _BV(BUSREQ
);
309 /* /BUSACK: Input, no pullup */
310 DDR_BUSACK
&= ~_BV(BUSACK
);
311 P_BUSACK
&= ~_BV(BUSACK
);
313 /* /IOCS1: Input, no pullup */
314 DDR_IOCS1
&= ~_BV(IOCS1
);
315 P_IOCS1
&= ~_BV(IOCS1
);
317 z80_addrbus_set_tristate();
324 zstate_t
z80_bus_state(void)
330 static void z80_busreq_hpulse(void)
333 z80_addrbus_set_tristate();
335 ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) {
337 Z80_O_BUSREQ
= 1; /* 2 AVR clock cycles */
338 Z80_O_BUSREQ
= 0; /* 2 AVR clock cycles */
341 if (zstate
& ZST_ACQUIRED
) {
342 while(Z80_I_BUSACK
== 1)
344 z80_addrbus_set_active();
352 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
356 ----------------+---------------+---------------+---------------+---------------+
358 Reset | 0 | 0 | 0 | 0 |
361 Request | 1 | | 3 | |
364 Release | | 0 | | 2 |
370 Restart | | | 2 | 3 |
378 zstate_t
z80_bus_cmd(bus_cmd_t cmd
)
384 z80_addrbus_set_tristate();
395 while(Z80_I_BUSACK
== 1)
397 z80_addrbus_set_active();
403 while(Z80_I_BUSACK
== 1)
405 z80_addrbus_set_active();
406 zstate
= RUNNING_AQRD
;
418 z80_addrbus_set_tristate();
425 z80_addrbus_set_tristate();
443 z80_addrbus_set_tristate();
445 z80_addrbus_set_active();
446 zstate
= RUNNING_AQRD
;
477 /*--------------------------------------------------------------------------*/
480 //inline __attribute__ ((always_inline))
481 void z80_setaddress(uint32_t addr
)
483 addr_t x
; x
.l
= addr
;
487 PIN_ADB
= ((x
.b
[2] << ADB_SHIFT
) ^ P_ADB
) & MASK(ADB_WIDTH
) << ADB_SHIFT
;
490 void z80_write(uint32_t addr
, uint8_t data
)
492 z80_setaddress(addr
);
503 uint8_t z80_read(uint32_t addr
)
507 z80_setaddress(addr
);
521 void z80_memset(uint32_t addr
, uint8_t data
, uint32_t length
)
526 z80_setaddress(addr
++);
536 void z80_write_block(const __flash
uint8_t *src
, uint32_t dest
, uint32_t length
)
543 z80_setaddress(dest
++);
555 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
556 017A' rx.in_idx: ds 1 ;
557 017B' rx.out_idx: ds 1 ;
558 017C' rx.buf: ds rx.buf_len ;
559 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
561 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
562 018D' tx.in_idx: ds 1 ;
563 018E' tx.out_idx: ds 1 ;
564 018F' tx.buf: ds tx.buf_len ;
565 019E' tx.buf_end equ $-1 ; last byte
569 typedef struct __attribute__((packed
)) {
578 #define FIFO_BUFSIZE_MASK -3
579 #define FIFO_INDEX_IN -2
580 #define FIFO_INDEX_OUT -1
588 } fifo_dsc
[NUM_FIFOS
];
591 void z80_memfifo_init(const fifo_t f
, uint32_t adr
)
594 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f
, adr
);
596 fifo_dsc
[f
].base
= adr
;
598 z80_bus_cmd(Request
);
600 fifo_dsc
[f
].mask
= z80_read(adr
+ FIFO_BUFSIZE_MASK
);
601 fifo_dsc
[f
].idx_in
= z80_read(adr
+ FIFO_INDEX_IN
);
602 fifo_dsc
[f
].idx_out
= z80_read(adr
+ FIFO_INDEX_OUT
);
604 z80_bus_cmd(Release
);
608 int z80_memfifo_is_empty(const fifo_t f
)
612 if (fifo_dsc
[f
].base
!= 0) {
614 uint32_t adr
= fifo_dsc
[f
].base
+ FIFO_INDEX_IN
;
617 z80_bus_cmd(Request
);
619 z80_bus_cmd(Release
);
620 rc
= idx
== fifo_dsc
[f
].idx_out
;
626 int z80_memfifo_is_full(const fifo_t f
)
630 if (fifo_dsc
[f
].base
!= 0) {
631 z80_bus_cmd(Request
);
632 rc
= ((fifo_dsc
[f
].idx_in
+ 1) & fifo_dsc
[f
].mask
)
633 == z80_read(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
);
634 z80_bus_cmd(Release
);
639 uint8_t z80_memfifo_getc(const fifo_t f
)
643 while (z80_memfifo_is_empty(f
))
646 z80_bus_cmd(Request
);
647 idx
= fifo_dsc
[f
].idx_out
;
648 rc
= z80_read(fifo_dsc
[f
].base
+idx
);
649 fifo_dsc
[f
].idx_out
= ++idx
& fifo_dsc
[f
].mask
;
650 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
, fifo_dsc
[f
].idx_out
);
651 z80_bus_cmd(Release
);
657 void z80_memfifo_putc(fifo_t f
, uint8_t val
)
661 while (z80_memfifo_is_full(f
))
664 z80_bus_cmd(Request
);
665 idx
= fifo_dsc
[f
].idx_in
;
666 z80_write(fifo_dsc
[f
].base
+idx
, val
);
667 fifo_dsc
[f
].idx_in
= ++idx
& fifo_dsc
[f
].mask
;
668 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_IN
, fifo_dsc
[f
].idx_in
);
669 z80_bus_cmd(Release
);
672 /*--------------------------------------------------------------------------*/
674 TODO: Rewrite msg_fifo routines for AVR
679 //uint8_t idx_out, idx_in;
684 /*--------------------------------------------------------------------------*/
688 static void tim1_setup(void)
690 RCC_APB2RSTR
|= RCC_APB2RSTR_TIM1RST
;
691 RCC_APB2RSTR
&= ~RCC_APB2RSTR_TIM1RST
;
697 /* | TIM_SMCR_ETF_CK_INT_N_2 */
702 TIM1_DIER
= TIM_DIER_TDE
;
706 | TIM_CCMR1_OC1M_FORCE_LOW
707 | TIM_CCMR1_CC1S_OUT
;
709 TIM1_SMCR
|= TIM_SMCR_SMS_TM
;
714 /*--------------------------------------------------------------------------*/
716 void z80_setup_msg_fifo(void)
718 // gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
719 // GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
723 // msg_fifo.count = NELEMS(msg_fifo.buf);
730 void z80_init_msg_fifo(uint32_t addr
)
733 DBG_P(1, "z80_init_msg_fifo: %lx\n", addr
);
735 z80_bus_cmd(Request
);
736 z80_write(addr
+FIFO_INDEX_OUT
, z80_read(addr
+FIFO_INDEX_IN
));
737 z80_bus_cmd(Release
);
738 msg_fifo
.base
= addr
;
742 int z80_msg_fifo_getc(void)
747 if (msg_fifo
.count
!= (NELEMS(msg_fifo
.buf
) /*- DMA1_CNDTR4 */ )) {
748 c
= msg_fifo
.buf
[msg_fifo
.count
];
749 if (++msg_fifo
.count
== NELEMS(msg_fifo
.buf
))
752 if (msg_fifo
.base
!= 0) {
753 z80_bus_cmd(Request
);
754 z80_write(msg_fifo
.base
+FIFO_INDEX_OUT
, msg_fifo
.count
);
755 z80_bus_cmd(Release
);