diff options
Diffstat (limited to 'avr/z80-if.c')
-rw-r--r-- | avr/z80-if.c | 249 |
1 files changed, 196 insertions, 53 deletions
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(); + } } /*--------------------------------------------------------------------------*/ |