]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
Command 'go <startaddr>' works now
authorLeo C <erbl259-lmu@yahoo.de>
Mon, 18 Aug 2014 21:40:36 +0000 (23:40 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Mon, 18 Aug 2014 21:40:36 +0000 (23:40 +0200)
Add debug command to display AVR RAM

avr/cmd_boot.c
avr/cmd_mem.c
avr/command.c
avr/command_tbl.c
avr/debug.c
avr/main.c
avr/z180-serv.c
avr/z80-if.c
avr/z80-if.h

index 4fb9c2ab53affdc84e199b83e0c79708005fd0ca..8c1779940d0de84751136a3ed9ae61eed90d6606 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include "common.h"
 #include <stdlib.h>
+#include <util/delay.h>
 #include <avr/pgmspace.h>
 
 #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;
 }
index df30196709e770584241f0717734ecab5208d0d1..49a46f6921151eaba6c88940e5ecc463977eac63 100644 (file)
@@ -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++;
                        }
index 89e88695c2289a5684cfc23f2faae05b3a3a80bb..df4bb98cff1ea0f32732c62cfe2e2ff94cec7f06 100644 (file)
@@ -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"));
index 31566b4c1253d9d22498f85da9cb6b1411893ff6..69f6273097a6980b38c9bcc3a24d93a9aaa357d4 100644 (file)
@@ -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",
index 620eb4dc372f523ff49b06d4ae1f9458ef2333dc..e62869b965fa95283d38e6d52ddb6eab6910d0a5 100644 (file)
@@ -1,5 +1,6 @@
 #include "common.h"
 #include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 #include <avr/eeprom.h>
 
@@ -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;
 }
index 79ca3e02e16ed7cedce8fa9d664fb3cdf10fa818..5c4cd0c0bca48ebdd29bf0242c67e715df061f5e 100644 (file)
 
 /*--------------------------------------------------------------------------*/
 
+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("<UNDEFINED>"));
@@ -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();
 
index a4ff05735acbe94084b9ec664328682246246317..051d6ef108cae2ea7b5418b753a83c44c32c0aad 100644 (file)
@@ -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
 /*--------------------------------------------------------------------------*/
 
 
index 949de17ffec7b19a9c1ca758b506c3d831e9fd63..ab8e293e2612c1ad315612886f7162a8a4f91c16 100644 (file)
@@ -55,6 +55,7 @@
 
 #include <avr/io.h>
 #include <util/delay.h>
+#include <util/atomic.h>
 #include <stdio.h>
 #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();
+       }
 }
 
 /*--------------------------------------------------------------------------*/
index a2617ce94a0151508670a7e5f7f8551de45f6e81..b656447fa2e36dcdbf71a8970b37cc179cbd918e 100644 (file)
@@ -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;