mirror of
https://github.com/hoglet67/AtomBusMon.git
synced 2025-01-02 23:32:02 +00:00
Reworked the 6502 single stepping to hide the fact that register writes are pipelined
Change-Id: I6d9157e3d9ade9af72e11d255b224cc7f210f376
This commit is contained in:
parent
9c4b9aa944
commit
344e03185d
BIN
AtomCpuMon.bit
BIN
AtomCpuMon.bit
Binary file not shown.
@ -10,7 +10,7 @@
|
||||
* VERSION and NAME are used in the start-up message
|
||||
********************************************************/
|
||||
|
||||
#define VERSION "0.64"
|
||||
#define VERSION "0.65"
|
||||
|
||||
#if (CPU == Z80)
|
||||
#define NAME "ICE-T80"
|
||||
|
@ -76,7 +76,7 @@ architecture behavioral of AtomCpuMon is
|
||||
signal Dout : std_logic_vector(7 downto 0);
|
||||
signal R_W_n_int : std_logic;
|
||||
signal Sync_int : std_logic;
|
||||
signal Rdy_int : std_logic;
|
||||
signal hold : std_logic;
|
||||
signal Addr_int : std_logic_vector(15 downto 0);
|
||||
signal IRQ_n_sync : std_logic;
|
||||
signal NMI_n_sync : std_logic;
|
||||
@ -93,6 +93,11 @@ architecture behavioral of AtomCpuMon is
|
||||
|
||||
signal Regs : std_logic_vector(63 downto 0);
|
||||
signal Regs1 : std_logic_vector(255 downto 0);
|
||||
signal last_PC : std_logic_vector(15 downto 0);
|
||||
signal SS_Single : std_logic;
|
||||
signal SS_Step : std_logic;
|
||||
signal CountCycle : std_logic;
|
||||
|
||||
signal memory_rd : std_logic;
|
||||
signal memory_rd1 : std_logic;
|
||||
signal memory_wr : std_logic;
|
||||
@ -115,10 +120,10 @@ begin
|
||||
RdIO_n => '1',
|
||||
WrIO_n => '1',
|
||||
Sync => Sync_int,
|
||||
Rdy => Rdy_int,
|
||||
Rdy => open,
|
||||
nRSTin => Res_n,
|
||||
nRSTout => Res_n,
|
||||
CountCycle => Rdy_int,
|
||||
CountCycle => CountCycle,
|
||||
trig => trig,
|
||||
lcd_rs => open,
|
||||
lcd_rw => open,
|
||||
@ -143,10 +148,33 @@ begin
|
||||
DataOut => memory_dout,
|
||||
DataIn => memory_din,
|
||||
Done => memory_done,
|
||||
SS_Step => open,
|
||||
SS_Single => open
|
||||
SS_Step => SS_Step,
|
||||
SS_Single => SS_Single
|
||||
);
|
||||
Regs1(63 downto 0) <= Regs;
|
||||
|
||||
-- The CPU09 is slightly pipelined and the register update of the last
|
||||
-- instruction overlaps with the opcode fetch of the next instruction.
|
||||
--
|
||||
-- If the single stepping stopped on the opcode fetch cycle, then the registers
|
||||
-- valued would not accurately reflect the previous instruction.
|
||||
--
|
||||
-- To work around this, when single stepping, we stop on the cycle after
|
||||
-- the opcode fetch, which means the program counter has advanced.
|
||||
--
|
||||
-- To hide this from the user single stepping, all we need to do is to
|
||||
-- also pipeline the value of the program counter by one stage to compensate.
|
||||
|
||||
last_pc_gen : process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if (hold = '0') then
|
||||
last_PC <= Regs(63 downto 48);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
Regs1( 47 downto 0) <= Regs( 47 downto 0);
|
||||
Regs1( 63 downto 48) <= last_PC;
|
||||
Regs1(255 downto 64) <= (others => '0');
|
||||
|
||||
GenT65Core: if UseT65Core generate
|
||||
@ -155,9 +183,9 @@ begin
|
||||
Abort_n => '1',
|
||||
SO_n => SO_n,
|
||||
Res_n => Res_n,
|
||||
Enable => '1',
|
||||
Enable => not hold,
|
||||
Clk => cpu_clk,
|
||||
Rdy => Rdy_int,
|
||||
Rdy => '1',
|
||||
IRQ_n => IRQ_n_sync,
|
||||
NMI_n => NMI_n_sync,
|
||||
R_W_n => R_W_n_int,
|
||||
@ -174,7 +202,7 @@ begin
|
||||
inst_r65c02: entity work.r65c02 port map (
|
||||
reset => RES_n,
|
||||
clk => cpu_clk,
|
||||
enable => Rdy_int,
|
||||
enable => not hold,
|
||||
nmi_n => NMI_n_sync,
|
||||
irq_n => IRQ_n_sync,
|
||||
di => unsigned(Din),
|
||||
@ -200,6 +228,25 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- This block generates a hold signal that acts as the inverse of a clock enable
|
||||
-- for the 6809. See comments above for why this is a cycle later than the way
|
||||
-- we would do if for the 6502.
|
||||
hold_gen : process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if (Sync_int = '1') then
|
||||
-- stop after the opcode has been fetched
|
||||
hold <= SS_Single;
|
||||
elsif (SS_Step = '1') then
|
||||
-- start again when the single step command is issues
|
||||
hold <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Only count cycles when the 6809 is actually running
|
||||
CountCycle <= not hold;
|
||||
|
||||
-- this block delays memory_rd, memory_wr, memory_addr until the start of the next cpu clk cycle
|
||||
-- necessary because the cpu mon block is clocked of the opposite edge of the clock
|
||||
-- this allows a full cpu clk cycle for cpu mon reads and writes
|
||||
|
Loading…
Reference in New Issue
Block a user