Added read and write breakpoints

Change-Id: Id528aed8058ad52d4d39cb9543dfc78d22dfd05d
This commit is contained in:
David Banks 2015-06-10 11:55:39 +01:00
parent 10afdff12c
commit 85fd68e43b
2 changed files with 118 additions and 36 deletions

View File

@ -20,6 +20,23 @@
#define BRKPT_INTERRUPTED_MASK 0x40
#define BRKPT_ACTIVE_MASK 0x80
// Breakpoint Modes
#define BRKPT_INSTR 0x01
#define BRKPT_READ 0x02
#define BRKPT_WRITE 0x04
char *brkptStrings[8] = {
"No breakpoint",
"Instruction breakpoint",
"Read breakpoint",
"Instruction, read breakpoints",
"Write breakpoint",
"Instruction, write breakpoints",
"Read, write breakpoints",
"Instruction, read, write breakpoints"
};
#define CTRL_MASK (SINGLE_MASK | STEP_MASK | RESET_MASK | BRKPT_ENABLE_MASK | BRKPT_CLOCK_MASK | BRKPT_DATA_MASK)
#define AL_PORT PORTD
@ -34,7 +51,7 @@
#define VERSION "0.11"
#define NUMCMDS 10
#define NUMCMDS 12
#define MAXBKPTS 4
int numbkpts = 0;
@ -50,6 +67,14 @@ unsigned int breakpoints[MAXBKPTS] = {
0
};
unsigned int modes[MAXBKPTS] = {
0,
0,
0,
0
};
char *cmdStrings[NUMCMDS] = {
"help",
"reset",
@ -58,7 +83,9 @@ char *cmdStrings[NUMCMDS] = {
"step",
"trace",
"blist",
"break",
"breaki",
"breakr",
"breakw",
"bclear",
"continue",
};
@ -135,6 +162,7 @@ void version() {
log0("Compiled at %s on %s\n",__TIME__,__DATE__);
}
/*******************************************
* Commands
*******************************************/
@ -211,43 +239,64 @@ void doCmdBList(char *params) {
int i;
if (numbkpts) {
for (i = 0; i < numbkpts; i++) {
log0("%d: %04X\n", i, breakpoints[i]);
log0("%d: %04X %s\n", i, breakpoints[i], brkptStrings[modes[i]]);
}
} else {
log0("No breakpoints set\n");
}
}
void doCmdBreak(char *params) {
void setBreakpoint(int i, int addr, int mode) {
log0("%s set at %04X\n", brkptStrings[mode], addr);
breakpoints[i] = addr;
modes[i] = mode;
}
void doCmdBreak(char *params, unsigned int mode) {
int i;
unsigned int addr;
sscanf(params, "%x", &addr);
for (i = 0; i < numbkpts; i++) {
if (breakpoints[i] == addr) {
if (modes[i] & mode) {
log0("%s already set at %04X\n", brkptStrings[mode], addr);
} else {
setBreakpoint(i, addr, modes[i] | mode);
}
doCmdBList(NULL);
return;
}
}
if (numbkpts == MAXBKPTS) {
log0("All breakpoints are already set\n");
doCmdBList(NULL);
return;
}
for (i = 0; i < numbkpts; i++) {
if (breakpoints[i] == addr) {
log0("Breakpoint already set at %04X\n", addr);
doCmdBList(NULL);
return;
}
}
numbkpts++;
for (i = numbkpts - 2; i >= -1; i--) {
if (i == -1 || breakpoints[i] < addr) {
log0("Setting breakpoint at %04X\n", addr);
breakpoints[i + 1] = addr;
setBreakpoint(i + 1, addr, mode);
doCmdBList(NULL);
return;
} else {
breakpoints[i + 1] = breakpoints[i];
modes[i + 1] = modes[i];
}
}
}
void doCmdBreakI(char *params) {
doCmdBreak(params, BRKPT_INSTR);
}
void doCmdBreakR(char *params) {
doCmdBreak(params, BRKPT_READ);
}
void doCmdBreakW(char *params) {
doCmdBreak(params, BRKPT_WRITE);
}
void doCmdBClear(char *params) {
int i;
int n = 0;
@ -255,20 +304,24 @@ void doCmdBClear(char *params) {
if (n >= numbkpts) {
log0("Breakpoint %d not set\n", n);
} else {
log0("Removing breakpoint at %04X\n", breakpoints[n]);
log0("Removing %s at %04X\n", brkptStrings[modes[n], breakpoints[n]);
for (i = n; i < numbkpts; i++) {
breakpoints[i] = breakpoints[i + 1];
modes[i] = modes[i + 1];
}
numbkpts--;
}
doCmdBList(NULL);
}
void shiftBreakpointRegister(unsigned int addr) {
void shiftBreakpointRegister(unsigned int addr, unsigned int mode) {
int i;
for (i = 0; i < 16; i++) {
long reg = mode;
reg <<= 16;
reg |= addr;
for (i = 0; i < 20; i++) {
CTRL_PORT &= ~BRKPT_CLOCK_MASK;
if (addr & 1) {
if (reg & 1) {
CTRL_PORT |= BRKPT_DATA_MASK;
} else {
CTRL_PORT &= ~BRKPT_DATA_MASK;
@ -276,7 +329,7 @@ void shiftBreakpointRegister(unsigned int addr) {
Delay_us(10);
CTRL_PORT |= BRKPT_CLOCK_MASK;
Delay_us(10);
addr >>= 1;
reg >>= 1;
}
}
@ -289,8 +342,11 @@ void doCmdContinue(char *params) {
CTRL_PORT &= ~BRKPT_ENABLE_MASK;
// Load breakpoints into comparators
for (i = 0; i < MAXBKPTS; i++) {
shiftBreakpointRegister(i < numbkpts ? breakpoints[i] : 0);
for (i = 0; i < numbkpts; i++) {
shiftBreakpointRegister(breakpoints[i], modes[i]);
}
for (i = numbkpts; i < MAXBKPTS; i++) {
shiftBreakpointRegister(0, 0);
}
// Enable breakpoints
@ -344,7 +400,9 @@ void (*cmdFuncs[NUMCMDS])(char *params) = {
doCmdStep,
doCmdTrace,
doCmdBList,
doCmdBreak,
doCmdBreakI,
doCmdBreakR,
doCmdBreakW,
doCmdBClear,
doCmdContinue
};

View File

@ -86,11 +86,7 @@ architecture behavioral of AtomBusMon is
signal brkpt_active : std_logic;
signal brkpt_active1 : std_logic;
signal brkpt_0 : std_logic_vector(15 downto 0);
signal brkpt_1 : std_logic_vector(15 downto 0);
signal brkpt_2 : std_logic_vector(15 downto 0);
signal brkpt_3 : std_logic_vector(15 downto 0);
signal brkpt_reg : std_logic_vector(63 downto 0);
signal brkpt_reg : std_logic_vector(79 downto 0);
begin
@ -186,15 +182,43 @@ begin
dy_data(1) <= hex & "0000" & Addr(7 downto 4);
dy_data(2) <= hex & "0000" & "00" & (not nsw2) & sw1;
brkpt_0 <= brkpt_reg(15 downto 0);
brkpt_1 <= brkpt_reg(31 downto 16);
brkpt_2 <= brkpt_reg(47 downto 32);
brkpt_3 <= brkpt_reg(63 downto 48);
brkpt_active <= '1' when brkpt_enable = '1' and Sync = '1' and
((Addr = brkpt_0) or (Addr = brkpt_1) or (Addr = brkpt_2) or (Addr = brkpt_3))
else '0';
brkpr_active: process (brkpt_reg, brkpt_enable, Addr, Sync)
variable tmp : std_logic;
variable i : integer;
variable brkpt_addr : std_logic_vector(15 downto 0);
variable brkpt_mode_i : std_logic;
variable brkpt_mode_ar : std_logic;
variable brkpt_mode_aw : std_logic;
begin
tmp := '0';
if (brkpt_enable = '1') then
for i in 0 to 3 loop
brkpt_addr := brkpt_reg(i * 20 + 15 downto i * 20);
brkpt_mode_i := brkpt_reg(i * 20 + 16);
brkpt_mode_ar := brkpt_reg(i * 20 + 17);
brkpt_mode_aw := brkpt_reg(i * 20 + 18);
if (Addr = brkpt_addr) then
if (Sync = '1') then
if (brkpt_mode_i = '1') then
tmp := '1';
end if;
else
if (RNW = '1') then
if (brkpt_mode_ar = '1') then
tmp := '1';
end if;
else
if (brkpt_mode_aw = '1') then
tmp := '1';
end if;
end if;
end if;
end if;
end loop;
end if;
brkpt_active <= tmp;
end process;
-- 6502 Control
syncProcess: process (Phi2)
@ -215,7 +239,7 @@ begin
brkpt_clock1 <= brkpt_clock;
brkpt_clock2 <= brkpt_clock1;
if (brkpt_enable = '0' and brkpt_clock2 = '0' and brkpt_clock1 = '1') then
brkpt_reg <= brkpt_data & brkpt_reg(63 downto 1);
brkpt_reg <= brkpt_data & brkpt_reg(brkpt_reg'length - 1 downto 1);
end if;
brkpt_active1 <= brkpt_active;
-- Single Stepping