mirror of
https://github.com/hoglet67/AtomBusMon.git
synced 2024-12-22 16:30:06 +00:00
Implemented IO watches/breakpoints; fixed a bug with stepping through CB/DD/ED/FD prefixed opcodes which have 2 M1 cycles; version not 0.47
Change-Id: Iad5cb406bd96a8020ccb65be5cd440bebec20481
This commit is contained in:
parent
caec07483d
commit
727a1c0f2a
@ -6,7 +6,7 @@
|
||||
|
||||
#include "AtomBusMon.h"
|
||||
|
||||
#define VERSION "0.46"
|
||||
#define VERSION "0.47"
|
||||
|
||||
#if (CPU == Z80)
|
||||
#define NAME "ICE-T80"
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
#ifdef CPUEMBEDDED
|
||||
#if (CPU == Z80)
|
||||
#define NUM_CMDS 24
|
||||
#define NUM_CMDS 28
|
||||
#else
|
||||
#define NUM_CMDS 22
|
||||
#endif
|
||||
@ -136,19 +136,49 @@
|
||||
#define BW_ACTIVE_MASK 0x80
|
||||
|
||||
// Breakpoint Modes
|
||||
#define BRKPT_EXEC 0
|
||||
#define BRKPT_READ 1
|
||||
#define BRKPT_WRITE 2
|
||||
#define WATCH_EXEC 3
|
||||
#define WATCH_READ 4
|
||||
#define WATCH_WRITE 5
|
||||
#define UNDEFINED 6
|
||||
#define BRKPT_MEM_READ 0
|
||||
#define WATCH_MEM_READ 1
|
||||
#define BRKPT_MEM_WRITE 2
|
||||
#define WATCH_MEM_WRITE 3
|
||||
#define BRKPT_IO_READ 4
|
||||
#define WATCH_IO_READ 5
|
||||
#define BRKPT_IO_WRITE 6
|
||||
#define WATCH_IO_WRITE 7
|
||||
#define BRKPT_EXEC 8
|
||||
#define WATCH_EXEC 9
|
||||
#define UNDEFINED 10
|
||||
|
||||
#define B_MASK ((1<<BRKPT_READ) | (1<<BRKPT_WRITE) | (1<<BRKPT_EXEC))
|
||||
#define W_MASK ((1<<WATCH_READ) | (1<<WATCH_WRITE) | (1<<WATCH_EXEC))
|
||||
#define B_MEM_MASK ((1<<BRKPT_READ) | (1<<BRKPT_WRITE))
|
||||
#define W_MEM_MASK ((1<<BRKPT_WRITE) | (1<<WATCH_WRITE))
|
||||
#define BW_MEM_MASK ((1<<BRKPT_READ) | (1<<BRKPT_WRITE) | (1<<WATCH_READ) | (1<<WATCH_WRITE))
|
||||
// Breakpoint Mode Strings, should match the modes
|
||||
char *modeStrings[10] = {
|
||||
"Mem Rd Brkpt",
|
||||
"Mem Rd Watch",
|
||||
"Mem Wr Brkpt",
|
||||
"Mem Wr Watch",
|
||||
"IO Rd Brkpt",
|
||||
"IO Rd Watch",
|
||||
"IO Wr Brkpt",
|
||||
"IO Wr Watch",
|
||||
"Ex Brkpt",
|
||||
"Ex Watch"
|
||||
};
|
||||
|
||||
// Mask for all breakpoint types
|
||||
#define B_MASK ((1<<BRKPT_MEM_READ) | (1<<BRKPT_MEM_WRITE) | (1<<BRKPT_IO_READ) | (1<<BRKPT_IO_WRITE) | (1<<BRKPT_EXEC))
|
||||
|
||||
// Mask for all watch types
|
||||
#define W_MASK ((1<<WATCH_MEM_READ) | (1<<WATCH_MEM_WRITE) | (1<<WATCH_IO_READ) | (1<<WATCH_IO_WRITE) | (1<<WATCH_EXEC))
|
||||
|
||||
// Mask for all breakpoints/watches that read memory or IO
|
||||
#define BW_RD_MASK ((1<<BRKPT_MEM_READ) | (1<<WATCH_MEM_READ) | (1<<BRKPT_IO_READ) | (1<<WATCH_IO_READ))
|
||||
|
||||
// Mask for all breakpoints/watches that write memory or IO
|
||||
#define BW_WR_MASK ((1<<BRKPT_MEM_WRITE) | (1<<WATCH_MEM_WRITE) | (1<<BRKPT_IO_WRITE) | (1<<WATCH_IO_WRITE))
|
||||
|
||||
// Mask for all breakpoint or watches that read/write Memory or IO
|
||||
#define BW_RDWR_MASK (BW_RD_MASK | BW_WR_MASK)
|
||||
|
||||
// Mask for all breakpoints that read/write Memory or IO
|
||||
#define B_RDWR_MASK (BW_RD_MASK & B_MASK)
|
||||
|
||||
char *testNames[6] = {
|
||||
"Fixed",
|
||||
@ -159,16 +189,6 @@ char *testNames[6] = {
|
||||
"Random"
|
||||
};
|
||||
|
||||
char *modeStrings[7] = {
|
||||
"Ex Breakpoint",
|
||||
"Rn Breakpoint",
|
||||
"Wr Breakpoint",
|
||||
"Ex watch",
|
||||
"Rd watch",
|
||||
"Wr watch",
|
||||
"Undefined"
|
||||
};
|
||||
|
||||
#define NUM_TRIGGERS 16
|
||||
#define TRIGGER_ALWAYS 15
|
||||
|
||||
@ -224,12 +244,12 @@ char *cmdStrings[NUM_CMDS] = {
|
||||
"fill",
|
||||
"crc",
|
||||
"mem",
|
||||
"readmem",
|
||||
"writemem",
|
||||
"rdm",
|
||||
"wrm",
|
||||
#if (CPU == Z80)
|
||||
"io",
|
||||
"readio",
|
||||
"writeio",
|
||||
"rdi",
|
||||
"wri",
|
||||
#else
|
||||
"test",
|
||||
#endif
|
||||
@ -238,12 +258,18 @@ char *cmdStrings[NUM_CMDS] = {
|
||||
"step",
|
||||
"trace",
|
||||
"blist",
|
||||
"breaki",
|
||||
"breakr",
|
||||
"breakw",
|
||||
"watchi",
|
||||
"watchr",
|
||||
"watchw",
|
||||
"breakx",
|
||||
"watchx",
|
||||
"breakrm",
|
||||
"watchrm",
|
||||
"breakwm",
|
||||
"watchwm",
|
||||
#if (CPU == Z80)
|
||||
"breakri",
|
||||
"watchri",
|
||||
"breakwi",
|
||||
"watchwi",
|
||||
#endif
|
||||
"clear",
|
||||
"trigger"
|
||||
};
|
||||
@ -396,11 +422,10 @@ void logMode(unsigned int mode) {
|
||||
int first = 1;
|
||||
for (i = 0; i < UNDEFINED; i++) {
|
||||
if (mode & 1) {
|
||||
if (first) {
|
||||
log0("%s", modeStrings[i]);
|
||||
} else {
|
||||
log0(", %c%s", tolower(*modeStrings[i]), modeStrings[i] + 1);
|
||||
if (!first) {
|
||||
log0(", ");
|
||||
}
|
||||
log0("%s", modeStrings[i]);
|
||||
first = 0;
|
||||
}
|
||||
mode >>= 1;
|
||||
@ -420,21 +445,19 @@ int logDetails() {
|
||||
unsigned int b_addr = hwRead16(OFFSET_BW_BAL);
|
||||
unsigned int b_data = hwRead8(OFFSET_BW_BD);
|
||||
unsigned int mode = hwRead8(OFFSET_BW_M);
|
||||
unsigned int watch = mode & 8;
|
||||
unsigned int watch = mode & 1;
|
||||
|
||||
// Convert from 4-bit compressed to 10 bit expanded mode representation
|
||||
mode = 1 << mode;
|
||||
|
||||
// Convert from 4-bit compressed to 6 bit expanded mode representation
|
||||
if (watch) {
|
||||
mode = (mode & 7) << 3;
|
||||
}
|
||||
// Update the serial console
|
||||
if (mode & W_MASK) {
|
||||
logCycleCount(OFFSET_BW_CNTL, OFFSET_BW_CNTH);
|
||||
}
|
||||
logMode(mode);
|
||||
log0(" hit at %04X", i_addr);
|
||||
if (mode & BW_MEM_MASK) {
|
||||
if (mode & W_MEM_MASK) {
|
||||
if (mode & BW_RDWR_MASK) {
|
||||
if (mode & BW_WR_MASK) {
|
||||
log0(" writing");
|
||||
} else {
|
||||
log0(" reading");
|
||||
@ -444,7 +467,7 @@ int logDetails() {
|
||||
log0("\n");
|
||||
}
|
||||
#ifdef CPUEMBEDDED
|
||||
if (mode & B_MEM_MASK) {
|
||||
if (mode & B_RDWR_MASK) {
|
||||
// It's only safe to do this for brkpts, as it makes memory accesses
|
||||
logCycleCount(OFFSET_BW_CNTL, OFFSET_BW_CNTH);
|
||||
disMem(i_addr);
|
||||
@ -846,7 +869,7 @@ void doCmdTrace(char *params) {
|
||||
setTrace(i);
|
||||
}
|
||||
|
||||
void doCmdBList(char *params) {
|
||||
void doCmdList(char *params) {
|
||||
int i;
|
||||
if (numbkpts) {
|
||||
for (i = 0; i < numbkpts; i++) {
|
||||
@ -913,30 +936,51 @@ void doCmdBreak(char *params, unsigned int mode) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void doCmdBreakI(char *params) {
|
||||
doCmdBreak(params, 1 << BRKPT_EXEC);
|
||||
}
|
||||
|
||||
void doCmdBreakR(char *params) {
|
||||
doCmdBreak(params, 1 << BRKPT_READ);
|
||||
}
|
||||
|
||||
void doCmdBreakW(char *params) {
|
||||
doCmdBreak(params, 1 << BRKPT_WRITE);
|
||||
}
|
||||
|
||||
void doCmdWatchI(char *params) {
|
||||
doCmdBreak(params, 1 << WATCH_EXEC);
|
||||
}
|
||||
|
||||
void doCmdWatchR(char *params) {
|
||||
doCmdBreak(params, 1 << WATCH_READ);
|
||||
void doCmdBreakRdMem(char *params) {
|
||||
doCmdBreak(params, 1 << BRKPT_MEM_READ);
|
||||
}
|
||||
|
||||
void doCmdWatchW(char *params) {
|
||||
doCmdBreak(params, 1 << WATCH_WRITE);
|
||||
void doCmdWatchRdMem(char *params) {
|
||||
doCmdBreak(params, 1 << WATCH_MEM_READ);
|
||||
}
|
||||
|
||||
void doCmdBreakWrMem(char *params) {
|
||||
doCmdBreak(params, 1 << BRKPT_MEM_WRITE);
|
||||
}
|
||||
|
||||
void doCmdWatchWrMem(char *params) {
|
||||
doCmdBreak(params, 1 << WATCH_MEM_WRITE);
|
||||
}
|
||||
|
||||
#if (CPU == Z80)
|
||||
|
||||
void doCmdBreakRdIO(char *params) {
|
||||
doCmdBreak(params, 1 << BRKPT_IO_READ);
|
||||
}
|
||||
|
||||
void doCmdWatchRdIO(char *params) {
|
||||
doCmdBreak(params, 1 << WATCH_IO_READ);
|
||||
}
|
||||
|
||||
void doCmdBreakWrIO(char *params) {
|
||||
doCmdBreak(params, 1 << BRKPT_IO_WRITE);
|
||||
}
|
||||
|
||||
void doCmdWatchWrIO(char *params) {
|
||||
doCmdBreak(params, 1 << WATCH_IO_WRITE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void doCmdClear(char *params) {
|
||||
int i;
|
||||
int n = lookupBreakpoint(params);
|
||||
@ -983,7 +1027,7 @@ void shiftBreakpointRegister(unsigned int addr, unsigned int mask, unsigned int
|
||||
hwCmd(CMD_LOAD_BRKPT, mask & 1);
|
||||
mask >>= 1;
|
||||
}
|
||||
for (i = 0; i <= 5; i++) {
|
||||
for (i = 0; i <= 9; i++) {
|
||||
hwCmd(CMD_LOAD_BRKPT, mode & 1);
|
||||
mode >>= 1;
|
||||
}
|
||||
@ -1106,13 +1150,19 @@ void (*cmdFuncs[NUM_CMDS])(char *params) = {
|
||||
doCmdReset,
|
||||
doCmdStep,
|
||||
doCmdTrace,
|
||||
doCmdBList,
|
||||
doCmdList,
|
||||
doCmdBreakI,
|
||||
doCmdBreakR,
|
||||
doCmdBreakW,
|
||||
doCmdWatchI,
|
||||
doCmdWatchR,
|
||||
doCmdWatchW,
|
||||
doCmdBreakRdMem,
|
||||
doCmdWatchRdMem,
|
||||
doCmdBreakWrMem,
|
||||
doCmdWatchWrMem,
|
||||
#if (CPU == Z80)
|
||||
doCmdBreakRdIO,
|
||||
doCmdWatchRdIO,
|
||||
doCmdBreakWrIO,
|
||||
doCmdWatchWrIO,
|
||||
#endif
|
||||
doCmdClear,
|
||||
doCmdTrigger
|
||||
};
|
||||
|
@ -25,18 +25,20 @@ use work.OhoPack.all ;
|
||||
entity BusMonCore is
|
||||
generic (
|
||||
num_comparators : integer := 8;
|
||||
reg_width : integer := 42;
|
||||
reg_width : integer := 46;
|
||||
fifo_width : integer := 72
|
||||
);
|
||||
port (
|
||||
clock49 : in std_logic;
|
||||
|
||||
-- 6502 Signals
|
||||
-- CPU Signals
|
||||
Addr : in std_logic_vector(15 downto 0);
|
||||
Data : in std_logic_vector(7 downto 0);
|
||||
Phi2 : in std_logic;
|
||||
Rd_n : in std_logic;
|
||||
Wr_n : in std_logic;
|
||||
RdIO_n : in std_logic;
|
||||
WrIO_n : in std_logic;
|
||||
Sync : in std_logic;
|
||||
Rdy : out std_logic;
|
||||
nRSTin : in std_logic;
|
||||
@ -44,11 +46,11 @@ entity BusMonCore is
|
||||
|
||||
CountCycle : in std_logic;
|
||||
|
||||
-- 6502 Registers
|
||||
-- CPU Registers
|
||||
-- unused in pure bus monitor mode
|
||||
Regs : in std_logic_vector(255 downto 0);
|
||||
|
||||
-- 6502 Memory Read/Write
|
||||
-- CPU Memory Read/Write
|
||||
-- unused in pure bus monitor mode
|
||||
RdMemOut : out std_logic;
|
||||
WrMemOut : out std_logic;
|
||||
@ -296,52 +298,22 @@ begin
|
||||
|
||||
Regs(8 * to_integer(unsigned(muxsel(4 downto 0))) + 7 downto 8 * to_integer(unsigned(muxsel(4 downto 0))));
|
||||
|
||||
-- Regs( 15 downto 8) when muxsel = 33 else
|
||||
-- Regs( 23 downto 16) when muxsel = 34 else
|
||||
-- Regs( 31 downto 24) when muxsel = 35 else
|
||||
-- Regs( 39 downto 32) when muxsel = 36 else
|
||||
-- Regs( 47 downto 40) when muxsel = 37 else
|
||||
-- Regs( 55 downto 48) when muxsel = 38 else
|
||||
-- Regs( 63 downto 56) when muxsel = 39 else
|
||||
-- Regs( 7 downto 64) when muxsel = 40 else
|
||||
-- Regs( 15 downto 72) when muxsel = 41 else
|
||||
-- Regs( 23 downto 80) when muxsel = 42 else
|
||||
-- Regs( 31 downto 88) when muxsel = 43 else
|
||||
-- Regs( 39 downto 96) when muxsel = 44 else
|
||||
-- Regs( 47 downto 104) when muxsel = 45 else
|
||||
-- Regs( 55 downto 112) when muxsel = 46 else
|
||||
-- Regs( 63 downto 120) when muxsel = 47 else
|
||||
-- Regs( 7 downto 128) when muxsel = 48 else
|
||||
-- Regs( 15 downto 136) when muxsel = 49 else
|
||||
-- Regs( 23 downto 144) when muxsel = 50 else
|
||||
-- Regs( 31 downto 24) when muxsel = 51 else
|
||||
-- Regs( 39 downto 32) when muxsel = 52 else
|
||||
-- Regs( 47 downto 40) when muxsel = 53 else
|
||||
-- Regs( 55 downto 48) when muxsel = 54 else
|
||||
-- Regs( 63 downto 56) when muxsel = 55 else
|
||||
-- Regs( 7 downto 0) when muxsel = 56 else
|
||||
-- Regs( 15 downto 8) when muxsel = 57 else
|
||||
-- Regs( 23 downto 16) when muxsel = 58 else
|
||||
-- Regs( 31 downto 24) when muxsel = 59 else
|
||||
-- Regs( 39 downto 32) when muxsel = 60 else
|
||||
-- Regs( 47 downto 40) when muxsel = 61 else
|
||||
-- Regs( 55 downto 48) when muxsel = 62 else
|
||||
-- Regs( 63 downto 56) when muxsel = 63 else
|
||||
--
|
||||
--
|
||||
-- "10101010";
|
||||
|
||||
-- Combinatorial set of comparators to decode breakpoint/watch addresses
|
||||
brkpt_active_process: process (brkpt_reg, brkpt_enable, Addr, Sync)
|
||||
brkpt_active_process: process (brkpt_reg, brkpt_enable, Addr, Sync, Rd_n, Wr_n, RdIO_n, WrIO_n)
|
||||
variable i : integer;
|
||||
variable reg_addr : std_logic_vector(15 downto 0);
|
||||
variable reg_mask : std_logic_vector(15 downto 0);
|
||||
variable reg_mode_bi : std_logic;
|
||||
variable reg_mode_bar : std_logic;
|
||||
variable reg_mode_baw : std_logic;
|
||||
variable reg_mode_wi : std_logic;
|
||||
variable reg_mode_war : std_logic;
|
||||
variable reg_mode_waw : std_logic;
|
||||
variable reg_mode_bmr : std_logic;
|
||||
variable reg_mode_bmw : std_logic;
|
||||
variable reg_mode_bir : std_logic;
|
||||
variable reg_mode_biw : std_logic;
|
||||
variable reg_mode_bx : std_logic;
|
||||
variable reg_mode_wmr : std_logic;
|
||||
variable reg_mode_wmw : std_logic;
|
||||
variable reg_mode_wir : std_logic;
|
||||
variable reg_mode_wiw : std_logic;
|
||||
variable reg_mode_wx : std_logic;
|
||||
variable reg_mode_all : std_logic_vector(9 downto 0);
|
||||
variable bactive : std_logic;
|
||||
variable wactive : std_logic;
|
||||
variable status : std_logic_vector(3 downto 0);
|
||||
@ -354,47 +326,60 @@ begin
|
||||
for i in 0 to num_comparators - 1 loop
|
||||
reg_addr := brkpt_reg(i * reg_width + 15 downto i * reg_width);
|
||||
reg_mask := brkpt_reg(i * reg_width + 31 downto i * reg_width + 16);
|
||||
reg_mode_bi := brkpt_reg(i * reg_width + 32);
|
||||
reg_mode_bar := brkpt_reg(i * reg_width + 33);
|
||||
reg_mode_baw := brkpt_reg(i * reg_width + 34);
|
||||
reg_mode_wi := brkpt_reg(i * reg_width + 35);
|
||||
reg_mode_war := brkpt_reg(i * reg_width + 36);
|
||||
reg_mode_waw := brkpt_reg(i * reg_width + 37);
|
||||
trigval := brkpt_reg(i * reg_width + 38 + to_integer(unsigned(trig)));
|
||||
if (trigval = '1' and ((Addr and reg_mask) = reg_addr or
|
||||
(reg_mode_bi = '0' and reg_mode_bar = '0' and reg_mode_baw = '0' and
|
||||
(reg_mode_wi = '0' and reg_mode_war = '0' and reg_mode_waw = '0')))) then
|
||||
reg_mode_bmr := brkpt_reg(i * reg_width + 32);
|
||||
reg_mode_wmr := brkpt_reg(i * reg_width + 33);
|
||||
reg_mode_bmw := brkpt_reg(i * reg_width + 34);
|
||||
reg_mode_wmw := brkpt_reg(i * reg_width + 35);
|
||||
reg_mode_bir := brkpt_reg(i * reg_width + 36);
|
||||
reg_mode_wir := brkpt_reg(i * reg_width + 37);
|
||||
reg_mode_biw := brkpt_reg(i * reg_width + 38);
|
||||
reg_mode_wiw := brkpt_reg(i * reg_width + 39);
|
||||
reg_mode_bx := brkpt_reg(i * reg_width + 40);
|
||||
reg_mode_wx := brkpt_reg(i * reg_width + 41);
|
||||
reg_mode_all := brkpt_reg(i * reg_width + 41 downto i * reg_width + 32);
|
||||
trigval := brkpt_reg(i * reg_width + 42 + to_integer(unsigned(trig)));
|
||||
if (trigval = '1' and ((Addr and reg_mask) = reg_addr or (reg_mode_all = "0000000000"))) then
|
||||
if (Sync = '1') then
|
||||
if (reg_mode_bi = '1') then
|
||||
if (reg_mode_bx = '1') then
|
||||
bactive := '1';
|
||||
status := "0001";
|
||||
end if;
|
||||
if (reg_mode_wi = '1') then
|
||||
status := "1000";
|
||||
elsif (reg_mode_wx = '1') then
|
||||
wactive := '1';
|
||||
status := "1001";
|
||||
end if;
|
||||
else
|
||||
if (Rd_n = '0') then
|
||||
if (reg_mode_bar = '1') then
|
||||
bactive := '1';
|
||||
status := "0010";
|
||||
end if;
|
||||
if (reg_mode_war = '1') then
|
||||
wactive := '1';
|
||||
status := "1010";
|
||||
end if;
|
||||
elsif (Rd_n = '0') then
|
||||
if (reg_mode_bmr = '1') then
|
||||
bactive := '1';
|
||||
status := "0000";
|
||||
elsif (reg_mode_wmr = '1') then
|
||||
wactive := '1';
|
||||
status := "0001";
|
||||
end if;
|
||||
if (Wr_n = '0') then
|
||||
if (reg_mode_baw = '1') then
|
||||
bactive := '1';
|
||||
status := "0100";
|
||||
end if;
|
||||
if (reg_mode_waw = '1') then
|
||||
wactive := '1';
|
||||
status := "1100";
|
||||
end if;
|
||||
elsif (Wr_n = '0') then
|
||||
if (reg_mode_bmw = '1') then
|
||||
bactive := '1';
|
||||
status := "0010";
|
||||
elsif (reg_mode_wmw = '1') then
|
||||
wactive := '1';
|
||||
status := "0011";
|
||||
end if;
|
||||
end if;
|
||||
elsif (RdIO_n = '0') then
|
||||
if (reg_mode_bir = '1') then
|
||||
bactive := '1';
|
||||
status := "0100";
|
||||
elsif (reg_mode_wir = '1') then
|
||||
wactive := '1';
|
||||
status := "0101";
|
||||
end if;
|
||||
elsif (WrIO_n = '0') then
|
||||
if (reg_mode_biw = '1') then
|
||||
bactive := '1';
|
||||
status := "0110";
|
||||
elsif (reg_mode_wiw = '1') then
|
||||
wactive := '1';
|
||||
status := "0111";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
@ -515,7 +500,7 @@ begin
|
||||
Rdy_int <= (not Sync);
|
||||
end if;
|
||||
|
||||
-- 6502 Reset needs to be open collector
|
||||
-- CPU Reset needs to be open collector
|
||||
if (reset = '1') then
|
||||
nRSTout <= '0';
|
||||
else
|
||||
|
@ -98,6 +98,7 @@ signal SS_Single : std_logic;
|
||||
signal SS_Step : std_logic;
|
||||
signal SS_Step_held : std_logic;
|
||||
signal CountCycle : std_logic;
|
||||
signal skipNextOpcode : std_logic;
|
||||
|
||||
signal Regs : std_logic_vector(255 downto 0);
|
||||
signal io_not_mem : std_logic;
|
||||
@ -119,8 +120,14 @@ signal Read_n0 : std_logic;
|
||||
signal Read_n1 : std_logic;
|
||||
signal Write_n : std_logic;
|
||||
signal Write_n0 : std_logic;
|
||||
signal ReadIO_n : std_logic;
|
||||
signal ReadIO_n0 : std_logic;
|
||||
signal ReadIO_n1 : std_logic;
|
||||
signal WriteIO_n : std_logic;
|
||||
signal WriteIO_n0 : std_logic;
|
||||
signal Sync : std_logic;
|
||||
signal Sync0 : std_logic;
|
||||
signal Mem_IO_n : std_logic;
|
||||
signal nRST : std_logic;
|
||||
|
||||
signal MemState : std_logic_vector(2 downto 0);
|
||||
@ -145,6 +152,8 @@ begin
|
||||
Phi2 => busmon_clk,
|
||||
Rd_n => Read_n,
|
||||
Wr_n => Write_n,
|
||||
RdIO_n => ReadIO_n,
|
||||
WrIO_n => WriteIO_n,
|
||||
Sync => Sync,
|
||||
Rdy => Rdy,
|
||||
nRSTin => RESET_n_int,
|
||||
@ -217,7 +226,7 @@ begin
|
||||
elsif rising_edge(CLK_n) then
|
||||
NMI_n_sync <= NMI_n;
|
||||
INT_n_sync <= INT_n;
|
||||
if (M1_n_int = '0' and TState = "001") then
|
||||
if (Sync0 = '1') then
|
||||
-- stop at the end of T1 instruction fetch
|
||||
SS_Step_held <= '0';
|
||||
elsif (SS_Step = '1') then
|
||||
@ -227,19 +236,33 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- Logic to ignore the second M1 in multi-byte opcodes
|
||||
skip_opcode_latch : process(CLK_n)
|
||||
begin
|
||||
if rising_edge(CLK_n) then
|
||||
if (M1_n_int = '0' and WAIT_n_int = '1' and TState = "010") then
|
||||
if (skipNextOpcode = '0' and (Data = x"CB" or Data = x"DD" or Data = x"ED" or Data = x"FD")) then
|
||||
skipNextOpcode <= '1';
|
||||
else
|
||||
skipNextOpcode <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- 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 <= not M1_n_int when TState = "001" else '0';
|
||||
Sync0 <= '1' when M1_n_int = '0' and TState = "001" and skipNextOpcode = '0' else '0';
|
||||
|
||||
-- For reads/write breakpoints we make the monitoring decision in the middle of T2
|
||||
-- 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.
|
||||
Read_n0 <= not (WAIT_n_int and (not RD_n_int) and (not MREQ_n_int) and (M1_n_int)) when TState = "010" else '1';
|
||||
Write_n0 <= not (WAIT_n_int and (not WR_n_int) and (not MREQ_n_int) and (M1_n_int)) when TState = "010" else '1';
|
||||
|
||||
-- These are useful for debugging IO Requests:
|
||||
-- Read_n0 <= not (WAIT_n_int and (not RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState = "010" else '1';
|
||||
-- Write_n0 <= not ( ( RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState = "011" else '1';
|
||||
ReadIO_n0 <= not (WAIT_n_int and (not RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState = "010" else '1';
|
||||
WriteIO_n0 <= not ( ( RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState = "011" else '1';
|
||||
|
||||
-- Hold the monitoring decision so it is valid on the rising edge of the clock
|
||||
-- For instruction fetches and writes, the monitor sees these at the start of T3
|
||||
@ -247,10 +270,13 @@ begin
|
||||
watch_gen : process(CLK_n)
|
||||
begin
|
||||
if falling_edge(CLK_n) then
|
||||
Sync <= Sync0;
|
||||
Read_n1 <= Read_n0;
|
||||
Read_n <= Read_n1;
|
||||
Write_n <= Write_n0;
|
||||
Sync <= Sync0;
|
||||
Read_n1 <= Read_n0;
|
||||
Read_n <= Read_n1;
|
||||
Write_n <= Write_n0;
|
||||
ReadIO_n1 <= ReadIO_n0;
|
||||
ReadIO_n <= ReadIO_n1;
|
||||
WriteIO_n <= WriteIO_n0;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@ -258,7 +284,7 @@ begin
|
||||
ex_data_latch : process(CLK_n)
|
||||
begin
|
||||
if rising_edge(CLK_n) then
|
||||
if (Sync = '1' or Write_n = '0') then
|
||||
if (Sync = '1' or Write_n = '0' or WriteIO_n = '0') then
|
||||
ex_data <= Data;
|
||||
end if;
|
||||
end if;
|
||||
@ -268,7 +294,7 @@ begin
|
||||
rd_data_latch : process(CLK_n)
|
||||
begin
|
||||
if falling_edge(CLK_n) then
|
||||
if (Read_n1 = '0') then
|
||||
if (Read_n1 = '0' or ReadIO_n1 = '0') then
|
||||
rd_data <= Data;
|
||||
end if;
|
||||
memory_din <= Data;
|
||||
@ -276,7 +302,7 @@ begin
|
||||
end process;
|
||||
|
||||
-- Mux the data seen by the bus monitor appropriately
|
||||
mon_data <= rd_data when Read_n <= '0' else ex_data;
|
||||
mon_data <= rd_data when Read_n <= '0' or ReadIO_n = '0' else ex_data;
|
||||
|
||||
-- Memory access
|
||||
Addr <= memory_addr when (state /= idle) else Addr_int;
|
||||
|
Loading…
Reference in New Issue
Block a user