diff --git a/CHANGES b/CHANGES index 57a9b957b..5cb6fe228 100644 --- a/CHANGES +++ b/CHANGES @@ -57,6 +57,7 @@ Other fixes: - Core: Fix threading improperly setting paused state while interrupted - Debugger: Don't skip undefined instructions when debugger attached - Debugger: Close trace log when done tracing + - Debugger: Fix change watchpoints (fixes mgba.io/i/1947) - FFmpeg: Fix some small memory leaks - FFmpeg: Fix encoding of time base - GB Video: Fix SGB video logs diff --git a/include/mgba/debugger/debugger.h b/include/mgba/debugger/debugger.h index f3404c02b..2adfa117c 100644 --- a/include/mgba/debugger/debugger.h +++ b/include/mgba/debugger/debugger.h @@ -38,7 +38,8 @@ enum mWatchpointType { WATCHPOINT_WRITE = 1, WATCHPOINT_READ = 2, WATCHPOINT_RW = 3, - WATCHPOINT_WRITE_CHANGE = 4, + WATCHPOINT_CHANGE = 4, + WATCHPOINT_WRITE_CHANGE = 5, }; enum mBreakpointType { diff --git a/src/arm/debugger/memory-debugger.c b/src/arm/debugger/memory-debugger.c index dce4b9771..8ccb592e7 100644 --- a/src/arm/debugger/memory-debugger.c +++ b/src/arm/debugger/memory-debugger.c @@ -106,17 +106,24 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st } } + uint32_t oldValue; switch (width + 1) { case 1: - info->type.wp.oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0); + oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0); break; case 2: - info->type.wp.oldValue = debugger->originalMemory.load16(debugger->cpu, address, 0); + oldValue = debugger->originalMemory.load16(debugger->cpu, address, 0); break; case 4: - info->type.wp.oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0); + oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0); break; + default: + continue; } + if ((watchpoint->type & WATCHPOINT_CHANGE) && newValue == oldValue) { + continue; + } + info->type.wp.oldValue = oldValue; info->type.wp.newValue = newValue; info->address = address; info->type.wp.watchType = watchpoint->type; diff --git a/src/sm83/debugger/memory-debugger.c b/src/sm83/debugger/memory-debugger.c index c41350c67..2cd81669e 100644 --- a/src/sm83/debugger/memory-debugger.c +++ b/src/sm83/debugger/memory-debugger.c @@ -55,7 +55,11 @@ static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, s return false; } } - info->type.wp.oldValue = debugger->originalMemory.load8(debugger->cpu, address); + uint8_t oldValue = debugger->originalMemory.load8(debugger->cpu, address); + if ((watchpoint->type & WATCHPOINT_CHANGE) && newValue == oldValue) { + continue; + } + info->type.wp.oldValue = oldValue; info->type.wp.newValue = newValue; info->address = address; info->type.wp.watchType = watchpoint->type;