summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
authorLeo C2014-08-18 23:40:36 +0200
committerLeo C2014-08-18 23:40:36 +0200
commitf338df2abc35f85961aa6266458f94ea2a102b81 (patch)
tree2f608280c2368cda835b6de19fa0ff8f6c85dfd7 /avr
parent1da3acc4b7215e76d459905c3e74675ffa679ce0 (diff)
downloadz180-stamp-f338df2abc35f85961aa6266458f94ea2a102b81.zip
Command 'go <startaddr>' works now
Add debug command to display AVR RAM
Diffstat (limited to 'avr')
-rw-r--r--avr/cmd_boot.c75
-rw-r--r--avr/cmd_mem.c34
-rw-r--r--avr/command.c4
-rw-r--r--avr/command_tbl.c18
-rw-r--r--avr/debug.c103
-rw-r--r--avr/main.c37
-rw-r--r--avr/z180-serv.c3
-rw-r--r--avr/z80-if.c249
-rw-r--r--avr/z80-if.h27
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 <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;
}
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,25 +13,37 @@ 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",
"[args..]\n"
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 <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;
}
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("<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();
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 <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();
+ }
}
/*--------------------------------------------------------------------------*/
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;