Debugger: Step into, step over, run ppu cycle/scanline/frame (+ call stack fixes)
This commit is contained in:
parent
75361b4bce
commit
0e26e5317d
13 changed files with 165 additions and 79 deletions
|
@ -32,9 +32,11 @@ void CallstackManager::Pop(uint32_t destAddress)
|
|||
return;
|
||||
}
|
||||
|
||||
uint32_t returnAddr = _callstack.back().Return;
|
||||
StackFrameInfo prevFrame = _callstack.back();
|
||||
_callstack.pop_back();
|
||||
|
||||
uint32_t returnAddr = prevFrame.Return;
|
||||
|
||||
if(!_callstack.empty() && destAddress != returnAddr) {
|
||||
//Mismatch, pop that stack frame and add the new one
|
||||
bool foundMatch = false;
|
||||
|
@ -65,4 +67,13 @@ void CallstackManager::GetCallstack(StackFrameInfo* callstackArray, uint32_t &ca
|
|||
i++;
|
||||
}
|
||||
callstackSize = i;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CallstackManager::GetReturnAddress()
|
||||
{
|
||||
DebugBreakHelper helper(_debugger);
|
||||
if(_callstack.empty()) {
|
||||
return -1;
|
||||
}
|
||||
return _callstack.back().Return;
|
||||
}
|
||||
|
|
|
@ -17,4 +17,5 @@ public:
|
|||
void Pop(uint32_t destAddr);
|
||||
|
||||
void GetCallstack(StackFrameInfo* callstackArray, uint32_t &callstackSize);
|
||||
int32_t GetReturnAddress();
|
||||
};
|
|
@ -593,6 +593,13 @@ void Console::ProcessPpuCycle()
|
|||
}
|
||||
}
|
||||
|
||||
void Console::ProcessInterrupt(uint32_t originalPc, uint32_t currentPc, bool forNmi)
|
||||
{
|
||||
if(_debugger) {
|
||||
_debugger->ProcessInterrupt(originalPc, currentPc, forNmi);
|
||||
}
|
||||
}
|
||||
|
||||
void Console::ProcessEvent(EventType type)
|
||||
{
|
||||
if(_debugger) {
|
||||
|
|
|
@ -127,5 +127,6 @@ public:
|
|||
void ProcessWorkRamRead(uint32_t addr, uint8_t value);
|
||||
void ProcessWorkRamWrite(uint32_t addr, uint8_t value);
|
||||
void ProcessPpuCycle();
|
||||
void ProcessInterrupt(uint32_t originalPc, uint32_t currentPc, bool forNmi);
|
||||
void ProcessEvent(EventType type);
|
||||
};
|
|
@ -73,12 +73,14 @@ void Cpu::Exec()
|
|||
|
||||
//Use the state of the IRQ/NMI flags on the previous cycle to determine if an IRQ is processed or not
|
||||
if(_state.PrevNmiFlag) {
|
||||
uint32_t originalPc = GetProgramAddress(_state.PC);
|
||||
ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyNmiVector : Cpu::NmiVector);
|
||||
_console->ProcessEvent(EventType::Nmi);
|
||||
_console->ProcessInterrupt(originalPc, GetProgramAddress(_state.PC), true);
|
||||
_state.NmiFlag = false;
|
||||
} else if(_state.PrevIrqSource && !CheckFlag(ProcFlags::IrqDisable)) {
|
||||
uint32_t originalPc = GetProgramAddress(_state.PC);
|
||||
ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyIrqVector : Cpu::IrqVector);
|
||||
_console->ProcessEvent(EventType::Irq);
|
||||
_console->ProcessInterrupt(originalPc, GetProgramAddress(_state.PC), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -204,4 +204,12 @@ struct StackFrameInfo
|
|||
uint32_t Target;
|
||||
uint32_t Return;
|
||||
StackFrameFlags Flags;
|
||||
};
|
||||
};
|
||||
|
||||
enum class StepType
|
||||
{
|
||||
CpuStep,
|
||||
CpuStepOut,
|
||||
CpuStepOver,
|
||||
PpuStep,
|
||||
};
|
||||
|
|
|
@ -109,6 +109,8 @@ void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
_callstackManager->Pop(pc);
|
||||
}
|
||||
|
||||
ProcessStepConditions(_prevOpCode, pc);
|
||||
|
||||
_prevOpCode = value;
|
||||
_prevProgramCounter = pc;
|
||||
|
||||
|
@ -187,6 +189,35 @@ void Debugger::ProcessPpuCycle()
|
|||
uint16_t scanline = _ppu->GetState().Scanline;
|
||||
uint16_t cycle = _ppu->GetState().Cycle;
|
||||
_ppuTools->UpdateViewers(scanline, cycle);
|
||||
|
||||
if(_ppuStepCount > 0) {
|
||||
_ppuStepCount--;
|
||||
if(_ppuStepCount == 0) {
|
||||
_cpuStepCount = 0;
|
||||
SleepUntilResume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::SleepUntilResume()
|
||||
{
|
||||
_console->GetSoundMixer()->StopAudio();
|
||||
_disassembler->Disassemble();
|
||||
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::CodeBreak);
|
||||
_executionStopped = true;
|
||||
while(_cpuStepCount == 0 || _breakRequestCount) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(10));
|
||||
}
|
||||
_executionStopped = false;
|
||||
}
|
||||
|
||||
void Debugger::ProcessStepConditions(uint8_t opCode, uint32_t currentPc)
|
||||
{
|
||||
if(_breakAddress == currentPc && (opCode == 0x60 || opCode == 0x40 || opCode == 0x6B || opCode == 0x44 || opCode == 0x54)) {
|
||||
//RTS/RTL/RTI found, if we're on the expected return address, break immediately (for step over/step out)
|
||||
_cpuStepCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::ProcessBreakConditions(MemoryOperationInfo &operation, AddressInfo &addressInfo)
|
||||
|
@ -196,31 +227,19 @@ void Debugger::ProcessBreakConditions(MemoryOperationInfo &operation, AddressInf
|
|||
}
|
||||
|
||||
if(_cpuStepCount == 0 || _breakRequestCount) {
|
||||
_console->GetSoundMixer()->StopAudio();
|
||||
_disassembler->Disassemble();
|
||||
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::CodeBreak);
|
||||
_executionStopped = true;
|
||||
while(_cpuStepCount == 0 || _breakRequestCount) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(10));
|
||||
}
|
||||
_executionStopped = false;
|
||||
SleepUntilResume();
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::ProcessInterrupt(bool forNmi)
|
||||
void Debugger::ProcessInterrupt(uint32_t originalPc, uint32_t currentPc, bool forNmi)
|
||||
{
|
||||
CpuState state = _cpu->GetState();
|
||||
_callstackManager->Push(_prevProgramCounter, (state.K << 16) | state.PC, _prevProgramCounter, forNmi ? StackFrameFlags::Nmi : StackFrameFlags::Irq);
|
||||
_callstackManager->Push(_prevProgramCounter, currentPc, originalPc, forNmi ? StackFrameFlags::Nmi : StackFrameFlags::Irq);
|
||||
_eventManager->AddEvent(forNmi ? DebugEventType::Nmi : DebugEventType::Irq);
|
||||
}
|
||||
|
||||
void Debugger::ProcessEvent(EventType type)
|
||||
{
|
||||
switch(type) {
|
||||
case EventType::Nmi: ProcessInterrupt(true); break;
|
||||
case EventType::Irq: ProcessInterrupt(false); break;
|
||||
|
||||
case EventType::StartFrame:
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::EventViewerRefresh);
|
||||
_eventManager->ClearFrameEvents();
|
||||
|
@ -244,11 +263,45 @@ int32_t Debugger::EvaluateExpression(string expression, EvalResultType &resultTy
|
|||
void Debugger::Run()
|
||||
{
|
||||
_cpuStepCount = -1;
|
||||
_breakAddress = -1;
|
||||
_ppuStepCount = -1;
|
||||
}
|
||||
|
||||
void Debugger::Step(int32_t stepCount)
|
||||
void Debugger::Step(int32_t stepCount, StepType type)
|
||||
{
|
||||
_cpuStepCount = stepCount;
|
||||
switch(type) {
|
||||
case StepType::CpuStep:
|
||||
_cpuStepCount = stepCount;
|
||||
_breakAddress = -1;
|
||||
_ppuStepCount = -1;
|
||||
break;
|
||||
|
||||
case StepType::CpuStepOut:
|
||||
_breakAddress = _callstackManager->GetReturnAddress();
|
||||
_cpuStepCount = -1;
|
||||
_ppuStepCount = -1;
|
||||
break;
|
||||
|
||||
case StepType::CpuStepOver:
|
||||
if(_prevOpCode == 0x20 || _prevOpCode == 0x22 || _prevOpCode == 0xFC || _prevOpCode == 0x00 || _prevOpCode == 0x02 || _prevOpCode == 0x44 || _prevOpCode == 0x54) {
|
||||
//JSR, JSL, BRK, COP, MVP, MVN
|
||||
_breakAddress = (_prevProgramCounter & 0xFF0000) | (((_prevProgramCounter & 0xFFFF) + DisassemblyInfo::GetOperandSize(_prevOpCode, 0) + 1) & 0xFFFF);
|
||||
_cpuStepCount = -1;
|
||||
_ppuStepCount = -1;
|
||||
} else {
|
||||
//For any other instruction, step over is the same as step into
|
||||
_cpuStepCount = 1;
|
||||
_breakAddress = -1;
|
||||
_ppuStepCount = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case StepType::PpuStep:
|
||||
_ppuStepCount = stepCount;
|
||||
_cpuStepCount = -1;
|
||||
_breakAddress = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Debugger::IsExecutionStopped()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "CpuTypes.h"
|
||||
#include "PpuTypes.h"
|
||||
#include "DebugTypes.h"
|
||||
|
||||
class Console;
|
||||
class Cpu;
|
||||
|
@ -20,15 +21,8 @@ class EventManager;
|
|||
class CallstackManager;
|
||||
|
||||
enum class EventType;
|
||||
enum class SnesMemoryType;
|
||||
enum class MemoryOperationType;
|
||||
enum class BreakpointCategory;
|
||||
enum class EvalResultType : int32_t;
|
||||
|
||||
struct DebugState;
|
||||
struct MemoryOperationInfo;
|
||||
struct AddressInfo;
|
||||
|
||||
class Debugger
|
||||
{
|
||||
private:
|
||||
|
@ -53,12 +47,15 @@ private:
|
|||
atomic<uint32_t> _breakRequestCount;
|
||||
|
||||
atomic<int32_t> _cpuStepCount;
|
||||
atomic<int32_t> _ppuStepCount;
|
||||
atomic<int32_t> _breakAddress;
|
||||
|
||||
uint8_t _prevOpCode = 0;
|
||||
uint32_t _prevProgramCounter = 0;
|
||||
|
||||
void SleepUntilResume();
|
||||
void ProcessStepConditions(uint8_t opCode, uint32_t currentPc);
|
||||
void ProcessBreakConditions(MemoryOperationInfo &operation, AddressInfo &addressInfo);
|
||||
void ProcessInterrupt(bool forNmi);
|
||||
|
||||
public:
|
||||
Debugger(shared_ptr<Console> console);
|
||||
|
@ -75,12 +72,13 @@ public:
|
|||
void ProcessPpuWrite(uint16_t addr, uint8_t value, SnesMemoryType memoryType);
|
||||
void ProcessPpuCycle();
|
||||
|
||||
void ProcessInterrupt(uint32_t originalPc, uint32_t currentPc, bool forNmi);
|
||||
void ProcessEvent(EventType type);
|
||||
|
||||
int32_t EvaluateExpression(string expression, EvalResultType &resultType, bool useCache);
|
||||
|
||||
void Run();
|
||||
void Step(int32_t stepCount);
|
||||
void Step(int32_t stepCount, StepType type = StepType::CpuStep);
|
||||
bool IsExecutionStopped();
|
||||
|
||||
void BreakRequest(bool release);
|
||||
|
|
|
@ -38,7 +38,7 @@ extern "C"
|
|||
|
||||
DllExport bool __stdcall IsExecutionStopped() { return GetDebugger()->IsExecutionStopped(); }
|
||||
DllExport void __stdcall ResumeExecution() { if(IsDebuggerRunning()) GetDebugger()->Run(); }
|
||||
DllExport void __stdcall Step(uint32_t count) { GetDebugger()->Step(count); }
|
||||
DllExport void __stdcall Step(uint32_t count, StepType type) { GetDebugger()->Step(count, type); }
|
||||
|
||||
DllExport void __stdcall GetDisassemblyLineData(uint32_t lineIndex, CodeLineData &data) { GetDebugger()->GetDisassembler()->GetLineData(lineIndex, data); }
|
||||
DllExport uint32_t __stdcall GetDisassemblyLineCount() { return GetDebugger()->GetDisassembler()->GetLineCount(); }
|
||||
|
|
|
@ -304,6 +304,12 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
} else if(keyData == ConfigManager.Config.Debug.Shortcuts.Find) {
|
||||
this.OpenSearchBox(true);
|
||||
return true;
|
||||
} else if(keyData == ConfigManager.Config.Debug.Shortcuts.FindNext) {
|
||||
this.FindNext();
|
||||
return true;
|
||||
} else if(keyData == ConfigManager.Config.Debug.Shortcuts.FindPrev) {
|
||||
this.FindPrevious();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(keyData == (Keys.Control | Keys.F)) {
|
||||
|
|
59
UI/Debugger/frmDebugger.Designer.cs
generated
59
UI/Debugger/frmDebugger.Designer.cs
generated
|
@ -49,7 +49,7 @@
|
|||
this.mnuDisableEnableBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuRunCpuCycle = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRun1000Cycles = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRun1000Instructions = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRunPpuCycle = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRunScanline = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRunOneFrame = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -113,7 +113,7 @@
|
|||
this.mnuDisableEnableBreakpoint,
|
||||
this.toolStripMenuItem2,
|
||||
this.mnuRunCpuCycle,
|
||||
this.mnuRun1000Cycles,
|
||||
this.mnuRun1000Instructions,
|
||||
this.mnuRunPpuCycle,
|
||||
this.mnuRunScanline,
|
||||
this.mnuRunOneFrame,
|
||||
|
@ -128,9 +128,8 @@
|
|||
//
|
||||
this.mnuContinue.Image = global::Mesen.GUI.Properties.Resources.MediaPlay;
|
||||
this.mnuContinue.Name = "mnuContinue";
|
||||
this.mnuContinue.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuContinue.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuContinue.Text = "Continue";
|
||||
this.mnuContinue.Click += new System.EventHandler(this.mnuContinue_Click);
|
||||
//
|
||||
// mnuBreak
|
||||
//
|
||||
|
@ -138,136 +137,134 @@
|
|||
this.mnuBreak.Image = global::Mesen.GUI.Properties.Resources.MediaPause;
|
||||
this.mnuBreak.Name = "mnuBreak";
|
||||
this.mnuBreak.ShortcutKeyDisplayString = "";
|
||||
this.mnuBreak.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuBreak.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuBreak.Text = "Break";
|
||||
//
|
||||
// toolStripMenuItem3
|
||||
//
|
||||
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
|
||||
this.toolStripMenuItem3.Size = new System.Drawing.Size(209, 6);
|
||||
this.toolStripMenuItem3.Size = new System.Drawing.Size(210, 6);
|
||||
//
|
||||
// mnuStepInto
|
||||
//
|
||||
this.mnuStepInto.Image = global::Mesen.GUI.Properties.Resources.StepInto;
|
||||
this.mnuStepInto.Name = "mnuStepInto";
|
||||
this.mnuStepInto.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuStepInto.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuStepInto.Text = "Step Into";
|
||||
this.mnuStepInto.Click += new System.EventHandler(this.mnuStepInto_Click);
|
||||
//
|
||||
// mnuStepOver
|
||||
//
|
||||
this.mnuStepOver.Image = global::Mesen.GUI.Properties.Resources.StepOver;
|
||||
this.mnuStepOver.Name = "mnuStepOver";
|
||||
this.mnuStepOver.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuStepOver.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuStepOver.Text = "Step Over";
|
||||
//
|
||||
// mnuStepOut
|
||||
//
|
||||
this.mnuStepOut.Image = global::Mesen.GUI.Properties.Resources.StepOut;
|
||||
this.mnuStepOut.Name = "mnuStepOut";
|
||||
this.mnuStepOut.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuStepOut.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuStepOut.Text = "Step Out";
|
||||
//
|
||||
// mnuStepBack
|
||||
//
|
||||
this.mnuStepBack.Image = global::Mesen.GUI.Properties.Resources.StepBack;
|
||||
this.mnuStepBack.Name = "mnuStepBack";
|
||||
this.mnuStepBack.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuStepBack.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuStepBack.Text = "Step Back";
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(209, 6);
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(210, 6);
|
||||
//
|
||||
// mnuReset
|
||||
//
|
||||
this.mnuReset.Image = global::Mesen.GUI.Properties.Resources.Refresh;
|
||||
this.mnuReset.Name = "mnuReset";
|
||||
this.mnuReset.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuReset.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuReset.Text = "Reset";
|
||||
//
|
||||
// mnuPowerCycle
|
||||
//
|
||||
this.mnuPowerCycle.Image = global::Mesen.GUI.Properties.Resources.PowerCycle;
|
||||
this.mnuPowerCycle.Name = "mnuPowerCycle";
|
||||
this.mnuPowerCycle.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuPowerCycle.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuPowerCycle.Text = "Power Cycle";
|
||||
//
|
||||
// toolStripMenuItem24
|
||||
//
|
||||
this.toolStripMenuItem24.Name = "toolStripMenuItem24";
|
||||
this.toolStripMenuItem24.Size = new System.Drawing.Size(209, 6);
|
||||
this.toolStripMenuItem24.Size = new System.Drawing.Size(210, 6);
|
||||
//
|
||||
// mnuToggleBreakpoint
|
||||
//
|
||||
this.mnuToggleBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Breakpoint;
|
||||
this.mnuToggleBreakpoint.Name = "mnuToggleBreakpoint";
|
||||
this.mnuToggleBreakpoint.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuToggleBreakpoint.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuToggleBreakpoint.Text = "Toggle Breakpoint";
|
||||
//
|
||||
// mnuDisableEnableBreakpoint
|
||||
//
|
||||
this.mnuDisableEnableBreakpoint.Image = global::Mesen.GUI.Properties.Resources.BreakpointDisabled;
|
||||
this.mnuDisableEnableBreakpoint.Name = "mnuDisableEnableBreakpoint";
|
||||
this.mnuDisableEnableBreakpoint.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuDisableEnableBreakpoint.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuDisableEnableBreakpoint.Text = "Disable/Enable Breakpoint";
|
||||
//
|
||||
// toolStripMenuItem2
|
||||
//
|
||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(209, 6);
|
||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(210, 6);
|
||||
//
|
||||
// mnuRunCpuCycle
|
||||
//
|
||||
this.mnuRunCpuCycle.Image = global::Mesen.GUI.Properties.Resources.JumpTarget;
|
||||
this.mnuRunCpuCycle.Name = "mnuRunCpuCycle";
|
||||
this.mnuRunCpuCycle.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuRunCpuCycle.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuRunCpuCycle.Text = "Run one CPU cycle";
|
||||
//
|
||||
// mnuRun1000Cycles
|
||||
// mnuRun1000Instructions
|
||||
//
|
||||
this.mnuRun1000Cycles.Name = "mnuRun1000Cycles";
|
||||
this.mnuRun1000Cycles.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuRun1000Cycles.Text = "Run 1000 CPU cycles";
|
||||
this.mnuRun1000Cycles.Click += new System.EventHandler(this.mnuRun1000Cycles_Click);
|
||||
this.mnuRun1000Instructions.Name = "mnuRun1000Instructions";
|
||||
this.mnuRun1000Instructions.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuRun1000Instructions.Text = "Run 1000 CPU instructions";
|
||||
//
|
||||
// mnuRunPpuCycle
|
||||
//
|
||||
this.mnuRunPpuCycle.Image = global::Mesen.GUI.Properties.Resources.RunPpuCycle;
|
||||
this.mnuRunPpuCycle.Name = "mnuRunPpuCycle";
|
||||
this.mnuRunPpuCycle.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuRunPpuCycle.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuRunPpuCycle.Text = "Run one PPU cycle";
|
||||
//
|
||||
// mnuRunScanline
|
||||
//
|
||||
this.mnuRunScanline.Image = global::Mesen.GUI.Properties.Resources.RunPpuScanline;
|
||||
this.mnuRunScanline.Name = "mnuRunScanline";
|
||||
this.mnuRunScanline.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuRunScanline.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuRunScanline.Text = "Run one scanline";
|
||||
//
|
||||
// mnuRunOneFrame
|
||||
//
|
||||
this.mnuRunOneFrame.Image = global::Mesen.GUI.Properties.Resources.RunPpuFrame;
|
||||
this.mnuRunOneFrame.Name = "mnuRunOneFrame";
|
||||
this.mnuRunOneFrame.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuRunOneFrame.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuRunOneFrame.Text = "Run one frame";
|
||||
//
|
||||
// toolStripMenuItem8
|
||||
//
|
||||
this.toolStripMenuItem8.Name = "toolStripMenuItem8";
|
||||
this.toolStripMenuItem8.Size = new System.Drawing.Size(209, 6);
|
||||
this.toolStripMenuItem8.Size = new System.Drawing.Size(210, 6);
|
||||
//
|
||||
// mnuBreakIn
|
||||
//
|
||||
this.mnuBreakIn.Name = "mnuBreakIn";
|
||||
this.mnuBreakIn.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuBreakIn.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuBreakIn.Text = "Break in...";
|
||||
//
|
||||
// mnuBreakOn
|
||||
//
|
||||
this.mnuBreakOn.Name = "mnuBreakOn";
|
||||
this.mnuBreakOn.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuBreakOn.Size = new System.Drawing.Size(213, 22);
|
||||
this.mnuBreakOn.Text = "Break on...";
|
||||
//
|
||||
// ctrlSplitContainer
|
||||
|
@ -440,7 +437,7 @@
|
|||
private System.Windows.Forms.GroupBox grpBreakpoints;
|
||||
private Controls.ctrlBreakpoints ctrlBreakpoints;
|
||||
private Controls.ctrlConsoleStatus ctrlStatus;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRun1000Cycles;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRun1000Instructions;
|
||||
private GUI.Controls.ctrlMesenToolStrip tsToolbar;
|
||||
private System.Windows.Forms.GroupBox grpCallstack;
|
||||
private Controls.ctrlCallstack ctrlCallstack;
|
||||
|
|
|
@ -66,6 +66,15 @@ namespace Mesen.GUI.Debugger
|
|||
mnuRunPpuCycle.InitShortcut(this, nameof(DebuggerShortcutsConfig.RunPpuCycle));
|
||||
mnuRunScanline.InitShortcut(this, nameof(DebuggerShortcutsConfig.RunPpuScanline));
|
||||
mnuRunOneFrame.InitShortcut(this, nameof(DebuggerShortcutsConfig.RunPpuFrame));
|
||||
|
||||
mnuStepInto.Click += (s, e) => { DebugApi.Step(1); };
|
||||
mnuStepOver.Click += (s, e) => { DebugApi.Step(1, StepType.CpuStepOver); };
|
||||
mnuStepOut.Click += (s, e) => { DebugApi.Step(1, StepType.CpuStepOut); };
|
||||
mnuRun1000Instructions.Click += (s, e) => { DebugApi.Step(1000); };
|
||||
mnuRunPpuCycle.Click += (s, e) => { DebugApi.Step(1, StepType.PpuStep); };
|
||||
mnuRunScanline.Click += (s, e) => { DebugApi.Step(341, StepType.PpuStep); };
|
||||
mnuRunOneFrame.Click += (s, e) => { DebugApi.Step(341*262, StepType.PpuStep); }; //TODO ntsc/pal
|
||||
mnuContinue.Click += (s, e) => { DebugApi.ResumeExecution(); };
|
||||
}
|
||||
|
||||
private void InitToolbar()
|
||||
|
@ -97,21 +106,6 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
}
|
||||
|
||||
private void mnuStepInto_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugApi.Step(1);
|
||||
}
|
||||
|
||||
private void mnuContinue_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugApi.ResumeExecution();
|
||||
}
|
||||
|
||||
private void mnuRun1000Cycles_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugApi.Step(1000);
|
||||
}
|
||||
|
||||
private void ctrlCallstack_FunctionSelected(uint address)
|
||||
{
|
||||
ctrlDisassemblyView.ScrollToAddress(address);
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Mesen.GUI
|
|||
[DllImport(DllPath)] public static extern void ReleaseDebugger();
|
||||
|
||||
[DllImport(DllPath)] public static extern void ResumeExecution();
|
||||
[DllImport(DllPath)] public static extern void Step(Int32 instructionCount);
|
||||
[DllImport(DllPath)] public static extern void Step(Int32 instructionCount, StepType type = StepType.CpuStep);
|
||||
|
||||
[DllImport(DllPath)] public static extern void StartTraceLogger([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string filename);
|
||||
[DllImport(DllPath)] public static extern void StopTraceLogger();
|
||||
|
@ -375,4 +375,12 @@ namespace Mesen.GUI
|
|||
Nmi = 1,
|
||||
Irq = 2
|
||||
}
|
||||
|
||||
public enum StepType
|
||||
{
|
||||
CpuStep,
|
||||
CpuStepOut,
|
||||
CpuStepOver,
|
||||
PpuStep,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue