Preparations for memory & i/o breakpoints

This commit is contained in:
tudnai 2022-11-17 11:44:39 -08:00
parent ed1a8a25a8
commit 41d33c19c3
5 changed files with 58 additions and 37 deletions

View File

@ -414,11 +414,11 @@ N V - B D I Z C
let line = getLine(inView: Disass_Display, forY: location.y) let line = getLine(inView: Disass_Display, forY: location.y)
let addr = getAddr(forLine: line) let addr = getAddr(forLine: line)
if m6502_dbg_bp_is_exists(addr) { if m6502_dbg_bp_exists(breakpoints, bp_last_idx, addr) {
m6502_dbg_bp_del(addr) bp_last_idx = m6502_dbg_bp_del(breakpoints, bp_last_idx, addr)
} }
else { else {
m6502_dbg_bp_add(addr) bp_last_idx = m6502_dbg_bp_add(breakpoints, bp_last_idx, addr)
} }
// force regenerate disassembly // force regenerate disassembly

View File

@ -35,9 +35,24 @@
/// Array of addresses of active breakpoints /// Array of addresses of active breakpoints
/// @note DEBUG_MAX_BREAKPOINTS controls its size /// @note DEBUG_MAX_BREAKPOINTS controls its size
uint16_t breakpoints[DEBUG_MAX_BREAKPOINTS]; uint16_t bp_array[DEBUG_MAX_BREAKPOINTS];
/// Pointer to the bp_array
/// @note We have to do this way because of interfacing problem with Swift
uint16_t * breakpoints = bp_array;
/// Array of addresses of memory read breakpoints
/// @note DEBUG_MAX_BREAKPOINTS controls its size
uint16_t mem_rd_bp[DEBUG_MAX_BREAKPOINTS];
uint16_t * mem_read_breakpoints = mem_rd_bp;
/// Array of addresses of memory write breakpoints
/// @note DEBUG_MAX_BREAKPOINTS controls its size
uint16_t mem_wr_bp[DEBUG_MAX_BREAKPOINTS];
uint16_t * mem_write_breakpoints = mem_wr_bp;
/// Index of last valid breakpoint element in the array /// Index of last valid breakpoint element in the array
int bp_last_idx = 0; int bp_last_idx = 0;
/// Index of last valid breakpoint element in the array
int bp_mem_read_last_idx = 0;
/// Index of last valid breakpoint element in the array
int bp_mem_write_last_idx = 0;
/// Index of current breapoint /// Index of current breapoint
/// @note It is more like a temporary variable /// @note It is more like a temporary variable
int bp_idx = 0; int bp_idx = 0;
@ -124,9 +139,9 @@ int m6502_dbg_bp_search(uint16_t arr[], int l, int r, uint16_t addr) {
/// Get index of the last BP /// Get index of the last BP
/// @param i Current last index /// @param i Current last index
/// @return Index of the last breakpoint or 0 if non /// @return Index of the last breakpoint or 0 if non
int m6502_dbg_bp_get_last(int i) { int m6502_dbg_bp_get_last(uint16_t *bp, int i) {
for(; i >= 0; i--) { for(; i >= 0; i--) {
if ( breakpoints[i] ) { if ( bp[i] ) {
return i; return i;
} }
} }
@ -186,20 +201,21 @@ int m6502_dbg_bp_get_not_empty() {
/// Move array down to eliminate leading zeros /// Move array down to eliminate leading zeros
/// @note: Array must be sorted before this! /// @note: Array must be sorted before this!
void m6502_dbg_bp_compact() { /// @return last index
int m6502_dbg_bp_compact(uint16_t * bp, int last) {
int i = m6502_dbg_bp_get_not_empty(); int i = m6502_dbg_bp_get_not_empty();
memcpy(breakpoints, breakpoints + i, bp_last_idx * sizeof(uint16_t)); memcpy(bp, bp + i, last * sizeof(uint16_t));
memset(breakpoints + bp_last_idx - i + 1, 0, (DEBUG_MAX_BREAKPOINTS - bp_last_idx + i - 1) * sizeof(uint16_t)); memset(bp + last - i + 1, 0, (DEBUG_MAX_BREAKPOINTS - last + i - 1) * sizeof(uint16_t));
bp_last_idx = m6502_dbg_bp_get_last(bp_last_idx); return m6502_dbg_bp_get_last(bp, last);
} }
/// Check if BP exists /// Check if BP exists
/// @param addr Address to check /// @param addr Address to check
/// @return 1 (true) if exists, 0 (false) if not /// @return 1 (true) if exists, 0 (false) if not
_Bool m6502_dbg_bp_is_exists(uint16_t addr) { _Bool m6502_dbg_bp_exists(uint16_t * bp, int last, uint16_t addr) {
if (addr) { if (addr) {
int i = m6502_dbg_bp_search(breakpoints, 0, bp_last_idx, addr); int i = m6502_dbg_bp_search(bp, 0, last, addr);
return i >= 0; return i >= 0;
} }
@ -209,35 +225,36 @@ _Bool m6502_dbg_bp_is_exists(uint16_t addr) {
/// Add breakpoint /// Add breakpoint
/// @param addr Address to add /// @param addr Address to add
/// @return Index of breakpoint or -1 if error /// @return Index of breakpoint or 0 if error
int m6502_dbg_bp_add(uint16_t addr) { int m6502_dbg_bp_add(uint16_t * bp, int last, uint16_t addr) {
if (bp_last_idx < DEBUG_MAX_BREAKPOINTS - 1) { if (last < DEBUG_MAX_BREAKPOINTS - 1) {
breakpoints[++bp_last_idx] = addr; bp[++last] = addr;
m6502_dbg_bp_sort(breakpoints, 0, bp_last_idx); m6502_dbg_bp_sort(bp, 0, last);
m6502_dbg_bp_compact(); last = m6502_dbg_bp_compact(bp, last);
return bp_last_idx; return last;
} }
// no empty slots // no empty slots
return -1; return 0;
} }
/// Remove a breakpoint /// Remove a breakpoint
/// @param addr address to remove /// @param addr address to remove
void m6502_dbg_bp_del(uint16_t addr) { int m6502_dbg_bp_del(uint16_t * bp, int last, uint16_t addr) {
int i = m6502_dbg_bp_search(breakpoints, 0, bp_last_idx, addr); int i = m6502_dbg_bp_search(bp, 0, last, addr);
if (i >= 0) { if (i >= 0) {
breakpoints[i] = 0; bp[i] = 0;
m6502_dbg_bp_sort(breakpoints, 0, bp_last_idx); m6502_dbg_bp_sort(breakpoints, 0, last);
m6502_dbg_bp_compact(); last = m6502_dbg_bp_compact(bp, last);
} }
return last;
} }
/// Delete all breakpoints /// Delete all breakpoints
void m6502_dbg_bp_del_all(void) { void m6502_dbg_bp_del_all(uint16_t * bp) {
bp_idx = 0; bp_idx = 0;
memset(breakpoints, 0, sizeof(breakpoints)); memset(bp, 0, sizeof(uint16_t) * DEBUG_MAX_BREAKPOINTS);
} }

View File

@ -12,13 +12,17 @@
#include <stdint.h> #include <stdint.h>
#define DEBUG_MAX_BREAKPOINTS 256 #define DEBUG_MAX_BREAKPOINTS 256
extern uint16_t breakpoints[DEBUG_MAX_BREAKPOINTS]; extern uint16_t * breakpoints;
extern uint16_t * mem_read_breakpoints;
extern uint16_t * mem_write_breakpoints;
extern int bp_last_idx; extern int bp_last_idx;
extern int bp_mem_read_last_idx;
extern int bp_mem_write_last_idx;
extern int m6502_dbg_bp_add(uint16_t addr); extern int m6502_dbg_bp_add(uint16_t * bp, int last, uint16_t addr);
extern void m6502_dbg_bp_del(uint16_t addr); extern int m6502_dbg_bp_del(uint16_t * bp, int last, uint16_t addr);
extern void m6502_dbg_bp_del_all(void); extern void m6502_dbg_bp_del_all(uint16_t * bp);
extern _Bool m6502_dbg_bp_is_exists(uint16_t addr); extern _Bool m6502_dbg_bp_exists(uint16_t * bp, int last, uint16_t addr);
#endif /* _6502_bp_h */ #endif /* _6502_bp_h */

View File

@ -188,10 +188,10 @@ void m6502_Debug(void) {
m6502.interrupt = NO_INT; m6502.interrupt = NO_INT;
if ( m6502_dbg_bp_is_exists(m6502.PC) ) { if ( m6502_dbg_bp_exists(breakpoints, bp_last_idx, m6502.PC) ) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0; // m6502.debugger.wMask = 0;
// m6502.debugger.on = 0; // m6502.debugger.on = 0;
m6502.interrupt = BREAKPOINT; m6502.interrupt = BREAKPOINT;
return; return;
} }
@ -226,7 +226,7 @@ void m6502_dbg_init(void) {
m6502.debugger.mask.brk = 1; m6502.debugger.mask.brk = 1;
m6502.debugger.mask.inv = 1; m6502.debugger.mask.inv = 1;
m6502.debugger.SP = 0xFF; m6502.debugger.SP = 0xFF;
m6502_dbg_bp_del_all(); m6502_dbg_bp_del_all(breakpoints);
} }

View File

@ -175,7 +175,7 @@ const char * disassemblyLine(_Bool highlight) {
static char line[256]; static char line[256];
snprintf( line, sizeof(line), "%s %s: %-11s%-4s%s", snprintf( line, sizeof(line), "%s %s: %-11s%-4s%s",
m6502_dbg_bp_is_exists(disassembly.addr) ? "*" : " ", m6502_dbg_bp_exists(breakpoints, bp_last_idx, disassembly.addr) ? "*" : " ",
disassembly.hexAddr, disassembly.hexAddr,
disassembly.opcode, disassembly.opcode,
disassembly.inst, disassembly.inst,