z80: rework wait state / break point logic

Change-Id: I2b41c014165e8d753693d3ed7806087e85202a6e
This commit is contained in:
David Banks 2019-10-14 17:33:32 +01:00
parent 4c746994cb
commit d9d552475a

View File

@ -105,7 +105,6 @@ type state_type is (idle, nop_t1, nop_t2, nop_t3, nop_t4, rd_t1, rd_wa, rd_t2, r
signal SS_Single : std_logic; signal SS_Single : std_logic;
signal SS_Step : std_logic; signal SS_Step : std_logic;
signal SS_Step_held : std_logic; signal SS_Step_held : std_logic;
signal SS_Running : std_logic;
signal CountCycle : std_logic; signal CountCycle : std_logic;
signal skipNextOpcode : std_logic; signal skipNextOpcode : std_logic;
@ -146,6 +145,7 @@ type state_type is (idle, nop_t1, nop_t2, nop_t3, nop_t4, rd_t1, rd_wa, rd_t2, r
signal WriteIO_n0 : std_logic; signal WriteIO_n0 : std_logic;
signal Sync : std_logic; signal Sync : std_logic;
signal Sync0 : std_logic; signal Sync0 : std_logic;
signal Sync1 : std_logic;
signal Mem_IO_n : std_logic; signal Mem_IO_n : std_logic;
signal nRST : std_logic; signal nRST : std_logic;
@ -281,38 +281,32 @@ begin
); );
end generate; end generate;
--------------------------------------------------------
-- Synchronise external interrupts
--------------------------------------------------------
int_gen : process(CLK_n)
begin
if rising_edge(CLK_n) then
NMI_n_sync <= NMI_n;
INT_n_sync <= INT_n;
end if;
end process;
-------------------------------------------------------- --------------------------------------------------------
-- Z80 specific single step / breakpoint logic -- Z80 specific single step / breakpoint logic
-------------------------------------------------------- --------------------------------------------------------
WAIT_n_int <= WAIT_n and SS_Running; CountCycle <= '1' when state = idle else '0';
CountCycle <= '1' when SS_Single = '0' or SS_Running = '1' else '0'; -- For the break point logic to work, the following must happen
-- SS_Single taken high by BusMonCore on the rising edge at the start of T2
-- WAIT_n_int must be taken low before the falling edge in the middle of T2
-- This implies a combinatorial path from SS_Single to WAIT_n_int
sync_gen : process(CLK_n, RESET_n_int) WAIT_n_int <= '0' when state = idle and SS_Single = '1' and Sync1 = '1' else
begin '0' when state /= idle else
if RESET_n_int = '0' then WAIT_n;
NMI_n_sync <= '1';
INT_n_sync <= '1';
SS_Running <= '1';
SS_Step_held <= '0';
elsif rising_edge(CLK_n) then
NMI_n_sync <= NMI_n;
INT_n_sync <= INT_n;
if Sync0 = '1' and SS_Single = '1' then
-- stop at the end of T1 instruction fetch
SS_Running <= '0';
elsif SS_Step_held = '1' and state = nop_t4 then
-- start again when the single step command is issued
SS_Running <= '1';
end if;
if SS_Step = '1' then
SS_Step_held <= '1';
elsif SS_Running = '1' then
SS_Step_held <= '0';
end if;
end if;
end process;
-- Logic to ignore the second M1 in multi-byte opcodes -- Logic to ignore the second M1 in multi-byte opcodes
skip_opcode_latch : process(CLK_n) skip_opcode_latch : process(CLK_n)
@ -419,6 +413,7 @@ begin
memory_wr1 <= '0'; memory_wr1 <= '0';
io_rd1 <= '0'; io_rd1 <= '0';
io_wr1 <= '0'; io_wr1 <= '0';
SS_Step_held <= '0';
elsif rising_edge(CLK_n) then elsif rising_edge(CLK_n) then
@ -444,13 +439,20 @@ begin
elsif state = wr_t1 then elsif state = wr_t1 then
io_wr1 <= '0'; io_wr1 <= '0';
end if; end if;
if SS_Step = '1' then
SS_Step_held <= '1';
elsif state = idle then
SS_Step_held <= '0';
end if;
Sync1 <= Sync0;
-- Main state machine, generating refresh, read and write cycles -- Main state machine, generating refresh, read and write cycles
-- (the timing should exactly match those of the Z80) -- (the timing should exactly match those of the Z80)
case state is case state is
-- Idle is when T80 is running -- Idle is when T80 is running
when idle => when idle =>
if SS_Running = '0' then if SS_Single = '1' and Sync1 = '1' then
-- If the T80 is stopped, start genering refresh cycles -- If the T80 is stopped, start genering refresh cycles
state <= nop_t1; state <= nop_t1;
-- Load the initial refresh address from I/R in the T80 -- Load the initial refresh address from I/R in the T80