Trace Logger: Added options + improved UI usability

This commit is contained in:
Souryo 2016-09-03 21:52:59 -04:00
parent 2b1bb57a67
commit 9ad4719d57
10 changed files with 309 additions and 33 deletions

View File

@ -518,7 +518,7 @@ void Debugger::SetNextStatement(uint16_t addr)
void Debugger::StartTraceLogger(TraceLoggerOptions options)
{
string traceFilepath = FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), "Trace.txt");
string traceFilepath = FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), "Trace - " + FolderUtilities::GetFilename(_romName, false) + ".log");
_traceLogger.reset(new TraceLogger(traceFilepath, options));
}

View File

@ -92,6 +92,7 @@ PPUDebugState PPU::GetState()
state.State = _state;
state.Cycle = _cycle;
state.Scanline = _scanline;
state.FrameCount = _frameCount;
return state;
}

View File

@ -86,6 +86,7 @@ struct PPUDebugState
PPUState State;
int32_t Scanline;
uint32_t Cycle;
uint32_t FrameCount;
};
class PPU : public IMemoryHandler, public Snapshotable

View File

@ -29,7 +29,7 @@ TraceLogger::~TraceLogger()
void TraceLogger::LogStatic(string log)
{
if(_instance) {
if(_instance && _instance->_options.ShowExtraInfo) {
_instance->_outputFile << " - [" << log << " - Cycle: " << std::to_string(CPU::GetCycleCount()) << "]";
}
}
@ -61,20 +61,46 @@ void TraceLogger::Log(DebugState &state, shared_ptr<DisassemblyInfo> disassembly
_outputFile << std::endl;
}
_outputFile << std::uppercase << std::hex
<< std::setfill('0') << std::setw(4) << std::right << (short)cpuState.DebugPC << " "
<< std::setfill(' ') << std::setw(10) << std::left << byteCode
<< std::setfill(' ') << std::setw(32) << std::left << assemblyCode
<< std::setfill('0')
<< "A:" << std::right << std::setw(2) << (short)cpuState.A
<< " X:" << std::setw(2) << (short)cpuState.X
<< " Y:" << std::setw(2) << (short)cpuState.Y
<< " P:" << std::setw(2) << (short)cpuState.PS
<< " SP:" << std::setw(2) << (short)cpuState.SP
<< std::dec << std::setfill(' ') << std::right
<< " CYC:" << std::setw(3) << ppuCycle << std::left
<< " SL:" << std::setw(3) << scanline
<< " CPU Cycle:" << cpuState.CycleCount;
_outputFile << std::uppercase << std::hex << std::setfill('0') << std::setw(4) << std::right << (short)cpuState.DebugPC << " ";
if(_options.ShowByteCode) {
_outputFile << std::setfill(' ') << std::setw(10) << std::left << byteCode;
}
int indentLevel = 0;
if(_options.IndentCode) {
indentLevel = 0xFF - state.CPU.SP;
_outputFile << std::string(indentLevel, ' ');
}
_outputFile << std::setfill(' ') << std::setw(32 - indentLevel) << std::left << assemblyCode;
if(_options.ShowRegisters) {
_outputFile << std::setfill('0')
<< "A:" << std::right << std::setw(2) << (short)cpuState.A
<< " X:" << std::setw(2) << (short)cpuState.X
<< " Y:" << std::setw(2) << (short)cpuState.Y
<< " P:" << std::setw(2) << (short)cpuState.PS
<< " SP:" << std::setw(2) << (short)cpuState.SP;
}
_outputFile << std::dec << std::setfill(' ');
if(_options.ShowPpuCycles) {
_outputFile << std::right << " CYC:" << std::setw(3) << ppuCycle;
}
if(_options.ShowPpuScanline) {
_outputFile << std::left << " SL:" << std::setw(3) << scanline;
}
if(_options.ShowPpuFrames) {
_outputFile << " FC:" << ppuState.FrameCount;
}
if(_options.ShowCpuCycles) {
_outputFile << " CPU Cycle:" << cpuState.CycleCount;
}
_firstLine = false;
}

View File

@ -6,7 +6,14 @@ struct DebugState;
struct TraceLoggerOptions
{
bool ShowByteCode;
bool ShowRegisters;
bool ShowCpuCycles;
bool ShowPpuCycles;
bool ShowPpuScanline;
bool ShowPpuFrames;
bool ShowExtraInfo;
bool IndentCode;
};
class TraceLogger

View File

@ -103,6 +103,18 @@ namespace Mesen.GUI.Config
}
}
public static string DebuggerFolder
{
get
{
string debuggerFolder = Path.Combine(ConfigManager.HomeFolder, "Debugger");
if(!Directory.Exists(debuggerFolder)) {
Directory.CreateDirectory(debuggerFolder);
}
return debuggerFolder;
}
}
public static string DownloadFolder
{
get

View File

@ -19,6 +19,7 @@ namespace Mesen.GUI.Debugger
private List<Form> _childForms = new List<Form>();
private InteropEmu.NotificationListener _notifListener;
private ctrlDebuggerCode _lastCodeWindow;
private frmTraceLogger _traceLogger;
public frmDebugger()
{
@ -388,7 +389,15 @@ namespace Mesen.GUI.Debugger
private void mnuTraceLogger_Click(object sender, EventArgs e)
{
new frmTraceLogger().Show();
if(_traceLogger == null) {
_traceLogger = new frmTraceLogger();
_traceLogger.FormClosed += (s, evt) => {
_traceLogger = null;
};
_traceLogger.Show(sender, this);
} else {
_traceLogger.Focus();
}
}
private void mnuPpuPartialDraw_Click(object sender, EventArgs e)

View File

@ -28,31 +28,62 @@
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.btnOpenTrace = new System.Windows.Forms.Button();
this.btnStartLogging = new System.Windows.Forms.Button();
this.btnStopLogging = new System.Windows.Forms.Button();
this.grpLogOptions = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.chkShowCpuCycles = new System.Windows.Forms.CheckBox();
this.chkShowPpuCycles = new System.Windows.Forms.CheckBox();
this.chkShowRegisters = new System.Windows.Forms.CheckBox();
this.chkShowPpuScanline = new System.Windows.Forms.CheckBox();
this.chkShowFrameCount = new System.Windows.Forms.CheckBox();
this.chkShowExtraInfo = new System.Windows.Forms.CheckBox();
this.chkShowByteCode = new System.Windows.Forms.CheckBox();
this.chkIndentCode = new System.Windows.Forms.CheckBox();
this.tableLayoutPanel1.SuspendLayout();
this.grpLogOptions.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnCount = 3;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Controls.Add(this.btnOpenTrace, 2, 0);
this.tableLayoutPanel1.Controls.Add(this.btnStartLogging, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.btnStopLogging, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.btnStopLogging, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.grpLogOptions, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.chkIndentCode, 0, 2);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(133, 59);
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(339, 150);
this.tableLayoutPanel1.TabIndex = 0;
//
// btnOpenTrace
//
this.btnOpenTrace.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnOpenTrace.Enabled = false;
this.btnOpenTrace.Location = new System.Drawing.Point(241, 3);
this.btnOpenTrace.Name = "btnOpenTrace";
this.btnOpenTrace.Size = new System.Drawing.Size(95, 23);
this.btnOpenTrace.TabIndex = 2;
this.btnOpenTrace.Text = "Open Trace File";
this.btnOpenTrace.UseVisualStyleBackColor = true;
this.btnOpenTrace.Click += new System.EventHandler(this.btnOpenTrace_Click);
//
// btnStartLogging
//
this.btnStartLogging.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.btnStartLogging.Location = new System.Drawing.Point(19, 3);
this.btnStartLogging.Location = new System.Drawing.Point(3, 3);
this.btnStartLogging.Name = "btnStartLogging";
this.btnStartLogging.Size = new System.Drawing.Size(95, 23);
this.btnStartLogging.TabIndex = 0;
@ -62,8 +93,8 @@
//
// btnStopLogging
//
this.btnStopLogging.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.btnStopLogging.Location = new System.Drawing.Point(19, 32);
this.btnStopLogging.Enabled = false;
this.btnStopLogging.Location = new System.Drawing.Point(104, 3);
this.btnStopLogging.Name = "btnStopLogging";
this.btnStopLogging.Size = new System.Drawing.Size(95, 23);
this.btnStopLogging.TabIndex = 1;
@ -71,11 +102,141 @@
this.btnStopLogging.UseVisualStyleBackColor = true;
this.btnStopLogging.Click += new System.EventHandler(this.btnStopLogging_Click);
//
// grpLogOptions
//
this.tableLayoutPanel1.SetColumnSpan(this.grpLogOptions, 3);
this.grpLogOptions.Controls.Add(this.tableLayoutPanel2);
this.grpLogOptions.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpLogOptions.Location = new System.Drawing.Point(3, 32);
this.grpLogOptions.Name = "grpLogOptions";
this.grpLogOptions.Size = new System.Drawing.Size(333, 90);
this.grpLogOptions.TabIndex = 3;
this.grpLogOptions.TabStop = false;
this.grpLogOptions.Text = "Log Contents";
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 3;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel2.Controls.Add(this.chkShowCpuCycles, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuCycles, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.chkShowRegisters, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuScanline, 1, 1);
this.tableLayoutPanel2.Controls.Add(this.chkShowFrameCount, 2, 1);
this.tableLayoutPanel2.Controls.Add(this.chkShowExtraInfo, 0, 2);
this.tableLayoutPanel2.Controls.Add(this.chkShowByteCode, 2, 2);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 4;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(327, 71);
this.tableLayoutPanel2.TabIndex = 0;
//
// chkShowCpuCycles
//
this.chkShowCpuCycles.AutoSize = true;
this.chkShowCpuCycles.Checked = true;
this.chkShowCpuCycles.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkShowCpuCycles.Location = new System.Drawing.Point(112, 3);
this.chkShowCpuCycles.Name = "chkShowCpuCycles";
this.chkShowCpuCycles.Size = new System.Drawing.Size(82, 17);
this.chkShowCpuCycles.TabIndex = 3;
this.chkShowCpuCycles.Text = "CPU Cycles";
this.chkShowCpuCycles.UseVisualStyleBackColor = true;
//
// chkShowPpuCycles
//
this.chkShowPpuCycles.AutoSize = true;
this.chkShowPpuCycles.Checked = true;
this.chkShowPpuCycles.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkShowPpuCycles.Location = new System.Drawing.Point(3, 26);
this.chkShowPpuCycles.Name = "chkShowPpuCycles";
this.chkShowPpuCycles.Size = new System.Drawing.Size(77, 17);
this.chkShowPpuCycles.TabIndex = 5;
this.chkShowPpuCycles.Text = "PPU Cycle";
this.chkShowPpuCycles.UseVisualStyleBackColor = true;
//
// chkShowRegisters
//
this.chkShowRegisters.AutoSize = true;
this.chkShowRegisters.Checked = true;
this.chkShowRegisters.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkShowRegisters.Location = new System.Drawing.Point(3, 3);
this.chkShowRegisters.Name = "chkShowRegisters";
this.chkShowRegisters.Size = new System.Drawing.Size(70, 17);
this.chkShowRegisters.TabIndex = 2;
this.chkShowRegisters.Text = "Registers";
this.chkShowRegisters.UseVisualStyleBackColor = true;
//
// chkShowPpuScanline
//
this.chkShowPpuScanline.AutoSize = true;
this.chkShowPpuScanline.Checked = true;
this.chkShowPpuScanline.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkShowPpuScanline.Location = new System.Drawing.Point(112, 26);
this.chkShowPpuScanline.Name = "chkShowPpuScanline";
this.chkShowPpuScanline.Size = new System.Drawing.Size(92, 17);
this.chkShowPpuScanline.TabIndex = 6;
this.chkShowPpuScanline.Text = "PPU Scanline";
this.chkShowPpuScanline.UseVisualStyleBackColor = true;
//
// chkShowFrameCount
//
this.chkShowFrameCount.AutoSize = true;
this.chkShowFrameCount.Location = new System.Drawing.Point(221, 26);
this.chkShowFrameCount.Name = "chkShowFrameCount";
this.chkShowFrameCount.Size = new System.Drawing.Size(86, 17);
this.chkShowFrameCount.TabIndex = 7;
this.chkShowFrameCount.Text = "Frame Count";
this.chkShowFrameCount.UseVisualStyleBackColor = true;
//
// chkShowExtraInfo
//
this.chkShowExtraInfo.AutoSize = true;
this.chkShowExtraInfo.Checked = true;
this.chkShowExtraInfo.CheckState = System.Windows.Forms.CheckState.Checked;
this.tableLayoutPanel2.SetColumnSpan(this.chkShowExtraInfo, 2);
this.chkShowExtraInfo.Location = new System.Drawing.Point(3, 49);
this.chkShowExtraInfo.Name = "chkShowExtraInfo";
this.chkShowExtraInfo.Size = new System.Drawing.Size(204, 17);
this.chkShowExtraInfo.TabIndex = 9;
this.chkShowExtraInfo.Text = "Additional information (IRQ, NMI, etc.)";
this.chkShowExtraInfo.UseVisualStyleBackColor = true;
//
// chkShowByteCode
//
this.chkShowByteCode.AutoSize = true;
this.chkShowByteCode.Checked = true;
this.chkShowByteCode.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkShowByteCode.Location = new System.Drawing.Point(221, 49);
this.chkShowByteCode.Name = "chkShowByteCode";
this.chkShowByteCode.Size = new System.Drawing.Size(75, 17);
this.chkShowByteCode.TabIndex = 4;
this.chkShowByteCode.Text = "Byte Code";
this.chkShowByteCode.UseVisualStyleBackColor = true;
//
// chkIndentCode
//
this.chkIndentCode.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.chkIndentCode, 3);
this.chkIndentCode.Location = new System.Drawing.Point(3, 128);
this.chkIndentCode.Name = "chkIndentCode";
this.chkIndentCode.Size = new System.Drawing.Size(194, 17);
this.chkIndentCode.TabIndex = 8;
this.chkIndentCode.Text = "Indent code based on stack pointer";
this.chkIndentCode.UseVisualStyleBackColor = true;
//
// frmTraceLogger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(133, 59);
this.ClientSize = new System.Drawing.Size(339, 150);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
@ -84,6 +245,10 @@
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Trace Logger";
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.grpLogOptions.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.ResumeLayout(false);
}
@ -93,6 +258,16 @@
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Button btnStopLogging;
private System.Windows.Forms.Button btnStartLogging;
private System.Windows.Forms.GroupBox grpLogOptions;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.CheckBox chkShowCpuCycles;
private System.Windows.Forms.CheckBox chkShowRegisters;
private System.Windows.Forms.CheckBox chkShowFrameCount;
private System.Windows.Forms.CheckBox chkShowPpuScanline;
private System.Windows.Forms.CheckBox chkShowPpuCycles;
private System.Windows.Forms.CheckBox chkShowByteCode;
private System.Windows.Forms.CheckBox chkShowExtraInfo;
private System.Windows.Forms.CheckBox chkIndentCode;
private System.Windows.Forms.Button btnOpenTrace;
}
}

View File

@ -3,30 +3,68 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmTraceLogger : BaseForm
{
private bool _loggingEnabled = false;
public frmTraceLogger()
{
InitializeComponent();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if(_loggingEnabled) {
InteropEmu.DebugStopTraceLogger();
}
}
private void btnStartLogging_Click(object sender, EventArgs e)
{
TraceLoggingOptions options;
TraceLoggerOptions options = new TraceLoggerOptions() {
ShowByteCode = chkShowByteCode.Checked,
ShowCpuCycles = chkShowCpuCycles.Checked,
ShowExtraInfo = chkShowExtraInfo.Checked,
ShowPpuCycles = chkShowPpuCycles.Checked,
ShowPpuFrames = chkShowFrameCount.Checked,
ShowPpuScanline = chkShowPpuScanline.Checked,
ShowRegisters = chkShowRegisters.Checked,
IndentCode = chkIndentCode.Checked
};
InteropEmu.DebugStartTraceLogger(options);
btnStartLogging.Enabled = false;
btnStopLogging.Enabled = true;
btnOpenTrace.Enabled = true;
_loggingEnabled = true;
}
private void btnStopLogging_Click(object sender, EventArgs e)
{
InteropEmu.DebugStopTraceLogger();
btnStartLogging.Enabled = true;
btnStopLogging.Enabled = false;
}
private void btnOpenTrace_Click(object sender, EventArgs e)
{
try {
System.Diagnostics.Process.Start(Path.Combine(ConfigManager.DebuggerFolder, "Trace - " + InteropEmu.GetRomInfo().GetRomName() + ".log"));
} catch { }
}
}
}

View File

@ -176,7 +176,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void DebugSetNextStatement(UInt16 addr);
[DllImport(DLLPath)] public static extern Int32 DebugEvaluateExpression([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string expression, out EvalResultType resultType);
[DllImport(DLLPath)] public static extern void DebugStartTraceLogger(TraceLoggingOptions options);
[DllImport(DLLPath)] public static extern void DebugStartTraceLogger(TraceLoggerOptions options);
[DllImport(DLLPath)] public static extern void DebugStopTraceLogger();
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool DebugLoadCdlFile([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string cdlFilepath);
@ -540,6 +540,7 @@ namespace Mesen.GUI
public PPUState State;
public Int32 Scanline;
public UInt32 Cycle;
public UInt32 FrameCount;
}
public struct PPUState
@ -599,10 +600,16 @@ namespace Mesen.GUI
public UInt16 DebugPC;
}
public struct TraceLoggingOptions
public struct TraceLoggerOptions
{
[MarshalAs(UnmanagedType.I1)] public bool ShowByteCode;
[MarshalAs(UnmanagedType.I1)] public bool ShowRegisters;
[MarshalAs(UnmanagedType.I1)] public bool ShowCpuCycles;
[MarshalAs(UnmanagedType.I1)] public bool ShowPpuCycles;
[MarshalAs(UnmanagedType.I1)] public bool ShowPpuScanline;
[MarshalAs(UnmanagedType.I1)] public bool ShowPpuFrames;
[MarshalAs(UnmanagedType.I1)] public bool ShowExtraInfo;
[MarshalAs(UnmanagedType.I1)] public bool IndentCode;
}
[Flags]