Memory Write Debug Breakpoint

This commit is contained in:
tudnai 2022-11-19 20:37:35 -08:00
parent f2a36f9e33
commit 4e29fc6ae3
6 changed files with 99 additions and 57 deletions

View File

@ -78,7 +78,7 @@
case 0x3A: DEA(); return 2; // DEA imm (DEC A)
// JMP - (abs,X) addressing mode
case 0x7C: JMP( addr_abs_X() ); return 6; // JMP abs,X
case 0x7C: JMP( abs_addr_X() ); return 6; // JMP abs,X
// Additional instructions

View File

@ -115,12 +115,12 @@ void m6502_Debug(void) {
}
}
for (
m6502_saved = m6502, clk_6502_per_frm_max = clk_6502_per_frm;
m6502.clkfrm < clk_6502_per_frm_max;
memcpy(&m6502_saved, &m6502, 7), // copy over only A, X, Y, Status, PC & SP...
m6502.clkfrm += m6502_Step_dbg()
){
clk_6502_per_frm_max = clk_6502_per_frm;
while ( m6502.clkfrm < clk_6502_per_frm_max ) {
m6502_saved = m6502;
m6502.clkfrm += m6502_Step_dbg();
switch (m6502.interrupt) {
case HALT:
if (m6502.debugger.mask.hlt) {
@ -139,26 +139,14 @@ void m6502_Debug(void) {
break;
case BREAKRDMEM:
if (m6502.debugger.mask.brk) {
cpuState = cpuState_halted;
// memory break happens *after* executing
// the instruction, therefore we need to
// step back to get it right in the debugger
memcpy(&m6502, &m6502_saved, 7); // copy over only A, X, Y, Status, PC & SP...
return;
}
break;
case BREAKWRMEM:
if (m6502.debugger.mask.brk) {
cpuState = cpuState_halted;
// memory break happens *after* executing
// the instruction, therefore we need to
// step back to get it right in the debugger
memcpy(&m6502, &m6502_saved, 7); // copy over only A, X, Y, Status, PC & SP...
// 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; // we need to keep the new interrupt though
m6502 = m6502_saved; // copy over only A, X, Y, Status, PC & SP...
return;
}
@ -260,6 +248,7 @@ void m6502_dbg_init(void) {
// TODO: TESTING ONLY!!!
// m6502_dbg_bp_add(mem_read_breakpoints, 0xC000);
// m6502_dbg_bp_add(mem_write_breakpoints, 0xC099);
}

View File

@ -83,7 +83,7 @@
case 0x4B: ASR( imm() ); return 2; // ASR* imm 2 (undocumented)
case 0x4F: SRE( abs_addr() ); return 6; // SRE* abs 6 (undocumented)
case 0x4F: SRE( addr_abs() ); return 6; // SRE* abs 6 (undocumented)
case 0x52: HLT(); return 0; // HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x53: SRE( addr_ind_Y() ); return 8; // SRE* izy 8 (undocumented)
@ -105,7 +105,7 @@
case 0x6B: ARC( imm() ); return 2; // ARR/ARC* imm 2 (undocumented)
case 0x6F: RRA( abs_addr() ); return 6; // RRA* abs 6 (undocumented)
case 0x6F: RRA( addr_abs() ); return 6; // RRA* abs 6 (undocumented)
case 0x72: HLT(); return 0; // HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x73: RRA( addr_ind_Y() ); return 8; // RRA* izy 8 (undocumented)

View File

@ -322,6 +322,8 @@ INSTR void SRE ( uint16_t addr ) {
#ifndef DISASSEMBLER
// LSR
m6502.C = WRLOMEM[addr] & 1;
// TODO: this and the next operation should be one!
// TODO: Review flag calculation!
set_flags_NZ( WRLOMEM[addr] >>= 1 );
// EOR M

View File

@ -972,7 +972,7 @@ INLINE void ioWrite( uint16_t addr, uint8_t val ) {
}
INLINE uint8_t is_mem_rd_bp(uint16_t addr) {
INLINE uint8_t check_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);
@ -987,7 +987,7 @@ INLINE uint8_t is_mem_rd_bp(uint16_t addr) {
}
INLINE uint8_t is_mem_wr_bp(uint16_t addr) {
INLINE uint8_t check_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);
@ -1035,9 +1035,13 @@ INLINE uint16_t memread16( uint16_t addr ) {
return memread16_low(addr);
}
INLINE uint16_t _memread16_dbg( uint16_t addr ) {
is_mem_rd_bp(addr);
check_mem_rd_bp(addr);
return memread16_low(addr);
}
INLINE uint16_t _memread16_wr_dbg( uint16_t addr ) {
check_mem_wr_bp(addr);
return addr;
}
INLINE uint8_t _memread( uint16_t addr ) {
if (addr >= 0xC000) {
@ -1055,7 +1059,7 @@ INLINE uint8_t _memread( uint16_t addr ) {
}
INLINE uint8_t _memread_dbg( uint16_t addr ) {
is_mem_rd_bp(addr);
check_mem_rd_bp(addr);
return _memread(addr);
}
@ -1191,6 +1195,11 @@ INLINE uint16_t _fetch16_dis() {
INLINE uint16_t _addr_abs() {
return _fetch16();
}
INLINE uint16_t _addr_abs_dbg() {
uint16_t addr = _fetch16();
check_mem_wr_bp(addr);
return addr;
}
INLINE uint16_t _addr_abs_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%04X", memread16(m6502.PC));
return _fetch16_dis();
@ -1212,21 +1221,11 @@ INLINE uint8_t _src_abs_dis() {
INLINE int8_t _rel_addr() {
return _fetch();
}
INLINE int8_t _rel_addr_dbg() {
uint16_t addr = _fetch();
is_mem_rd_bp(addr);
return addr;
}
INLINE int8_t _rel_addr_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%04X", m6502.PC + 1 + (int8_t)memread8(m6502.PC));
return _fetch_dis();
}
INLINE uint16_t _abs_addr() {
uint16_t addr = _fetch16();
is_mem_rd_bp(addr);
return addr;
}
INLINE uint16_t _abs_addr_dbg() {
return _fetch16();
}
INLINE uint16_t _abs_addr_dis() {
@ -1250,9 +1249,21 @@ INLINE uint16_t _ind_addr_dis() {
abs,X .... absolute, X-indexed OPC $LLHH,X
operand is address; effective address is address incremented by X with carry **
**/
INLINE uint16_t _abs_addr_X() {
return _fetch16() + m6502.X;
}
INLINE uint16_t _abs_addr_X_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%04X,X", memread16(m6502.PC));
return _fetch16_dis() + m6502.X;
}
INLINE uint16_t _addr_abs_X() {
return _fetch16() + m6502.X;
}
INLINE uint16_t _addr_abs_X_dbg() {
uint16_t addr = _fetch16() + m6502.X;
check_mem_wr_bp(addr);
return addr;
}
INLINE uint16_t _addr_abs_X_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%04X,X", memread16(m6502.PC));
return _fetch16_dis() + m6502.X;
@ -1278,6 +1289,11 @@ INLINE uint8_t _src_abs_X_dis() {
INLINE uint16_t _addr_abs_Y() {
return _fetch16() + m6502.Y;
}
INLINE uint16_t _addr_abs_Y_dbg() {
uint16_t addr = _fetch16() + m6502.Y;
check_mem_wr_bp(addr);
return addr;
}
INLINE uint16_t _addr_abs_Y_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%04X,Y", memread16(m6502.PC));
return _fetch16_dis() + m6502.Y;
@ -1309,7 +1325,14 @@ INLINE uint8_t _imm_dis() {
operand is zeropage address (hi-byte is zero, address = $00LL)
**/
INLINE uint8_t _addr_zp() {
return _fetch();
uint16_t addr = _fetch();
check_mem_wr_bp(addr);
return addr;
}
INLINE uint8_t _addr_zp_dbg() {
uint16_t addr = _fetch();
check_mem_wr_bp(addr);
return addr;
}
INLINE uint8_t _addr_zp_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%02X", memread8(m6502.PC));
@ -1319,7 +1342,7 @@ INLINE uint8_t _src_zp() {
return memread8_low(_addr_zp());
}
INLINE uint8_t _src_zp_dbg() {
return _memread_dbg(_addr_zp());
return _memread_dbg(_addr_zp_dbg());
}
INLINE uint8_t _src_zp_dis() {
return memread8_low(_addr_zp_dis());
@ -1347,7 +1370,9 @@ INLINE uint16_t _addr_ind() {
return memread16( _fetch() );
}
INLINE uint16_t _addr_ind_dbg() {
return _memread16_dbg( _fetch() );
uint16_t addr = _memread16_dbg(_fetch());
check_mem_wr_bp(addr); // write debug on the target address
return addr;
}
INLINE uint16_t _addr_ind_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "($%02X,X)", memread8(m6502.PC) );
@ -1373,9 +1398,14 @@ INLINE uint8_t _src_ind_dis() {
INLINE uint16_t _addr_ind_X() {
return memread16( _fetch() + m6502.X );
}
INLINE uint16_t _addr_ind_X_dbg() {
INLINE uint16_t _addr_ind_X_rd_dbg() {
return _memread16_dbg( _fetch() + m6502.X );
}
INLINE uint16_t _addr_ind_X_dbg() {
uint16_t addr = _memread16_dbg(_fetch() + m6502.X);
check_mem_wr_bp(addr); // write debug on the target address
return addr;
}
INLINE uint16_t _addr_ind_X_dis() {
_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) );
@ -1386,7 +1416,7 @@ INLINE uint8_t _src_X_ind() {
return _memread( _addr_ind_X() );
}
INLINE uint8_t _src_X_ind_dbg() {
return _memread_dbg( _addr_ind_X_dbg() );
return _memread_dbg( _addr_ind_X_rd_dbg() );
}
INLINE uint8_t _src_X_ind_dis() {
return _memread_dis( _addr_ind_X_dis() );
@ -1405,7 +1435,7 @@ INLINE uint16_t _addr_ind_Y() {
}
INLINE uint16_t _addr_ind_Y_dbg() {
uint16_t addr = _memread16_dbg( _fetch() ) + m6502.Y;
is_mem_rd_bp(addr);
check_mem_wr_bp(addr);
return addr;
}
INLINE uint16_t _addr_ind_Y_dis() {
@ -1436,6 +1466,11 @@ INLINE uint8_t _src_ind_Y_dis() {
INLINE uint8_t _addr_zp_X() {
return _fetch() + m6502.X;
}
INLINE uint8_t _addr_zp_X_dbg() {
uint16_t addr = _fetch() + m6502.X;
check_mem_wr_bp(addr);
return addr;
}
INLINE uint8_t _addr_zp_X_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%02X,X", memread8(m6502.PC));
@ -1462,6 +1497,11 @@ INLINE uint8_t _src_zp_X_dis() {
INLINE uint8_t _addr_zp_Y() {
return _fetch() + m6502.Y;
}
INLINE uint8_t _addr_zp_Y_dbg() {
uint16_t addr = _fetch() + m6502.Y;
check_mem_wr_bp(addr);
return addr;
}
INLINE uint8_t _addr_zp_Y_dis() {
_disPrintf(disassembly.oper, sizeof(disassembly.oper), "$%02X,Y", memread8(m6502.PC));

View File

@ -422,25 +422,28 @@ INLINE uint8_t _fetch_dis(void);
INLINE uint16_t _fetch16(void);
INLINE uint16_t _fetch16_dis(void);
INLINE uint16_t _addr_abs(void);
INLINE uint16_t _addr_abs_dbg(void);
INLINE uint16_t _addr_abs_dis(void);
INLINE uint8_t _src_abs(void);
INLINE uint8_t _src_abs_dbg(void);
INLINE uint8_t _src_abs_dis(void);
INLINE int8_t _rel_addr(void);
INLINE int8_t _rel_addr_dbg(void);
INLINE int8_t _rel_addr_dis(void);
INLINE uint16_t _abs_addr(void);
INLINE uint16_t _abs_addr_dbg(void);
INLINE uint16_t _abs_addr_dis(void);
INLINE uint16_t _ind_addr(void);
INLINE uint16_t _ind_addr_dbg(void);
INLINE uint16_t _ind_addr_dis(void);
INLINE uint16_t _addr_abs_X(void);
INLINE uint16_t _addr_abs_X_dbg(void);
INLINE uint16_t _addr_abs_X_dis(void);
INLINE uint16_t _abs_addr_X(void);
INLINE uint16_t _abs_addr_X_dis(void);
INLINE uint8_t _src_abs_X(void);
INLINE uint8_t _src_abs_X_dbg(void);
INLINE uint8_t _src_abs_X_dis(void);
INLINE uint16_t _addr_abs_Y(void);
INLINE uint16_t _addr_abs_Y_dbg(void);
INLINE uint16_t _addr_abs_Y_dis(void);
INLINE uint8_t _src_abs_Y(void);
INLINE uint8_t _src_abs_Y_dbg(void);
@ -448,16 +451,19 @@ INLINE uint8_t _src_abs_Y_dis(void);
INLINE uint8_t _imm(void);
INLINE uint8_t _imm_dis(void);
INLINE uint8_t _addr_zp(void);
INLINE uint8_t _addr_zp_dbg(void);
INLINE uint8_t _addr_zp_dis(void);
INLINE uint8_t _src_zp(void);
INLINE uint8_t _src_zp_dbg(void);
INLINE uint8_t _src_zp_dis(void);
INLINE uint16_t _addr_ind(void);
INLINE uint16_t _addr_ind_dbg(void);
INLINE uint16_t _addr_ind_dis(void);
INLINE uint8_t _src_ind(void);
INLINE uint8_t _src_ind_dbg(void);
INLINE uint8_t _src_ind_dis(void);
INLINE uint16_t _addr_ind_X(void);
INLINE uint16_t _addr_ind_X_dbg(void);
INLINE uint16_t _addr_ind_X_dis(void);
INLINE uint8_t _src_X_ind(void);
INLINE uint8_t _src_X_ind_dbg(void);
@ -469,11 +475,13 @@ INLINE uint8_t _src_ind_Y(void);
INLINE uint8_t _src_ind_Y_dbg(void);
INLINE uint8_t _src_ind_Y_dis(void);
INLINE uint8_t _addr_zp_X(void);
INLINE uint8_t _addr_zp_X_dbg(void);
INLINE uint8_t _addr_zp_X_dis(void);
INLINE uint8_t _src_zp_X(void);
INLINE uint8_t _src_zp_X_dbg(void);
INLINE uint8_t _src_zp_X_dis(void);
INLINE uint8_t _addr_zp_Y(void);
INLINE uint8_t _addr_zp_Y_dbg(void);
INLINE uint8_t _addr_zp_Y_dis(void);
INLINE uint8_t _src_zp_Y(void);
INLINE uint8_t _src_zp_Y_dbg(void);
@ -495,6 +503,7 @@ INLINE uint8_t _src_zp_Y_dis(void);
#define abs_addr() _abs_addr_dis()
#define ind_addr() _ind_addr_dis()
#define addr_abs_X() _addr_abs_X_dis()
#define abs_addr_X() _abs_addr_X_dis()
#define src_abs_X() _src_abs_X_dis()
#define addr_abs_Y() _addr_abs_Y_dis()
#define src_abs_Y() _src_abs_Y_dis()
@ -521,27 +530,28 @@ INLINE uint8_t _src_zp_Y_dis(void);
#define memwrite8_bank(addr,data) _memwrite8_bank(addr,data)
#define memwrite8_high(addr,data) _memwrite8_high(addr,data)
#define memwrite(addr,data) _memwrite(addr,data);
#define addr_abs() _addr_abs()
#define addr_abs() _addr_abs_dbg()
#define src_abs() _src_abs_dbg()
#define rel_addr() _rel_addr_dbg()
#define abs_addr() _abs_addr_dbg()
#define rel_addr() _rel_addr()
#define abs_addr() _abs_addr()
#define ind_addr() _ind_addr_dbg()
#define addr_abs_X() _addr_abs_X()
#define addr_abs_X() _addr_abs_X_dbg()
#define abs_addr_X() _abs_addr_X()
#define src_abs_X() _src_abs_X_dbg()
#define addr_abs_Y() _addr_abs_Y()
#define addr_abs_Y() _addr_abs_Y_dbg()
#define src_abs_Y() _src_abs_Y_dbg()
#define imm() _imm()
#define addr_zp() _addr_zp()
#define addr_zp() _addr_zp_dbg()
#define src_zp() _src_zp_dbg()
#define addr_ind() _addr_ind()
#define addr_ind() _addr_ind_dbg()
#define src_ind() _src_ind_dbg()
#define addr_ind_X() _addr_ind_X()
#define addr_ind_X() _addr_ind_X_dbg()
#define src_X_ind() _src_X_ind_dbg()
#define addr_ind_Y() _addr_ind_Y_dbg()
#define src_ind_Y() _src_ind_Y_dbg()
#define addr_zp_X() _addr_zp_X()
#define addr_zp_X() _addr_zp_X_dbg()
#define src_zp_X() _src_zp_X_dbg()
#define addr_zp_Y() _addr_zp_Y()
#define addr_zp_Y() _addr_zp_Y_dbg()
#define src_zp_Y() _src_zp_Y_dbg()
#else // DEBUGGER
@ -559,6 +569,7 @@ INLINE uint8_t _src_zp_Y_dis(void);
#define abs_addr() _abs_addr()
#define ind_addr() _ind_addr()
#define addr_abs_X() _addr_abs_X()
#define abs_addr_X() _abs_addr_X()
#define src_abs_X() _src_abs_X()
#define addr_abs_Y() _addr_abs_Y()
#define src_abs_Y() _src_abs_Y()