mirror of
https://github.com/hoglet67/AtomBusMon.git
synced 2024-12-22 16:30:06 +00:00
Z80: Stop T80 in T3 not T2 (work in progress)
Change-Id: I19fa754cc09a068b628116b9636a995c162ad964
This commit is contained in:
parent
d479dedf4b
commit
e76bdc6da2
115
src/T80/T80a.vhd
115
src/T80/T80a.vhd
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user