From 091da2164c0958aca3b84631d9629e2f3d8cc2e3 Mon Sep 17 00:00:00 2001 From: Sour Date: Sat, 26 May 2018 01:14:37 -0400 Subject: [PATCH] Debugger: Trace Logger - Added output format customization --- Core/CPU.cpp | 8 +- Core/CPU.h | 4 +- Core/Disassembler.cpp | 2 +- Core/DisassemblyInfo.cpp | 8 +- Core/DisassemblyInfo.h | 2 +- Core/TraceLogger.cpp | 230 +++++++++----- Core/TraceLogger.h | 50 ++- GUI.NET/Config/DebugInfo.cs | 32 +- .../Controls/ctrlConsoleStatus.Designer.cs | 60 ++-- GUI.NET/Debugger/Controls/ctrlTextbox.cs | 23 +- GUI.NET/Debugger/frmTraceLogger.Designer.cs | 289 +++++++++++++----- GUI.NET/Debugger/frmTraceLogger.cs | 179 +++++++++-- GUI.NET/InteropEmu.cs | 26 +- Utilities/HexUtilities.cpp | 5 + Utilities/HexUtilities.h | 1 + 15 files changed, 669 insertions(+), 250 deletions(-) diff --git a/Core/CPU.cpp b/Core/CPU.cpp index d5644c3a..e49aadc8 100644 --- a/Core/CPU.cpp +++ b/Core/CPU.cpp @@ -101,7 +101,7 @@ void CPU::Reset(bool softReset, NesModel model) _state.SP = 0xFD; _state.X = 0; _state.Y = 0; - _state.PS = PSFlags::Reserved | PSFlags::Interrupt; + _state.PS = PSFlags::Interrupt; _runIrq = false; } @@ -136,7 +136,7 @@ void CPU::IRQ() Push((uint16_t)(PC())); if(_state.NMIFlag) { - Push((uint8_t)PS()); + Push((uint8_t)(PS() | PSFlags::Reserved)); SetFlags(PSFlags::Interrupt); SetPC(MemoryReadWord(CPU::NMIVector)); @@ -145,7 +145,7 @@ void CPU::IRQ() TraceLogger::LogStatic("NMI"); Debugger::ProcessInterrupt(originalPc, _state.PC, true); } else { - Push((uint8_t)PS()); + Push((uint8_t)(PS() | PSFlags::Reserved)); SetFlags(PSFlags::Interrupt); SetPC(MemoryReadWord(CPU::IRQVector)); @@ -157,7 +157,7 @@ void CPU::IRQ() void CPU::BRK() { Push((uint16_t)(PC() + 1)); - uint8_t flags = PS() | PSFlags::Break; + uint8_t flags = PS() | PSFlags::Break | PSFlags::Reserved; if(_state.NMIFlag) { Push((uint8_t)flags); SetFlags(PSFlags::Interrupt); diff --git a/Core/CPU.h b/Core/CPU.h index 7cd7daa5..23d5c2ed 100644 --- a/Core/CPU.h +++ b/Core/CPU.h @@ -184,7 +184,7 @@ private: uint8_t SP() { return _state.SP; } void SetSP(uint8_t value) { _state.SP = value; } uint8_t PS() { return _state.PS; } - void SetPS(uint8_t value) { _state.PS = (value & 0xCF) | PSFlags::Reserved; } + void SetPS(uint8_t value) { _state.PS = value & 0xCF; } uint16_t PC() { return _state.PC; } void SetPC(uint16_t value) { _state.PC = value; } @@ -484,7 +484,7 @@ private: void PHA() { Push(A()); } void PHP() { - uint8_t flags = PS() | PSFlags::Break; + uint8_t flags = PS() | PSFlags::Break | PSFlags::Reserved; Push((uint8_t)flags); } void PLA() { diff --git a/Core/Disassembler.cpp b/Core/Disassembler.cpp index 6f67964e..db545f57 100644 --- a/Core/Disassembler.cpp +++ b/Core/Disassembler.cpp @@ -556,7 +556,7 @@ string Disassembler::GetCode(AddressTypeInfo &addressInfo, uint32_t endAddr, uin if(showEffectiveAddresses) { info->GetEffectiveAddressString(effAddress, cpuState, memoryManager.get(), labelManager.get()); } - info->ToString(code, memoryAddr, memoryManager.get(), labelManager.get()); + info->ToString(code, memoryAddr, memoryManager.get(), labelManager.get(), false); info->GetByteCode(byteCode); GetCodeLine(output, code, commentString, memoryAddr, addr & mask, byteCode, effAddress, dataType, true, memoryType); diff --git a/Core/DisassemblyInfo.cpp b/Core/DisassemblyInfo.cpp index fb67796f..351b0684 100644 --- a/Core/DisassemblyInfo.cpp +++ b/Core/DisassemblyInfo.cpp @@ -33,7 +33,7 @@ DisassemblyInfo::DisassemblyInfo() { } -void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager) +void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager, bool extendZeroPage) { char buffer[500]; uint8_t opCode = _byteCode[0]; @@ -54,6 +54,12 @@ void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* if(_opSize == 2 && _opMode != AddrMode::Rel) { memcpy(operandBuffer + 1, hexTable[opAddr], 2); operandLength = 3; + if(extendZeroPage && (_opMode == AddrMode::Zero || _opMode == AddrMode::ZeroX || _opMode == AddrMode::ZeroY || + _opMode == AddrMode::IndY|| _opMode == AddrMode::IndYW || _opMode == AddrMode::IndX)) { + operandBuffer[3] = '0'; + operandBuffer[4] = '0'; + operandLength += 2; + } } else { memcpy(operandBuffer + 1, hexTable[opAddr >> 8], 2); memcpy(operandBuffer + 3, hexTable[opAddr & 0xFF], 2); diff --git a/Core/DisassemblyInfo.h b/Core/DisassemblyInfo.h index f5ed2ecd..c2ce168d 100644 --- a/Core/DisassemblyInfo.h +++ b/Core/DisassemblyInfo.h @@ -30,7 +30,7 @@ public: void GetEffectiveAddressString(string &out, State& cpuState, MemoryManager* memoryManager, LabelManager* labelManager); int32_t GetMemoryValue(State& cpuState, MemoryManager* memoryManager); - void ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager); + void ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager, bool extendZeroPage); void GetByteCode(string &out); uint32_t GetSize(); uint16_t GetOpAddr(uint16_t memoryAddr); diff --git a/Core/TraceLogger.cpp b/Core/TraceLogger.cpp index 20e5b985..b4f5d226 100644 --- a/Core/TraceLogger.cpp +++ b/Core/TraceLogger.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include #include "TraceLogger.h" #include "DisassemblyInfo.h" #include "DebuggerTypes.h" @@ -36,6 +37,7 @@ void TraceLogger::SetOptions(TraceLoggerOptions options) { _options = options; string condition = _options.Condition; + string format = _options.Format; auto lock = _lock.AcquireSafe(); _conditionRpnList.clear(); @@ -45,6 +47,68 @@ void TraceLogger::SetOptions(TraceLoggerOptions options) _conditionRpnList = *rpnList; } } + + _rowParts.clear(); + + std::regex formatRegex = std::regex("(\\[([^,[]*?)(,([\\d]*)(h){0,1})?\\])|([^[]*)", std::regex_constants::icase); + std::sregex_iterator start = std::sregex_iterator(format.cbegin(), format.cend(), formatRegex); + std::sregex_iterator end = std::sregex_iterator(); + + for(std::sregex_iterator it = start; it != end; it++) { + const std::smatch& match = *it; + + if(match.str(1) == "") { + RowPart part = {}; + part.DataType = RowDataType::Text; + part.Text = match.str(6); + _rowParts.push_back(part); + } else { + RowPart part = {}; + + string dataType = match.str(2); + if(dataType == "ByteCode") { + part.DataType = RowDataType::ByteCode; + } else if(dataType == "Disassembly") { + part.DataType = RowDataType::Disassembly; + } else if(dataType == "EffectiveAddress") { + part.DataType = RowDataType::EffectiveAddress; + } else if(dataType == "MemoryValue") { + part.DataType = RowDataType::MemoryValue; + } else if(dataType == "Align") { + part.DataType = RowDataType::Align; + } else if(dataType == "PC") { + part.DataType = RowDataType::PC; + } else if(dataType == "A") { + part.DataType = RowDataType::A; + } else if(dataType == "X") { + part.DataType = RowDataType::X; + } else if(dataType == "Y") { + part.DataType = RowDataType::Y; + } else if(dataType == "P") { + part.DataType = RowDataType::PS; + } else if(dataType == "SP") { + part.DataType = RowDataType::SP; + } else if(dataType == "Cycle") { + part.DataType = RowDataType::Cycle; + } else if(dataType == "Scanline") { + part.DataType = RowDataType::Scanline; + } else if(dataType == "FrameCount") { + part.DataType = RowDataType::FrameCount; + } else if(dataType == "CycleCount") { + part.DataType = RowDataType::CycleCount; + } + + if(!match.str(4).empty()) { + try { + part.MinWidth = std::stoi(match.str(4)); + } catch(std::exception) { + } + } + part.DisplayInHex = match.str(5) == "h"; + + _rowParts.push_back(part); + } + } } void TraceLogger::StartLogging(string filename) @@ -80,96 +144,118 @@ void TraceLogger::LogStatic(string log) //Flush current buffer _instance->_outputFile << _instance->_outputBuffer; _instance->_outputBuffer.clear(); - - _instance->_outputFile << " - [" << log << " - Cycle: " << std::to_string(CPU::GetCycleCount()) << "]"; + _instance->_outputFile << "[" << log << " - Cycle: " << std::to_string(CPU::GetCycleCount()) << "]" << (_instance->_options.UseWindowsEol ? "\r\n" : "\n"); } } -void TraceLogger::GetStatusFlag(string &output, uint8_t ps) +void TraceLogger::GetStatusFlag(string &output, uint8_t ps, RowPart& part) { - output += " P:"; - if(_options.StatusFormat == StatusFlagFormat::Hexadecimal) { - output.append(HexUtilities::ToHex(ps)); + if(part.DisplayInHex) { + WriteValue(output, ps, part); } else { - constexpr char activeStatusLetters[8] = { 'N', 'V', 'B', '-', 'D', 'I', 'Z', 'C' }; - constexpr char inactiveStatusLetters[8] = { 'n', 'v', 'b', '-', 'd', 'i', 'z', 'c' }; + constexpr char activeStatusLetters[8] = { 'N', 'V', '-', '-', 'D', 'I', 'Z', 'C' }; + constexpr char inactiveStatusLetters[8] = { 'n', 'v', '-', '-', 'd', 'i', 'z', 'c' }; int padding = 6; + string flags; for(int i = 0; i < 8; i++) { if(ps & 0x80) { - output += activeStatusLetters[i]; - padding--; - } else if(_options.StatusFormat == StatusFlagFormat::Text) { - output += inactiveStatusLetters[i]; - padding--; + flags += activeStatusLetters[i]; + } else if(part.MinWidth >= 8) { + flags += inactiveStatusLetters[i]; } ps <<= 1; } - if(padding > 0) { - output += string(padding, ' '); - } + WriteValue(output, flags, part); } } -void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo, bool forceByteCode) +template +void TraceLogger::WriteValue(string &output, T value, RowPart& rowPart) { - output += HexUtilities::ToHex(cpuState.DebugPC) + " "; - - if(_options.ShowByteCode || forceByteCode) { - string byteCode; - disassemblyInfo.GetByteCode(byteCode); - output += byteCode + std::string(13 - byteCode.size(), ' '); + string str = rowPart.DisplayInHex ? HexUtilities::ToHex(value) : std::to_string(value); + output += str; + if(rowPart.MinWidth > str.size()) { + output += std::string(rowPart.MinWidth - str.size(), ' '); } +} - int indentLevel = 0; - if(_options.IndentCode) { - indentLevel = 0xFF - cpuState.SP; - output += std::string(indentLevel, ' '); +template<> +void TraceLogger::WriteValue(string &output, string value, RowPart& rowPart) +{ + output += value; + if(rowPart.MinWidth > value.size()) { + output += std::string(rowPart.MinWidth - value.size(), ' '); } +} - string code; - LabelManager* labelManager = _options.UseLabels ? _labelManager.get() : nullptr; - disassemblyInfo.ToString(code, cpuState.DebugPC, _memoryManager.get(), labelManager); - disassemblyInfo.GetEffectiveAddressString(code, cpuState, _memoryManager.get(), labelManager); +void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo) +{ + size_t originalSize = output.size(); + for(RowPart& rowPart : _rowParts) { + switch(rowPart.DataType) { + case RowDataType::Text: output += rowPart.Text; break; - int paddingSize = 32; - if(_options.ShowMemoryValues) { - int32_t value = disassemblyInfo.GetMemoryValue(cpuState, _memoryManager.get()); - if(value >= 0) { - code += " = $" + HexUtilities::ToHex((uint8_t)value); + case RowDataType::ByteCode: { + string byteCode; + disassemblyInfo.GetByteCode(byteCode); + if(!rowPart.DisplayInHex) { + //Remove $ marks if not in "hex" mode (but still display the bytes as hex) + byteCode.erase(std::remove(byteCode.begin(), byteCode.end(), '$'), byteCode.end()); + } + WriteValue(output, byteCode, rowPart); + break; + } + + case RowDataType::Disassembly: { + int indentLevel = 0; + string code; + + if(_options.IndentCode) { + indentLevel = 0xFF - cpuState.SP; + code = std::string(indentLevel, ' '); + } + + LabelManager* labelManager = _options.UseLabels ? _labelManager.get() : nullptr; + disassemblyInfo.ToString(code, cpuState.DebugPC, _memoryManager.get(), labelManager, _options.ExtendZeroPage); + WriteValue(output, code, rowPart); + break; + } + + case RowDataType::EffectiveAddress:{ + string effectiveAddress; + disassemblyInfo.GetEffectiveAddressString(effectiveAddress, cpuState, _memoryManager.get(), _options.UseLabels ? _labelManager.get() : nullptr); + WriteValue(output, effectiveAddress, rowPart); + break; + } + + case RowDataType::MemoryValue:{ + int32_t value = disassemblyInfo.GetMemoryValue(cpuState, _memoryManager.get()); + if(value >= 0) { + output += rowPart.DisplayInHex ? "= $" : "= "; + WriteValue(output, (uint8_t)value, rowPart); + } + break; + } + + case RowDataType::Align: + if(output.size() - originalSize < rowPart.MinWidth) { + output += std::string(rowPart.MinWidth - (output.size() - originalSize), ' '); + } + break; + + case RowDataType::PC: WriteValue(output, cpuState.DebugPC, rowPart); break; + case RowDataType::A: WriteValue(output, cpuState.A, rowPart); break; + case RowDataType::X: WriteValue(output, cpuState.X, rowPart); break; + case RowDataType::Y: WriteValue(output, cpuState.Y, rowPart); break; + case RowDataType::SP: WriteValue(output, cpuState.SP, rowPart); break; + case RowDataType::PS: GetStatusFlag(output, cpuState.PS, rowPart); break; + case RowDataType::Cycle: WriteValue(output, ppuState.Cycle, rowPart); break; + case RowDataType::Scanline: WriteValue(output, ppuState.Scanline, rowPart); break; + case RowDataType::FrameCount: WriteValue(output, ppuState.FrameCount, rowPart); break; + case RowDataType::CycleCount: WriteValue(output, cpuState.CycleCount, rowPart); break; } - paddingSize += 6; } - code += std::string(std::max(0, (int)(paddingSize - code.size())), ' '); - output += code; - - if(_options.ShowRegisters) { - output += " A:" + HexUtilities::ToHex(cpuState.A) + - " X:" + HexUtilities::ToHex(cpuState.X) + - " Y:" + HexUtilities::ToHex(cpuState.Y); - - GetStatusFlag(output, cpuState.PS); - - output += " SP:" + HexUtilities::ToHex(cpuState.SP); - } - - if(_options.ShowPpuCycles) { - string str = std::to_string(ppuState.Cycle); - output += " CYC:" + std::string(3 - str.size(), ' ') + str; - } - - if(_options.ShowPpuScanline) { - string str = std::to_string(ppuState.Scanline); - output += " SL:" + std::string(3 - str.size(), ' ') + str; - } - - if(_options.ShowPpuFrames) { - output += " FC:" + std::to_string(ppuState.FrameCount); - } - - if(_options.ShowCpuCycles) { - output += " CPU Cycle:" + std::to_string(cpuState.CycleCount); - } - output += "\n"; + output += _options.UseWindowsEol ? "\r\n" : "\n"; } bool TraceLogger::ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo) @@ -202,7 +288,7 @@ void TraceLogger::AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state) } if(_logToFile) { - GetTraceRow(_outputBuffer, state.CPU, state.PPU, disassemblyInfo, false); + GetTraceRow(_outputBuffer, state.CPU, state.PPU, disassemblyInfo); if(_outputBuffer.size() > 32768) { _outputFile << _outputBuffer; _outputBuffer.clear(); @@ -244,7 +330,11 @@ const char* TraceLogger::GetExecutionTrace(uint32_t lineCount) for(int i = 0; i < (int)lineCount; i++) { int index = (startPos + i) % ExecutionLogSize; - GetTraceRow(_executionTrace, _cpuStateCacheCopy[index], _ppuStateCacheCopy[index], _disassemblyCacheCopy[index], true); + _executionTrace += HexUtilities::ToHex(_cpuStateCacheCopy[index].DebugPC) + "\x1"; + string byteCode; + _disassemblyCacheCopy[index].GetByteCode(byteCode); + _executionTrace += byteCode + "\x1"; + GetTraceRow(_executionTrace, _cpuStateCacheCopy[index], _ppuStateCacheCopy[index], _disassemblyCacheCopy[index]); } return _executionTrace.c_str(); diff --git a/Core/TraceLogger.h b/Core/TraceLogger.h index 75fe5440..d6d92e20 100644 --- a/Core/TraceLogger.h +++ b/Core/TraceLogger.h @@ -9,29 +9,44 @@ class LabelManager; class ExpressionEvaluator; class Debugger; -enum class StatusFlagFormat +enum class RowDataType { - Hexadecimal = 0, - Text = 1, - CompactText = 2 + Text = 0, + ByteCode, + Disassembly, + EffectiveAddress, + MemoryValue, + Align, + PC, + A, + X, + Y, + SP, + PS, + Cycle, + Scanline, + FrameCount, + CycleCount +}; + +struct RowPart +{ + RowDataType DataType; + string Text; + bool DisplayInHex; + int MinWidth; }; struct TraceLoggerOptions { - bool ShowByteCode; - bool ShowRegisters; - bool ShowCpuCycles; - bool ShowPpuCycles; - bool ShowPpuScanline; - bool ShowPpuFrames; bool ShowExtraInfo; bool IndentCode; - bool ShowEffectiveAddresses; - bool ShowMemoryValues; bool UseLabels; - StatusFlagFormat StatusFormat; + bool UseWindowsEol; + bool ExtendZeroPage; char Condition[1000]; + char Format[1000]; }; class TraceLogger @@ -52,6 +67,8 @@ private: shared_ptr _expEvaluator; vector _conditionRpnList; + vector _rowParts; + bool _pendingLog; DebugState _lastState; DisassemblyInfo _lastDisassemblyInfo; @@ -70,11 +87,14 @@ private: SimpleLock _lock; - void GetStatusFlag(string &output, uint8_t ps); + void GetStatusFlag(string &output, uint8_t ps, RowPart& part); void AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state); bool ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo); - void GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo, bool forceByteCode); + void GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo); + + template void WriteValue(string &output, T value, RowPart& rowPart); + template<> void WriteValue(string &output, string value, RowPart& rowPart); public: TraceLogger(Debugger* debugger, shared_ptr memoryManager, shared_ptr labelManager); diff --git a/GUI.NET/Config/DebugInfo.cs b/GUI.NET/Config/DebugInfo.cs index 930e29da..4f06d48e 100644 --- a/GUI.NET/Config/DebugInfo.cs +++ b/GUI.NET/Config/DebugInfo.cs @@ -82,7 +82,36 @@ namespace Mesen.GUI.Config } } } - + + public enum StatusFlagFormat + { + Hexadecimal = 0, + Text = 1, + CompactText = 2 + } + + public class TraceLoggerOptions + { + public bool ShowByteCode; + public bool ShowRegisters; + public bool ShowCpuCycles; + public bool ShowPpuCycles; + public bool ShowPpuScanline; + public bool ShowPpuFrames; + public bool ShowExtraInfo; + public bool IndentCode; + public bool ShowEffectiveAddresses; + public bool ShowMemoryValues; + public bool UseLabels; + public bool ExtendZeroPage; + public bool UseWindowsEol = !Program.IsMono; + + public StatusFlagFormat StatusFormat; + + public bool OverrideFormat; + public string Format; + } + public class DebugInfo { private const int MaxRecentScripts = 10; @@ -255,7 +284,6 @@ namespace Mesen.GUI.Config public TraceLoggerOptions TraceLoggerOptions; public bool TraceAutoRefresh = true; public int TraceLineCount = 1000; - public bool TraceIndentCode = false; public Size TraceLoggerSize = new Size(0, 0); public string TraceFontFamily = BaseControl.MonospaceFontFamily; diff --git a/GUI.NET/Debugger/Controls/ctrlConsoleStatus.Designer.cs b/GUI.NET/Debugger/Controls/ctrlConsoleStatus.Designer.cs index 78ed0ebc..7f667776 100644 --- a/GUI.NET/Debugger/Controls/ctrlConsoleStatus.Designer.cs +++ b/GUI.NET/Debugger/Controls/ctrlConsoleStatus.Designer.cs @@ -77,11 +77,9 @@ this.chkExternal = new System.Windows.Forms.CheckBox(); this.chkNMI = new System.Windows.Forms.CheckBox(); this.chkDMC = new System.Windows.Forms.CheckBox(); - this.chkBreak = new System.Windows.Forms.CheckBox(); this.chkNegative = new System.Windows.Forms.CheckBox(); this.chkOverflow = new System.Windows.Forms.CheckBox(); this.chkDecimal = new System.Windows.Forms.CheckBox(); - this.chkReserved = new System.Windows.Forms.CheckBox(); this.txtStatus = new System.Windows.Forms.TextBox(); this.chkInterrupt = new System.Windows.Forms.CheckBox(); this.lblStatus = new System.Windows.Forms.Label(); @@ -123,6 +121,8 @@ this.mnuGoToPlayHandler = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); this.mnuGoToProgramCounter = new System.Windows.Forms.ToolStripMenuItem(); + this.chkReserved = new System.Windows.Forms.CheckBox(); + this.chkBreak = new System.Windows.Forms.CheckBox(); this.tableLayoutPanel2.SuspendLayout(); this.grpPPUStatus.SuspendLayout(); this.tableLayoutPanel8.SuspendLayout(); @@ -822,18 +822,6 @@ this.chkDMC.UseVisualStyleBackColor = true; this.chkDMC.Click += new System.EventHandler(this.OnOptionChanged); // - // chkBreak - // - this.chkBreak.AutoSize = true; - this.chkBreak.Location = new System.Drawing.Point(49, 17); - this.chkBreak.Margin = new System.Windows.Forms.Padding(0); - this.chkBreak.Name = "chkBreak"; - this.chkBreak.Size = new System.Drawing.Size(54, 17); - this.chkBreak.TabIndex = 4; - this.chkBreak.Text = "Break"; - this.chkBreak.UseVisualStyleBackColor = true; - this.chkBreak.Click += new System.EventHandler(this.chkCpuFlag_Click); - // // chkNegative // this.chkNegative.AutoSize = true; @@ -870,18 +858,6 @@ this.chkDecimal.UseVisualStyleBackColor = true; this.chkDecimal.Click += new System.EventHandler(this.chkCpuFlag_Click); // - // chkReserved - // - this.chkReserved.AutoSize = true; - this.chkReserved.Location = new System.Drawing.Point(103, 17); - this.chkReserved.Margin = new System.Windows.Forms.Padding(0); - this.chkReserved.Name = "chkReserved"; - this.chkReserved.Size = new System.Drawing.Size(72, 17); - this.chkReserved.TabIndex = 5; - this.chkReserved.Text = "Reserved"; - this.chkReserved.UseVisualStyleBackColor = true; - this.chkReserved.Click += new System.EventHandler(this.chkCpuFlag_Click); - // // txtStatus // this.txtStatus.Anchor = System.Windows.Forms.AnchorStyles.Left; @@ -1022,7 +998,7 @@ this.txtStack.BackColor = System.Drawing.SystemColors.Window; this.txtStack.Dock = System.Windows.Forms.DockStyle.Fill; this.txtStack.Location = new System.Drawing.Point(0, 21); - this.txtStack.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0); + this.txtStack.Margin = new System.Windows.Forms.Padding(0); this.txtStack.Multiline = true; this.txtStack.Name = "txtStack"; this.txtStack.ReadOnly = true; @@ -1338,6 +1314,32 @@ this.mnuGoToProgramCounter.ToolTipText = "Alt+*"; this.mnuGoToProgramCounter.Click += new System.EventHandler(this.mnuGoToProgramCounter_Click); // + // chkReserved + // + this.chkReserved.AutoSize = true; + this.chkReserved.Enabled = false; + this.chkReserved.Location = new System.Drawing.Point(103, 17); + this.chkReserved.Margin = new System.Windows.Forms.Padding(0); + this.chkReserved.Name = "chkReserved"; + this.chkReserved.Size = new System.Drawing.Size(72, 17); + this.chkReserved.TabIndex = 5; + this.chkReserved.Text = "Reserved"; + this.chkReserved.UseVisualStyleBackColor = true; + this.chkReserved.Click += new System.EventHandler(this.chkCpuFlag_Click); + // + // chkBreak + // + this.chkBreak.AutoSize = true; + this.chkBreak.Enabled = false; + this.chkBreak.Location = new System.Drawing.Point(49, 17); + this.chkBreak.Margin = new System.Windows.Forms.Padding(0); + this.chkBreak.Name = "chkBreak"; + this.chkBreak.Size = new System.Drawing.Size(54, 17); + this.chkBreak.TabIndex = 4; + this.chkBreak.Text = "Break"; + this.chkBreak.UseVisualStyleBackColor = true; + this.chkBreak.Click += new System.EventHandler(this.chkCpuFlag_Click); + // // ctrlConsoleStatus // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1428,8 +1430,6 @@ private System.Windows.Forms.TextBox txtStatus; private System.Windows.Forms.CheckBox chkNegative; private System.Windows.Forms.CheckBox chkOverflow; - private System.Windows.Forms.CheckBox chkReserved; - private System.Windows.Forms.CheckBox chkBreak; private System.Windows.Forms.CheckBox chkDecimal; private System.Windows.Forms.CheckBox chkInterrupt; private System.Windows.Forms.CheckBox chkZero; @@ -1481,5 +1481,7 @@ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem mnuGoToProgramCounter; private System.Windows.Forms.TextBox txtStack; + private System.Windows.Forms.CheckBox chkBreak; + private System.Windows.Forms.CheckBox chkReserved; } } diff --git a/GUI.NET/Debugger/Controls/ctrlTextbox.cs b/GUI.NET/Debugger/Controls/ctrlTextbox.cs index a965f6e5..f733d48c 100644 --- a/GUI.NET/Debugger/Controls/ctrlTextbox.cs +++ b/GUI.NET/Debugger/Controls/ctrlTextbox.cs @@ -44,7 +44,7 @@ namespace Mesen.GUI.Debugger public partial class ctrlTextbox : Control { - private Regex _codeRegex = new Regex("^([a-z]{3})([*]{0,1})($|[ ]){1}([(]{0,1})(([$][0-9a-f]*)|(#[@$:_0-9a-z]*)|([@_a-z]([@_a-z0-9])*)){0,1}([)]{0,1})(,X|,Y){0,1}([)]{0,1})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled); + private Regex _codeRegex = new Regex("^(\\s*)([a-z]{3})([*]{0,1})($|[ ]){1}([(]{0,1})(([$][0-9a-f]*)|(#[@$:_0-9a-z]*)|([@_a-z]([@_a-z0-9])*)){0,1}([)]{0,1})(,X|,Y){0,1}([)]{0,1})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled); public event EventHandler ScrollPositionChanged; public event EventHandler SelectedLineChanged; private bool _disableScrollPositionChangedEvent; @@ -1066,19 +1066,20 @@ namespace Mesen.GUI.Debugger if(codeString.Length > 0) { Match match = CodeHighlightingEnabled ? _codeRegex.Match(codeString) : null; if(match != null && match.Success && !codeString.EndsWith(":")) { - string opcode = match.Groups[1].Value; - string invalidStar = match.Groups[2].Value; - string paren1 = match.Groups[4].Value; - string operand = match.Groups[5].Value; - string paren2 = match.Groups[10].Value; - string indirect = match.Groups[11].Value; - string paren3 = match.Groups[12].Value; - string rest = match.Groups[13].Value; + string padding = match.Groups[1].Value; + string opcode = match.Groups[2].Value; + string invalidStar = match.Groups[3].Value; + string paren1 = match.Groups[5].Value; + string operand = match.Groups[6].Value; + string paren2 = match.Groups[11].Value; + string indirect = match.Groups[12].Value; + string paren3 = match.Groups[13].Value; + string rest = match.Groups[14].Value; Color operandColor = operand.Length > 0 ? (operand[0] == '#' ? (Color)info.AssemblerImmediateColor : (operand[0] == '$' ? (Color)info.AssemblerAddressColor : (Color)info.AssemblerLabelDefinitionColor)) : Color.Black; - List colors = new List() { info.AssemblerOpcodeColor, defaultColor, defaultColor, defaultColor, operandColor, defaultColor, defaultColor, defaultColor }; + List colors = new List() { defaultColor, info.AssemblerOpcodeColor, defaultColor, defaultColor, defaultColor, operandColor, defaultColor, defaultColor, defaultColor }; int codePartCount = colors.Count; - List parts = new List() { opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 }; + List parts = new List() { padding, opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 }; string memoryAddress = ""; if(!string.IsNullOrWhiteSpace(addressString)) { colors.Add(info.CodeEffectiveAddressColor); diff --git a/GUI.NET/Debugger/frmTraceLogger.Designer.cs b/GUI.NET/Debugger/frmTraceLogger.Designer.cs index 4c71ca59..33d424be 100644 --- a/GUI.NET/Debugger/frmTraceLogger.Designer.cs +++ b/GUI.NET/Debugger/frmTraceLogger.Designer.cs @@ -34,24 +34,31 @@ this.btnStopLogging = new System.Windows.Forms.Button(); this.grpLogOptions = new System.Windows.Forms.GroupBox(); this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel(); + this.chkOverrideFormat = new System.Windows.Forms.CheckBox(); + this.picFormatHelp = new System.Windows.Forms.PictureBox(); + this.lblFormat = new System.Windows.Forms.Label(); + this.txtFormat = new System.Windows.Forms.TextBox(); this.chkShowMemoryValues = new System.Windows.Forms.CheckBox(); this.chkShowRegisters = new System.Windows.Forms.CheckBox(); - this.chkIndentCode = new System.Windows.Forms.CheckBox(); - this.chkUseLabels = new System.Windows.Forms.CheckBox(); this.chkShowByteCode = new System.Windows.Forms.CheckBox(); - this.label1 = new System.Windows.Forms.Label(); this.chkShowCpuCycles = new System.Windows.Forms.CheckBox(); this.chkShowPpuCycles = new System.Windows.Forms.CheckBox(); this.chkShowPpuScanline = new System.Windows.Forms.CheckBox(); this.chkShowFrameCount = new System.Windows.Forms.CheckBox(); this.chkShowEffectiveAddresses = new System.Windows.Forms.CheckBox(); - this.cboStatusFlagFormat = new System.Windows.Forms.ComboBox(); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); this.picHelp = new System.Windows.Forms.PictureBox(); this.picExpressionWarning = new System.Windows.Forms.PictureBox(); this.lblCondition = new System.Windows.Forms.Label(); this.txtCondition = new System.Windows.Forms.TextBox(); this.chkShowExtraInfo = new System.Windows.Forms.CheckBox(); + this.chkIndentCode = new System.Windows.Forms.CheckBox(); + this.chkUseLabels = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.cboStatusFlagFormat = new System.Windows.Forms.ComboBox(); + this.chkUseWindowsEol = new System.Windows.Forms.CheckBox(); + this.chkExtendZeroPage = new System.Windows.Forms.CheckBox(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.grpExecutionLog = new System.Windows.Forms.GroupBox(); this.txtTraceLog = new Mesen.GUI.Debugger.ctrlScrollableTextbox(); @@ -75,6 +82,8 @@ this.tableLayoutPanel1.SuspendLayout(); this.grpLogOptions.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); + this.tableLayoutPanel5.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picFormatHelp)).BeginInit(); this.tableLayoutPanel4.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picHelp)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.picExpressionWarning)).BeginInit(); @@ -94,21 +103,21 @@ this.tableLayoutPanel1.Controls.Add(this.btnStopLogging, 1, 0); this.tableLayoutPanel1.Controls.Add(this.grpLogOptions, 0, 1); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 274); + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 200); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 3; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); 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(781, 181); + this.tableLayoutPanel1.Size = new System.Drawing.Size(706, 182); 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(683, 3); + this.btnOpenTrace.Location = new System.Drawing.Point(608, 3); this.btnOpenTrace.Name = "btnOpenTrace"; this.btnOpenTrace.Size = new System.Drawing.Size(95, 23); this.btnOpenTrace.TabIndex = 2; @@ -145,57 +154,130 @@ 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(775, 146); + this.grpLogOptions.Size = new System.Drawing.Size(700, 150); this.grpLogOptions.TabIndex = 3; this.grpLogOptions.TabStop = false; this.grpLogOptions.Text = "Log Options"; // // tableLayoutPanel2 // - this.tableLayoutPanel2.ColumnCount = 4; + this.tableLayoutPanel2.ColumnCount = 7; this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel5, 0, 4); this.tableLayoutPanel2.Controls.Add(this.chkShowMemoryValues, 3, 1); this.tableLayoutPanel2.Controls.Add(this.chkShowRegisters, 0, 0); - this.tableLayoutPanel2.Controls.Add(this.chkIndentCode, 0, 5); - this.tableLayoutPanel2.Controls.Add(this.chkUseLabels, 3, 5); this.tableLayoutPanel2.Controls.Add(this.chkShowByteCode, 0, 1); - this.tableLayoutPanel2.Controls.Add(this.label1, 0, 2); this.tableLayoutPanel2.Controls.Add(this.chkShowCpuCycles, 1, 0); this.tableLayoutPanel2.Controls.Add(this.chkShowPpuCycles, 2, 0); this.tableLayoutPanel2.Controls.Add(this.chkShowPpuScanline, 2, 1); this.tableLayoutPanel2.Controls.Add(this.chkShowFrameCount, 1, 1); this.tableLayoutPanel2.Controls.Add(this.chkShowEffectiveAddresses, 3, 0); - this.tableLayoutPanel2.Controls.Add(this.cboStatusFlagFormat, 1, 2); - this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 3); - this.tableLayoutPanel2.Controls.Add(this.chkShowExtraInfo, 3, 2); + this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 5); + this.tableLayoutPanel2.Controls.Add(this.chkShowExtraInfo, 4, 0); + this.tableLayoutPanel2.Controls.Add(this.chkIndentCode, 0, 2); + this.tableLayoutPanel2.Controls.Add(this.chkUseLabels, 2, 2); + this.tableLayoutPanel2.Controls.Add(this.label1, 4, 2); + this.tableLayoutPanel2.Controls.Add(this.cboStatusFlagFormat, 5, 2); + this.tableLayoutPanel2.Controls.Add(this.chkUseWindowsEol, 3, 2); + this.tableLayoutPanel2.Controls.Add(this.chkExtendZeroPage, 4, 1); this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; - this.tableLayoutPanel2.RowCount = 6; + this.tableLayoutPanel2.RowCount = 8; 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.Absolute, 5F)); + 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.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel2.Size = new System.Drawing.Size(769, 127); + this.tableLayoutPanel2.Size = new System.Drawing.Size(694, 131); this.tableLayoutPanel2.TabIndex = 0; // + // tableLayoutPanel5 + // + this.tableLayoutPanel5.ColumnCount = 5; + this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel5, 7); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel5.Controls.Add(this.chkOverrideFormat, 0, 0); + this.tableLayoutPanel5.Controls.Add(this.picFormatHelp, 4, 0); + this.tableLayoutPanel5.Controls.Add(this.lblFormat, 0, 0); + this.tableLayoutPanel5.Controls.Add(this.txtFormat, 2, 0); + this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel5.Location = new System.Drawing.Point(0, 78); + this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel5.Name = "tableLayoutPanel5"; + this.tableLayoutPanel5.RowCount = 1; + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel5.Size = new System.Drawing.Size(694, 25); + this.tableLayoutPanel5.TabIndex = 18; + // + // chkOverrideFormat + // + this.chkOverrideFormat.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.chkOverrideFormat.AutoSize = true; + this.chkOverrideFormat.Location = new System.Drawing.Point(51, 5); + this.chkOverrideFormat.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); + this.chkOverrideFormat.Name = "chkOverrideFormat"; + this.chkOverrideFormat.Size = new System.Drawing.Size(66, 17); + this.chkOverrideFormat.TabIndex = 18; + this.chkOverrideFormat.Text = "Override"; + this.chkOverrideFormat.UseVisualStyleBackColor = true; + this.chkOverrideFormat.CheckedChanged += new System.EventHandler(this.chkOverrideFormat_CheckedChanged); + // + // picFormatHelp + // + this.picFormatHelp.Image = global::Mesen.GUI.Properties.Resources.Help; + this.picFormatHelp.Location = new System.Drawing.Point(673, 5); + this.picFormatHelp.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); + this.picFormatHelp.Name = "picFormatHelp"; + this.picFormatHelp.Size = new System.Drawing.Size(18, 17); + this.picFormatHelp.TabIndex = 17; + this.picFormatHelp.TabStop = false; + // + // lblFormat + // + this.lblFormat.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblFormat.AutoSize = true; + this.lblFormat.Location = new System.Drawing.Point(3, 6); + this.lblFormat.Name = "lblFormat"; + this.lblFormat.Size = new System.Drawing.Size(42, 13); + this.lblFormat.TabIndex = 14; + this.lblFormat.Text = "Format:"; + // + // txtFormat + // + this.txtFormat.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtFormat.Location = new System.Drawing.Point(123, 3); + this.txtFormat.Name = "txtFormat"; + this.txtFormat.Size = new System.Drawing.Size(544, 20); + this.txtFormat.TabIndex = 15; + this.txtFormat.TextChanged += new System.EventHandler(this.txtFormat_TextChanged); + // // chkShowMemoryValues // + this.chkShowMemoryValues.Anchor = System.Windows.Forms.AnchorStyles.Left; this.chkShowMemoryValues.AutoSize = true; this.chkShowMemoryValues.Checked = true; this.chkShowMemoryValues.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkShowMemoryValues.Location = new System.Drawing.Point(332, 26); + this.chkShowMemoryValues.Location = new System.Drawing.Point(301, 26); this.chkShowMemoryValues.Name = "chkShowMemoryValues"; this.chkShowMemoryValues.Size = new System.Drawing.Size(128, 17); this.chkShowMemoryValues.TabIndex = 17; this.chkShowMemoryValues.Text = "Show Memory Values"; this.chkShowMemoryValues.UseVisualStyleBackColor = true; + this.chkShowMemoryValues.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // chkShowRegisters // @@ -208,30 +290,11 @@ this.chkShowRegisters.TabIndex = 2; this.chkShowRegisters.Text = "Registers"; this.chkShowRegisters.UseVisualStyleBackColor = true; - // - // chkIndentCode - // - this.chkIndentCode.AutoSize = true; - this.tableLayoutPanel2.SetColumnSpan(this.chkIndentCode, 3); - this.chkIndentCode.Location = new System.Drawing.Point(3, 107); - 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; - // - // chkUseLabels - // - this.chkUseLabels.AutoSize = true; - this.chkUseLabels.Location = new System.Drawing.Point(332, 107); - this.chkUseLabels.Name = "chkUseLabels"; - this.chkUseLabels.Size = new System.Drawing.Size(79, 17); - this.chkUseLabels.TabIndex = 11; - this.chkUseLabels.Text = "Use Labels"; - this.chkUseLabels.UseVisualStyleBackColor = true; + this.chkShowRegisters.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // chkShowByteCode // + this.chkShowByteCode.Anchor = System.Windows.Forms.AnchorStyles.Left; this.chkShowByteCode.AutoSize = true; this.chkShowByteCode.Checked = true; this.chkShowByteCode.CheckState = System.Windows.Forms.CheckState.Checked; @@ -241,88 +304,77 @@ this.chkShowByteCode.TabIndex = 4; this.chkShowByteCode.Text = "Byte Code"; this.chkShowByteCode.UseVisualStyleBackColor = true; - // - // label1 - // - this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(3, 53); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(98, 13); - this.label1.TabIndex = 12; - this.label1.Text = "Status Flag Format:"; + this.chkShowByteCode.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // chkShowCpuCycles // this.chkShowCpuCycles.AutoSize = true; this.chkShowCpuCycles.Checked = true; this.chkShowCpuCycles.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkShowCpuCycles.Location = new System.Drawing.Point(107, 3); + this.chkShowCpuCycles.Location = new System.Drawing.Point(84, 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; + this.chkShowCpuCycles.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // chkShowPpuCycles // this.chkShowPpuCycles.AutoSize = true; this.chkShowPpuCycles.Checked = true; this.chkShowPpuCycles.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkShowPpuCycles.Location = new System.Drawing.Point(234, 3); + this.chkShowPpuCycles.Location = new System.Drawing.Point(203, 3); 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; + this.chkShowPpuCycles.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // chkShowPpuScanline // + this.chkShowPpuScanline.Anchor = System.Windows.Forms.AnchorStyles.Left; this.chkShowPpuScanline.AutoSize = true; this.chkShowPpuScanline.Checked = true; this.chkShowPpuScanline.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkShowPpuScanline.Location = new System.Drawing.Point(234, 26); + this.chkShowPpuScanline.Location = new System.Drawing.Point(203, 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; + this.chkShowPpuScanline.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // chkShowFrameCount // + this.chkShowFrameCount.Anchor = System.Windows.Forms.AnchorStyles.Left; this.chkShowFrameCount.AutoSize = true; - this.chkShowFrameCount.Location = new System.Drawing.Point(107, 26); + this.chkShowFrameCount.Location = new System.Drawing.Point(84, 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; + this.chkShowFrameCount.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // chkShowEffectiveAddresses // this.chkShowEffectiveAddresses.AutoSize = true; this.chkShowEffectiveAddresses.Checked = true; this.chkShowEffectiveAddresses.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkShowEffectiveAddresses.Location = new System.Drawing.Point(332, 3); + this.chkShowEffectiveAddresses.Location = new System.Drawing.Point(301, 3); this.chkShowEffectiveAddresses.Name = "chkShowEffectiveAddresses"; this.chkShowEffectiveAddresses.Size = new System.Drawing.Size(150, 17); this.chkShowEffectiveAddresses.TabIndex = 10; this.chkShowEffectiveAddresses.Text = "Show Effective Addresses"; this.chkShowEffectiveAddresses.UseVisualStyleBackColor = true; - // - // cboStatusFlagFormat - // - this.cboStatusFlagFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboStatusFlagFormat.FormattingEnabled = true; - this.cboStatusFlagFormat.Location = new System.Drawing.Point(107, 49); - this.cboStatusFlagFormat.Name = "cboStatusFlagFormat"; - this.cboStatusFlagFormat.Size = new System.Drawing.Size(121, 21); - this.cboStatusFlagFormat.TabIndex = 13; + this.chkShowEffectiveAddresses.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // tableLayoutPanel4 // this.tableLayoutPanel4.ColumnCount = 4; - this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel4, 4); + this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel4, 7); this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); @@ -332,18 +384,18 @@ this.tableLayoutPanel4.Controls.Add(this.lblCondition, 0, 0); this.tableLayoutPanel4.Controls.Add(this.txtCondition, 1, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 73); + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 103); this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 1; this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel4.Size = new System.Drawing.Size(769, 25); + this.tableLayoutPanel4.Size = new System.Drawing.Size(694, 25); this.tableLayoutPanel4.TabIndex = 16; // // picHelp // this.picHelp.Image = global::Mesen.GUI.Properties.Resources.Help; - this.picHelp.Location = new System.Drawing.Point(748, 5); + this.picHelp.Location = new System.Drawing.Point(673, 5); this.picHelp.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); this.picHelp.Name = "picHelp"; this.picHelp.Size = new System.Drawing.Size(18, 17); @@ -353,7 +405,7 @@ // picExpressionWarning // this.picExpressionWarning.Image = global::Mesen.GUI.Properties.Resources.Warning; - this.picExpressionWarning.Location = new System.Drawing.Point(724, 5); + this.picExpressionWarning.Location = new System.Drawing.Point(649, 5); this.picExpressionWarning.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); this.picExpressionWarning.Name = "picExpressionWarning"; this.picExpressionWarning.Size = new System.Drawing.Size(18, 17); @@ -376,7 +428,7 @@ this.txtCondition.Dock = System.Windows.Forms.DockStyle.Fill; this.txtCondition.Location = new System.Drawing.Point(63, 3); this.txtCondition.Name = "txtCondition"; - this.txtCondition.Size = new System.Drawing.Size(655, 20); + this.txtCondition.Size = new System.Drawing.Size(580, 20); this.txtCondition.TabIndex = 15; // // chkShowExtraInfo @@ -384,12 +436,84 @@ this.chkShowExtraInfo.AutoSize = true; this.chkShowExtraInfo.Checked = true; this.chkShowExtraInfo.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkShowExtraInfo.Location = new System.Drawing.Point(332, 49); + this.tableLayoutPanel2.SetColumnSpan(this.chkShowExtraInfo, 2); + this.chkShowExtraInfo.Location = new System.Drawing.Point(462, 3); 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; + this.chkShowExtraInfo.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); + // + // chkIndentCode + // + this.chkIndentCode.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.chkIndentCode.AutoSize = true; + this.tableLayoutPanel2.SetColumnSpan(this.chkIndentCode, 2); + this.chkIndentCode.Location = new System.Drawing.Point(3, 51); + 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; + this.chkIndentCode.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); + // + // chkUseLabels + // + this.chkUseLabels.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.chkUseLabels.AutoSize = true; + this.chkUseLabels.Location = new System.Drawing.Point(203, 51); + this.chkUseLabels.Name = "chkUseLabels"; + this.chkUseLabels.Size = new System.Drawing.Size(79, 17); + this.chkUseLabels.TabIndex = 11; + this.chkUseLabels.Text = "Use Labels"; + this.chkUseLabels.UseVisualStyleBackColor = true; + this.chkUseLabels.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); + // + // label1 + // + this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(462, 53); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(98, 13); + this.label1.TabIndex = 12; + this.label1.Text = "Status Flag Format:"; + // + // cboStatusFlagFormat + // + this.tableLayoutPanel2.SetColumnSpan(this.cboStatusFlagFormat, 2); + this.cboStatusFlagFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboStatusFlagFormat.FormattingEnabled = true; + this.cboStatusFlagFormat.Location = new System.Drawing.Point(566, 49); + this.cboStatusFlagFormat.Name = "cboStatusFlagFormat"; + this.cboStatusFlagFormat.Size = new System.Drawing.Size(121, 21); + this.cboStatusFlagFormat.TabIndex = 13; + this.cboStatusFlagFormat.SelectedIndexChanged += new System.EventHandler(this.cboStatusFlagFormat_SelectedIndexChanged); + // + // chkUseWindowsEol + // + this.chkUseWindowsEol.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.chkUseWindowsEol.AutoSize = true; + this.chkUseWindowsEol.Location = new System.Drawing.Point(301, 51); + this.chkUseWindowsEol.Name = "chkUseWindowsEol"; + this.chkUseWindowsEol.Size = new System.Drawing.Size(155, 17); + this.chkUseWindowsEol.TabIndex = 19; + this.chkUseWindowsEol.Text = "Use Windows EOL (CR LF)"; + this.chkUseWindowsEol.UseVisualStyleBackColor = true; + // + // chkExtendZeroPage + // + this.chkExtendZeroPage.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.chkExtendZeroPage.AutoSize = true; + this.tableLayoutPanel2.SetColumnSpan(this.chkExtendZeroPage, 2); + this.chkExtendZeroPage.Location = new System.Drawing.Point(462, 26); + this.chkExtendZeroPage.Name = "chkExtendZeroPage"; + this.chkExtendZeroPage.Size = new System.Drawing.Size(205, 17); + this.chkExtendZeroPage.TabIndex = 20; + this.chkExtendZeroPage.Text = "Show zero page addresses as 2 bytes"; + this.chkExtendZeroPage.UseVisualStyleBackColor = true; + this.chkExtendZeroPage.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged); // // tableLayoutPanel3 // @@ -404,7 +528,7 @@ this.tableLayoutPanel3.RowCount = 2; this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel3.Size = new System.Drawing.Size(787, 458); + this.tableLayoutPanel3.Size = new System.Drawing.Size(712, 385); this.tableLayoutPanel3.TabIndex = 1; // // grpExecutionLog @@ -413,7 +537,7 @@ this.grpExecutionLog.Dock = System.Windows.Forms.DockStyle.Fill; this.grpExecutionLog.Location = new System.Drawing.Point(3, 3); this.grpExecutionLog.Name = "grpExecutionLog"; - this.grpExecutionLog.Size = new System.Drawing.Size(781, 265); + this.grpExecutionLog.Size = new System.Drawing.Size(706, 191); this.grpExecutionLog.TabIndex = 2; this.grpExecutionLog.TabStop = false; this.grpExecutionLog.Text = "Execution Log"; @@ -421,6 +545,7 @@ // txtTraceLog // this.txtTraceLog.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtTraceLog.CodeHighlightingEnabled = true; this.txtTraceLog.Dock = System.Windows.Forms.DockStyle.Fill; this.txtTraceLog.HideSelection = false; this.txtTraceLog.Location = new System.Drawing.Point(3, 16); @@ -432,7 +557,7 @@ this.txtTraceLog.ShowScrollbars = true; this.txtTraceLog.ShowSingleContentLineNotes = true; this.txtTraceLog.ShowSingleLineLineNumberNotes = false; - this.txtTraceLog.Size = new System.Drawing.Size(775, 246); + this.txtTraceLog.Size = new System.Drawing.Size(700, 172); this.txtTraceLog.TabIndex = 0; // // tmrUpdateLog @@ -446,7 +571,7 @@ this.showToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(787, 24); + this.menuStrip1.Size = new System.Drawing.Size(712, 24); this.menuStrip1.TabIndex = 2; this.menuStrip1.Text = "menuStrip1"; // @@ -578,10 +703,10 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(787, 482); + this.ClientSize = new System.Drawing.Size(712, 409); this.Controls.Add(this.tableLayoutPanel3); this.Controls.Add(this.menuStrip1); - this.MinimumSize = new System.Drawing.Size(669, 448); + this.MinimumSize = new System.Drawing.Size(728, 448); this.Name = "frmTraceLogger"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Trace Logger"; @@ -589,6 +714,9 @@ this.grpLogOptions.ResumeLayout(false); this.tableLayoutPanel2.ResumeLayout(false); this.tableLayoutPanel2.PerformLayout(); + this.tableLayoutPanel5.ResumeLayout(false); + this.tableLayoutPanel5.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picFormatHelp)).EndInit(); this.tableLayoutPanel4.ResumeLayout(false); this.tableLayoutPanel4.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.picHelp)).EndInit(); @@ -648,5 +776,12 @@ private System.Windows.Forms.ToolStripMenuItem mnuResetFontSize; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem12; private System.Windows.Forms.ToolStripMenuItem mnuSelectFont; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5; + private System.Windows.Forms.PictureBox picFormatHelp; + private System.Windows.Forms.Label lblFormat; + private System.Windows.Forms.TextBox txtFormat; + private System.Windows.Forms.CheckBox chkOverrideFormat; + private System.Windows.Forms.CheckBox chkUseWindowsEol; + private System.Windows.Forms.CheckBox chkExtendZeroPage; } } \ No newline at end of file diff --git a/GUI.NET/Debugger/frmTraceLogger.cs b/GUI.NET/Debugger/frmTraceLogger.cs index e7e9557f..eca8d8c0 100644 --- a/GUI.NET/Debugger/frmTraceLogger.cs +++ b/GUI.NET/Debugger/frmTraceLogger.cs @@ -23,6 +23,7 @@ namespace Mesen.GUI.Debugger private int _previousCycleCount; private string _previousTrace; private volatile bool _refreshRunning; + private bool _initialized; public frmTraceLogger() { @@ -51,13 +52,40 @@ namespace Mesen.GUI.Debugger _entityBinder.AddBinding("ShowRegisters", chkShowRegisters); _entityBinder.AddBinding("IndentCode", chkIndentCode); _entityBinder.AddBinding("UseLabels", chkUseLabels); + _entityBinder.AddBinding("ExtendZeroPage", chkExtendZeroPage); + _entityBinder.AddBinding("UseWindowsEol", chkUseWindowsEol); _entityBinder.AddBinding("StatusFormat", cboStatusFlagFormat); + _entityBinder.AddBinding("OverrideFormat", chkOverrideFormat); _entityBinder.UpdateUI(); this.toolTip.SetToolTip(this.picExpressionWarning, "Condition contains invalid syntax or symbols."); this.toolTip.SetToolTip(this.picHelp, "When a condition is given, instructions will only be logged by the trace logger if the condition returns a value not equal to 0 or false." + Environment.NewLine + Environment.NewLine + frmBreakpoint.GetConditionTooltip(false)); + this.toolTip.SetToolTip(this.picFormatHelp, + "You can customize the trace logger's output by enabling the 'Override' option and altering the format." + Environment.NewLine + Environment.NewLine + + "The following tags are available: " + Environment.NewLine + + "[ByteCode]: The byte code for the instruction (1 to 3 bytes)." + Environment.NewLine + + "[Disassembly]: The disassembly for the current instruction." + Environment.NewLine + + "[EffectiveAddress]: The effective address used for indirect addressing modes." + Environment.NewLine + + "[MemoryValue]: The value stored at the memory location referred to by the instruction." + Environment.NewLine + + "[PC]: Program Counter" + Environment.NewLine + + "[A]: A register" + Environment.NewLine + + "[X]: X register" + Environment.NewLine + + "[Y]: Y register" + Environment.NewLine + + "[SP]: Stack Pointer" + Environment.NewLine + + "[P]: Processor Flags" + Environment.NewLine + + "[Cycle]: The current PPU cycle." + Environment.NewLine + + "[Scanline]: The current PPU scanline." + Environment.NewLine + + "[FrameCount]: The current PPU frame." + Environment.NewLine + + "[CycleCount]: The current CPU cycle (32-bit signed value, resets to 0 at power on)" + Environment.NewLine + Environment.NewLine + + "You can also specify some options by using a comma. e.g:" + Environment.NewLine + + "[Cycle,3] will display the cycle and pad out the output to always be 3 characters wide." + Environment.NewLine + + "[Scanline,h] will display the scanline in hexadecimal." + Environment.NewLine + + "[Align,50]: Align is a special tag that is useful when trying to align some content. [Align,50] will make the next tag start on column 50." + ); this.InitShortcuts(); + + this._initialized = true; } private void InitShortcuts() @@ -74,7 +102,7 @@ namespace Mesen.GUI.Debugger UpdateMenu(); tmrUpdateLog.Start(); - RefreshLog(true); + RefreshLog(true, true); } protected override void OnFormClosing(FormClosingEventArgs e) @@ -89,7 +117,6 @@ namespace Mesen.GUI.Debugger DebugInfo debugInfo = ConfigManager.Config.DebugInfo; debugInfo.TraceAutoRefresh = mnuAutoRefresh.Checked; debugInfo.TraceLineCount = _lineCount; - debugInfo.TraceIndentCode = chkIndentCode.Checked; debugInfo.TraceLoggerSize = this.WindowState == FormWindowState.Maximized ? this.RestoreBounds.Size : this.Size; debugInfo.TraceFontFamily = txtTraceLog.BaseFont.FontFamily.Name; @@ -97,9 +124,7 @@ namespace Mesen.GUI.Debugger debugInfo.TraceFontStyle = txtTraceLog.BaseFont.Style; debugInfo.TraceTextZoom = txtTraceLog.TextZoom; - _entityBinder.Entity = debugInfo.TraceLoggerOptions; _entityBinder.UpdateObject(); - debugInfo.TraceLoggerOptions = (TraceLoggerOptions)_entityBinder.Entity; ConfigManager.ApplyChanges(); @@ -108,14 +133,84 @@ namespace Mesen.GUI.Debugger } } + protected void UpdateFormatOptions() + { + if(!chkOverrideFormat.Checked) { + string format = "[PC,h] "; + if(chkShowByteCode.Checked) { + format += "[ByteCode,11h] "; + } + format += "[Disassembly]"; + int alignValue = 40; + if(chkShowEffectiveAddresses.Checked) { + format += "[EffectiveAddress]"; + alignValue += 8; + } + if(chkShowMemoryValues.Checked) { + format += " [MemoryValue,h]"; + alignValue += 6; + } + format += "[Align," + alignValue.ToString() + "] "; + + if(chkShowRegisters.Checked) { + format += "A:[A,h] X:[X,h] Y:[Y,h] "; + switch(cboStatusFlagFormat.GetEnumValue()) { + case StatusFlagFormat.Hexadecimal: format += "P:[P,h]"; break; + case StatusFlagFormat.CompactText: format += "P:[P]"; break; + case StatusFlagFormat.Text: format += "P:[P,8]"; break; + } + format += " SP:[SP,h] "; + } + if(chkShowPpuCycles.Checked) { + format += "CYC:[Cycle,3] "; + } + if(chkShowPpuScanline.Checked) { + format += "SL:[Scanline,3] "; + } + if(chkShowFrameCount.Checked) { + format += "FC:[FrameCount] "; + } + if(chkShowCpuCycles.Checked) { + format += "CPU Cycle:[CycleCount]"; + } + txtFormat.Text = format.Trim(); + } + + txtFormat.ReadOnly = !chkOverrideFormat.Checked; + chkShowByteCode.Enabled = !chkOverrideFormat.Checked; + chkShowRegisters.Enabled = !chkOverrideFormat.Checked; + chkShowPpuCycles.Enabled = !chkOverrideFormat.Checked; + chkShowPpuScanline.Enabled = !chkOverrideFormat.Checked; + chkShowFrameCount.Enabled = !chkOverrideFormat.Checked; + chkShowCpuCycles.Enabled = !chkOverrideFormat.Checked; + chkShowEffectiveAddresses.Enabled = !chkOverrideFormat.Checked; + chkShowMemoryValues.Enabled = !chkOverrideFormat.Checked; + cboStatusFlagFormat.Enabled = !chkOverrideFormat.Checked; + + if(_initialized) { + RefreshLog(false, true); + } + } + private void SetOptions() { - _entityBinder.Entity = ConfigManager.Config.DebugInfo.TraceLoggerOptions; _entityBinder.UpdateObject(); TraceLoggerOptions options = (TraceLoggerOptions)_entityBinder.Entity; - options.Condition = Encoding.UTF8.GetBytes(txtCondition.Text); - Array.Resize(ref options.Condition, 1000); - InteropEmu.DebugSetTraceOptions(options); + + InteropTraceLoggerOptions interopOptions = new InteropTraceLoggerOptions(); + interopOptions.IndentCode = options.IndentCode; + interopOptions.ShowExtraInfo = options.ShowExtraInfo; + interopOptions.UseLabels = options.UseLabels; + interopOptions.UseWindowsEol = options.UseWindowsEol; + interopOptions.ExtendZeroPage = options.ExtendZeroPage; + + interopOptions.Condition = Encoding.UTF8.GetBytes(txtCondition.Text); + Array.Resize(ref interopOptions.Condition, 1000); + + interopOptions.Format = Encoding.UTF8.GetBytes(txtFormat.Text.Replace("\t", "\\t")); + Array.Resize(ref interopOptions.Format, 1000); + + InteropEmu.DebugSetTraceOptions(interopOptions); } private void btnStartLogging_Click(object sender, EventArgs e) @@ -169,7 +264,7 @@ namespace Mesen.GUI.Debugger return base.ProcessCmdKey(ref msg, keyData); } - private void RefreshLog(bool scrollToBottom) + private void RefreshLog(bool scrollToBottom, bool forceUpdate) { if(_refreshRunning) { return; @@ -184,7 +279,7 @@ namespace Mesen.GUI.Debugger //Update trace log in another thread for performance DebugState state = new DebugState(); InteropEmu.DebugGetState(ref state); - if(_previousCycleCount != state.CPU.CycleCount) { + if(_previousCycleCount != state.CPU.CycleCount || forceUpdate) { string newTrace = InteropEmu.DebugGetExecutionTrace((UInt32)_lineCount); _previousCycleCount = state.CPU.CycleCount; _previousTrace = newTrace; @@ -207,16 +302,34 @@ namespace Mesen.GUI.Debugger List lineContent = new List(30000); List indent = new List(30000); + bool showByteCode = false; char[] splitter = new char[] { ' ' }; while(readLine()) { - programCounter.Add(Int32.Parse(line.Substring(0, 4), System.Globalization.NumberStyles.HexNumber)); - byteCode.Add(line.Substring(6, 11)); - lineContent.Add(line.Substring(19)); - indent.Add(6); + string[] parts = line.Split('\x1'); + programCounter.Add(Int32.Parse(parts[0], System.Globalization.NumberStyles.HexNumber)); + byteCode.Add(parts[1]); + + string content = parts[2]; + while(true) { + string str = content.TrimStart(); + if(str.StartsWith(parts[0])) { + content = str.Substring(4); + } else if(str.StartsWith(parts[1])) { + content = str.Substring(11); + showByteCode = true; + } else if(str.StartsWith(parts[1].Replace("$", ""))) { + content = str.Substring(8); + showByteCode = true; + } else { + break; + } + } + lineContent.Add(content); + indent.Add(0); } this.BeginInvoke((Action)(() => { - txtTraceLog.ShowContentNotes = chkShowByteCode.Checked; - txtTraceLog.ShowSingleContentLineNotes = chkShowByteCode.Checked; + txtTraceLog.ShowContentNotes = showByteCode; + txtTraceLog.ShowSingleContentLineNotes = showByteCode; txtTraceLog.LineIndentations = indent.ToArray(); txtTraceLog.LineNumbers = programCounter.ToArray(); @@ -257,7 +370,7 @@ namespace Mesen.GUI.Debugger } if(mnuAutoRefresh.Checked) { - RefreshLog(false); + RefreshLog(false, false); } } @@ -287,7 +400,7 @@ namespace Mesen.GUI.Debugger private void mnuRefresh_Click(object sender, EventArgs e) { - RefreshLog(false); + RefreshLog(false, true); } private void mnuIncreaseFontSize_Click(object sender, EventArgs e) @@ -309,5 +422,35 @@ namespace Mesen.GUI.Debugger { txtTraceLog.BaseFont = FontDialogHelper.SelectFont(txtTraceLog.BaseFont); } + + private void chkOptions_CheckedChanged(object sender, EventArgs e) + { + UpdateFormatOptions(); + } + + private void cboStatusFlagFormat_SelectedIndexChanged(object sender, EventArgs e) + { + UpdateFormatOptions(); + } + + private void txtFormat_TextChanged(object sender, EventArgs e) + { + if(chkOverrideFormat.Checked) { + //Only save format string when override flag is set + ((TraceLoggerOptions)_entityBinder.Entity).Format = txtFormat.Text; + } + } + + private void chkOverrideFormat_CheckedChanged(object sender, EventArgs e) + { + if(chkOverrideFormat.Checked) { + string format = ((TraceLoggerOptions)_entityBinder.Entity).Format; + if(string.IsNullOrWhiteSpace(format)) { + format = txtFormat.Text; + } + txtFormat.Text = format; + } + UpdateFormatOptions(); + } } } diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 4e49e19a..e0a5d540 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -264,7 +264,7 @@ namespace Mesen.GUI [DllImport(DLLPath)] public static extern void DebugStartTraceLogger([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename); [DllImport(DLLPath)] public static extern void DebugStopTraceLogger(); - [DllImport(DLLPath)] public static extern void DebugSetTraceOptions(TraceLoggerOptions options); + [DllImport(DLLPath)] public static extern void DebugSetTraceOptions(InteropTraceLoggerOptions options); [DllImport(DLLPath, EntryPoint = "DebugGetExecutionTrace")] private static extern IntPtr DebugGetExecutionTraceWrapper(UInt32 lineCount); public static string DebugGetExecutionTrace(UInt32 lineCount) { return PtrToStringUtf8(InteropEmu.DebugGetExecutionTraceWrapper(lineCount)); } @@ -1409,32 +1409,20 @@ namespace Mesen.GUI public ApuFrameCounterState FrameCounter; } - public enum StatusFlagFormat - { - Hexadecimal = 0, - Text = 1, - CompactText = 2 - } - [Serializable] - public struct TraceLoggerOptions + public struct InteropTraceLoggerOptions { - [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; - [MarshalAs(UnmanagedType.I1)] public bool ShowEffectiveAddresses; - [MarshalAs(UnmanagedType.I1)] public bool ShowMemoryValues; [MarshalAs(UnmanagedType.I1)] public bool UseLabels; - public StatusFlagFormat StatusFormat; + [MarshalAs(UnmanagedType.I1)] public bool UseWindowsEol; + [MarshalAs(UnmanagedType.I1)] public bool ExtendZeroPage; - [NonSerialized] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)] public byte[] Condition; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)] + public byte[] Format; } public enum ProfilerDataType diff --git a/Utilities/HexUtilities.cpp b/Utilities/HexUtilities.cpp index 5aacdfc5..0697b33c 100644 --- a/Utilities/HexUtilities.cpp +++ b/Utilities/HexUtilities.cpp @@ -46,6 +46,11 @@ string HexUtilities::ToHex(uint16_t value) return _hexCache[value >> 8] + _hexCache[value & 0xFF]; } +string HexUtilities::ToHex(int32_t value, bool fullSize) +{ + return HexUtilities::ToHex((uint32_t)value, fullSize); +} + string HexUtilities::ToHex(uint32_t value, bool fullSize) { if(fullSize || value > 0xFFFFFF) { diff --git a/Utilities/HexUtilities.h b/Utilities/HexUtilities.h index d62b4a0b..b6f1a989 100644 --- a/Utilities/HexUtilities.h +++ b/Utilities/HexUtilities.h @@ -10,6 +10,7 @@ public: static string ToHex(uint8_t value); static string ToHex(uint16_t value); static string ToHex(uint32_t value, bool fullSize = false); + static string ToHex(int32_t value, bool fullSize = false); static string ToHex(vector &data); static int FromHex(string hex);