diff --git a/docs/debugger.html b/docs/debugger.html index 068239884..46bd7c164 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -1007,6 +1007,7 @@ clearSaveStateIfs - Clear all saveState points loadAllStates - Load all emulator states loadState - Load emulator state xx (0-9) logBreaks - Logs breaks and traps and continues emulation + logTrace - Logs emulation (note: emulation may slow down and the log becomes huge soon) n - Negative Flag: set (0 or 1), or toggle (no arg) palette - Show current TIA palette pc - Set Program Counter to address xx diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 7c5619eeb..89c95bacd 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -485,7 +485,6 @@ void Debugger::log(string_view triggerMsg) break; } - const CartDebug::DisassemblyTag& tag = disasm.list[pos]; ostringstream msg; msg << std::left << std::setw(10) << std::setfill(' ') << triggerMsg; @@ -515,13 +514,17 @@ void Debugger::log(string_view triggerMsg) else msg << " "; - msg << Base::HEX4 << pc << " " - << std::left << std::setw(8) << std::setfill(' ') << tag.bytes << " " - << tag.disasm.substr(0, 7); + if(disasm.list.size() > pos) + { + const CartDebug::DisassemblyTag& tag = disasm.list[pos]; - if(tag.disasm.length() > 8) - msg << tag.disasm.substr(8); + msg << Base::HEX4 << pc << " " + << std::left << std::setw(8) << std::setfill(' ') << tag.bytes << " " + << tag.disasm.substr(0, 7); + if(tag.disasm.length() > 8) + msg << tag.disasm.substr(8); + } Logger::log(msg.str()); } diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index e71555782..8a8a4daae 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -1796,6 +1796,16 @@ void DebuggerParser::executeLogBreaks() commandResult << "logBreaks " << (enable ? "enabled" : "disabled"); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void DebuggerParser::executeLogTrace() +{ + const bool enable = !debugger.mySystem.m6502().getLogTrace(); + + debugger.mySystem.m6502().setLogTrace(enable); + settings.setValue("dbg.logtrace", enable); + commandResult << "logTrace " << (enable ? "enabled" : "disabled"); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "n" void DebuggerParser::executeN() @@ -3361,6 +3371,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { { std::mem_fn(&DebuggerParser::executeLogBreaks) }, + { + "logTrace", + "Toggle emulation logging", + "Example: logBreaks", + false, + true, + { Parameters::ARG_END_ARGS }, + std::mem_fn(&DebuggerParser::executeLogTrace) + }, + { "n", "Negative Flag: set (0 or 1), or toggle (no arg)", diff --git a/src/debugger/DebuggerParser.hxx b/src/debugger/DebuggerParser.hxx index cef58eaff..ad467471d 100644 --- a/src/debugger/DebuggerParser.hxx +++ b/src/debugger/DebuggerParser.hxx @@ -101,7 +101,7 @@ class DebuggerParser std::array parms; std::function executor; }; - using CommandArray = std::array; + using CommandArray = std::array; static CommandArray commands; struct Trap @@ -211,6 +211,7 @@ class DebuggerParser void executeLoadConfig(); void executeLoadState(); void executeLogBreaks(); + void executeLogTrace(); void executeN(); void executePalette(); void executePc(); diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index d6d1c056f..c9219f601 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -411,6 +411,11 @@ void PromptWidget::loadConfig() print(DebuggerParser::inverse(" logBreaks enabled ")); extra = true; } + if(instance().settings().getBool("dbg.logtrace")) + { + print(DebuggerParser::inverse(" logTrace enabled ")); + extra = true; + } if(extra) print("\n"); diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx index ace6b3f9a..b3d368716 100644 --- a/src/emucore/M6502.cxx +++ b/src/emucore/M6502.cxx @@ -95,6 +95,7 @@ void M6502::reset() myReadFromWritePortBreak = devSettings ? mySettings.getBool("dev.rwportbreak") : false; myWriteToReadPortBreak = devSettings ? mySettings.getBool("dev.wrportbreak") : false; myLogBreaks = mySettings.getBool("dbg.logbreaks"); + myLogTrace = mySettings.getBool("dbg.logtrace"); myLastBreakCycle = ULLONG_MAX; } @@ -317,6 +318,14 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) return; } } + + if(myLogTrace && myDebugger) + { + // Make sure that the TIA state matches the current system clock. + // Else Scanlines, Cycles and Pixels are not updated for logging. + mySystem->tia().updateEmulation(); + myDebugger->log("trace"); + } } const int cond = evalCondSaveStates(); diff --git a/src/emucore/M6502.hxx b/src/emucore/M6502.hxx index eab1fd428..54e4d2114 100644 --- a/src/emucore/M6502.hxx +++ b/src/emucore/M6502.hxx @@ -268,6 +268,8 @@ class M6502 : public Serializable void setWriteToReadPortBreak(bool enable) { myWriteToReadPortBreak = enable; } void setLogBreaks(bool enable) { myLogBreaks = enable; } bool getLogBreaks() const { return myLogBreaks; } + void setLogTrace(bool enable) { myLogTrace = enable; } + bool getLogTrace() const { return myLogTrace; } #endif // DEBUGGER_SUPPORT private: @@ -486,6 +488,7 @@ class M6502 : public Serializable bool myWriteToReadPortBreak{false}; // trap on writes to read ports bool myStepStateByInstruction{false}; bool myLogBreaks{false}; // log breaks/taps and continue emulation + bool myLogTrace{false}; // log emulation private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 53131849f..3e3bbeec9 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -235,6 +235,7 @@ Settings::Settings() setPermanent("dbg.uhex", "false"); setPermanent("dbg.ghostreadstrap", "true"); setPermanent("dbg.logbreaks", "false"); + setPermanent("dbg.logtrace", "false"); setPermanent("dbg.autosave", "false"); setPermanent("dis.resolve", "true"); setPermanent("dis.gfxformat", "2"); @@ -743,6 +744,7 @@ void Settings::usage() << " -dbg.ghostreadstrap <1|0> Debugger traps on 'ghost' reads\n" << " -dbg.uhex <0|1> Lower-/uppercase HEX display\n" << " -dbg.logbreaks <0|1> Log breaks and traps and continue emulation\n" + << " -dbg.logtrace <0|1> Log emulation\n" << " -dbg.autosave <0|1> Automatically save breaks, traps etc.\n" << " -break
Set a breakpoint at 'address'\n" << " -debug Start in debugger mode\n"