mirror of
https://github.com/hoglet67/AtomBusMon.git
synced 2025-08-15 15:27:23 +00:00
Firmware: show break/watch points when stepping (big change)
Change-Id: I106f3c6ac860d1f1bbae312b154491b5f8a0f86f
This commit is contained in:
@@ -742,11 +742,11 @@ int lookupBreakpointN(int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lookupBreakpoint(char *params) {
|
int lookupBreakpoint(char *params) {
|
||||||
int n = -1;
|
int addr = -1;
|
||||||
sscanf(params, "%x", &n);
|
sscanf(params, "%x", &addr);
|
||||||
n = lookupBreakpointN(n);
|
int n = lookupBreakpointN(addr);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
log0("Breakpoint/watch not set at %04X\n", n);
|
log0("Breakpoint/watch not set at %04X\n", addr);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -777,11 +777,29 @@ void logTooManyBreakpoints() {
|
|||||||
log0("All %d breakpoints are already set\n", numbkpts);
|
log0("All %d breakpoints are already set\n", numbkpts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uploadBreakpoints() {
|
||||||
|
int i;
|
||||||
|
// Disable breakpoints to allow loading
|
||||||
|
hwCmd(CMD_BRKPT_ENABLE, 0);
|
||||||
|
|
||||||
|
// Load breakpoints into comparators
|
||||||
|
for (i = 0; i < numbkpts; i++) {
|
||||||
|
shiftBreakpointRegister(breakpoints[i], masks[i], modes[i], triggers[i]);
|
||||||
|
}
|
||||||
|
for (i = numbkpts; i < MAXBKPTS; i++) {
|
||||||
|
shiftBreakpointRegister(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
// Enable breakpoints
|
||||||
|
hwCmd(CMD_BRKPT_ENABLE, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void setBreakpoint(int n, unsigned int addr, unsigned int mask, unsigned int mode, int trigger) {
|
void setBreakpoint(int n, unsigned int addr, unsigned int mask, unsigned int mode, int trigger) {
|
||||||
breakpoints[n] = addr & mask;
|
breakpoints[n] = addr & mask;
|
||||||
masks[n] = mask;
|
masks[n] = mask;
|
||||||
modes[n] = mode;
|
modes[n] = mode;
|
||||||
triggers[n] = trigger;
|
triggers[n] = trigger;
|
||||||
|
// Update the hardware copy of the breakpoints
|
||||||
|
uploadBreakpoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearBreakpoint(int n) {
|
void clearBreakpoint(int n) {
|
||||||
@@ -793,6 +811,9 @@ void clearBreakpoint(int n) {
|
|||||||
triggers[i] = triggers[i + 1];
|
triggers[i] = triggers[i + 1];
|
||||||
}
|
}
|
||||||
numbkpts--;
|
numbkpts--;
|
||||||
|
// Update the hardware copy of the breakpoints
|
||||||
|
uploadBreakpoints();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A generic helper that does most of the work of the watch/breakpoint commands
|
// A generic helper that does most of the work of the watch/breakpoint commands
|
||||||
@@ -802,46 +823,49 @@ void genericBreakpoint(char *params, unsigned int mode) {
|
|||||||
unsigned int mask = 0xFFFF;
|
unsigned int mask = 0xFFFF;
|
||||||
int trigger = -1;
|
int trigger = -1;
|
||||||
sscanf(params, "%x %x %x", &addr, &mask, &trigger);
|
sscanf(params, "%x %x %x", &addr, &mask, &trigger);
|
||||||
|
// First, see if a breakpoint with this address already exists
|
||||||
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) {
|
||||||
logMode(mode);
|
logMode(mode);
|
||||||
log0(" already set at %04X\n", addr);
|
log0(" already set at %04X\n", addr);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Preserve the existing trigger, unless it is overridden
|
// Preserve the existing trigger, unless it is overridden
|
||||||
if (trigger == -1) {
|
if (trigger == -1) {
|
||||||
trigger = triggers[i];
|
trigger = triggers[i];
|
||||||
}
|
}
|
||||||
logBreakpoint(addr, mode);
|
// Preserve the existing modes
|
||||||
setBreakpoint(i, addr, mask, modes[i] | mode, trigger);
|
mode |= modes[i];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (numbkpts == MAXBKPTS) {
|
// If existing breakpoint not find, then create a new one
|
||||||
logTooManyBreakpoints();
|
if (i == numbkpts) {
|
||||||
return;
|
if (numbkpts == MAXBKPTS) {
|
||||||
}
|
logTooManyBreakpoints();
|
||||||
numbkpts++;
|
|
||||||
// New breakpoint, so if trigger not specified, set to ALWAYS
|
|
||||||
if (trigger == -1) {
|
|
||||||
trigger = TRIGGER_ALWAYS;
|
|
||||||
}
|
|
||||||
for (i = numbkpts - 2; i >= -1; i--) {
|
|
||||||
if (i == -1 || breakpoints[i] < addr) {
|
|
||||||
logBreakpoint(addr, mode);
|
|
||||||
setBreakpoint(i + 1, addr, mask, mode, trigger);
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
breakpoints[i + 1] = breakpoints[i];
|
|
||||||
masks[i + 1] = masks[i];
|
|
||||||
modes[i + 1] = modes[i];
|
|
||||||
triggers[i + 1] = triggers[i];
|
|
||||||
}
|
}
|
||||||
|
// New breakpoint, so if trigger not specified, set to ALWAYS
|
||||||
|
if (trigger == -1) {
|
||||||
|
trigger = TRIGGER_ALWAYS;
|
||||||
|
}
|
||||||
|
// Maintain the breakpoints in order of address
|
||||||
|
while (i > 0 && breakpoints[i - 1] > addr) {
|
||||||
|
breakpoints[i] = breakpoints[i - 1];
|
||||||
|
masks[i] = masks[i - 1];
|
||||||
|
modes[i] = modes[i - 1];
|
||||||
|
triggers[i] = triggers[i - 1];
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
numbkpts++;
|
||||||
}
|
}
|
||||||
|
// At this point, i contains the index of the new breakpoint
|
||||||
|
logBreakpoint(addr, mode);
|
||||||
|
setBreakpoint(i, addr, mask, mode, trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Test Helpers
|
* Test Helpers
|
||||||
********************************************************/
|
********************************************************/
|
||||||
@@ -921,6 +945,25 @@ void test(unsigned int start, unsigned int end, int data) {
|
|||||||
}
|
}
|
||||||
#endif // CPU_EMBEDDED
|
#endif // CPU_EMBEDDED
|
||||||
|
|
||||||
|
int pollForEvents() {
|
||||||
|
int cont = 1;
|
||||||
|
while (STATUS_DIN & BW_ACTIVE_MASK) {
|
||||||
|
cont = logDetails();
|
||||||
|
hwCmd(CMD_WATCH_READ, 0);
|
||||||
|
Delay_us(10);
|
||||||
|
}
|
||||||
|
if (STATUS_DIN & INTERRUPTED_MASK) {
|
||||||
|
cont = 0;
|
||||||
|
}
|
||||||
|
if (Serial_ByteRecieved0()) {
|
||||||
|
// Interrupt on a return, ignore other characters
|
||||||
|
if (Serial_RxByte0() == 13) {
|
||||||
|
cont = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************
|
/*******************************************
|
||||||
* User Commands
|
* User Commands
|
||||||
*******************************************/
|
*******************************************/
|
||||||
@@ -935,7 +978,7 @@ void doCmdHelp(char *params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void doCmdStep(char *params) {
|
void doCmdStep(char *params) {
|
||||||
static long instructions = 1;
|
long instructions = 1;
|
||||||
long i;
|
long i;
|
||||||
long j;
|
long j;
|
||||||
sscanf(params, "%ld", &instructions);
|
sscanf(params, "%ld", &instructions);
|
||||||
@@ -950,6 +993,11 @@ void doCmdStep(char *params) {
|
|||||||
for (i = 1; i <= instructions; i++) {
|
for (i = 1; i <= instructions; i++) {
|
||||||
// Step the CPU
|
// Step the CPU
|
||||||
hwCmd(CMD_STEP, 0);
|
hwCmd(CMD_STEP, 0);
|
||||||
|
// Output any watch/breakpoint messages
|
||||||
|
if (!pollForEvents()) {
|
||||||
|
log0("Interrupted after %ld instructions\n", i);
|
||||||
|
i = instructions;
|
||||||
|
}
|
||||||
if (i == instructions || (trace && (--j == 0))) {
|
if (i == instructions || (trace && (--j == 0))) {
|
||||||
Delay_us(10);
|
Delay_us(10);
|
||||||
logAddr();
|
logAddr();
|
||||||
@@ -1302,35 +1350,20 @@ void doCmdNext(char *params) {
|
|||||||
logTooManyBreakpoints();
|
logTooManyBreakpoints();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setBreakpoint(numbkpts++, nextAddr, 0xffff, (1 << BRKPT_EXEC) | (1 << TRANSIENT), TRIGGER_ALWAYS);
|
numbkpts++;
|
||||||
|
setBreakpoint(numbkpts - 1, nextAddr, 0xffff, (1 << BRKPT_EXEC) | (1 << TRANSIENT), TRIGGER_ALWAYS);
|
||||||
doCmdContinue(params);
|
doCmdContinue(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doCmdContinue(char *params) {
|
void doCmdContinue(char *params) {
|
||||||
int i;
|
|
||||||
int status;
|
|
||||||
int reset = 0;
|
int reset = 0;
|
||||||
sscanf(params, "%d", &reset);
|
sscanf(params, "%d", &reset);
|
||||||
|
|
||||||
// Disable breakpoints to allow loading
|
|
||||||
hwCmd(CMD_BRKPT_ENABLE, 0);
|
|
||||||
|
|
||||||
// Load breakpoints into comparators
|
|
||||||
for (i = 0; i < numbkpts; i++) {
|
|
||||||
shiftBreakpointRegister(breakpoints[i], masks[i], modes[i], triggers[i]);
|
|
||||||
}
|
|
||||||
for (i = numbkpts; i < MAXBKPTS; i++) {
|
|
||||||
shiftBreakpointRegister(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CPU_6809)
|
#if defined(CPU_6809)
|
||||||
// Step the 6809, otherwise the breakpoint happends again immediately
|
// Step the 6809, otherwise the breakpoint happends again immediately
|
||||||
hwCmd(CMD_STEP, 0);
|
hwCmd(CMD_STEP, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable breakpoints
|
|
||||||
hwCmd(CMD_BRKPT_ENABLE, 1);
|
|
||||||
|
|
||||||
// Disable single stepping
|
// Disable single stepping
|
||||||
setSingle(0);
|
setSingle(0);
|
||||||
|
|
||||||
@@ -1344,32 +1377,12 @@ void doCmdContinue(char *params) {
|
|||||||
|
|
||||||
// Wait for breakpoint to become active
|
// Wait for breakpoint to become active
|
||||||
log0("CPU free running...\n");
|
log0("CPU free running...\n");
|
||||||
int cont = 1;
|
while (pollForEvents());
|
||||||
do {
|
|
||||||
status = STATUS_DIN;
|
|
||||||
if (status & BW_ACTIVE_MASK) {
|
|
||||||
cont = logDetails();
|
|
||||||
hwCmd(CMD_WATCH_READ, 0);
|
|
||||||
}
|
|
||||||
if (status & INTERRUPTED_MASK) {
|
|
||||||
cont = 0;
|
|
||||||
}
|
|
||||||
if (Serial_ByteRecieved0()) {
|
|
||||||
// Interrupt on a return, ignore other characters
|
|
||||||
if (Serial_RxByte0() == 13) {
|
|
||||||
cont = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Delay_us(10);
|
|
||||||
} while (cont);
|
|
||||||
log0("Interrupted\n");
|
log0("Interrupted\n");
|
||||||
|
|
||||||
// Enable single stepping
|
// Enable single stepping
|
||||||
setSingle(1);
|
setSingle(1);
|
||||||
|
|
||||||
// Disable breakpoints
|
|
||||||
hwCmd(CMD_BRKPT_ENABLE, 0);
|
|
||||||
|
|
||||||
// Show current instruction
|
// Show current instruction
|
||||||
logAddr();
|
logAddr();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user