summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--avr/cmd_boot.c7
-rw-r--r--avr/cmd_mem.c58
-rw-r--r--avr/z80-if.c232
-rw-r--r--include/z80-if.h7
4 files changed, 202 insertions, 102 deletions
diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c
index 2c3a533..4775b6e 100644
--- a/avr/cmd_boot.c
+++ b/avr/cmd_boot.c
@@ -34,7 +34,7 @@ static void z80_load_mem(void)
hdrom_length_of_sections[sec]);
z80_bus_cmd(Request);
- z80_write_block((const FLASH unsigned char *) &hdrom[sec_base], /* src */
+ z80_write_block_P((const FLASH unsigned char *) &hdrom[sec_base], /* src */
hdrom_address[sec], /* dest */
hdrom_length_of_sections[sec]); /* len */
z80_bus_cmd(Release);
@@ -176,7 +176,7 @@ command_ret_t do_console(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
// uint8_t help_prompt = 0;
uint8_t code = 0;
uint8_t state = 0;
-
+
(void) cmdtp; (void) flag; (void) argc; (void) argv;
@@ -198,7 +198,7 @@ command_ret_t do_console(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
/* TODO: Timer starten */
} else {
z80_memfifo_putc(fifo_conin, ch);
- }
+ }
break;
case 2:
printf_P(PSTR("\n"
@@ -272,4 +272,3 @@ command_ret_t do_console(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
quit:
return CMD_RET_SUCCESS;
}
-
diff --git a/avr/cmd_mem.c b/avr/cmd_mem.c
index 66ace10..0bc5742 100644
--- a/avr/cmd_mem.c
+++ b/avr/cmd_mem.c
@@ -41,10 +41,10 @@ static uint32_t base_address = 0;
void z180_read_buf(uint8_t *buf, uint32_t addr, uint8_t count)
{
- z80_bus_cmd(Request);
- while (count--)
- *buf++ = z80_read(addr++);
- z80_bus_cmd(Release);
+ if (z80_bus_cmd(Request) & ZST_ACQUIRED) {
+ z80_read_block (buf, addr, count);
+ z80_bus_cmd(Release);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -132,10 +132,13 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
* the next value. A non-converted value exits.
*/
do {
- z80_bus_cmd(Request);
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
+ }
data = z80_read(addr);
- printf_P(PSTR("%05lx: %02x"), addr, data);
z80_bus_cmd(Release);
+ printf_P(PSTR("%05lx: %02x"), addr, data);
nbytes = cli_readline(PSTR(" ? "));
if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
@@ -151,7 +154,10 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
data = strtoul(console_buffer, &endp, 16);
nbytes = endp - console_buffer;
if (nbytes) {
- z80_bus_cmd(Request);
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
+ }
z80_write(addr, data);
z80_bus_cmd(Release);
if (incrflag)
@@ -201,11 +207,11 @@ command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
count = 1;
}
- z80_bus_cmd(Request);
- while (count-- > 0) {
- z80_write(addr, writeval);
- ++addr;
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
}
+ z80_memset(addr, writeval, count);
z80_bus_cmd(Release);
return CMD_RET_SUCCESS;
@@ -289,7 +295,11 @@ command_ret_t do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
count = strtoul(argv[3], NULL, 16);
for (ngood = 0; ngood < count; ++ngood) {
- z80_bus_cmd(Request);
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ rcode = CMD_RET_FAILURE;
+ break;
+ }
byte1 = z80_read(addr1);
byte2 = z80_read(addr2);
z80_bus_cmd(Release);
@@ -345,7 +355,10 @@ command_ret_t do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
while (count-- > 0) {
uint8_t data;
- z80_bus_cmd(Request);
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
+ }
data = z80_read(src);
z80_write(dest, data);
z80_bus_cmd(Release);
@@ -398,13 +411,19 @@ command_ret_t do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
* If we have only one object, just run infinite loops.
*/
if (length == 1) {
- z80_bus_cmd(Request);
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
+ }
for (;;)
z80_read(addr);
z80_bus_cmd(Release);
}
- z80_bus_cmd(Request);
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
+ }
for (;;) {
uint32_t i = length;
uint32_t p = addr;
@@ -440,11 +459,18 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
* If we have only one object, just run infinite loops.
*/
if (length == 1) {
- z80_bus_cmd(Request);
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
+ }
for (;;)
z80_write(addr, data);
}
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+ my_puts_P(PSTR("Bus timeout\n"));
+ return CMD_RET_FAILURE;
+ }
for (;;) {
uint32_t i = length;
uint32_t p = addr;
diff --git a/avr/z80-if.c b/avr/z80-if.c
index 4544997..cc0bab1 100644
--- a/avr/z80-if.c
+++ b/avr/z80-if.c
@@ -2,57 +2,58 @@
*
* Pin assignments
*
- * | Z180-Sig | AVR-Port | Dir | Special Function |
+ * | Z180-Sig | AVR-Port | Dir | Special Function |
* +------------+---------------+-------+-----------------------+
- * | A0 | PA 0 | O | |
- * | A1 | PA 1 | O | |
- * | A2 | PA 2 | O | |
- * | A3 | PA 3 | O | |
- * | A4 | PA 4 | O | |
- * | A5 | PA 5 | O | |
- * | A6 | PA 6 | O | |
- * | A7 | PA 7 | O | |
- * | A8 | PC 0 | O | |
- * | A9 | PC 1 | O | |
- * | A10 | PC 2 | O | |
- * | A11 | PC 3 | O | |
- * | A12 | PC 4 | O | |
- * | A13 | PC 5 | O | |
- * | A14 | PC 6 | O | |
- * | A15 | PC 7 | O | |
- * | A16 | PE 2 | O | |
- * | A17 | PE 3 | O | |
- * | A18 | PE 4 | O | |
- * | D0 | PF 0 | I/O | |
- * | D1 | PF 1 | I/O | |
- * | D2 | PF 2 | I/O | |
- * | D3 | PF 3 | I/O | |
- * | D4 | PF 4 | I/O | |
- * | D5 | PF 5 | I/O | |
- * | D6 | PF 6 | I/O | |
- * | D7 | PF 7 | I/O | |
- * | RD | PD 3 | O | |
- * | WR | PD 2 | O | |
- * | MREQ | PD 4 | O | |
- * | RST | PD 5 | O | |
- * | BUSREQ | PD 7 | O | |
- * | BUSACK | PD 6 | I | |
- * | IOCS1 | PE 5 | I | |
- * |* HALT | P | | |
- * |* NMI | P | | |
- * | | P | | |
- * | | P | | af1 USART1_TX |
- * | | P | | af1 USART1_RX |
- * | | P |JTDI | remap SPI1_NSS' |
- * | | P |JTDO | remap SPI1_SCK' |
- * | | P |JTRST | remap SPI1_MISO' |
- * | | P | | remap SPI1_MOSI' |
- * | | P | | af1 OSC32 |
- * | | P | | af1 OSC32 |
+ * | A0 | PA 0 | O | |
+ * | A1 | PA 1 | O | |
+ * | A2 | PA 2 | O | |
+ * | A3 | PA 3 | O | |
+ * | A4 | PA 4 | O | |
+ * | A5 | PA 5 | O | |
+ * | A6 | PA 6 | O | |
+ * | A7 | PA 7 | O | |
+ * | A8 | PC 0 | O | |
+ * | A9 | PC 1 | O | |
+ * | A10 | PC 2 | O | |
+ * | A11 | PC 3 | O | |
+ * | A12 | PC 4 | O | |
+ * | A13 | PC 5 | O | |
+ * | A14 | PC 6 | O | |
+ * | A15 | PC 7 | O | |
+ * | A16 | PE 2 | O | |
+ * | A17 | PE 3 | O | |
+ * | A18 | PE 4 | O | |
+ * | D0 | PF 0 | I/O | |
+ * | D1 | PF 1 | I/O | |
+ * | D2 | PF 2 | I/O | |
+ * | D3 | PF 3 | I/O | |
+ * | D4 | PF 4 | I/O | |
+ * | D5 | PF 5 | I/O | |
+ * | D6 | PF 6 | I/O | |
+ * | D7 | PF 7 | I/O | |
+ * | RD | PD 3 | O | |
+ * | WR | PD 2 | O | |
+ * | MREQ | PD 4 | O | |
+ * | RST | PD 5 | O | |
+ * | BUSREQ | PD 7 | O | |
+ * | BUSACK | PD 6 | I | |
+ * | IOCS1 | PE 5 | I | |
+ * |* HALT | P | | |
+ * |* NMI | P | | |
+ * | | P | | |
+ * | | P | | af1 USART1_TX |
+ * | | P | | af1 USART1_RX |
+ * | | P |JTDI | remap SPI1_NSS' |
+ * | | P |JTDO | remap SPI1_SCK' |
+ * | | P |JTRST | remap SPI1_MISO' |
+ * | | P | | remap SPI1_MOSI' |
+ * | | P | | af1 OSC32 |
+ * | | P | | af1 OSC32 |
*/
+
#include "common.h"
#include <util/atomic.h>
#include "debug.h"
@@ -117,6 +118,9 @@
//#define Z80_I_HALT SBIT(P_HALT, )
+#define BUS_TO 20
+
+
#define MASK(n) ((1<<(n))-1)
#define SMASK(w,s) (MASK(w) << (s))
@@ -129,6 +133,20 @@ typedef union {
static zstate_t zstate;
+static volatile uint8_t timer; /* used for bus timeout */
+
+/*---------------------------------------------------------*/
+/* 10Hz timer interrupt generated by OC4A */
+/*---------------------------------------------------------*/
+
+ISR(TIMER4_COMPA_vect)
+{
+
+ uint8_t i = timer;
+
+ if (i)
+ timer = i - 1;
+}
/*--------------------------------------------------------------------------*/
@@ -207,6 +225,13 @@ void z80_setup_bus(void)
z80_dbus_set_in();
zstate = RESET;
+
+ /* Timer 4 */
+ PRR1 &= ~_BV(PRTIM4);
+ OCR4A = F_CPU / 1024 / 10 - 1; /* Timer: 10Hz interval (OC4A) */
+ TCCR4B = (0b01<<WGM42)|(0b101<<CS30); /* CTC Mode, Prescaler 1024 */
+ TIMSK4 = _BV(OCIE4A); /* Enable oca interrupt */
+
}
@@ -228,40 +253,42 @@ static void z80_busreq_hpulse(void)
}
if (zstate & ZST_ACQUIRED) {
- while(Z80_I_BUSACK == 1)
+ timer = BUS_TO;
+ while (Z80_I_BUSACK == 1 && timer)
;
- z80_addrbus_set_active();
+ if (Z80_I_BUSACK == 0)
+ z80_addrbus_set_active();
}
}
/*
- + | | | | |
+ + | | | | |
+ State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
- + | | | | |
- + | 0 | 1 | 2 | 3 |
-Event + | | | | |
+ + | | | | |
+ + | 0 | 1 | 2 | 3 |
+Event + | | | | |
----------------+---------------+---------------+---------------+---------------+
- | | | | |
-Reset | 0 | 0 | 0 | 0 |
- | | | | |
- | | | | |
-Request | 1 | | 3 | |
- | | | | |
- | | | | |
-Release | | 0 | | 2 |
- | | | | |
- | | | | |
-Run | 2 | 3 | | |
- | | | | |
- | | | | |
-Restart | | | 2 | 3 |
- | | | | |
- | | | | |
-M_Cycle | | | | 3 |
- | | | | |
- | | | | |
+ | | | | |
+Reset | 0 | 0 | 0 | 0 |
+ | | | | |
+ | | | | |
+Request | 1 | | 3 | |
+ | | | | |
+ | | | | |
+Release | | 0 | | 2 |
+ | | | | |
+ | | | | |
+Run | 2 | 3 | | |
+ | | | | |
+ | | | | |
+Restart | | | 2 | 3 |
+ | | | | |
+ | | | | |
+M_Cycle | | | | 3 |
+ | | | | |
+ | | | | |
*/
zstate_t z80_bus_cmd(bus_cmd_t cmd)
@@ -281,18 +308,29 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
case RESET:
Z80_O_BUSREQ = 0;
Z80_O_RST = 1;
- while(Z80_I_BUSACK == 1)
+ timer = BUS_TO;
+ while (Z80_I_BUSACK == 1 && timer)
;
- z80_addrbus_set_active();
- zstate = RESET_AQRD;
+ if (Z80_I_BUSACK == 0) {
+ z80_addrbus_set_active();
+ zstate = RESET_AQRD;
+ } else {
+ Z80_O_RST = 0;
+ Z80_O_BUSREQ = 1;
+ }
break;
case RUNNING:
Z80_O_BUSREQ = 0;
- while(Z80_I_BUSACK == 1)
+ timer = BUS_TO;
+ while (Z80_I_BUSACK == 1 && timer)
;
- z80_addrbus_set_active();
- zstate = RUNNING_AQRD;
+ if (Z80_I_BUSACK == 0) {
+ z80_addrbus_set_active();
+ zstate = RUNNING_AQRD;
+ } else {
+ Z80_O_BUSREQ = 1;
+ }
break;
default:
@@ -353,7 +391,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
case M_Cycle:
switch (zstate) {
case RUNNING_AQRD:
- z80_busreq_hpulse();
+ z80_busreq_hpulse(); /* TODO: */
break;
default:
break;
@@ -411,8 +449,25 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
{
z80_dbus_set_out();
Z80_O_MREQ = 0;
+ P_DB = data;
while(length--) {
z80_setaddress(addr++);
+ Z80_O_WR = 0;
+ Z80_O_WR = 0;
+ Z80_O_WR = 1;
+ }
+ Z80_O_MREQ = 1;
+}
+
+void z80_write_block_P(const FLASH uint8_t *src, uint32_t dest, uint32_t length)
+{
+ uint8_t data;
+
+ z80_dbus_set_out();
+ Z80_O_MREQ = 0;
+ while(length--) {
+ z80_setaddress(dest++);
+ data = *src++;
P_DB = data;
P_DB = data;
Z80_O_WR = 0;
@@ -422,7 +477,7 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
Z80_O_MREQ = 1;
}
-void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
+void z80_write_block(const uint8_t *src, uint32_t dest, uint32_t length)
{
uint8_t data;
@@ -440,6 +495,25 @@ void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
Z80_O_MREQ = 1;
}
+void z80_read_block (uint8_t *dest, uint32_t src, size_t length)
+{
+ uint8_t data;
+
+ Z80_O_MREQ = 0;
+ z80_dbus_set_in();
+ while(length--) {
+ z80_setaddress(src++);
+ Z80_O_RD = 0;
+ Z80_O_RD = 0;
+ Z80_O_RD = 0;
+ data = PIN_DB;
+ Z80_O_RD = 1;
+ *dest++ = data;
+ }
+ Z80_O_MREQ = 1;
+}
+
+
/*
0179' rx.bs_mask: ds 1 ; (buf_len - 1)
017A' rx.in_idx: ds 1 ;
diff --git a/include/z80-if.h b/include/z80-if.h
index 24fda5d..d4ee57b 100644
--- a/include/z80-if.h
+++ b/include/z80-if.h
@@ -31,11 +31,13 @@ int z80_stat_halt(void);
void z80_write(uint32_t addr, uint8_t data);
uint8_t z80_read(uint32_t addr);
void z80_memset(uint32_t addr, uint8_t data, uint32_t length);
-void z80_write_block(const FLASH uint8_t *src, uint32_t dest, uint32_t length);
+void z80_write_block_P(const FLASH uint8_t *src, uint32_t dest, uint32_t length);
+void z80_write_block(const uint8_t *src, uint32_t dest, uint32_t length);
+void z80_read_block (uint8_t *dest, uint32_t src, size_t length);
typedef enum fifo_t {
- fifo_msgin, fifo_msgout,
+ fifo_msgin, fifo_msgout,
fifo_conout, fifo_conin,
NUM_FIFOS
} fifo_t;
@@ -46,4 +48,3 @@ int z80_memfifo_is_full(const fifo_t f);
int z80_memfifo_getc(const fifo_t f);
uint8_t z80_memfifo_getc_wait(const fifo_t f);
void z80_memfifo_putc(fifo_t f, uint8_t val);
-