Added mask to breakpoint/watches; improved disassembly of breakpoints; incremented version to 0.31

Change-Id: If2a68ba1597d8be5479302f15110602614cc25e1
This commit is contained in:
David Banks 2015-06-19 16:10:07 +01:00
parent 73fc5a7eb1
commit 993f04e395
2 changed files with 119 additions and 95 deletions

View File

@ -156,7 +156,7 @@ char *triggerStrings[NUM_TRIGGERS] = {
}; };
#define VERSION "0.30" #define VERSION "0.31"
#ifdef EMBEDDED_6502 #ifdef EMBEDDED_6502
#define NUM_CMDS 25 #define NUM_CMDS 25
@ -187,6 +187,17 @@ unsigned int breakpoints[MAXBKPTS] = {
0 0
}; };
unsigned int masks[MAXBKPTS] = {
0,
0,
0,
0,
0,
0,
0,
0
};
unsigned int modes[MAXBKPTS] = { unsigned int modes[MAXBKPTS] = {
0, 0,
0, 0,
@ -198,7 +209,7 @@ unsigned int modes[MAXBKPTS] = {
0 0
}; };
unsigned int triggers[MAXBKPTS] = { int triggers[MAXBKPTS] = {
0, 0,
0, 0,
0, 0,
@ -354,48 +365,6 @@ void lcdAddr(unsigned int addr) {
#endif #endif
void logMode(unsigned int mode) {
int i;
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);
}
first = 0;
}
mode >>= 1;
}
}
void logTrigger(unsigned int trigger) {
if (trigger >= 0 && trigger < NUM_TRIGGERS) {
log0("trigger: %s", triggerStrings[trigger]);
} else {
log0("trigger: ILLEGAL");
}
}
int logDetails() {
unsigned int i_addr = hwRead16(OFFSET_BW_IAL);
unsigned int b_addr = hwRead16(OFFSET_BW_BAL);
unsigned int mode = hwRead8(OFFSET_BW_M);
unsigned int watch = mode & 8;
// Convert from 4-bit compressed to 6 bit expanded mode representation
if (watch) {
mode = (mode & 7) << 3;
}
// Update the serial console
logMode(mode);
log0(" hit at %04X", i_addr);
if (mode & BW_MEM_MASK) {
log0(" accessing %04X", b_addr);
}
log0("\n");
return watch;
}
int lookupBreakpoint(char *params) { int lookupBreakpoint(char *params) {
int i; int i;
@ -536,22 +505,54 @@ unsigned int disMem(unsigned int addr) {
return disassemble(addr); return disassemble(addr);
} }
#endif void logMode(unsigned int mode) {
/*******************************************
* Commands
*******************************************/
void doCmdHelp(char *params) {
int i; int i;
version(); int first = 1;
log0("Commands:\n"); for (i = 0; i < UNDEFINED; i++) {
for (i = 0; i < NUM_CMDS; i++) { if (mode & 1) {
log0(" %s\n", cmdStrings[i]); if (first) {
log0("%s", modeStrings[i]);
} else {
log0(", %c%s", tolower(*modeStrings[i]), modeStrings[i] + 1);
}
first = 0;
}
mode >>= 1;
} }
} }
void doCmdAddr() { void logTrigger(int trigger) {
if (trigger >= 0 && trigger < NUM_TRIGGERS) {
log0("trigger: %s", triggerStrings[trigger]);
} else {
log0("trigger: ILLEGAL");
}
}
int logDetails() {
unsigned int i_addr = hwRead16(OFFSET_BW_IAL);
unsigned int b_addr = hwRead16(OFFSET_BW_BAL);
unsigned int mode = hwRead8(OFFSET_BW_M);
unsigned int watch = mode & 8;
// Convert from 4-bit compressed to 6 bit expanded mode representation
if (watch) {
mode = (mode & 7) << 3;
}
// Update the serial console
logMode(mode);
log0(" hit at %04X", i_addr);
if (mode & BW_MEM_MASK) {
log0(" accessing %04X\n", b_addr);
disMem(i_addr);
} else {
log0("\n");
}
return watch;
}
#endif
void logAddr() {
memAddr = hwRead16(OFFSET_IAL); memAddr = hwRead16(OFFSET_IAL);
// Update the LCD display // Update the LCD display
#ifdef LCD #ifdef LCD
@ -567,6 +568,20 @@ void doCmdAddr() {
return; return;
} }
/*******************************************
* Commands
*******************************************/
void doCmdHelp(char *params) {
int i;
version();
log0("Commands:\n");
for (i = 0; i < NUM_CMDS; i++) {
log0(" %s\n", cmdStrings[i]);
}
}
void doCmdStep(char *params) { void doCmdStep(char *params) {
long i; long i;
long j; long j;
@ -590,7 +605,7 @@ void doCmdStep(char *params) {
hwCmd(CMD_STEP, 0); hwCmd(CMD_STEP, 0);
if (i == instructions || (trace && (--j == 0))) { if (i == instructions || (trace && (--j == 0))) {
Delay_us(10); Delay_us(10);
doCmdAddr(); logAddr();
j = trace; j = trace;
} }
} }
@ -702,7 +717,7 @@ void doCmdBList(char *params) {
int i; int i;
if (numbkpts) { if (numbkpts) {
for (i = 0; i < numbkpts; i++) { for (i = 0; i < numbkpts; i++) {
log0("%d: %04X: ", i, breakpoints[i]); log0("%d: %04X mask %04X: ", i, breakpoints[i], masks[i]);
logMode(modes[i]); logMode(modes[i]);
log0(" ("); log0(" (");
logTrigger(triggers[i]); logTrigger(triggers[i]);
@ -713,10 +728,11 @@ void doCmdBList(char *params) {
} }
} }
void setBreakpoint(int i, unsigned int addr, unsigned int mode, unsigned int trigger) { void setBreakpoint(int i, unsigned int addr, unsigned int mask, unsigned int mode, int trigger) {
logMode(mode); logMode(mode);
log0(" set at %04X\n", addr); log0(" set at %04X\n", addr);
breakpoints[i] = addr; breakpoints[i] = addr & mask;
masks[i] = mask;
modes[i] = mode; modes[i] = mode;
triggers[i] = trigger; triggers[i] = trigger;
} }
@ -724,8 +740,9 @@ void setBreakpoint(int i, unsigned int addr, unsigned int mode, unsigned int tri
void doCmdBreak(char *params, unsigned int mode) { void doCmdBreak(char *params, unsigned int mode) {
int i; int i;
unsigned int addr; unsigned int addr;
unsigned int trigger = -1; unsigned int mask = 0xFFFF;
sscanf(params, "%x %x", &addr, &trigger); int trigger = -1;
sscanf(params, "%x %x %x", &addr, &mask, &trigger);
for (i = 0; i < numbkpts; i++) { for (i = 0; i < numbkpts; i++) {
if (breakpoints[i] == addr) { if (breakpoints[i] == addr) {
if (modes[i] & mode) { if (modes[i] & mode) {
@ -736,7 +753,7 @@ void doCmdBreak(char *params, unsigned int mode) {
if (trigger == -1) { if (trigger == -1) {
trigger = triggers[i]; trigger = triggers[i];
} }
setBreakpoint(i, addr, modes[i] | mode, trigger); setBreakpoint(i, addr, mask, modes[i] | mode, trigger);
} }
return; return;
} }
@ -752,10 +769,11 @@ void doCmdBreak(char *params, unsigned int mode) {
} }
for (i = numbkpts - 2; i >= -1; i--) { for (i = numbkpts - 2; i >= -1; i--) {
if (i == -1 || breakpoints[i] < addr) { if (i == -1 || breakpoints[i] < addr) {
setBreakpoint(i + 1, addr, mode, trigger); setBreakpoint(i + 1, addr, mask, mode, trigger);
return; return;
} else { } else {
breakpoints[i + 1] = breakpoints[i]; breakpoints[i + 1] = breakpoints[i];
masks[i + 1] = masks[i];
modes[i + 1] = modes[i]; modes[i + 1] = modes[i];
triggers[i + 1] = triggers[i]; triggers[i + 1] = triggers[i];
} }
@ -800,6 +818,7 @@ void doCmdBClear(char *params, unsigned int mode) {
if (modes[n] == 0) { if (modes[n] == 0) {
for (i = n; i < numbkpts; i++) { for (i = n; i < numbkpts; i++) {
breakpoints[i] = breakpoints[i + 1]; breakpoints[i] = breakpoints[i + 1];
masks[i] = masks[i + 1];
modes[i] = modes[i + 1]; modes[i] = modes[i + 1];
triggers[i] = triggers[i + 1]; triggers[i] = triggers[i + 1];
} }
@ -853,20 +872,23 @@ void doCmdTrigger(char *params) {
} }
} }
void shiftBreakpointRegister(unsigned int addr, unsigned int mode, unsigned int trigger) { void shiftBreakpointRegister(unsigned int addr, unsigned int mask, unsigned int mode, int trigger) {
int i; int i;
// Trigger is 4 bits for (i = 0; i <= 15; i++) {
long reg = trigger; hwCmd(CMD_LOAD_BRKPT, addr & 1);
// Mode is 6 bits addr >>= 1;
reg <<= 6; }
reg |= mode; for (i = 0; i <= 15; i++) {
// Address is 16 bits hwCmd(CMD_LOAD_BRKPT, mask & 1);
reg <<= 16; mask >>= 1;
reg |= addr; }
// Total size is 26 bits for (i = 0; i <= 5; i++) {
for (i = 0; i <= 25; i++) { hwCmd(CMD_LOAD_BRKPT, mode & 1);
hwCmd(CMD_LOAD_BRKPT, reg & 1); mode >>= 1;
reg >>= 1; }
for (i = 0; i <= 3; i++) {
hwCmd(CMD_LOAD_BRKPT, trigger & 1);
trigger >>= 1;
} }
} }
@ -885,10 +907,10 @@ void doCmdContinue(char *params) {
// Load breakpoints into comparators // Load breakpoints into comparators
for (i = 0; i < numbkpts; i++) { for (i = 0; i < numbkpts; i++) {
shiftBreakpointRegister(breakpoints[i], modes[i], triggers[i]); shiftBreakpointRegister(breakpoints[i], masks[i], modes[i], triggers[i]);
} }
for (i = numbkpts; i < MAXBKPTS; i++) { for (i = numbkpts; i < MAXBKPTS; i++) {
shiftBreakpointRegister(0, 0, 0); shiftBreakpointRegister(0, 0, 0, 0);
} }
// Enable breakpoints // Enable breakpoints
@ -931,7 +953,7 @@ void doCmdContinue(char *params) {
hwCmd(CMD_BRKPT_ENABLE, 0); hwCmd(CMD_BRKPT_ENABLE, 0);
// Show current instruction // Show current instruction
doCmdAddr(); logAddr();
} }

View File

@ -25,7 +25,7 @@ use work.OhoPack.all ;
entity BusMonCore is entity BusMonCore is
generic ( generic (
num_comparators : integer := 8; num_comparators : integer := 8;
reg_width : integer := 26; reg_width : integer := 42;
fifo_width : integer := 36 fifo_width : integer := 36
); );
port ( port (
@ -270,6 +270,7 @@ begin
brkpt_active_process: process (brkpt_reg, brkpt_enable, Addr, Sync) brkpt_active_process: process (brkpt_reg, brkpt_enable, Addr, Sync)
variable i : integer; variable i : integer;
variable reg_addr : std_logic_vector(15 downto 0); 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_bi : std_logic;
variable reg_mode_bar : std_logic; variable reg_mode_bar : std_logic;
variable reg_mode_baw : std_logic; variable reg_mode_baw : std_logic;
@ -287,43 +288,44 @@ begin
if (brkpt_enable = '1') then if (brkpt_enable = '1') then
for i in 0 to num_comparators - 1 loop for i in 0 to num_comparators - 1 loop
reg_addr := brkpt_reg(i * reg_width + 15 downto i * reg_width); reg_addr := brkpt_reg(i * reg_width + 15 downto i * reg_width);
reg_mode_bi := brkpt_reg(i * reg_width + 16); reg_mask := brkpt_reg(i * reg_width + 31 downto i * reg_width + 16);
reg_mode_bar := brkpt_reg(i * reg_width + 17); reg_mode_bi := brkpt_reg(i * reg_width + 32);
reg_mode_baw := brkpt_reg(i * reg_width + 18); reg_mode_bar := brkpt_reg(i * reg_width + 33);
reg_mode_wi := brkpt_reg(i * reg_width + 19); reg_mode_baw := brkpt_reg(i * reg_width + 34);
reg_mode_war := brkpt_reg(i * reg_width + 20); reg_mode_wi := brkpt_reg(i * reg_width + 35);
reg_mode_waw := brkpt_reg(i * reg_width + 21); reg_mode_war := brkpt_reg(i * reg_width + 36);
trigval := brkpt_reg(i * reg_width + 22 + to_integer(unsigned(trig))); reg_mode_waw := brkpt_reg(i * reg_width + 37);
if (trigval = '1' and (Addr = reg_addr or 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_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_wi = '0' and reg_mode_war = '0' and reg_mode_waw = '0')))) then
if (Sync = '1') then if (Sync = '1') then
if (reg_mode_bi = '1') then if (reg_mode_bi = '1') then
bactive := '1'; bactive := '1';
status := "0001" & reg_addr; status := "0001" & Addr;
end if; end if;
if (reg_mode_wi = '1') then if (reg_mode_wi = '1') then
wactive := '1'; wactive := '1';
status := "1001" & reg_addr; status := "1001" & Addr;
end if; end if;
else else
if (RNW = '1') then if (RNW = '1') then
if (reg_mode_bar = '1') then if (reg_mode_bar = '1') then
bactive := '1'; bactive := '1';
status := "0010" & reg_addr; status := "0010" & Addr;
end if; end if;
if (reg_mode_war = '1') then if (reg_mode_war = '1') then
wactive := '1'; wactive := '1';
status := "1010" & reg_addr; status := "1010" & Addr;
end if; end if;
else else
if (reg_mode_baw = '1') then if (reg_mode_baw = '1') then
bactive := '1'; bactive := '1';
status := "0100" & reg_addr; status := "0100" & Addr;
end if; end if;
if (reg_mode_waw = '1') then if (reg_mode_waw = '1') then
wactive := '1'; wactive := '1';
status := "1100" & reg_addr; status := "1100" & Addr;
end if; end if;
end if; end if;
end if; end if;