diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index a13cd79d..11f2180b 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -270,6 +270,7 @@
+
@@ -357,6 +358,7 @@
+
@@ -404,6 +406,7 @@
Create
Create
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 2e47f733..aad3a74c 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -335,6 +335,12 @@
Debugger
+
+ Debugger
+
+
+ Debugger
+
@@ -442,5 +448,8 @@
Debugger
+
+ Debugger
+
\ No newline at end of file
diff --git a/Core/DebugState.h b/Core/DebugState.h
new file mode 100644
index 00000000..694c22f4
--- /dev/null
+++ b/Core/DebugState.h
@@ -0,0 +1,10 @@
+#pragma once
+#include "stdafx.h"
+#include "CPU.h"
+#include "PPU.h"
+
+struct DebugState
+{
+ State CPU;
+ PPUDebugState PPU;
+};
diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp
index f60994b6..5c178586 100644
--- a/Core/Debugger.cpp
+++ b/Core/Debugger.cpp
@@ -230,6 +230,12 @@ void Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
_disassembler->BuildCache(absoluteAddr, addr);
_lastInstruction = _memoryManager->DebugRead(addr);
+ if(_traceLogger) {
+ DebugState state;
+ GetState(&state);
+ _traceLogger->Log(state, _disassembler->GetDisassemblyInfo(absoluteAddr));
+ }
+
UpdateCallstack(addr);
ProcessStepConditions(addr);
@@ -414,6 +420,17 @@ void Debugger::SetNextStatement(uint16_t addr)
}
}
+void Debugger::StartTraceLogger(TraceLoggerOptions options)
+{
+ string traceFilepath = FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), "Trace.txt");
+ _traceLogger.reset(new TraceLogger(traceFilepath, options));
+}
+
+void Debugger::StopTraceLogger()
+{
+ _traceLogger.release();
+}
+
void Debugger::ProcessPpuCycle()
{
if(Debugger::Instance) {
diff --git a/Core/Debugger.h b/Core/Debugger.h
index b6f17319..d5a40ca8 100644
--- a/Core/Debugger.h
+++ b/Core/Debugger.h
@@ -8,7 +8,9 @@ using std::deque;
#include "CPU.h"
#include "PPU.h"
+#include "DebugState.h"
#include "Breakpoint.h"
+#include "TraceLogger.h"
#include "../Utilities/SimpleLock.h"
#include "CodeDataLogger.h"
@@ -16,12 +18,6 @@ class MemoryManager;
class Console;
class Disassembler;
-struct DebugState
-{
- State CPU;
- PPUDebugState PPU;
-};
-
enum class DebugMemoryType
{
CpuMemory = 0,
@@ -59,6 +55,8 @@ private:
SimpleLock _bpLock;
SimpleLock _breakLock;
+ unique_ptr _traceLogger;
+
uint16_t *_currentReadAddr; //Used to alter the executing address via "Set Next Statement"
string _romFilepath;
@@ -115,6 +113,9 @@ public:
uint8_t GetMemoryValue(uint32_t addr);
uint32_t GetRelativeAddress(uint32_t addr);
+ void StartTraceLogger(TraceLoggerOptions options);
+ void StopTraceLogger();
+
int32_t EvaluateExpression(string expression, EvalResultType &resultType);
static void ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t value);
diff --git a/Core/Disassembler.cpp b/Core/Disassembler.cpp
index 1e45cc9c..25203a33 100644
--- a/Core/Disassembler.cpp
+++ b/Core/Disassembler.cpp
@@ -192,3 +192,8 @@ string Disassembler::GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t &mem
return output.str();
}
+
+shared_ptr Disassembler::GetDisassemblyInfo(uint32_t address)
+{
+ return _disassembleCache[address];
+}
\ No newline at end of file
diff --git a/Core/Disassembler.h b/Core/Disassembler.h
index 7113dd8a..34d473d4 100644
--- a/Core/Disassembler.h
+++ b/Core/Disassembler.h
@@ -20,4 +20,6 @@ public:
uint32_t BuildCache(uint32_t absoluteAddr, uint16_t memoryAddr);
string GetRAMCode();
string GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t &memoryAddr);
+
+ shared_ptr GetDisassemblyInfo(uint32_t address);
};
diff --git a/Core/DisassemblyInfo.cpp b/Core/DisassemblyInfo.cpp
index 7f37d721..d1b95fb6 100644
--- a/Core/DisassemblyInfo.cpp
+++ b/Core/DisassemblyInfo.cpp
@@ -18,9 +18,12 @@ void DisassemblyInfo::Initialize(uint32_t memoryAddr)
//Output raw byte code
for(uint32_t i = 0; i < 3; i++) {
if(i < _opSize) {
- output << "$" << std::hex << std::uppercase << std::setfill('0') << std::setw(2) << (short)*(_opPointer+i) << " ";
+ output << "$" << std::hex << std::uppercase << std::setfill('0') << std::setw(2) << (short)*(_opPointer + i);
} else {
- output << " ";
+ output << " ";
+ }
+ if(i != 2) {
+ output << " ";
}
}
output << ":";
diff --git a/Core/EmulationSettings.cpp b/Core/EmulationSettings.cpp
index bbb5bdba..741c1024 100644
--- a/Core/EmulationSettings.cpp
+++ b/Core/EmulationSettings.cpp
@@ -1,7 +1,7 @@
#include "stdafx.h"
#include "EmulationSettings.h"
-uint32_t EmulationSettings::_flags = 0;
+uint32_t EmulationSettings::_flags = EmulationFlags::LowLatency;
bool EmulationSettings::_audioEnabled = true;
uint32_t EmulationSettings::_audioLatency = 20000;
diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h
index 4d721076..04f2771c 100644
--- a/Core/EmulationSettings.h
+++ b/Core/EmulationSettings.h
@@ -8,6 +8,7 @@ enum EmulationFlags
Paused = 0x01,
ShowFPS = 0x02,
VerticalSync = 0x04,
+ LowLatency = 0x08,
Mmc3IrqAltBehavior = 0x8000,
};
diff --git a/Core/TraceLogger.cpp b/Core/TraceLogger.cpp
new file mode 100644
index 00000000..c61eb9ed
--- /dev/null
+++ b/Core/TraceLogger.cpp
@@ -0,0 +1,33 @@
+#include "stdafx.h"
+#include "TraceLogger.h"
+#include "DisassemblyInfo.h"
+#include "DebugState.h"
+
+TraceLogger::TraceLogger(string outputFilepath, TraceLoggerOptions options)
+{
+ _outputFile.open(outputFilepath, ios::out | ios::binary);
+ _options = options;
+}
+
+TraceLogger::~TraceLogger()
+{
+ if(_outputFile) {
+ _outputFile.close();
+ }
+}
+
+void TraceLogger::Log(DebugState &state, shared_ptr disassemblyInfo)
+{
+ State &cpuState = state.CPU;
+ PPUDebugState &ppuState = state.PPU;
+
+ string disassembly = disassemblyInfo->ToString(cpuState.DebugPC);
+ while(disassembly.size() < 30) {
+ disassembly += " ";
+ }
+
+ _outputFile << std::uppercase << std::hex << (short)cpuState.DebugPC << ": " << disassembly << " "
+ << "A:" << (short)cpuState.A << " X:" << (short)cpuState.X << " Y:" << (short)cpuState.Y << " P:" << (short)cpuState.PS << " SP:" << (short)cpuState.SP
+ << std::dec
+ << " CYC:" << (short)ppuState.Cycle << " SL:" << (short)ppuState.Scanline << std::endl;
+}
\ No newline at end of file
diff --git a/Core/TraceLogger.h b/Core/TraceLogger.h
new file mode 100644
index 00000000..f309beb2
--- /dev/null
+++ b/Core/TraceLogger.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "stdafx.h"
+#include "DebugState.h"
+#include "DisassemblyInfo.h"
+
+struct TraceLoggerOptions
+{
+
+};
+
+class TraceLogger
+{
+private:
+ TraceLoggerOptions _options;
+ string _outputFilepath;
+ ofstream _outputFile;
+
+public:
+ TraceLogger(string outputFilepath, TraceLoggerOptions options);
+ ~TraceLogger();
+
+ void Log(DebugState &state, shared_ptr disassemblyInfo);
+};
\ No newline at end of file
diff --git a/GUI.NET/Debugger/frmDebugger.Designer.cs b/GUI.NET/Debugger/frmDebugger.Designer.cs
index 1974a517..490df475 100644
--- a/GUI.NET/Debugger/frmDebugger.Designer.cs
+++ b/GUI.NET/Debugger/frmDebugger.Designer.cs
@@ -73,6 +73,10 @@
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFindPrev = new System.Windows.Forms.ToolStripMenuItem();
this.mnuGoTo = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuGoToAddress = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuGoToIrqHandler = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuGoToNmiHandler = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuGoToResetHandler = new System.Windows.Forms.ToolStripMenuItem();
this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
@@ -85,16 +89,14 @@
this.generateROMToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveStrippedDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveUnusedDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.lblPrgAnalysis = new System.Windows.Forms.ToolStripStatusLabel();
this.lblPrgAnalysisResult = new System.Windows.Forms.ToolStripStatusLabel();
this.lblChrAnalysis = new System.Windows.Forms.ToolStripStatusLabel();
this.lblChrAnalysisResult = new System.Windows.Forms.ToolStripStatusLabel();
this.tmrCdlRatios = new System.Windows.Forms.Timer(this.components);
- this.mnuGoToAddress = new System.Windows.Forms.ToolStripMenuItem();
- this.mnuGoToIrqHandler = new System.Windows.Forms.ToolStripMenuItem();
- this.mnuGoToNmiHandler = new System.Windows.Forms.ToolStripMenuItem();
- this.mnuGoToResetHandler = new System.Windows.Forms.ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
@@ -308,12 +310,12 @@
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
- this.toolStripMenuItem3.Size = new System.Drawing.Size(149, 6);
+ this.toolStripMenuItem3.Size = new System.Drawing.Size(100, 6);
//
// mnuClose
//
this.mnuClose.Name = "mnuClose";
- this.mnuClose.Size = new System.Drawing.Size(152, 22);
+ this.mnuClose.Size = new System.Drawing.Size(103, 22);
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
@@ -330,7 +332,7 @@
//
this.mnuSplitView.CheckOnClick = true;
this.mnuSplitView.Name = "mnuSplitView";
- this.mnuSplitView.Size = new System.Drawing.Size(152, 22);
+ this.mnuSplitView.Size = new System.Drawing.Size(125, 22);
this.mnuSplitView.Text = "Split View";
this.mnuSplitView.Click += new System.EventHandler(this.mnuSplitView_Click);
//
@@ -341,7 +343,7 @@
this.mnuDecreaseFontSize,
this.mnuResetFontSize});
this.fontSizeToolStripMenuItem.Name = "fontSizeToolStripMenuItem";
- this.fontSizeToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+ this.fontSizeToolStripMenuItem.Size = new System.Drawing.Size(125, 22);
this.fontSizeToolStripMenuItem.Text = "Text Size";
//
// mnuIncreaseFontSize
@@ -510,12 +512,42 @@
this.mnuGoTo.Size = new System.Drawing.Size(196, 22);
this.mnuGoTo.Text = "Go To...";
//
+ // mnuGoToAddress
+ //
+ this.mnuGoToAddress.Name = "mnuGoToAddress";
+ this.mnuGoToAddress.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G)));
+ this.mnuGoToAddress.Size = new System.Drawing.Size(158, 22);
+ this.mnuGoToAddress.Text = "Address";
+ this.mnuGoToAddress.Click += new System.EventHandler(this.mnuGoToAddress_Click);
+ //
+ // mnuGoToIrqHandler
+ //
+ this.mnuGoToIrqHandler.Name = "mnuGoToIrqHandler";
+ this.mnuGoToIrqHandler.Size = new System.Drawing.Size(158, 22);
+ this.mnuGoToIrqHandler.Text = "IRQ Handler";
+ this.mnuGoToIrqHandler.Click += new System.EventHandler(this.mnuGoToIrqHandler_Click);
+ //
+ // mnuGoToNmiHandler
+ //
+ this.mnuGoToNmiHandler.Name = "mnuGoToNmiHandler";
+ this.mnuGoToNmiHandler.Size = new System.Drawing.Size(158, 22);
+ this.mnuGoToNmiHandler.Text = "NMI Handler";
+ this.mnuGoToNmiHandler.Click += new System.EventHandler(this.mnuGoToNmiHandler_Click);
+ //
+ // mnuGoToResetHandler
+ //
+ this.mnuGoToResetHandler.Name = "mnuGoToResetHandler";
+ this.mnuGoToResetHandler.Size = new System.Drawing.Size(158, 22);
+ this.mnuGoToResetHandler.Text = "Reset Handler";
+ this.mnuGoToResetHandler.Click += new System.EventHandler(this.mnuGoToResetHandler_Click);
+ //
// toolsToolStripMenuItem
//
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuPpuViewer,
this.mnuMemoryViewer,
- this.mnuCodeDataLogger});
+ this.mnuCodeDataLogger,
+ this.mnuTraceLogger});
this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
this.toolsToolStripMenuItem.Size = new System.Drawing.Size(48, 20);
this.toolsToolStripMenuItem.Text = "Tools";
@@ -604,6 +636,20 @@
this.saveUnusedDataToolStripMenuItem.Size = new System.Drawing.Size(170, 22);
this.saveUnusedDataToolStripMenuItem.Text = "Save unused data";
//
+ // mnuTraceLogger
+ //
+ this.mnuTraceLogger.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.toolStripMenuItem5});
+ this.mnuTraceLogger.Name = "mnuTraceLogger";
+ this.mnuTraceLogger.Size = new System.Drawing.Size(171, 22);
+ this.mnuTraceLogger.Text = "Trace Logger";
+ this.mnuTraceLogger.Click += new System.EventHandler(this.mnuTraceLogger_Click);
+ //
+ // toolStripMenuItem5
+ //
+ this.toolStripMenuItem5.Name = "toolStripMenuItem5";
+ this.toolStripMenuItem5.Size = new System.Drawing.Size(152, 22);
+ //
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -649,35 +695,6 @@
this.tmrCdlRatios.Interval = 300;
this.tmrCdlRatios.Tick += new System.EventHandler(this.tmrCdlRatios_Tick);
//
- // mnuGoToAddress
- //
- this.mnuGoToAddress.Name = "mnuGoToAddress";
- this.mnuGoToAddress.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G)));
- this.mnuGoToAddress.Size = new System.Drawing.Size(158, 22);
- this.mnuGoToAddress.Text = "Address";
- this.mnuGoToAddress.Click += new System.EventHandler(this.mnuGoToAddress_Click);
- //
- // mnuGoToIrqHandler
- //
- this.mnuGoToIrqHandler.Name = "mnuGoToIrqHandler";
- this.mnuGoToIrqHandler.Size = new System.Drawing.Size(158, 22);
- this.mnuGoToIrqHandler.Text = "IRQ Handler";
- this.mnuGoToIrqHandler.Click += new System.EventHandler(this.mnuGoToIrqHandler_Click);
- //
- // mnuGoToNmiHandler
- //
- this.mnuGoToNmiHandler.Name = "mnuGoToNmiHandler";
- this.mnuGoToNmiHandler.Size = new System.Drawing.Size(158, 22);
- this.mnuGoToNmiHandler.Text = "NMI Handler";
- this.mnuGoToNmiHandler.Click += new System.EventHandler(this.mnuGoToNmiHandler_Click);
- //
- // mnuGoToResetHandler
- //
- this.mnuGoToResetHandler.Name = "mnuGoToResetHandler";
- this.mnuGoToResetHandler.Size = new System.Drawing.Size(158, 22);
- this.mnuGoToResetHandler.Text = "Reset Handler";
- this.mnuGoToResetHandler.Click += new System.EventHandler(this.mnuGoToResetHandler_Click);
- //
// frmDebugger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -775,5 +792,7 @@
private System.Windows.Forms.ToolStripMenuItem mnuGoToIrqHandler;
private System.Windows.Forms.ToolStripMenuItem mnuGoToNmiHandler;
private System.Windows.Forms.ToolStripMenuItem mnuGoToResetHandler;
+ private System.Windows.Forms.ToolStripMenuItem mnuTraceLogger;
+ private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem5;
}
}
\ No newline at end of file
diff --git a/GUI.NET/Debugger/frmDebugger.cs b/GUI.NET/Debugger/frmDebugger.cs
index d0b9464a..e501d3e0 100644
--- a/GUI.NET/Debugger/frmDebugger.cs
+++ b/GUI.NET/Debugger/frmDebugger.cs
@@ -9,10 +9,11 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
+using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
- public partial class frmDebugger : Form
+ public partial class frmDebugger : BaseForm
{
private List