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"