diff options
author | Leo C | 2014-11-25 10:53:39 +0100 |
---|---|---|
committer | Leo C | 2014-11-25 10:53:39 +0100 |
commit | ea6971b809eae9ca238cd859316fdcef2839b002 (patch) | |
tree | 0da98ff5e85175fb2879d9f32eb8e69dd6b65131 /avr | |
parent | c79c80b49dcde54add2e9ba323c9d07033723f52 (diff) | |
download | z180-stamp-ea6971b809eae9ca238cd859316fdcef2839b002.zip |
Timeout for Z180 bus access
Diffstat (limited to 'avr')
-rw-r--r-- | avr/cmd_boot.c | 7 | ||||
-rw-r--r-- | avr/cmd_mem.c | 58 | ||||
-rw-r--r-- | avr/z80-if.c | 232 |
3 files changed, 198 insertions, 99 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 ; |