Z80: Stop T80 in T3 not T2 (work in progress)

Change-Id: I19fa754cc09a068b628116b9636a995c162ad964
This commit is contained in:
David Banks 2019-10-27 14:52:42 +00:00
parent d479dedf4b
commit e76bdc6da2
2 changed files with 85 additions and 74 deletions

View File

@ -77,6 +77,7 @@ entity T80a is
-- Original Signals
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
@ -98,7 +99,6 @@ end T80a;
architecture rtl of T80a is
signal CEN : std_logic;
signal Reset_s : std_logic;
signal IntCycle_n : std_logic;
signal IORQ : std_logic;
@ -125,7 +125,6 @@ architecture rtl of T80a is
begin
CEN <= '1';
BUSAK_n <= BUSAK_n_i;
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
@ -183,13 +182,14 @@ begin
Regs(255 downto 212) <= (others => '0');
process (CLK_n)
begin
if CLK_n'event and CLK_n = '0' then
Wait_s <= WAIT_n;
if TState = "011" and BUSAK_n_i = '1' then
DI_Reg <= to_x01(Din);
if CEN = '1' then
Wait_s <= WAIT_n;
if TState = "011" and BUSAK_n_i = '1' then
DI_Reg <= to_x01(Din);
end if;
end if;
end if;
end process;
@ -197,7 +197,7 @@ begin
process (CLK_n) -- 0247a
begin
if CLK_n'event and CLK_n = '1' then
-- IReq_Inhibit <= not IORQ;
-- IReq_Inhibit <= not IORQ;
end if;
end process;
@ -206,17 +206,19 @@ begin
if Reset_s = '0' then
WR_n_i <= '1';
elsif CLK_n'event and CLK_n = '0' then
if (IORQ = '0') then
if TState = "010" then
WR_n_i <= not Write;
elsif Tstate = "011" then
WR_n_i <= '1';
end if;
else
if TState = "001" and IORQ_n_i = '0' then
WR_n_i <= not Write;
elsif Tstate = "011" then
WR_n_i <= '1';
if CEN = '1' then
if (IORQ = '0') then
if TState = "010" then
WR_n_i <= not Write;
elsif Tstate = "011" then
WR_n_i <= '1';
end if;
else
if TState = "001" and IORQ_n_i = '0' then
WR_n_i <= not Write;
elsif Tstate = "011" then
WR_n_i <= '1';
end if;
end if;
end if;
end if;
@ -227,10 +229,12 @@ begin
if Reset_s = '0' then
Req_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '1' then
if MCycle = "001" and TState = "010" and wait_s = '1' then
Req_Inhibit <= '1';
else
Req_Inhibit <= '0';
if CEN = '1' then
if MCycle = "001" and TState = "010" and wait_s = '1' then
Req_Inhibit <= '1';
else
Req_Inhibit <= '0';
end if;
end if;
end if;
end process;
@ -240,10 +244,12 @@ begin
if Reset_s = '0' then
MReq_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" and TState = "010" then
MReq_Inhibit <= '1';
else
MReq_Inhibit <= '0';
if CEN = '1' then
if MCycle = "001" and TState = "010" then
MReq_Inhibit <= '1';
else
MReq_Inhibit <= '0';
end if;
end if;
end if;
end process;
@ -255,35 +261,36 @@ begin
IORQ_n_i <= '1';
MREQ <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
IORQ_n_i <= IntCycle_n;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '1';
end if;
if TState = "100" then
MREQ <= '0';
end if;
else
if TState = "001" and NoRead = '0' then
IORQ_n_i <= not IORQ;
MREQ <= not IORQ;
if IORQ = '0' then
RD <= not Write;
elsif IORQ_n_i = '0' then
RD <= not Write;
if CEN = '1' then
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
IORQ_n_i <= IntCycle_n;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '1';
end if;
if TState = "100" then
MREQ <= '0';
end if;
else
if TState = "001" and NoRead = '0' then
IORQ_n_i <= not IORQ;
MREQ <= not IORQ;
if IORQ = '0' then
RD <= not Write;
elsif IORQ_n_i = '0' then
RD <= not Write;
end if;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
end if;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
end if;
end if;
end if;

View File

@ -97,6 +97,7 @@ type state_type is (idle, resume, nop_t1, nop_t2, nop_t3, nop_t4, rd_t1, rd_wa,
signal RESET_n_int : std_logic;
signal cpu_clk : std_logic;
signal cpu_clken : std_logic;
signal busmon_clk : std_logic;
signal Addr_int : std_logic_vector(15 downto 0);
@ -273,6 +274,7 @@ begin
Regs => Regs,
RESET_n => RESET_n_int,
CLK_n => cpu_clk,
CEN => cpu_clken,
WAIT_n => WAIT_n_int,
INT_n => INT_n_sync,
NMI_n => NMI_n_sync,
@ -315,9 +317,11 @@ begin
-- 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
WAIT_n_int <= '0' when state = idle and SS_Single = '1' and Sync1 = '1' else
WAIT_n_int <= WAIT_n;
cpu_clken <= '0' when state = idle and SS_Single = '1' and Sync1 = '1' else
'0' when state /= idle else
WAIT_n;
'1';
-- Logic to ignore the second M1 in multi-byte opcodes
skip_opcode_latch : process(CLK_n)
@ -336,7 +340,7 @@ begin
-- For instruction breakpoints, we make the monitoring decision as early as possibe
-- to allow time to stop the current instruction, which is possible because we don't
-- really care about the data (it's re-read from memory by the disassembler).
Sync0 <= '1' when M1_n_int = '0' and TState = "001" and skipNextOpcode = '0' else '0';
Sync0 <= '1' when WAIT_n_int = '1' and M1_n_int = '0' and TState = "010" and skipNextOpcode = '0' else '0';
-- For memory reads/write breakpoints we make the monitoring decision in the middle of T2
-- but only if WAIT_n is '1' so we catch the right data.
@ -478,7 +482,7 @@ begin
SS_Step_held <= '0';
end if;
Sync1 <= Sync0;
Sync1 <= Sync;
-- Main state machine, generating refresh, read and write cycles
-- (the timing should exactly match those of the Z80)
@ -489,13 +493,8 @@ begin
-- Load the initial refresh address from I/R in the T80
rfsh_addr <= Regs(199 downto 192) & Regs(207 downto 200);
-- Start genering NOP cycles
if mon_wait_n = '1' then
state <= nop_t3;
else
mon_m1_n <= mode;
mon_xx_n <= mode;
state <= nop_t2;
end if;
mon_rfsh_n <= '0';
state <= nop_t3;
end if;
-- NOP cycle
@ -506,10 +505,14 @@ begin
mon_xx_n <= mode;
when nop_t2 =>
if mon_wait_n = '1' then
mon_rfsh_n <= '0';
state <= nop_t3;
mon_m1_n <= '1';
mon_xx_n <= '1';
if SS_Step_held = '1' or SS_Single = '0' then
state <= idle;
else
mon_rfsh_n <= '0';
state <= nop_t3;
end if;
end if;
when nop_t3 =>
state <= nop_t4;
@ -521,8 +524,6 @@ begin
elsif memory_rd1 = '1' or io_rd1 = '1' then
state <= rd_t1;
io_not_mem <= io_rd1;
elsif SS_Step_held = '1' or SS_Single = '0' then
state <= resume;
else
state <= nop_t1;
mon_m1_n <= mode;
@ -547,6 +548,7 @@ begin
end if;
when rd_t3 =>
state <= nop_t1;
mon_m1_n <= mode;
-- Write cycle
when wr_t1 =>
@ -563,6 +565,8 @@ begin
end if;
when wr_t3 =>
state <= nop_t1;
mon_m1_n <= mode;
end case;
end if;
end process;
@ -582,7 +586,7 @@ begin
mon_mreq_n <= '1';
mon_iorq_n <= '0';
end if;
elsif state = nop_t1 or state = nop_t3 then
elsif (state = nop_t1 and mode = '0') or state = nop_t3 then
-- M1 cycle
mon_mreq_n <= '0';
mon_iorq_n <= '1';
@ -612,9 +616,9 @@ begin
avr_TxD <= avr_Txd_int;
test1 <= '1';
test2 <= '1';
test3 <= '1';
test4 <= '1';
test1 <= Sync1;
test2 <= TState(0);
test3 <= TState(1);
test4 <= TState(2);
end behavioral;