Memory debugger to break at the instruction instead of at the next one

This commit is contained in:
tudnai 2022-11-18 18:36:19 -08:00
parent e48c71c254
commit ba4a99ad0d
6 changed files with 128 additions and 29 deletions

View File

@ -1274,6 +1274,20 @@
</PersistentString> </PersistentString>
</PersistentStrings> </PersistentStrings>
</ContextState> </ContextState>
<ContextState
contextName = "m6502_Debug:6502_dbg.c">
<PersistentStrings>
<PersistentString
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "m6502_saved.PC">
</PersistentString>
<PersistentString
value = "m6502_saved">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState <ContextState
contextName = "DisplayView.mouseExited(with:):DisplayView.swift"> contextName = "DisplayView.mouseExited(with:):DisplayView.swift">
<PersistentStrings> <PersistentStrings>

View File

@ -118,9 +118,20 @@ class DebuggerWindowController: NSWindowController, NSWindowDelegate {
PauseButtonUpdate() PauseButtonUpdate()
m6502.debugger.SP = 0xFF m6502.debugger.SP = 0xFF
m6502.debugger.wMask = 0 m6502.debugger.wMask = 0
m6502.debugger.mask.hlt = 1;
m6502.debugger.mask.brk = 1;
m6502.debugger.mask.inv = 1;
m6502.debugger.on = true m6502.debugger.on = true
m6502.interrupt = NO_INT
// because of memory debugger first we need to step over one instruction
// otherwise it would not step over that instruction
m6502_Step_dbg()
// now we cn resume to run
ViewController.shared?.Resume() ViewController.shared?.Resume()
} }
@ -130,7 +141,6 @@ class DebuggerWindowController: NSWindowController, NSWindowDelegate {
ViewController.shared?.Pause(0) ViewController.shared?.Pause(0)
// m6502.debugger.wMask = 0
m6502.debugger.on = false m6502.debugger.on = false
} }
@ -152,9 +162,21 @@ class DebuggerWindowController: NSWindowController, NSWindowDelegate {
@IBAction func Step_Over(_ sender: Any) { @IBAction func Step_Over(_ sender: Any) {
if MEM[Int(m6502.PC)] == 0x20 { if MEM[Int(m6502.PC)] == 0x20 {
m6502.debugger.SP = m6502.SP > 1 ? m6502.SP : 0 m6502.debugger.SP = m6502.SP > 1 ? m6502.SP : 0
m6502.debugger.wMask = 0
m6502.debugger.mask.out = 1 m6502.debugger.mask.out = 1
m6502.debugger.mask.hlt = 1;
m6502.debugger.mask.brk = 1;
m6502.debugger.mask.inv = 1;
m6502.debugger.on = true m6502.debugger.on = true
m6502.interrupt = NO_INT
// because of memory debugger first we need to step over one instruction
// otherwise it would not step over that instruction
m6502_Step_dbg()
// now we cn resume to run
ViewController.shared?.Resume() ViewController.shared?.Resume()
} }
else { else {
@ -165,7 +187,7 @@ class DebuggerWindowController: NSWindowController, NSWindowDelegate {
@IBAction func Step_In(_ sender: Any) { @IBAction func Step_In(_ sender: Any) {
m6502_Step() m6502_Step_dbg()
// TODO: This should be in Debugger! // TODO: This should be in Debugger!
if let debugger = DebuggerViewController.shared { if let debugger = DebuggerViewController.shared {
@ -181,9 +203,21 @@ class DebuggerWindowController: NSWindowController, NSWindowDelegate {
PauseButtonUpdate() PauseButtonUpdate()
m6502.debugger.SP = m6502.SP < 0xFE ? m6502.SP + 1 : 0xFF m6502.debugger.SP = m6502.SP < 0xFE ? m6502.SP + 1 : 0xFF
m6502.debugger.wMask = 0
m6502.debugger.mask.out = 1 m6502.debugger.mask.out = 1
m6502.debugger.mask.hlt = 1;
m6502.debugger.mask.brk = 1;
m6502.debugger.mask.inv = 1;
m6502.debugger.on = true m6502.debugger.on = true
m6502.interrupt = NO_INT
// because of memory debugger first we need to step over one instruction
// otherwise it would not step over that instruction
m6502_Step_dbg()
// now we cn resume to run
ViewController.shared?.Resume() ViewController.shared?.Resume()
} }

View File

@ -1349,6 +1349,8 @@ class ViewController: NSViewController {
break break
} }
// clear iterrupt
m6502.interrupt = NO_INT
} }
else { else {
m6502_Run() m6502_Run()

View File

@ -54,6 +54,7 @@
#define IRQ_VECTOR 0xFFFE #define IRQ_VECTOR 0xFFFE
extern m6502_t m6502; extern m6502_t m6502;
m6502_t m6502_saved;
uint16_t disass_addr = 0xFDED; uint16_t disass_addr = 0xFDED;
@ -100,7 +101,7 @@ INLINE int m6502_Step_dbg(void) {
void m6502_Debug(void) { void m6502_Debug(void) {
m6502.clktime += m6502.clkfrm; m6502.clktime += m6502.clkfrm;
m6502.clkfrm = 0;
m6502.lastIO = 0; m6502.lastIO = 0;
m6502.interrupt = NO_INT; // TODO: This should be taken care by the interrupt handler m6502.interrupt = NO_INT; // TODO: This should be taken care by the interrupt handler
@ -114,14 +115,16 @@ void m6502_Debug(void) {
} }
} }
clk_6502_per_frm_max = clk_6502_per_frm; for (
pc = m6502.PC; m6502_saved = m6502, clk_6502_per_frm_max = clk_6502_per_frm;
for ( m6502.clkfrm = m6502_Step_dbg(); m6502.clkfrm < clk_6502_per_frm_max; m6502.clkfrm += m6502_Step_dbg() ) { m6502.clkfrm < clk_6502_per_frm_max;
m6502_saved = m6502, m6502.clkfrm += m6502_Step_dbg()
){
switch (m6502.interrupt) { switch (m6502.interrupt) {
case HALT: case HALT:
if (m6502.debugger.mask.hlt) { if (m6502.debugger.mask.hlt) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
return; return;
} }
break; break;
@ -129,7 +132,7 @@ void m6502_Debug(void) {
case BREAK: case BREAK:
if (m6502.debugger.mask.brk) { if (m6502.debugger.mask.brk) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
return; return;
} }
break; break;
@ -137,8 +140,13 @@ void m6502_Debug(void) {
case BREAKRDMEM: case BREAKRDMEM:
if (m6502.debugger.mask.brk) { if (m6502.debugger.mask.brk) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
m6502.PC = pc; // memory break happens *after* executing
// the instruction, therefore we need to
// step back to get it right in the debugger
m6502_saved.interrupt = m6502.interrupt;
m6502 = m6502_saved;
return; return;
} }
break; break;
@ -146,7 +154,13 @@ void m6502_Debug(void) {
case BREAKWRMEM: case BREAKWRMEM:
if (m6502.debugger.mask.brk) { if (m6502.debugger.mask.brk) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
// memory break happens *after* executing
// the instruction, therefore we need to
// step back to get it right in the debugger
m6502_saved.interrupt = m6502.interrupt;
m6502 = m6502_saved;
return; return;
} }
break; break;
@ -154,7 +168,7 @@ void m6502_Debug(void) {
case IRQ: case IRQ:
if (m6502.debugger.mask.irq) { if (m6502.debugger.mask.irq) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
return; return;
} }
break; break;
@ -162,7 +176,7 @@ void m6502_Debug(void) {
case NMI: case NMI:
if (m6502.debugger.mask.nmi) { if (m6502.debugger.mask.nmi) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
return; return;
} }
break; break;
@ -170,7 +184,7 @@ void m6502_Debug(void) {
case INV: case INV:
if (m6502.debugger.mask.inv) { if (m6502.debugger.mask.inv) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
return; return;
} }
break; break;
@ -180,7 +194,7 @@ void m6502_Debug(void) {
if (m6502.debugger.mask.out) { if (m6502.debugger.mask.out) {
if ( m6502.SP >= m6502.debugger.SP ) { if ( m6502.SP >= m6502.debugger.SP ) {
cpuState = cpuState_halted; cpuState = cpuState_halted;
// m6502.debugger.wMask = 0;
return; return;
} }
} }

View File

@ -9,6 +9,7 @@
#ifndef _6502_dbg_h #ifndef _6502_dbg_h
#define _6502_dbg_h #define _6502_dbg_h
extern m6502_t m6502_saved;
extern uint16_t disass_addr; extern uint16_t disass_addr;
extern void m6502_Debug(void); extern void m6502_Debug(void);

View File

@ -971,6 +971,37 @@ INLINE void ioWrite( uint16_t addr, uint8_t val ) {
return; return;
} }
INLINE uint8_t is_mem_rd_bp(uint16_t addr) {
if (LAST_IDX(mem_read_breakpoints)) {
if ( m6502_dbg_bp_exists(mem_read_breakpoints, addr) ) {
// printf("MEM BP $%04X (bp:%04X)\n", addr, m6502.PC);
// cpuState = cpuState_halted;
m6502.interrupt = BREAKRDMEM;
return 1;
}
}
return 0;
}
INLINE uint8_t is_mem_wr_bp(uint16_t addr) {
if (LAST_IDX(mem_write_breakpoints)) {
if ( m6502_dbg_bp_exists(mem_write_breakpoints, addr) ) {
// printf("MEM BP $%04X (bp:%04X)\n", addr, m6502.PC);
// cpuState = cpuState_halted;
m6502.interrupt = BREAKWRMEM;
return 1;
}
}
return 0;
}
/** /**
Naive implementation of RAM read from address Naive implementation of RAM read from address
**/ **/
@ -996,11 +1027,15 @@ INLINE uint16_t memread16_low( uint16_t addr ) {
// return * (uint16_t*) ( RDHIMEM + addr ); // return * (uint16_t*) ( RDHIMEM + addr );
//} //}
INLINE uint16_t memread16( uint16_t addr ) { INLINE uint16_t memread16( uint16_t addr ) {
// if (addr >= 0xC000) {
// return memread16_high(addr);
// }
// if (addr >= 0xC000) { return memread16_low(addr);
// return memread16_high(addr); }
// } INLINE uint16_t _memread16_dbg( uint16_t addr ) {
is_mem_rd_bp(addr);
return memread16_low(addr); return memread16_low(addr);
} }
@ -1020,14 +1055,7 @@ INLINE uint8_t _memread( uint16_t addr ) {
} }
INLINE uint8_t _memread_dbg( uint16_t addr ) { INLINE uint8_t _memread_dbg( uint16_t addr ) {
if (LAST_IDX(mem_read_breakpoints)) { is_mem_rd_bp(addr);
if ( m6502_dbg_bp_exists(mem_read_breakpoints, addr) ) {
// printf("MEM BP $%04X (bp:%04X)\n", addr, m6502.PC);
// cpuState = cpuState_halted;
m6502.interrupt = BREAKRDMEM;
}
}
return _memread(addr); return _memread(addr);
} }
@ -1302,6 +1330,9 @@ INLINE uint8_t _src_zp_dis() {
INLINE uint16_t _addr_ind() { INLINE uint16_t _addr_ind() {
return memread16( _fetch() ); return memread16( _fetch() );
} }
INLINE uint16_t _addr_ind_dbg() {
return _memread16_dbg( _fetch() );
}
INLINE uint16_t _addr_ind_dis() { INLINE uint16_t _addr_ind_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "($%02X,X)", memread8(m6502.PC) ); _disPrintf(disassembly.oper, sizeof(disassembly.oper), "($%02X,X)", memread8(m6502.PC) );
_disPrintf(disassembly.comment, sizeof(disassembly.comment), "ind_addr:%04X", memread16( memread8(m6502.PC)) ); _disPrintf(disassembly.comment, sizeof(disassembly.comment), "ind_addr:%04X", memread16( memread8(m6502.PC)) );
@ -1312,7 +1343,7 @@ INLINE uint8_t _src_ind() {
return _memread( _addr_ind() ); return _memread( _addr_ind() );
} }
INLINE uint8_t _src_ind_dbg() { INLINE uint8_t _src_ind_dbg() {
return _memread_dbg( _addr_ind() ); return _memread_dbg( _addr_ind_dbg() );
} }
INLINE uint8_t _src_ind_dis() { INLINE uint8_t _src_ind_dis() {
return _memread_dis( _addr_ind_dis() ); return _memread_dis( _addr_ind_dis() );
@ -1326,6 +1357,9 @@ INLINE uint8_t _src_ind_dis() {
INLINE uint16_t _addr_ind_X() { INLINE uint16_t _addr_ind_X() {
return memread16( _fetch() + m6502.X ); return memread16( _fetch() + m6502.X );
} }
INLINE uint16_t _addr_ind_X_dbg() {
return _memread16_dbg( _fetch() + m6502.X );
}
INLINE uint16_t _addr_ind_X_dis() { INLINE uint16_t _addr_ind_X_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "($%02X,X)", memread8(m6502.PC) ); _disPrintf(disassembly.oper, sizeof(disassembly.oper), "($%02X,X)", memread8(m6502.PC) );
_disPrintf(disassembly.comment, sizeof(disassembly.comment), "ind_addr:%04X", memread16( memread8(m6502.PC) + m6502.X) ); _disPrintf(disassembly.comment, sizeof(disassembly.comment), "ind_addr:%04X", memread16( memread8(m6502.PC) + m6502.X) );
@ -1336,7 +1370,7 @@ INLINE uint8_t _src_X_ind() {
return _memread( _addr_ind_X() ); return _memread( _addr_ind_X() );
} }
INLINE uint8_t _src_X_ind_dbg() { INLINE uint8_t _src_X_ind_dbg() {
return _memread_dbg( _addr_ind_X() ); return _memread_dbg( _addr_ind_X_dbg() );
} }
INLINE uint8_t _src_X_ind_dis() { INLINE uint8_t _src_X_ind_dis() {
return _memread_dis( _addr_ind_X_dis() ); return _memread_dis( _addr_ind_X_dis() );