From f338df2abc35f85961aa6266458f94ea2a102b81 Mon Sep 17 00:00:00 2001 From: Leo C Date: Mon, 18 Aug 2014 23:40:36 +0200 Subject: [PATCH] Command 'go ' works now Add debug command to display AVR RAM --- avr/cmd_boot.c | 75 ++++++++++---- avr/cmd_mem.c | 34 +++---- avr/command.c | 4 +- avr/command_tbl.c | 18 +++- avr/debug.c | 103 ++++++++++++++----- avr/main.c | 37 +++++++ avr/z180-serv.c | 3 +- avr/z80-if.c | 249 ++++++++++++++++++++++++++++++++++++---------- avr/z80-if.h | 27 +++-- 9 files changed, 427 insertions(+), 123 deletions(-) diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c index 4fb9c2a..8c17799 100644 --- a/avr/cmd_boot.c +++ b/avr/cmd_boot.c @@ -4,6 +4,7 @@ */ #include "common.h" #include +#include #include #include "command.h" @@ -29,11 +30,11 @@ static void z80_load_mem(void) hdrom_address[sec]+hdrom_length_of_sections[sec] - 1, hdrom_length_of_sections[sec]); - z80_request_bus(); + zstate_t state = z80_request_bus_save(); z80_write_block((const FLASH unsigned char *) &hdrom[sec_base], /* src */ hdrom_address[sec], /* dest */ hdrom_length_of_sections[sec]); /* len */ - z80_release_bus(); + z80_release_bus_save(state); sec_base+=hdrom_length_of_sections[sec]; sec++; } @@ -43,7 +44,7 @@ int do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { (void) cmdtp; (void) flag; (void) argc; (void) argv; - if (z80_runstate() != 0) { + if (z80_runstate() & ZST_RUNNING) { printf_P(PSTR("## Can't load while CPU is running!\n")); return 1; } @@ -54,34 +55,72 @@ int do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } -int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - uint32_t addr; + uint16_t count=1; - (void) cmdtp; (void) flag; (void) argc; + (void) cmdtp; (void) flag; - if (z80_runstate() != 0) { - printf_P(PSTR("## CPU allready running!\n")); + if (!(z80_runstate() & ZST_RUNNING)) { + printf_P(PSTR("## CPU is not running!\n")); return 1; } - addr = strtoul(argv[1], NULL, 16); + if (argc > 1) + count = (uint16_t) strtoul(argv[2], NULL, 16); + + z80_request_bus(); + while (count--) + z80_busreq_hpulse(); - if (addr > (1UL<<16) - 1) { + return 0; +} + + +int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + uint32_t addr; + + (void) cmdtp; (void) flag; + + if (argc < 2) + return CMD_RET_USAGE; + addr = strtoul(argv[1], NULL, 16); + if (addr >= (1UL<<16)) { printf_P(PSTR("## Startaddress 0x%05lx too high.\n" " (Out of logical address space (0x00000-0x0ffff))\n"), addr); return 1; - } else if (addr != 0) { - printf_P(PSTR("## Starting application at " - "address != 0x0000 not implemented yet.\n")); + } + + if (z80_runstate() & ZST_RUNNING) { + printf_P(PSTR("## CPU allready running!\n")); return 1; - } else { - printf_P(PSTR("## Starting application at 0x%05lX ...\n"), addr); - z80_release_bus(); - z80_reset(HIGH); } + printf_P(PSTR("## Starting application at 0x%04lx ...\n"), addr); + + if (addr != 0) { + uint8_t tmp[3]; + uint_fast8_t i; + + z80_request_bus(); + for (i = 0; i < 3; i++) + tmp[i] = z80_read(i); + z80_write(0, 0xc3); + z80_write(1, addr); + z80_write(2, (addr >> 8)); + + z80_run(); + z80_busreq_hpulse(); + z80_busreq_hpulse(); + for (i = 0; i < 3; i++) + z80_write(i, tmp[i]); + } else + z80_run(); + + z80_release_bus(); + return 0; } @@ -90,7 +129,7 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) (void) cmdtp; (void) flag; (void) argc; (void) argv; printf_P(PSTR("## CPU now in reset state.\n")); - z80_reset(LOW); + z80_reset(); return 0; } diff --git a/avr/cmd_mem.c b/avr/cmd_mem.c index df30196..49a46f6 100644 --- a/avr/cmd_mem.c +++ b/avr/cmd_mem.c @@ -65,10 +65,10 @@ int z180_dump_mem(uint32_t startaddr, uint32_t len, const char *title) if (len < 16) llen = len; - z80_request_bus(); + zstate_t state = z80_request_bus_save(); for (i = pre; i < llen; i++) buf[i] = z80_read(addr + i); - z80_release_bus(); + z80_release_bus_save(state); printf_P(PSTR("%.5lx:"), addr); #if 0 @@ -193,12 +193,12 @@ int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) count = 1; } - z80_request_bus(); + zstate_t state = z80_request_bus_save(); while (count-- > 0) { z80_write(addr, writeval); ++addr; } - z80_release_bus(); + z80_release_bus_save(state); return 0; } @@ -281,10 +281,10 @@ int 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_request_bus(); + zstate_t state = z80_request_bus_save(); byte1 = z80_read(addr1); byte2 = z80_read(addr2); - z80_release_bus(); + z80_release_bus_save(state); if (byte1 != byte2) { printf( "byte at 0x%05lx (%#02x) != " "byte at 0x%05lx (%#02x)\n", @@ -337,10 +337,10 @@ int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (count-- > 0) { uint8_t data; - z80_request_bus(); + zstate_t state = z80_request_bus_save(); data = z80_read(src); z80_write(dest, data); - z80_release_bus(); + z80_release_bus_save(state); src += step; dest += step; @@ -390,20 +390,20 @@ int 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_request_bus(); + zstate_t state = z80_request_bus_save(); for (;;) z80_read(addr); - z80_release_bus(); + z80_release_bus_save(state); } - z80_request_bus(); + zstate_t state = z80_request_bus_save(); for (;;) { uint32_t i = length; uint32_t p = addr; while (i-- > 0) z80_read(p++); } - z80_release_bus(); + z80_release_bus_save(state); return 0; } @@ -432,7 +432,7 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * If we have only one object, just run infinite loops. */ if (length == 1) { - z80_request_bus(); + zstate_t state = z80_request_bus_save(); for (;;) z80_write(addr, data); } @@ -844,10 +844,10 @@ 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_request_bus(); + zstate_t state = z80_request_bus_save(); data = z80_read(addr); printf("%05lx: %02x", addr, data); - z80_release_bus(); + z80_release_bus_save(state); nbytes = cli_readline(PSTR(" ? ")); if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) { @@ -863,9 +863,9 @@ 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_request_bus(); + zstate_t state = z80_request_bus_save(); z80_write(addr, data); - z80_release_bus(); + z80_release_bus_save(state); if (incrflag) addr++; } diff --git a/avr/command.c b/avr/command.c index 89e8869..df4bb98 100644 --- a/avr/command.c +++ b/avr/command.c @@ -21,7 +21,7 @@ static void print_blanks(int_fast8_t count) { while(count--) - putchar(' '); + my_puts_P(PSTR(" ")); } static void print_usage_line(const FLASH char *name, const FLASH char *usage) @@ -177,7 +177,7 @@ int cmd_usage(const FLASH cmd_tbl_t *cmdtp) // printf("Usage:\n%s ", cmdtp->name); my_puts_P(PSTR("Usage:\n")); my_puts_P(cmdtp->name); - putchar(' '); + my_puts_P(PSTR(" ")); if (!cmdtp->help) { my_puts_P(PSTR(" - No additional help available.\n")); diff --git a/avr/command_tbl.c b/avr/command_tbl.c index 31566b4..69f6273 100644 --- a/avr/command_tbl.c +++ b/avr/command_tbl.c @@ -13,24 +13,36 @@ extern int do_env_save(cmd_tbl_t *, int, int, char * const []); extern int do_loadf(cmd_tbl_t *, int, int, char * const []); extern int do_go(cmd_tbl_t *, int, int, char * const []); extern int do_restart(cmd_tbl_t *, int, int, char * const []); -extern int do_dump_eep(cmd_tbl_t *, int, int, char * const []); +extern int do_dump_mem(cmd_tbl_t *, int, int, char * const []); extern int do_eep_cp(cmd_tbl_t *, int, int, char * const []); +extern int do_busreq_pulse(cmd_tbl_t *, int, int, char * const []); cmd_tbl_t cmd_tbl[] = { #ifdef DEBUG CMD_TBL_ITEM( - !emd, 3, 0, do_dump_eep, + !mdr, 3, 1, do_dump_mem, + "RAM dump", + "address [count]" +), +CMD_TBL_ITEM( + !mde, 3, 1, do_dump_mem, "EEPROM dump", "address [count]" ), CMD_TBL_ITEM( - !ecp, 4, 1, do_eep_cp, + !cpe, 4, 0, do_eep_cp, "EEPROM copy", "source target count" ), #endif +CMD_TBL_ITEM( + mstep, 2, 1, do_busreq_pulse, + "execute one M cycle", + "[count]\n" + " - repeat count times" +), CMD_TBL_ITEM( echo, CONFIG_SYS_MAXARGS, 1, do_echo, "echo args to console", diff --git a/avr/debug.c b/avr/debug.c index 620eb4d..e62869b 100644 --- a/avr/debug.c +++ b/avr/debug.c @@ -1,5 +1,6 @@ #include "common.h" #include +#include #include #include @@ -11,6 +12,7 @@ */ #ifdef DEBUG +//uint8_t eeprom_read_byte (const uint8_t *__p) static void print_blanks(uint_fast8_t count) { @@ -18,7 +20,54 @@ static void print_blanks(uint_fast8_t count) putchar(' '); } +static uint8_t ram_read_byte(const uint8_t *p) +{ + return *p; +} +void dump_mem(const uint8_t *startaddr, int len, + uint8_t (*readfkt)(const uint8_t *), char *title) +{ + uint8_t buf[16]; + uint8_t llen = 16; + uint8_t pre = (size_t) startaddr % 16; + const uint8_t *addr = (uint8_t *) ((size_t) startaddr & ~0x0f); + len += pre; + uint8_t i; + + if (title && *title) + printf_P(PSTR("%s\n"),title); + + while (len) { + if (len < 16) + llen = len; + + for (i = pre; i < llen; i++) + buf[i] = readfkt(addr + i); + + printf_P(PSTR("%04x:"), addr); + for (i = 0; i < llen; i++) { + if ((i % 8) == 0) + putchar(' '); + if (i < pre) + printf_P(PSTR(".. ")); + else + printf_P(PSTR("%.2x "), buf[i]); + } + /* fill line with whitespace for nice ASCII print */ + print_blanks(3 * (16u - i) + (16u-i)/8 + 1 + pre); + /* Print data in ASCII characters */ + for (i = pre; i < llen; i++) + printf_P(PSTR("%c"), isprint(buf[i]) ? buf[i] : '.'); + putchar('\n'); + + pre = 0; + addr += 16; + len -= llen; + } +} + +#if 0 void dump_ram(const uint8_t *startaddr, int len, char *title) { uint8_t llen = 16; @@ -48,7 +97,8 @@ void dump_ram(const uint8_t *startaddr, int len, char *title) len -= llen; } } - +#endif +#if 0 void dump_heap(void) { extern unsigned int __brkval; @@ -57,9 +107,12 @@ void dump_heap(void) __brkval - (unsigned int) __malloc_heap_start, "=== Heap:"); } +#endif +#if 0 /* TODO: combine with dump_ram() */ -void dump_eep(const uint8_t *addr, unsigned int len) +void dump_eep(const uint8_t *addr, unsigned int len, + uint8_t (*readfkt)(const uint8_t *)) { uint_fast8_t i; uint8_t buf[16]; @@ -68,7 +121,7 @@ void dump_eep(const uint8_t *addr, unsigned int len) while (len) { printf_P(PSTR("\n 0x%.4x:"), (unsigned int) addr); for (i = 0; i<16; i++) - buf[i] = eeprom_read_byte(addr + i); + buf[i] = readfkt(addr + i); for (i = 0; i<16; i++) printf_P(PSTR(" %.2x"), buf[i]); printf_P(PSTR(" ")); @@ -80,39 +133,43 @@ void dump_eep(const uint8_t *addr, unsigned int len) } putchar('\n'); } +#endif + /* * EEPROM Display * md addr {len} */ -int do_dump_eep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int do_dump_mem(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - const uint8_t *addr; - uint16_t length; - - (void) cmdtp; - - - /* We use the last specified parameters, unless new ones are - * entered. - */ - addr = 0; - length = 128; +// static const uint8_t *addr; +// static uint16_t length = 128; + uint8_t (*readhow)(const uint8_t *); + + (void) cmdtp; (void) flag; if (argc < 2) return CMD_RET_USAGE; - if ((flag & CMD_FLAG_REPEAT) == 0) { - /* Address is specified since argc > 1 */ - addr = (const uint8_t *) (size_t) strtoul(argv[1], NULL, 16); + const uint8_t *addr; + uint16_t length = 128; + + if (strchr(argv[0],'r') != NULL) + readhow = ram_read_byte; + else if (strchr(argv[0],'e') != NULL) + readhow = eeprom_read_byte; + else + return CMD_RET_USAGE; - /* If another parameter, it is the length to display. */ - if (argc > 2) - length = (uint16_t) strtoul(argv[2], NULL, 16); - } + /* Address is specified since argc > 1 */ + addr = (const uint8_t *) (size_t) strtoul(argv[1], NULL, 16); + + /* If another parameter, it is the length to display. */ + if (argc > 2) + length = (uint16_t) strtoul(argv[2], NULL, 16); /* Print the lines. */ - dump_eep(addr, length); + dump_mem(addr, length, readhow, NULL); return 0; } diff --git a/avr/main.c b/avr/main.c index 79ca3e0..5c4cd0c 100644 --- a/avr/main.c +++ b/avr/main.c @@ -29,8 +29,15 @@ /*--------------------------------------------------------------------------*/ +static uint8_t mcusr; + +static void setup_avr(void) { + /* save and clear reset reason(s) */ + mcusr = MCUSR; + MCUSR = 0; + /* WD */ /* CPU */ @@ -59,6 +66,30 @@ void setup_avr(void) TIMSK1 = _BV(OCIE1A); // Enable TC1.oca interrupt } +static const FLASH char * const FLASH rreasons[] = { + FSTR("Power on"), + FSTR("External"), + FSTR("Brown out"), + FSTR("Watchdog"), + FSTR("JTAG"), + }; + +static +void print_reset_reason(void) +{ + uint8_t r = mcusr & 0x1f; + const FLASH char * const FLASH *p = rreasons; + + printf_P(PSTR("Reset reason(s): ")); + for ( ; r; p++, r >>= 1) { + if (r & 1) { + my_puts_P(*p); + if (r & ~1) + printf_P(PSTR(", ")); + } + } + printf_P(PSTR(".\n")); +} /*******************************************************************************/ @@ -120,6 +151,7 @@ static int abortboot(int bootdelay) return abort; } +static const char *bootdelay_process(void) { char *s; @@ -137,6 +169,7 @@ const char *bootdelay_process(void) return s; } +static void autoboot_command(const char *s) { debug("### main_loop: bootcmd=\"%s\"\n", s ? s : PSTR("")); @@ -148,6 +181,7 @@ void autoboot_command(const char *s) } +static void main_loop(void) { const char *s; @@ -166,6 +200,9 @@ int main(void) sei(); debug("\n=========================< (RE)START DEBUG >=========================\n"); +#if DEBUG + print_reset_reason(); +#endif env_init(); diff --git a/avr/z180-serv.c b/avr/z180-serv.c index a4ff057..051d6ef 100644 --- a/avr/z180-serv.c +++ b/avr/z180-serv.c @@ -255,6 +255,7 @@ void check_msg_fifo(void) /*--------------------------------------------------------------------------*/ +#if 0 void dump_mem(const FLASH uint8_t *addr, uint32_t len) { DBG_P(1, "hdrom dump:"); @@ -266,7 +267,7 @@ void dump_mem(const FLASH uint8_t *addr, uint32_t len) } DBG_P(1, "\n"); } - +#endif /*--------------------------------------------------------------------------*/ diff --git a/avr/z80-if.c b/avr/z80-if.c index 949de17..ab8e293 100644 --- a/avr/z80-if.c +++ b/avr/z80-if.c @@ -55,6 +55,7 @@ #include #include +#include #include #include "debug.h" #include "z80-if.h" @@ -137,48 +138,6 @@ struct bits { //#define Z80_I_HALT SBIT(P_HALT, ) -#if 0 -void z80_busreq(level_t level) -{ - Z80_O_BUSREQ = level; -} -#endif - -void z80_reset(level_t level) -{ - Z80_O_RST = level; - if (level) - Stat |= S_Z180_RUNNING; - else - Stat &= ~S_Z180_RUNNING; -} - -int z80_stat_reset(void) -{ - return Z80_O_RST; -} - -void z80_reset_pulse(void) -{ - Z80_O_RST = 0; - _delay_us(10); - Z80_O_RST = 1; - Stat |= S_Z180_RUNNING; -} - -int z80_runstate(void) -{ - return (Stat & S_Z180_RUNNING) != 0; -} - -#if 0 -int z80_stat_halt(void) -{ - return Z80_I_HALT; -} -#endif - - #define MASK(n) ((1<<(n))-1) #define SMASK(w,s) (MASK(w) << (s)) @@ -189,7 +148,9 @@ typedef union { uint16_t w[2]; uint8_t b[4]; } addr_t; - + + +static zstate_t zstate; /*--------------------------------------------------------------------------*/ @@ -258,32 +219,214 @@ void z80_setup_bus(void) z80_setup_addrbus_tristate(); z80_setup_dbus_in(); - Stat &= ~S_Z180_RUNNING; + zstate = RESET; +// Stat &= ~S_Z180_RUNNING; } +/*--------------------------------------------------------------------------*/ +#if 0 + switch (zstate) { + case RESET: + break; + case RESET_AQRD: + break; + case RUN: + break; + case RUN_AQRD: + break; + } +#endif /*--------------------------------------------------------------------------*/ -void z80_request_bus(void) +#if 0 +void z80_busreq(level_t level) +{ + Z80_O_BUSREQ = level; +} + +int z80_stat_reset(void) +{ +// return Z80_O_RESET; +} + +int z80_stat_halt(void) +{ + return Z80_I_HALT; +} +#endif + + +zstate_t z80_runstate(void) +{ + return zstate; +} + +void z80_reset(void) +{ +#if DEBUG + zstate_t old = zstate; +#endif + z80_setup_dbus_in(); + z80_setup_addrbus_tristate(); + Z80_O_RST = 0; + Z80_O_BUSREQ = 1; + zstate = RESET; + + debug("z80_reset: state: %02x --> %02x\n", old, zstate); +} + +void z80_reset_pulse(void) { - Z80_O_BUSREQ = 0; +#if DEBUG + zstate_t old = zstate; +#endif + switch (zstate) { + case RESET: + case RESET_AQRD: + break; - if (!(Stat & S_Z180_RUNNING)) + case RUN: + case RUN_AQRD: + Z80_O_RST = 0; + _delay_us(10); Z80_O_RST = 1; + break; + } - while(Z80_I_BUSACK == 1); - z80_setup_addrbus_active(); + debug("z80_reset_pulse: state: %02x --> %02x\n", old, zstate); +} + +void z80_request_bus(void) +{ +#if DEBUG + zstate_t old = zstate; +#endif + + switch (zstate) { + case RESET: + Z80_O_BUSREQ = 0; + Z80_O_RST = 1; + while(Z80_I_BUSACK == 1) + ; + z80_setup_addrbus_active(); + zstate = RESET_AQRD; + break; + + case RESET_AQRD: + break; + + case RUN: + Z80_O_BUSREQ = 0; + while(Z80_I_BUSACK == 1); + z80_setup_addrbus_active(); + zstate = RUN_AQRD; + break; + + case RUN_AQRD: + break; + } + debug("z80_request_bus: state: %02x --> %02x\n", old, zstate); } void z80_release_bus(void) +{ +#if DEBUG + zstate_t old = zstate; +#endif + switch (zstate) { + case RESET: + break; + case RESET_AQRD: + z80_setup_dbus_in(); + z80_setup_addrbus_tristate(); + Z80_O_RST = 0; + Z80_O_BUSREQ = 1; + zstate = RESET; + break; + case RUN: + break; + case RUN_AQRD: + z80_setup_dbus_in(); + z80_setup_addrbus_tristate(); + Z80_O_BUSREQ = 1; + zstate = RUN; + break; + } + + debug("z80_release_bus: state: %02x --> %02x\n", old, zstate); +} + +/* + * Do nothing, if we have the bus allready + * + * return previous state + */ +zstate_t z80_request_bus_save(void) +{ + zstate_t state; + + state = z80_runstate(); + if (!(state & ZST_ACQUIRED)) + z80_request_bus(); + + return state; +} + +/* + * Do nothing, if we had the bus before + */ +void z80_release_bus_save(zstate_t prev) +{ + if (!(prev & ZST_ACQUIRED)) + z80_release_bus(); +} + +void z80_run(void) +{ +#if DEBUG + zstate_t old = zstate; +#endif + switch (zstate) { + case RESET: + Z80_O_RST = 1; + zstate = RUN; + break; + + case RESET_AQRD: + z80_setup_dbus_in(); + z80_setup_addrbus_tristate(); + Z80_O_RST = 0; + _delay_us(10); + Z80_O_RST = 1; + z80_setup_addrbus_active(); + zstate = RUN_AQRD; + break; + + case RUN: + break; + case RUN_AQRD: + break; + } + + debug("z80_run: state: %02x --> %02x\n", old, zstate); +} + +void z80_busreq_hpulse(void) { z80_setup_dbus_in(); z80_setup_addrbus_tristate(); - if (!(Stat & S_Z180_RUNNING)) - Z80_O_RST = 0; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + Z80_O_BUSREQ = 1; + Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */ + Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */ + } - Z80_O_BUSREQ = 1; - //while(Z80_I_BUSACK == 0); + if (zstate & ZST_ACQUIRED) { + while(Z80_I_BUSACK == 1) + ; + z80_setup_addrbus_active(); + } } /*--------------------------------------------------------------------------*/ diff --git a/avr/z80-if.h b/avr/z80-if.h index a2617ce..b656447 100644 --- a/avr/z80-if.h +++ b/avr/z80-if.h @@ -1,20 +1,35 @@ +#define ZST_ACQUIRED 0x01 +#define ZST_RUNNING 0x02 + +typedef enum { + RESET = 0x00, + RESET_AQRD = ZST_ACQUIRED, + RUN = ZST_RUNNING, + RUN_AQRD = ZST_RUNNING | ZST_ACQUIRED, +} zstate_t; + typedef enum {LOW, HIGH} level_t; +zstate_t z80_runstate(void); void z80_setup_bus(void); -void z80_write(uint32_t addr, uint8_t data); -uint8_t z80_read(uint32_t addr); void z80_request_bus(void); void z80_release_bus(void); -void z80_memset(uint32_t addr, uint8_t data, uint32_t length); -void z80_reset(level_t level); +zstate_t z80_request_bus_save(void); +void z80_release_bus_save(zstate_t prev); +void z80_reset(void); void z80_reset_pulse(void); +void z80_run(void); int z80_stat_reset(void); -int z80_runstate(void); //void z80_busreq(level_t level); -void z80_write_block(const FLASH uint8_t *src, uint32_t dest, uint32_t length); +void z80_busreq_hpulse(void); 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); + typedef enum fifo_t {fifo_in, fifo_out, NUM_FIFOS} fifo_t; -- 2.39.2