Debugger: Added option to show current instruction's progress (cycle count, exec/read/write cycle display)

This commit is contained in:
Sour 2018-12-23 11:56:28 -05:00
parent 4459b18fa3
commit 022085082b
14 changed files with 178 additions and 43 deletions

View file

@ -206,6 +206,10 @@ uint8_t CPU::MemoryRead(uint16_t addr, MemoryOperationType operationType) {
}
IncCycleCount();
}
if(operationType == MemoryOperationType::ExecOpCode) {
_state.DebugPC = _state.PC;
}
uint8_t value = _memoryManager->Read(addr, operationType);
return value;
}

View file

@ -68,7 +68,6 @@ private:
uint8_t GetOPCode()
{
_state.DebugPC = _state.PC;
uint8_t opCode = MemoryRead(_state.PC, MemoryOperationType::ExecOpCode);
_state.PC++;
return opCode;

View file

@ -70,6 +70,7 @@ Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<
_stopFlag = false;
_suspendCount = 0;
_opCodeCycle = 0;
_lastInstruction = 0;
_stepOutReturnAddress = -1;
@ -524,6 +525,8 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
{
OperationInfo operationInfo { addr, (int16_t)value, type };
_memoryOperationType = type;
bool isDmcRead = false;
if(type == MemoryOperationType::DmcRead) {
//Used to flag the data in the CDL file
@ -614,6 +617,7 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
}
if(type == MemoryOperationType::ExecOpCode) {
_opCodeCycle = 0;
_prevInstructionCycle = _curInstructionCycle;
_curInstructionCycle = _cpu->GetCycleCount();
@ -671,6 +675,7 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
}
_traceLogger->Log(_debugState, disassemblyInfo, operationInfo);
} else {
_opCodeCycle++;
_traceLogger->LogNonExec(operationInfo);
_profiler->ProcessCycle();
}
@ -795,6 +800,13 @@ void Debugger::ProcessVramWriteOperation(uint16_t addr, uint8_t &value)
ProcessPpuOperation(addr, value, MemoryOperationType::Write);
}
void Debugger::GetInstructionProgress(InstructionProgress &state)
{
state.OpCode = _lastInstruction;
state.OpCycle = _opCodeCycle;
state.OpMemoryOperationType = _memoryOperationType;
}
void Debugger::GetApuState(ApuState *state)
{
//Pause the emulation

View file

@ -74,6 +74,9 @@ private:
vector<uint8_t> _frozenAddresses;
uint32_t _opCodeCycle;
MemoryOperationType _memoryOperationType;
deque<StackFrameInfo> _callstack;
deque<int32_t> _subReturnAddresses;
@ -168,6 +171,7 @@ public:
void GetCallstack(StackFrameInfo* callstackArray, uint32_t &callstackSize);
void GetInstructionProgress(InstructionProgress &state);
void GetApuState(ApuState *state);
__forceinline void GetState(DebugState *state, bool includeMapperInfo = true);
void SetState(DebugState state);

View file

@ -129,6 +129,13 @@ struct DebugState
uint32_t ClockRate;
};
struct InstructionProgress
{
uint8_t OpCode;
uint32_t OpCycle;
MemoryOperationType OpMemoryOperationType;
};
struct OperationInfo
{
uint16_t Address;

View file

@ -141,6 +141,8 @@ namespace Mesen.GUI.Config
public bool ShowCommentsInLabelList = false;
public bool ShowBreakNotifications = true;
public bool ShowInstructionProgression = true;
public bool AlwaysScrollToCenter = false;
public bool SplitView = false;
public bool VerticalLayout = false;

View file

@ -400,6 +400,29 @@ namespace Mesen.GUI.Debugger
return null;
}
public static void ConfigureActiveStatement(LineProperties props)
{
props.FgColor = Color.Black;
props.TextBgColor = ConfigManager.Config.DebugInfo.CodeActiveStatementColor;
props.Symbol |= LineSymbol.Arrow;
if(ConfigManager.Config.DebugInfo.ShowInstructionProgression) {
InstructionProgress state = new InstructionProgress();
InteropEmu.DebugGetInstructionProgress(ref state);
LineProgress progress = new LineProgress();
progress.Current = (int)state.OpCycle;
progress.Maxixum = frmOpCodeTooltip.OpCycles[state.OpCode];
switch(state.OpMemoryOperationType) {
case InteropMemoryOperationType.DummyRead: progress.Color = Color.FromArgb(184, 160, 255); break;
case InteropMemoryOperationType.Read: progress.Color = Color.FromArgb(150, 176, 255); break;
case InteropMemoryOperationType.Write: progress.Color = Color.FromArgb(255, 171, 150); break;
default: progress.Color = Color.FromArgb(143, 255, 173); break;
}
props.Progress = progress;
}
}
public LineProperties GetLineStyle(int cpuAddress, int lineNumber)
{
DebugInfo info = ConfigManager.Config.DebugInfo;
@ -409,9 +432,7 @@ namespace Mesen.GUI.Debugger
bool isActiveStatement = _code._currentActiveAddress.HasValue && _code.ctrlCodeViewer.GetLineIndex((int)_code._currentActiveAddress.Value) == lineNumber;
if(isActiveStatement) {
props.FgColor = Color.Black;
props.TextBgColor = info.CodeActiveStatementColor;
props.Symbol |= LineSymbol.Arrow;
ConfigureActiveStatement(props);
} else if(_code._code.UnexecutedAddresses.Contains(lineNumber)) {
props.LineBgColor = info.CodeUnexecutedCodeColor;
} else if(_code._code.SpeculativeCodeAddreses.Contains(lineNumber)) {

View file

@ -427,9 +427,7 @@ namespace Mesen.GUI.Debugger.Controls
}
if(isActiveStatement) {
props.FgColor = Color.Black;
props.TextBgColor = info.CodeActiveStatementColor;
props.Symbol |= LineSymbol.Arrow;
ctrlDebuggerCode.LineStyleProvider.ConfigureActiveStatement(props);
}
return props;

View file

@ -993,6 +993,8 @@ namespace Mesen.GUI.Debugger
}
this.DrawLineText(g, currentLine, marginLeft, positionY, codeString, addressString, commentString, codeStringLength, addressStringLength, textColor, lineHeight);
this.DrawLineProgress(g, positionY, lineProperties?.Progress, lineHeight);
}
private void DrawLineNumber(Graphics g, int currentLine, int marginLeft, int positionY, Color addressColor)
@ -1237,6 +1239,30 @@ namespace Mesen.GUI.Debugger
}
}
private void DrawLineProgress(Graphics g, int positionY, LineProgress progress, int lineHeight)
{
if(progress != null) {
int currentStep = progress.Current + 1;
int stepCount = Math.Max(progress.Maxixum, currentStep);
string display = currentStep.ToString() + "/" + stepCount.ToString();
SizeF size = g.MeasureString(display, this._noteFont, int.MaxValue, StringFormat.GenericTypographic);
float width = size.Width + 16;
float left = this.ClientSize.Width - 5 - width;
float height = size.Height;
float top = positionY + (lineHeight - height) / 2;
g.FillRectangle(Brushes.White, left, top, width, height);
using(SolidBrush brush = new SolidBrush(progress.Color)) {
g.FillRectangle(brush, left, top, width * currentStep / stepCount, height);
}
g.DrawRectangle(Pens.Black, left, top, width, height);
g.DrawString(display, this._noteFont, Brushes.Black, left + (width - size.Width) / 2, top, StringFormat.GenericTypographic);
}
}
private void DrawHighlightedCompareString(Graphics g, string lineText, int currentLine, int marginLeft, int positionY)
{
if(_compareContents != null && _compareContents.Length > currentLine) {
@ -1305,6 +1331,20 @@ namespace Mesen.GUI.Debugger
this.DrawLineSymbols(g, positionY, lineProperties, lineHeight);
}
}
private void DrawMessage(Graphics g)
{
if(this._message != null && !string.IsNullOrWhiteSpace(this._message.Message)) {
//Display message if one is active
SizeF textSize = g.MeasureString(this._message.Message, this.Font, int.MaxValue, StringFormat.GenericTypographic);
using(SolidBrush brush = new SolidBrush(Color.FromArgb(255, 246, 168))) {
g.FillRectangle(brush, ClientRectangle.Width - textSize.Width - 10, ClientRectangle.Bottom - textSize.Height - 10, textSize.Width + 4, textSize.Height + 1);
}
g.DrawRectangle(Pens.Black, ClientRectangle.Width - textSize.Width - 10, ClientRectangle.Bottom - textSize.Height - 10, textSize.Width + 4, textSize.Height + 1);
g.DrawString(this._message.Message, this.Font, Brushes.Black, ClientRectangle.Width - textSize.Width - 8, ClientRectangle.Bottom - textSize.Height - 10, StringFormat.GenericTypographic);
}
}
protected override void OnPaint(PaintEventArgs pe)
{
@ -1359,16 +1399,7 @@ namespace Mesen.GUI.Debugger
currentLine++;
}
if(this._message != null && !string.IsNullOrWhiteSpace(this._message.Message)) {
//Display message if one is active
SizeF textSize = pe.Graphics.MeasureString(this._message.Message, this.Font, int.MaxValue, StringFormat.GenericTypographic);
using(SolidBrush brush = new SolidBrush(Color.FromArgb(255, 246, 168))) {
pe.Graphics.FillRectangle(brush, ClientRectangle.Width - textSize.Width - 20, ClientRectangle.Bottom - textSize.Height - 20, textSize.Width + 6, textSize.Height + 6);
}
pe.Graphics.DrawRectangle(Pens.Black, ClientRectangle.Width - textSize.Width - 20, ClientRectangle.Bottom - textSize.Height - 20, textSize.Width + 6, textSize.Height + 6);
pe.Graphics.DrawString(this._message.Message, this.Font, Brushes.Black, ClientRectangle.Width - textSize.Width - 17, ClientRectangle.Bottom - textSize.Height - 17, StringFormat.GenericTypographic);
}
this.DrawMessage(pe.Graphics);
}
}
@ -1398,6 +1429,15 @@ namespace Mesen.GUI.Debugger
public Color? OutlineColor;
public Color? AddressColor;
public LineSymbol Symbol;
public LineProgress Progress;
}
public class LineProgress
{
public int Current;
public int Maxixum;
public Color Color;
}
public class TextboxMessageInfo

View file

@ -211,6 +211,8 @@ namespace Mesen.GUI.Debugger
this.ctrlPpuMemoryMapping = new Mesen.GUI.Debugger.Controls.ctrlMemoryMapping();
this.ctrlCpuMemoryMapping = new Mesen.GUI.Debugger.Controls.ctrlMemoryMapping();
this.tsToolbar = new Mesen.GUI.Controls.ctrlMesenToolStrip();
this.mnuShowInstructionProgression = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem27 = new System.Windows.Forms.ToolStripSeparator();
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
@ -255,7 +257,7 @@ namespace Mesen.GUI.Debugger
this.splitContainer.Panel2.Controls.Add(this.tableLayoutPanel10);
this.splitContainer.Panel2MinSize = 100;
this.splitContainer.Size = new System.Drawing.Size(1075, 570);
this.splitContainer.SplitterDistance = 419;
this.splitContainer.SplitterDistance = 416;
this.splitContainer.SplitterWidth = 7;
this.splitContainer.TabIndex = 1;
this.splitContainer.TabStop = false;
@ -279,7 +281,7 @@ namespace Mesen.GUI.Debugger
//
this.ctrlSplitContainerTop.Panel2.Controls.Add(this.tlpFunctionLabelLists);
this.ctrlSplitContainerTop.Panel2MinSize = 150;
this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1075, 419);
this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1075, 416);
this.ctrlSplitContainerTop.SplitterDistance = 750;
this.ctrlSplitContainerTop.SplitterWidth = 7;
this.ctrlSplitContainerTop.TabIndex = 3;
@ -300,8 +302,8 @@ namespace Mesen.GUI.Debugger
this.tlpTop.Name = "tlpTop";
this.tlpTop.RowCount = 1;
this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 419F));
this.tlpTop.Size = new System.Drawing.Size(750, 419);
this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 416F));
this.tlpTop.Size = new System.Drawing.Size(750, 416);
this.tlpTop.TabIndex = 2;
//
// panel1
@ -312,7 +314,7 @@ namespace Mesen.GUI.Debugger
this.panel1.Location = new System.Drawing.Point(3, 0);
this.panel1.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(286, 419);
this.panel1.Size = new System.Drawing.Size(286, 416);
this.panel1.TabIndex = 5;
//
// ctrlSourceViewer
@ -321,7 +323,7 @@ namespace Mesen.GUI.Debugger
this.ctrlSourceViewer.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlSourceViewer.Location = new System.Drawing.Point(0, 0);
this.ctrlSourceViewer.Name = "ctrlSourceViewer";
this.ctrlSourceViewer.Size = new System.Drawing.Size(286, 419);
this.ctrlSourceViewer.Size = new System.Drawing.Size(286, 416);
this.ctrlSourceViewer.SymbolProvider = null;
this.ctrlSourceViewer.TabIndex = 7;
this.ctrlSourceViewer.Visible = false;
@ -334,7 +336,7 @@ namespace Mesen.GUI.Debugger
this.ctrlDebuggerCode.Location = new System.Drawing.Point(0, 0);
this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
this.ctrlDebuggerCode.ShowMemoryValues = false;
this.ctrlDebuggerCode.Size = new System.Drawing.Size(286, 419);
this.ctrlDebuggerCode.Size = new System.Drawing.Size(286, 416);
this.ctrlDebuggerCode.SymbolProvider = null;
this.ctrlDebuggerCode.TabIndex = 2;
this.ctrlDebuggerCode.OnEditCode += new Mesen.GUI.Debugger.ctrlDebuggerCode.AssemblerEventHandler(this.ctrlDebuggerCode_OnEditCode);
@ -348,7 +350,7 @@ namespace Mesen.GUI.Debugger
this.panel2.Location = new System.Drawing.Point(292, 0);
this.panel2.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(1, 419);
this.panel2.Size = new System.Drawing.Size(1, 416);
this.panel2.TabIndex = 6;
//
// ctrlSourceViewerSplit
@ -357,7 +359,7 @@ namespace Mesen.GUI.Debugger
this.ctrlSourceViewerSplit.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlSourceViewerSplit.Location = new System.Drawing.Point(0, 0);
this.ctrlSourceViewerSplit.Name = "ctrlSourceViewerSplit";
this.ctrlSourceViewerSplit.Size = new System.Drawing.Size(1, 419);
this.ctrlSourceViewerSplit.Size = new System.Drawing.Size(1, 416);
this.ctrlSourceViewerSplit.SymbolProvider = null;
this.ctrlSourceViewerSplit.TabIndex = 8;
this.ctrlSourceViewerSplit.Visible = false;
@ -370,7 +372,7 @@ namespace Mesen.GUI.Debugger
this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(0, 0);
this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit";
this.ctrlDebuggerCodeSplit.ShowMemoryValues = false;
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 419);
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 416);
this.ctrlDebuggerCodeSplit.SymbolProvider = null;
this.ctrlDebuggerCodeSplit.TabIndex = 4;
this.ctrlDebuggerCodeSplit.Visible = false;
@ -390,7 +392,7 @@ namespace Mesen.GUI.Debugger
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(458, 419);
this.tableLayoutPanel1.Size = new System.Drawing.Size(458, 416);
this.tableLayoutPanel1.TabIndex = 7;
//
// ctrlConsoleStatus
@ -414,7 +416,7 @@ namespace Mesen.GUI.Debugger
this.tlpVerticalLayout.Name = "tlpVerticalLayout";
this.tlpVerticalLayout.RowCount = 1;
this.tlpVerticalLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tlpVerticalLayout.Size = new System.Drawing.Size(458, 19);
this.tlpVerticalLayout.Size = new System.Drawing.Size(458, 16);
this.tlpVerticalLayout.TabIndex = 4;
//
// tlpFunctionLabelLists
@ -430,16 +432,16 @@ namespace Mesen.GUI.Debugger
this.tlpFunctionLabelLists.RowCount = 2;
this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tlpFunctionLabelLists.Size = new System.Drawing.Size(318, 419);
this.tlpFunctionLabelLists.Size = new System.Drawing.Size(318, 416);
this.tlpFunctionLabelLists.TabIndex = 5;
//
// grpLabels
//
this.grpLabels.Controls.Add(this.ctrlLabelList);
this.grpLabels.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpLabels.Location = new System.Drawing.Point(3, 212);
this.grpLabels.Location = new System.Drawing.Point(3, 211);
this.grpLabels.Name = "grpLabels";
this.grpLabels.Size = new System.Drawing.Size(312, 204);
this.grpLabels.Size = new System.Drawing.Size(312, 202);
this.grpLabels.TabIndex = 6;
this.grpLabels.TabStop = false;
this.grpLabels.Text = "Labels";
@ -449,7 +451,7 @@ namespace Mesen.GUI.Debugger
this.ctrlLabelList.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlLabelList.Location = new System.Drawing.Point(3, 16);
this.ctrlLabelList.Name = "ctrlLabelList";
this.ctrlLabelList.Size = new System.Drawing.Size(306, 185);
this.ctrlLabelList.Size = new System.Drawing.Size(306, 183);
this.ctrlLabelList.TabIndex = 0;
this.ctrlLabelList.OnFindOccurrence += new System.EventHandler(this.ctrlLabelList_OnFindOccurrence);
this.ctrlLabelList.OnLabelSelected += new System.EventHandler(this.ctrlLabelList_OnLabelSelected);
@ -460,7 +462,7 @@ namespace Mesen.GUI.Debugger
this.grpFunctions.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpFunctions.Location = new System.Drawing.Point(3, 3);
this.grpFunctions.Name = "grpFunctions";
this.grpFunctions.Size = new System.Drawing.Size(312, 203);
this.grpFunctions.Size = new System.Drawing.Size(312, 202);
this.grpFunctions.TabIndex = 5;
this.grpFunctions.TabStop = false;
this.grpFunctions.Text = "Functions";
@ -470,7 +472,7 @@ namespace Mesen.GUI.Debugger
this.ctrlFunctionList.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlFunctionList.Location = new System.Drawing.Point(3, 16);
this.ctrlFunctionList.Name = "ctrlFunctionList";
this.ctrlFunctionList.Size = new System.Drawing.Size(306, 184);
this.ctrlFunctionList.Size = new System.Drawing.Size(306, 183);
this.ctrlFunctionList.TabIndex = 0;
this.ctrlFunctionList.OnFindOccurrence += new System.EventHandler(this.ctrlFunctionList_OnFindOccurrence);
this.ctrlFunctionList.OnFunctionSelected += new System.EventHandler(this.ctrlFunctionList_OnFunctionSelected);
@ -501,7 +503,7 @@ namespace Mesen.GUI.Debugger
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel10.Size = new System.Drawing.Size(1075, 144);
this.tableLayoutPanel10.Size = new System.Drawing.Size(1075, 147);
this.tableLayoutPanel10.TabIndex = 0;
//
// grpWatch
@ -510,7 +512,7 @@ namespace Mesen.GUI.Debugger
this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpWatch.Location = new System.Drawing.Point(3, 3);
this.grpWatch.Name = "grpWatch";
this.grpWatch.Size = new System.Drawing.Size(352, 138);
this.grpWatch.Size = new System.Drawing.Size(352, 141);
this.grpWatch.TabIndex = 2;
this.grpWatch.TabStop = false;
this.grpWatch.Text = "Watch";
@ -520,7 +522,7 @@ namespace Mesen.GUI.Debugger
this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlWatch.Location = new System.Drawing.Point(3, 16);
this.ctrlWatch.Name = "ctrlWatch";
this.ctrlWatch.Size = new System.Drawing.Size(346, 119);
this.ctrlWatch.Size = new System.Drawing.Size(346, 122);
this.ctrlWatch.TabIndex = 0;
//
// grpBreakpoints
@ -529,7 +531,7 @@ namespace Mesen.GUI.Debugger
this.grpBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpBreakpoints.Location = new System.Drawing.Point(361, 3);
this.grpBreakpoints.Name = "grpBreakpoints";
this.grpBreakpoints.Size = new System.Drawing.Size(352, 138);
this.grpBreakpoints.Size = new System.Drawing.Size(352, 141);
this.grpBreakpoints.TabIndex = 3;
this.grpBreakpoints.TabStop = false;
this.grpBreakpoints.Text = "Breakpoints";
@ -539,7 +541,7 @@ namespace Mesen.GUI.Debugger
this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16);
this.ctrlBreakpoints.Name = "ctrlBreakpoints";
this.ctrlBreakpoints.Size = new System.Drawing.Size(346, 119);
this.ctrlBreakpoints.Size = new System.Drawing.Size(346, 122);
this.ctrlBreakpoints.TabIndex = 0;
this.ctrlBreakpoints.BreakpointNavigation += new System.EventHandler(this.ctrlBreakpoints_BreakpointNavigation);
//
@ -549,7 +551,7 @@ namespace Mesen.GUI.Debugger
this.grpCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpCallstack.Location = new System.Drawing.Point(719, 3);
this.grpCallstack.Name = "grpCallstack";
this.grpCallstack.Size = new System.Drawing.Size(353, 138);
this.grpCallstack.Size = new System.Drawing.Size(353, 141);
this.grpCallstack.TabIndex = 4;
this.grpCallstack.TabStop = false;
this.grpCallstack.Text = "Call Stack";
@ -559,7 +561,7 @@ namespace Mesen.GUI.Debugger
this.ctrlCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlCallstack.Location = new System.Drawing.Point(3, 16);
this.ctrlCallstack.Name = "ctrlCallstack";
this.ctrlCallstack.Size = new System.Drawing.Size(347, 119);
this.ctrlCallstack.Size = new System.Drawing.Size(347, 122);
this.ctrlCallstack.TabIndex = 0;
this.ctrlCallstack.FunctionSelected += new System.EventHandler(this.ctrlCallstack_FunctionSelected);
//
@ -1037,6 +1039,8 @@ namespace Mesen.GUI.Debugger
this.mnuPpuShowPreviousFrame,
this.toolStripMenuItem19,
this.mnuShowBreakNotifications,
this.mnuShowInstructionProgression,
this.toolStripMenuItem27,
this.mnuAlwaysScrollToCenter,
this.mnuRefreshWhileRunning,
this.toolStripMenuItem6,
@ -1870,6 +1874,19 @@ namespace Mesen.GUI.Debugger
this.tsToolbar.Text = "toolStrip1";
this.tsToolbar.Visible = false;
//
// mnuShowInstructionProgression
//
this.mnuShowInstructionProgression.CheckOnClick = true;
this.mnuShowInstructionProgression.Name = "mnuShowInstructionProgression";
this.mnuShowInstructionProgression.Size = new System.Drawing.Size(266, 22);
this.mnuShowInstructionProgression.Text = "Show instruction progression";
this.mnuShowInstructionProgression.Click += new System.EventHandler(this.mnuShowInstructionProgression_Click);
//
// toolStripMenuItem27
//
this.toolStripMenuItem27.Name = "toolStripMenuItem27";
this.toolStripMenuItem27.Size = new System.Drawing.Size(263, 6);
//
// frmDebugger
//
this.AllowDrop = true;
@ -2101,5 +2118,7 @@ namespace Mesen.GUI.Debugger
private System.Windows.Forms.ToolStripMenuItem mnuAutoCreateJumpLabels;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem25;
private System.Windows.Forms.ToolStripMenuItem mnuShowBreakNotifications;
private System.Windows.Forms.ToolStripMenuItem mnuShowInstructionProgression;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem27;
}
}

View file

@ -123,6 +123,7 @@ namespace Mesen.GUI.Debugger
this.mnuShowUnidentifiedData.Checked = ConfigManager.Config.DebugInfo.ShowUnidentifiedData;
this.mnuShowBreakNotifications.Checked = ConfigManager.Config.DebugInfo.ShowBreakNotifications;
this.mnuShowInstructionProgression.Checked = ConfigManager.Config.DebugInfo.ShowInstructionProgression;
this.mnuAlwaysScrollToCenter.Checked = ConfigManager.Config.DebugInfo.AlwaysScrollToCenter;
this.mnuRefreshWhileRunning.Checked = ConfigManager.Config.DebugInfo.RefreshWhileRunning;
this.mnuShowMemoryValues.Checked = ConfigManager.Config.DebugInfo.ShowMemoryValuesInCodeWindow;
@ -1261,6 +1262,14 @@ namespace Mesen.GUI.Debugger
ConfigManager.ApplyChanges();
}
private void mnuShowInstructionProgression_Click(object sender, EventArgs e)
{
ConfigManager.Config.DebugInfo.ShowInstructionProgression = mnuShowInstructionProgression.Checked;
ConfigManager.ApplyChanges();
UpdateDebugger(false, false);
}
private void mnuAlwaysScrollToCenter_Click(object sender, EventArgs e)
{
ConfigManager.Config.DebugInfo.AlwaysScrollToCenter = mnuAlwaysScrollToCenter.Checked;

View file

@ -215,7 +215,7 @@ namespace Mesen.GUI.Debugger
AddrMode.Rel, AddrMode.IndY, AddrMode.None, AddrMode.IndYW, AddrMode.ZeroX, AddrMode.ZeroX, AddrMode.ZeroX, AddrMode.ZeroX, AddrMode.Imp, AddrMode.AbsY, AddrMode.Imp, AddrMode.AbsYW,AddrMode.AbsX, AddrMode.AbsX, AddrMode.AbsXW,AddrMode.AbsXW,
};
private int[] OpCycles = new int[256] {
public static readonly int[] OpCycles = new int[256] {
7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6,
2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7,
6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6,

View file

@ -225,6 +225,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void DebugSetFlags(DebuggerFlags flags);
[DllImport(DLLPath)] public static extern void DebugGetState(ref DebugState state);
[DllImport(DLLPath)] public static extern void DebugGetApuState(ref ApuState state);
[DllImport(DLLPath)] public static extern void DebugGetInstructionProgress(ref InstructionProgress progress);
[DllImport(DLLPath)] public static extern void DebugSetState(DebugState state);
[DllImport(DLLPath)] public static extern void DebugSetBreakpoints([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]InteropBreakpoint[] breakpoints, UInt32 length);
[DllImport(DLLPath)] public static extern void DebugSetLabel(UInt32 address, AddressType addressType, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string label, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string comment);
@ -1247,6 +1248,13 @@ namespace Mesen.GUI
public StackFrameFlags Flags;
};
public struct InstructionProgress
{
public byte OpCode;
public UInt32 OpCycle;
public InteropMemoryOperationType OpMemoryOperationType;
}
public struct DebugState
{
public CPUState CPU;
@ -2326,6 +2334,17 @@ namespace Mesen.GUI
}
}
public enum InteropMemoryOperationType
{
Read = 0,
Write = 1,
ExecOpCode = 2,
ExecOperand = 3,
PpuRenderingRead = 4,
DummyRead = 5,
DmcRead = 6
}
public enum MemoryOperationType
{
//Note: Not identical to the C++ enum

View file

@ -50,6 +50,7 @@ extern "C"
DllExport void __stdcall DebugGetState(DebugState *state) { GetDebugger()->GetState(state); }
DllExport void __stdcall DebugSetState(DebugState state) { GetDebugger()->SetState(state); }
DllExport void __stdcall DebugGetApuState(ApuState *state) { GetDebugger()->GetApuState(state); }
DllExport void __stdcall DebugGetInstructionProgress(InstructionProgress *state) { GetDebugger()->GetInstructionProgress(*state); }
DllExport void __stdcall DebugSetBreakpoints(Breakpoint breakpoints[], uint32_t length) { GetDebugger()->SetBreakpoints(breakpoints, length); }
DllExport void __stdcall DebugSetLabel(uint32_t address, AddressType addressType, char* label, char* comment) { GetDebugger()->GetLabelManager()->SetLabel(address, addressType, label, comment); }