Debugger: Trace Logger - Added output format customization

This commit is contained in:
Sour 2018-05-26 01:14:37 -04:00
parent 0911cfe118
commit 091da2164c
15 changed files with 669 additions and 250 deletions

View File

@ -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);

View File

@ -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() {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include <regex>
#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<typename T>
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();

View File

@ -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<ExpressionEvaluator> _expEvaluator;
vector<int> _conditionRpnList;
vector<RowPart> _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<typename T> void WriteValue(string &output, T value, RowPart& rowPart);
template<> void WriteValue(string &output, string value, RowPart& rowPart);
public:
TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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<Color> colors = new List<Color>() { info.AssemblerOpcodeColor, defaultColor, defaultColor, defaultColor, operandColor, defaultColor, defaultColor, defaultColor };
List<Color> colors = new List<Color>() { defaultColor, info.AssemblerOpcodeColor, defaultColor, defaultColor, defaultColor, operandColor, defaultColor, defaultColor, defaultColor };
int codePartCount = colors.Count;
List<string> parts = new List<string>() { opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 };
List<string> parts = new List<string>() { padding, opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 };
string memoryAddress = "";
if(!string.IsNullOrWhiteSpace(addressString)) {
colors.Add(info.CodeEffectiveAddressColor);

View File

@ -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;
}
}

View File

@ -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<StatusFlagFormat>()) {
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<string> lineContent = new List<string>(30000);
List<int> indent = new List<int>(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();
}
}
}

View File

@ -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

View File

@ -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) {

View File

@ -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<uint8_t> &data);
static int FromHex(string hex);