]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
5d888420ed0d282242d1e2e6aeec3771c9a8586c
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0
11 * | Z180-Sig | AVR-Port | Dir |
12 * +------------+---------------+-------+
44 * | BUSREQ | PD 7 | O |
45 * | BUSACK | PD 6 | I |
48 * +------------------------------------+
57 #include <util/atomic.h>
63 //#define P_ZCLK PORTB
65 //#define DDR_ZCLK DDRB
73 #define P_BUSREQ PORTD
75 #define DDR_BUSREQ DDRD
76 #define P_BUSACK PORTD
77 #define PIN_BUSACK PIND
79 #define DDR_BUSACK DDRD
100 //#define ADB_PORT PORTE
103 //#define Z80_O_ZCLK SBIT(P_ZCLK, 5)
104 #define Z80_O_MREQ SBIT(P_MREQ, 4)
105 #define Z80_O_RD SBIT(P_RD, 3)
106 #define Z80_O_WR SBIT(P_WR, 2)
107 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
108 //#define Z80_O_NMI SBIT(P_NMI, )
109 #define Z80_O_RST SBIT(P_RST, 5)
110 #define Z80_I_RST SBIT(PIN_RST, 5)
111 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
112 //#define Z80_I_HALT SBIT(P_HALT, )
120 #define DDR_STEP DDRG
123 #define DDR_WAIT DDRG
124 /* All three signals are on the same Port (PortG) */
125 #define PORT_SS PORTG
128 #define Z80_O_RUN SBIT(PORT_SS, RUN)
129 #define Z80_O_STEP SBIT(PORT_SS, STEP)
130 #define Z80_I_WAIT SBIT(PORT_SS, WAIT)
136 #define MASK(n) ((1<<(n))-1)
137 #define SMASK(w,s) (MASK(w) << (s))
139 void z80_bus_request_or_exit(void)
141 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
))
142 cmd_error(CMD_RET_FAILURE
, EBUSTO
, NULL
);
145 static zstate_t zstate
;
146 static volatile uint8_t timer
; /* used for bus timeout */
149 static volatile uint16_t req_cycles_ovl
;
151 ISR(TIMER4_COMPB_vect
)
157 /*---------------------------------------------------------*/
158 /* 10Hz timer interrupt generated by OC5A */
159 /*---------------------------------------------------------*/
161 ISR(TIMER5_COMPA_vect
)
170 /*--------------------------------------------------------------------------*/
173 static void z80_addrbus_set_in(void)
175 /* /MREQ, /RD, /WR: Input, no pullup */
176 DDR_MREQ
&= ~(_BV(MREQ
) | _BV(RD
) | _BV(WR
));
185 PIN_ADB
= P_ADB
& (MASK(ADB_WIDTH
) << ADB_SHIFT
);
186 DDR_ADB
= DDR_ADB
& ~(MASK(ADB_WIDTH
) << ADB_SHIFT
);
190 static void z80_addrbus_set_out(void)
192 /* /MREQ, /RD, /WR: Output and high */
196 DDR_MREQ
|= _BV(MREQ
) | _BV(RD
) | _BV(WR
);
200 DDR_ADB
= DDR_ADB
| (MASK(ADB_WIDTH
) << ADB_SHIFT
);
204 static void z80_dbus_set_in(void)
211 static void z80_dbus_set_out(void)
216 static void z80_reset_active(void)
218 if (Stat
& S_RESET_POLARITY
)
224 static void z80_reset_inactive(void)
226 if (Stat
& S_RESET_POLARITY
)
232 static void z80_reset_pulse(void)
236 z80_reset_inactive();
240 void z80_setup_bus(void)
242 ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) {
244 /* /ZRESET: Input, no pullup */
245 DDR_RST
&= ~_BV(RST
);
248 /* /BUSREQ: Output and high */
250 DDR_BUSREQ
|= _BV(BUSREQ
);
252 /* /BUSACK: Input, no pullup */
253 DDR_BUSACK
&= ~_BV(BUSACK
);
254 P_BUSACK
&= ~_BV(BUSACK
);
256 z80_addrbus_set_in();
259 if (getenv_yesno(PSTR(ENV_SINGLESTEP
))) {
260 /* /RUN & /STEP: output, /WAIT: input */
262 PORT_SS
= (PORT_SS
& ~_BV(RUN
)) | _BV(STEP
);
263 DDR_SS
= (DDR_SS
& ~_BV(WAIT
)) | _BV(RUN
) | _BV(STEP
);
267 Stat
|= S_RESET_POLARITY
;
269 Stat
&= ~S_RESET_POLARITY
;
277 PRR1
&= ~_BV(PRTIM5
);
278 OCR5A
= F_CPU
/ 1024 / 10 - 1; /* Timer: 10Hz interval (OC4A) */
279 TCCR5B
= (0b01<<WGM52
)|(0b101<<CS40
); /* CTC Mode, Prescaler 1024 */
280 TIMSK5
= _BV(OCIE5A
); /* Enable oca interrupt */
285 zstate_t
z80_bus_state(void)
291 static void z80_busreq_hpulse(void)
294 z80_addrbus_set_in();
297 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
299 Z80_O_BUSREQ
= 1; /* 2 AVR clock cycles */
300 Z80_O_BUSREQ
= 0; /* 2 AVR clock cycles */
305 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
309 if (Z80_I_BUSACK
== 1) {
317 if (zstate
& ZST_ACQUIRED
) {
319 while (Z80_I_BUSACK
== 1 && timer
)
321 if (Z80_I_BUSACK
== 0)
322 z80_addrbus_set_out();
330 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
334 ----------------+---------------+---------------+---------------+---------------+
336 Reset | 0 | 0 | 0 | 0 |
339 Request | 1 | | 3 | |
342 Release | | 0 | | 2 |
348 Restart | | | 2 | 3 |
356 zstate_t
z80_bus_cmd(bus_cmd_t cmd
)
362 z80_addrbus_set_in();
367 while (Z80_I_BUSACK
== 0 && timer
)
376 z80_reset_inactive();
378 while (Z80_I_BUSACK
== 1 && timer
)
380 if (Z80_I_BUSACK
== 0) {
381 z80_addrbus_set_out();
392 while (Z80_I_BUSACK
== 1 && timer
)
394 if (Z80_I_BUSACK
== 0) {
395 z80_addrbus_set_out();
396 zstate
= RUNNING_AQRD
;
411 z80_addrbus_set_in();
416 while (Z80_I_BUSACK
== 0 && timer
)
422 z80_addrbus_set_in();
425 while (Z80_I_BUSACK
== 0 && timer
)
437 _delay_ms(20); /* TODO: */
438 z80_reset_inactive();
444 z80_addrbus_set_in();
446 z80_addrbus_set_out();
447 zstate
= RUNNING_AQRD
;
468 z80_busreq_hpulse(); /* TODO: */
478 /*--------------------------------------------------------------------------*/
481 //inline __attribute__ ((always_inline))
482 void z80_setaddress(uint32_t addr
)
485 P_ADH
= (addr
& 0xff00) >> 8;
486 PIN_ADB
= (((addr
>> 16) << ADB_SHIFT
) ^ P_ADB
) & MASK(ADB_WIDTH
) << ADB_SHIFT
;
489 int32_t z80_memsize_detect(void)
491 const uint8_t PATTERN_1
= 0x55;
492 const uint8_t PATTERN_2
= ~PATTERN_1
;
495 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
))
498 uint8_t ram_0
= z80_read(0);
499 uint8_t ram_1
= z80_read(1);
501 z80_write(0, ram_0
^ 0xff);
503 if ((z80_read(0) ^ ram_0
) != 0xff) {
506 z80_write(0, PATTERN_1
);
507 for (addr
=1; addr
< CONFIG_SYS_RAMSIZE_MAX
; addr
<<= 1) {
508 uint8_t ram_i
= z80_read(addr
);
509 z80_write(addr
, PATTERN_2
);
510 if (z80_read(0) != PATTERN_1
|| z80_read(addr
) != PATTERN_2
)
512 z80_write(addr
, ram_i
);
517 z80_bus_cmd(Release
);
522 /*--------------------------------------------------------------------------*/
524 void z80_write(uint32_t addr
, uint8_t data
)
526 z80_setaddress(addr
);
537 uint8_t z80_read(uint32_t addr
)
541 z80_setaddress(addr
);
555 void z80_memset(uint32_t addr
, uint8_t data
, uint32_t length
)
561 z80_setaddress(addr
++);
569 void z80_write_block_P(const FLASH
uint8_t *src
, uint32_t dest
, uint32_t length
)
576 z80_setaddress(dest
++);
587 void z80_write_block(const uint8_t *src
, uint32_t dest
, uint32_t length
)
594 z80_setaddress(dest
++);
605 void z80_read_block (uint8_t *dest
, uint32_t src
, size_t length
)
612 z80_setaddress(src
++);
623 /*--------------------------------------------------------------------------*/
626 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
627 017A' rx.in_idx: ds 1 ;
628 017B' rx.out_idx: ds 1 ;
629 017C' rx.buf: ds rx.buf_len ;
630 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
632 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
633 018D' tx.in_idx: ds 1 ;
634 018E' tx.out_idx: ds 1 ;
635 018F' tx.buf: ds tx.buf_len ;
636 019E' tx.buf_end equ $-1 ; last byte
640 typedef struct __attribute__((packed
)) {
649 #define FIFO_BUFSIZE_MASK -3
650 #define FIFO_INDEX_IN -2
651 #define FIFO_INDEX_OUT -1
659 } fifo_dsc
[NUM_FIFOS
];
662 void z80_memfifo_init(const fifo_t f
, uint32_t addr
)
664 fifo_dsc
[f
].base
= addr
;
668 z80_bus_cmd(Request
);
669 fifo_dsc
[f
].mask
= z80_read(addr
+ FIFO_BUFSIZE_MASK
);
670 fifo_dsc
[f
].idx_in
= z80_read(addr
+ FIFO_INDEX_IN
);
671 fifo_dsc
[f
].idx_out
= z80_read(addr
+ FIFO_INDEX_OUT
);
672 z80_bus_cmd(Release
);
674 if (fifo_dsc
[f
].idx_in
!= 0 || fifo_dsc
[f
].idx_out
!= 0) {
675 DBG_P(1, "## z80_memfifo_init: %i, %lx, in: %.2x, out: %.2x, mask: %.2x\n",
676 f
, addr
, fifo_dsc
[f
].idx_in
, fifo_dsc
[f
].idx_out
, fifo_dsc
[f
].mask
);
682 int z80_memfifo_is_empty(const fifo_t f
)
686 if (fifo_dsc
[f
].base
!= 0) {
688 uint32_t adr
= fifo_dsc
[f
].base
+ FIFO_INDEX_IN
;
691 z80_bus_cmd(Request
);
693 z80_bus_cmd(Release
);
694 rc
= idx
== fifo_dsc
[f
].idx_out
;
700 int z80_memfifo_is_full(const fifo_t f
)
704 if (fifo_dsc
[f
].base
!= 0) {
705 z80_bus_cmd(Request
);
706 rc
= ((fifo_dsc
[f
].idx_in
+ 1) & fifo_dsc
[f
].mask
)
707 == z80_read(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
);
708 z80_bus_cmd(Release
);
714 uint8_t z80_memfifo_getc_wait(const fifo_t f
)
718 while (z80_memfifo_is_empty(f
))
721 z80_bus_cmd(Request
);
722 idx
= fifo_dsc
[f
].idx_out
;
723 rc
= z80_read(fifo_dsc
[f
].base
+idx
);
724 fifo_dsc
[f
].idx_out
= ++idx
& fifo_dsc
[f
].mask
;
725 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
, fifo_dsc
[f
].idx_out
);
726 z80_bus_cmd(Release
);
731 int z80_memfifo_getc(const fifo_t f
)
735 if (fifo_dsc
[f
].base
!= 0) {
736 uint8_t idx
= fifo_dsc
[f
].idx_out
;
737 z80_bus_cmd(Request
);
738 if (idx
!= z80_read(fifo_dsc
[f
].base
+ FIFO_INDEX_IN
)) {
739 rc
= z80_read(fifo_dsc
[f
].base
+idx
);
740 fifo_dsc
[f
].idx_out
= ++idx
& fifo_dsc
[f
].mask
;
741 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_OUT
, fifo_dsc
[f
].idx_out
);
743 z80_bus_cmd(Release
);
750 void z80_memfifo_putc(fifo_t f
, uint8_t val
)
754 while (z80_memfifo_is_full(f
))
757 z80_bus_cmd(Request
);
758 idx
= fifo_dsc
[f
].idx_in
;
759 z80_write(fifo_dsc
[f
].base
+idx
, val
);
760 fifo_dsc
[f
].idx_in
= ++idx
& fifo_dsc
[f
].mask
;
761 z80_write(fifo_dsc
[f
].base
+FIFO_INDEX_IN
, fifo_dsc
[f
].idx_in
);
762 z80_bus_cmd(Release
);
765 /*--------------------------------------------------------------------------*/
767 void z80_load_mem(int_fast8_t verbosity
,
768 const FLASH
unsigned char data
[],
769 const FLASH
unsigned long *sections
,
770 const FLASH
unsigned long address
[],
771 const FLASH
unsigned long length_of_sections
[])
773 uint32_t sec_base
= 0;
776 printf_P(PSTR("Loading Z180 memory... \n"));
778 for (unsigned sec
= 0; sec
< *sections
; sec
++) {
780 printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"),
782 address
[sec
]+length_of_sections
[sec
] - 1,
783 length_of_sections
[sec
]);
786 z80_write_block_P((const FLASH
unsigned char *) &data
[sec_base
], /* src */
787 address
[sec
], /* dest */
788 length_of_sections
[sec
]); /* len */
789 sec_base
+= length_of_sections
[sec
];