mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-23 09:09:45 +00:00
Debugger: Add option to trigger breakpoints on dummy read/writes (+ distinguish between writes & dummy writes)
This commit is contained in:
parent
195da9fa3d
commit
35192daeed
@ -10,8 +10,12 @@ Breakpoint::~Breakpoint()
|
||||
{
|
||||
}
|
||||
|
||||
bool Breakpoint::Matches(uint32_t memoryAddr, AddressTypeInfo &info)
|
||||
bool Breakpoint::Matches(uint32_t memoryAddr, AddressTypeInfo &info, MemoryOperationType opType)
|
||||
{
|
||||
if(!_processDummyReadWrites && (opType == MemoryOperationType::DummyRead || opType == MemoryOperationType::DummyWrite)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(_startAddr == -1) {
|
||||
return true;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
Breakpoint();
|
||||
~Breakpoint();
|
||||
|
||||
bool Matches(uint32_t memoryAddr, AddressTypeInfo &info);
|
||||
bool Matches(uint32_t memoryAddr, AddressTypeInfo &info, MemoryOperationType opType);
|
||||
bool Matches(uint32_t memoryAddr, PpuAddressTypeInfo &info);
|
||||
bool HasBreakpointType(BreakpointType type);
|
||||
string GetCondition();
|
||||
@ -38,5 +38,6 @@ private:
|
||||
int32_t _endAddr;
|
||||
bool _enabled;
|
||||
bool _markEvent;
|
||||
bool _processDummyReadWrites;
|
||||
char _condition[1000];
|
||||
};
|
@ -176,7 +176,7 @@ void CPU::BRK() {
|
||||
_prevRunIrq = false;
|
||||
}
|
||||
|
||||
void CPU::MemoryWrite(uint16_t addr, uint8_t value)
|
||||
void CPU::MemoryWrite(uint16_t addr, uint8_t value, MemoryOperationType operationType)
|
||||
{
|
||||
_cpuWrite = true;;
|
||||
_writeAddr = addr;
|
||||
@ -184,7 +184,7 @@ void CPU::MemoryWrite(uint16_t addr, uint8_t value)
|
||||
while(_dmcDmaRunning) {
|
||||
IncCycleCount();
|
||||
}
|
||||
_memoryManager->Write(addr, value);
|
||||
_memoryManager->Write(addr, value, operationType);
|
||||
|
||||
//DMA DMC might have started after a write to $4015, stall CPU if needed
|
||||
while(_dmcDmaRunning) {
|
||||
|
28
Core/CPU.h
28
Core/CPU.h
@ -77,7 +77,7 @@ private:
|
||||
{
|
||||
MemoryRead(_state.PC, MemoryOperationType::DummyRead);
|
||||
}
|
||||
|
||||
|
||||
uint8_t ReadByte()
|
||||
{
|
||||
uint8_t value = MemoryRead(_state.PC, MemoryOperationType::ExecOperand);
|
||||
@ -126,7 +126,7 @@ private:
|
||||
return ((valA + valB) & 0xFF00) != (valA & 0xFF00);
|
||||
}
|
||||
|
||||
void MemoryWrite(uint16_t addr, uint8_t value);
|
||||
void MemoryWrite(uint16_t addr, uint8_t value, MemoryOperationType operationType = MemoryOperationType::Write);
|
||||
uint8_t MemoryRead(uint16_t addr, MemoryOperationType operationType = MemoryOperationType::Read);
|
||||
|
||||
uint16_t MemoryReadWord(uint16_t addr, MemoryOperationType operationType = MemoryOperationType::Read) {
|
||||
@ -323,7 +323,7 @@ private:
|
||||
ClearFlags(PSFlags::Negative | PSFlags::Zero);
|
||||
uint8_t value = MemoryRead(addr);
|
||||
|
||||
MemoryWrite(addr, value); //Dummy write
|
||||
MemoryWrite(addr, value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
|
||||
value++;
|
||||
SetZeroNegativeFlags(value);
|
||||
@ -335,7 +335,7 @@ private:
|
||||
uint16_t addr = GetOperand();
|
||||
ClearFlags(PSFlags::Negative | PSFlags::Zero);
|
||||
uint8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, value); //Dummy write
|
||||
MemoryWrite(addr, value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
|
||||
value--;
|
||||
SetZeroNegativeFlags(value);
|
||||
@ -393,28 +393,28 @@ private:
|
||||
void ASLAddr() {
|
||||
uint16_t addr = GetOperand();
|
||||
uint8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, value); //Dummy write
|
||||
MemoryWrite(addr, value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
MemoryWrite(addr, ASL(value));
|
||||
}
|
||||
|
||||
void LSRAddr() {
|
||||
uint16_t addr = GetOperand();
|
||||
uint8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, value); //Dummy write
|
||||
MemoryWrite(addr, value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
MemoryWrite(addr, LSR(value));
|
||||
}
|
||||
|
||||
void ROLAddr() {
|
||||
uint16_t addr = GetOperand();
|
||||
uint8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, value); //Dummy write
|
||||
MemoryWrite(addr, value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
MemoryWrite(addr, ROL(value));
|
||||
}
|
||||
|
||||
void RORAddr() {
|
||||
uint16_t addr = GetOperand();
|
||||
uint8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, value); //Dummy write
|
||||
MemoryWrite(addr, value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
MemoryWrite(addr, ROR(value));
|
||||
}
|
||||
|
||||
@ -578,7 +578,7 @@ private:
|
||||
{
|
||||
//ASL & ORA
|
||||
uint8_t value = GetOperandValue();
|
||||
MemoryWrite(GetOperand(), value); //Dummy write
|
||||
MemoryWrite(GetOperand(), value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
uint8_t shiftedValue = ASL(value);
|
||||
SetA(A() | shiftedValue);
|
||||
MemoryWrite(GetOperand(), shiftedValue);
|
||||
@ -588,7 +588,7 @@ private:
|
||||
{
|
||||
//ROL & AND
|
||||
uint8_t value = GetOperandValue();
|
||||
MemoryWrite(GetOperand(), value); //Dummy write
|
||||
MemoryWrite(GetOperand(), value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
uint8_t shiftedValue = LSR(value);
|
||||
SetA(A() ^ shiftedValue);
|
||||
MemoryWrite(GetOperand(), shiftedValue);
|
||||
@ -598,7 +598,7 @@ private:
|
||||
{
|
||||
//LSR & EOR
|
||||
uint8_t value = GetOperandValue();
|
||||
MemoryWrite(GetOperand(), value); //Dummy write
|
||||
MemoryWrite(GetOperand(), value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
uint8_t shiftedValue = ROL(value);
|
||||
SetA(A() & shiftedValue);
|
||||
MemoryWrite(GetOperand(), shiftedValue);
|
||||
@ -608,7 +608,7 @@ private:
|
||||
{
|
||||
//ROR & ADC
|
||||
uint8_t value = GetOperandValue();
|
||||
MemoryWrite(GetOperand(), value); //Dummy write
|
||||
MemoryWrite(GetOperand(), value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
uint8_t shiftedValue = ROR(value);
|
||||
ADD(shiftedValue);
|
||||
MemoryWrite(GetOperand(), shiftedValue);
|
||||
@ -632,7 +632,7 @@ private:
|
||||
{
|
||||
//DEC & CMP
|
||||
uint8_t value = GetOperandValue();
|
||||
MemoryWrite(GetOperand(), value); //Dummy write
|
||||
MemoryWrite(GetOperand(), value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
value--;
|
||||
CMP(A(), value);
|
||||
MemoryWrite(GetOperand(), value);
|
||||
@ -642,7 +642,7 @@ private:
|
||||
{
|
||||
//INC & SBC
|
||||
uint8_t value = GetOperandValue();
|
||||
MemoryWrite(GetOperand(), value); //Dummy write
|
||||
MemoryWrite(GetOperand(), value, MemoryOperationType::DummyWrite); //Dummy write
|
||||
value++;
|
||||
ADD(value ^ 0xFF);
|
||||
MemoryWrite(GetOperand(), value);
|
||||
|
@ -76,7 +76,7 @@ protected:
|
||||
|
||||
case 0x9004: case 0x9008: case 0x900C:
|
||||
if(addr & 0x800) {
|
||||
_console->GetMemoryManager()->Write(0x4011, (value & 0x0F) << 3);
|
||||
_console->GetMemoryManager()->Write(0x4011, (value & 0x0F) << 3, MemoryOperationType::Write);
|
||||
} else {
|
||||
_prgReg = value & 0x0C;
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ void Debugger::ProcessBreakpoints(BreakpointType type, OperationInfo &operationI
|
||||
Breakpoint &breakpoint = breakpoints[i];
|
||||
if(
|
||||
type == BreakpointType::Global ||
|
||||
(!isPpuBreakpoint && breakpoint.Matches(operationInfo.Address, info)) ||
|
||||
(!isPpuBreakpoint && breakpoint.Matches(operationInfo.Address, info, operationInfo.OperationType)) ||
|
||||
(isPpuBreakpoint && breakpoint.Matches(operationInfo.Address, ppuInfo))
|
||||
) {
|
||||
if(!breakpoint.HasCondition()) {
|
||||
@ -585,7 +585,7 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
|
||||
int32_t absoluteAddr = addressInfo.Type == AddressType::PrgRom ? addressInfo.Address : -1;
|
||||
int32_t absoluteRamAddr = addressInfo.Type == AddressType::WorkRam ? addressInfo.Address : -1;
|
||||
|
||||
if(addressInfo.Address >= 0 && type != MemoryOperationType::DummyRead) {
|
||||
if(addressInfo.Address >= 0 && type != MemoryOperationType::DummyRead && type != MemoryOperationType::DummyWrite) {
|
||||
if(type == MemoryOperationType::Write && CheckFlag(DebuggerFlags::IgnoreRedundantWrites)) {
|
||||
if(_memoryManager->DebugRead(addr) != value) {
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _cpu->GetCycleCount());
|
||||
@ -680,17 +680,19 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
|
||||
_profiler->ProcessCycle();
|
||||
}
|
||||
|
||||
if(type != MemoryOperationType::DummyRead) {
|
||||
BreakpointType breakpointType;
|
||||
switch(type) {
|
||||
default: breakpointType = BreakpointType::Execute; break;
|
||||
case MemoryOperationType::Read: breakpointType = BreakpointType::ReadRam; break;
|
||||
case MemoryOperationType::Write: breakpointType = BreakpointType::WriteRam; break;
|
||||
}
|
||||
BreakpointType breakpointType;
|
||||
switch(type) {
|
||||
default: breakpointType = BreakpointType::Execute; break;
|
||||
|
||||
case MemoryOperationType::DummyRead:
|
||||
case MemoryOperationType::Read: breakpointType = BreakpointType::ReadRam; break;
|
||||
|
||||
if(_hasBreakpoint[breakpointType]) {
|
||||
ProcessBreakpoints(breakpointType, operationInfo, !breakDone);
|
||||
}
|
||||
case MemoryOperationType::DummyWrite:
|
||||
case MemoryOperationType::Write: breakpointType = BreakpointType::WriteRam; break;
|
||||
}
|
||||
|
||||
if(_hasBreakpoint[breakpointType]) {
|
||||
ProcessBreakpoints(breakpointType, operationInfo, !breakDone);
|
||||
}
|
||||
|
||||
_currentReadAddr = nullptr;
|
||||
|
@ -339,8 +339,8 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, DebugState &state, E
|
||||
case EvalValues::Value: token = operationInfo.Value; break;
|
||||
case EvalValues::Address: token = operationInfo.Address; break;
|
||||
case EvalValues::AbsoluteAddress: token = _debugger->GetAbsoluteAddress(operationInfo.Address); break;
|
||||
case EvalValues::IsWrite: token = operationInfo.OperationType == MemoryOperationType::Write; break;
|
||||
case EvalValues::IsRead: token = operationInfo.OperationType == MemoryOperationType::Read; break;
|
||||
case EvalValues::IsWrite: token = operationInfo.OperationType == MemoryOperationType::Write || operationInfo.OperationType == MemoryOperationType::DummyWrite; break;
|
||||
case EvalValues::IsRead: token = operationInfo.OperationType == MemoryOperationType::Read || operationInfo.OperationType == MemoryOperationType::DummyRead; break;
|
||||
}
|
||||
}
|
||||
} else if(token >= EvalOperators::Multiplication) {
|
||||
|
@ -134,9 +134,9 @@ uint8_t MemoryManager::Read(uint16_t addr, MemoryOperationType operationType)
|
||||
return value;
|
||||
}
|
||||
|
||||
void MemoryManager::Write(uint16_t addr, uint8_t value)
|
||||
void MemoryManager::Write(uint16_t addr, uint8_t value, MemoryOperationType operationType)
|
||||
{
|
||||
if(_console->DebugProcessRamOperation(MemoryOperationType::Write, addr, value)) {
|
||||
if(_console->DebugProcessRamOperation(operationType, addr, value)) {
|
||||
_ramWriteHandlers[addr]->WriteRAM(addr, value);
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class MemoryManager : public Snapshotable
|
||||
uint8_t* GetInternalRAM();
|
||||
|
||||
uint8_t Read(uint16_t addr, MemoryOperationType operationType = MemoryOperationType::Read);
|
||||
void Write(uint16_t addr, uint8_t value);
|
||||
void Write(uint16_t addr, uint8_t value, MemoryOperationType operationType);
|
||||
|
||||
uint32_t ToAbsolutePrgAddress(uint16_t ramAddr);
|
||||
|
||||
|
@ -32,7 +32,8 @@ enum class MemoryOperationType
|
||||
ExecOperand = 3,
|
||||
PpuRenderingRead = 4,
|
||||
DummyRead = 5,
|
||||
DmcRead = 6
|
||||
DmcRead = 6,
|
||||
DummyWrite = 7
|
||||
};
|
||||
|
||||
struct State
|
||||
|
@ -32,6 +32,7 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
public bool Enabled = true;
|
||||
public bool MarkEvent = false;
|
||||
public bool ProcessDummyReadWrites = false;
|
||||
public UInt32 Address;
|
||||
public UInt32 StartAddress;
|
||||
public UInt32 EndAddress;
|
||||
@ -193,6 +194,7 @@ namespace Mesen.GUI.Debugger
|
||||
MemoryType = MemoryType,
|
||||
Type = Type,
|
||||
MarkEvent = MarkEvent,
|
||||
ProcessDummyReadWrites = ProcessDummyReadWrites,
|
||||
Enabled = Enabled
|
||||
};
|
||||
switch(AddressType) {
|
||||
|
@ -414,10 +414,11 @@ namespace Mesen.GUI.Debugger
|
||||
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;
|
||||
case InteropMemoryOperationType.DummyRead: progress.Color = Color.FromArgb(184, 160, 255); progress.Text = "DR"; break;
|
||||
case InteropMemoryOperationType.DummyWrite: progress.Color = Color.FromArgb(255, 245, 137); progress.Text = "DW"; break;
|
||||
case InteropMemoryOperationType.Read: progress.Color = Color.FromArgb(150, 176, 255); progress.Text = "R"; break;
|
||||
case InteropMemoryOperationType.Write: progress.Color = Color.FromArgb(255, 171, 150); progress.Text = "W"; break;
|
||||
default: progress.Color = Color.FromArgb(143, 255, 173); progress.Text = "X"; break;
|
||||
}
|
||||
props.Progress = progress;
|
||||
}
|
||||
|
@ -1245,7 +1245,7 @@ namespace Mesen.GUI.Debugger
|
||||
int currentStep = progress.Current + 1;
|
||||
int stepCount = Math.Max(progress.Maxixum, currentStep);
|
||||
|
||||
string display = currentStep.ToString() + "/" + stepCount.ToString();
|
||||
string display = currentStep.ToString() + "/" + stepCount.ToString() + " " + progress.Text;
|
||||
SizeF size = g.MeasureString(display, this._noteFont, int.MaxValue, StringFormat.GenericTypographic);
|
||||
|
||||
float width = size.Width + 16;
|
||||
@ -1437,6 +1437,7 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public int Current;
|
||||
public int Maxixum;
|
||||
public string Text;
|
||||
public Color Color;
|
||||
}
|
||||
|
||||
|
76
GUI.NET/Debugger/frmBreakpoint.Designer.cs
generated
76
GUI.NET/Debugger/frmBreakpoint.Designer.cs
generated
@ -28,7 +28,6 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkMarkOnEventViewer = new System.Windows.Forms.CheckBox();
|
||||
this.lblBreakpointType = new System.Windows.Forms.Label();
|
||||
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.chkRead = new System.Windows.Forms.CheckBox();
|
||||
@ -57,8 +56,10 @@
|
||||
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.lblCondition = new System.Windows.Forms.Label();
|
||||
this.chkMarkOnEventViewer = new System.Windows.Forms.CheckBox();
|
||||
this.chkEnabled = new System.Windows.Forms.CheckBox();
|
||||
this.baseConfigPanel.SuspendLayout();
|
||||
this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkProcessDummyReadWrites = new System.Windows.Forms.CheckBox();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.flowLayoutPanel2.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
@ -68,21 +69,19 @@
|
||||
this.tableLayoutPanel5.SuspendLayout();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
this.tableLayoutPanel6.SuspendLayout();
|
||||
this.tableLayoutPanel7.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// baseConfigPanel
|
||||
//
|
||||
this.baseConfigPanel.Controls.Add(this.chkEnabled);
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 212);
|
||||
this.baseConfigPanel.Size = new System.Drawing.Size(426, 29);
|
||||
this.baseConfigPanel.Controls.SetChildIndex(this.chkEnabled, 0);
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkMarkOnEventViewer, 0, 5);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblBreakpointType, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblBreakOn, 0, 1);
|
||||
@ -101,21 +100,10 @@
|
||||
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(426, 241);
|
||||
this.tableLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// chkMarkOnEventViewer
|
||||
//
|
||||
this.chkMarkOnEventViewer.AutoSize = true;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.chkMarkOnEventViewer, 2);
|
||||
this.chkMarkOnEventViewer.Location = new System.Drawing.Point(6, 194);
|
||||
this.chkMarkOnEventViewer.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.chkMarkOnEventViewer.Name = "chkMarkOnEventViewer";
|
||||
this.chkMarkOnEventViewer.Size = new System.Drawing.Size(131, 17);
|
||||
this.chkMarkOnEventViewer.TabIndex = 15;
|
||||
this.chkMarkOnEventViewer.Text = "Mark on Event Viewer";
|
||||
this.chkMarkOnEventViewer.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lblBreakpointType
|
||||
//
|
||||
this.lblBreakpointType.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
@ -148,6 +136,7 @@
|
||||
this.chkRead.TabIndex = 4;
|
||||
this.chkRead.Text = "Read";
|
||||
this.chkRead.UseVisualStyleBackColor = true;
|
||||
this.chkRead.CheckedChanged += new System.EventHandler(this.chkRead_CheckedChanged);
|
||||
//
|
||||
// chkWrite
|
||||
//
|
||||
@ -158,6 +147,7 @@
|
||||
this.chkWrite.TabIndex = 5;
|
||||
this.chkWrite.Text = "Write";
|
||||
this.chkWrite.UseVisualStyleBackColor = true;
|
||||
this.chkWrite.CheckedChanged += new System.EventHandler(this.chkWrite_CheckedChanged);
|
||||
//
|
||||
// chkExec
|
||||
//
|
||||
@ -461,21 +451,64 @@
|
||||
this.lblCondition.TabIndex = 7;
|
||||
this.lblCondition.Text = "Condition:";
|
||||
//
|
||||
// chkMarkOnEventViewer
|
||||
//
|
||||
this.chkMarkOnEventViewer.AutoSize = true;
|
||||
this.chkMarkOnEventViewer.Location = new System.Drawing.Point(3, 17);
|
||||
this.chkMarkOnEventViewer.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.chkMarkOnEventViewer.Name = "chkMarkOnEventViewer";
|
||||
this.chkMarkOnEventViewer.Size = new System.Drawing.Size(131, 17);
|
||||
this.chkMarkOnEventViewer.TabIndex = 15;
|
||||
this.chkMarkOnEventViewer.Text = "Mark on Event Viewer";
|
||||
this.chkMarkOnEventViewer.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkEnabled
|
||||
//
|
||||
this.chkEnabled.AutoSize = true;
|
||||
this.chkEnabled.Location = new System.Drawing.Point(6, 7);
|
||||
this.chkEnabled.Location = new System.Drawing.Point(3, 34);
|
||||
this.chkEnabled.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.chkEnabled.Name = "chkEnabled";
|
||||
this.chkEnabled.Size = new System.Drawing.Size(104, 17);
|
||||
this.chkEnabled.TabIndex = 2;
|
||||
this.chkEnabled.Text = "Break Execution";
|
||||
this.chkEnabled.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tableLayoutPanel7
|
||||
//
|
||||
this.tableLayoutPanel7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.tableLayoutPanel7.ColumnCount = 1;
|
||||
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel7.Controls.Add(this.chkProcessDummyReadWrites, 0, 1);
|
||||
this.tableLayoutPanel7.Controls.Add(this.chkEnabled, 0, 3);
|
||||
this.tableLayoutPanel7.Controls.Add(this.chkMarkOnEventViewer, 0, 2);
|
||||
this.tableLayoutPanel7.Location = new System.Drawing.Point(0, 189);
|
||||
this.tableLayoutPanel7.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel7.Name = "tableLayoutPanel7";
|
||||
this.tableLayoutPanel7.RowCount = 4;
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel7.Size = new System.Drawing.Size(243, 51);
|
||||
this.tableLayoutPanel7.TabIndex = 3;
|
||||
//
|
||||
// chkProcessDummyReadWrites
|
||||
//
|
||||
this.chkProcessDummyReadWrites.AutoSize = true;
|
||||
this.chkProcessDummyReadWrites.Location = new System.Drawing.Point(3, 0);
|
||||
this.chkProcessDummyReadWrites.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.chkProcessDummyReadWrites.Name = "chkProcessDummyReadWrites";
|
||||
this.chkProcessDummyReadWrites.Size = new System.Drawing.Size(229, 17);
|
||||
this.chkProcessDummyReadWrites.TabIndex = 16;
|
||||
this.chkProcessDummyReadWrites.Text = "Process breakpoint on dummy reads/writes";
|
||||
this.chkProcessDummyReadWrites.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// frmBreakpoint
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(426, 241);
|
||||
this.Controls.Add(this.tableLayoutPanel7);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "frmBreakpoint";
|
||||
@ -483,8 +516,7 @@
|
||||
this.Text = "Breakpoint";
|
||||
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
|
||||
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
|
||||
this.baseConfigPanel.ResumeLayout(false);
|
||||
this.baseConfigPanel.PerformLayout();
|
||||
this.Controls.SetChildIndex(this.tableLayoutPanel7, 0);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.flowLayoutPanel2.ResumeLayout(false);
|
||||
@ -501,6 +533,8 @@
|
||||
this.tableLayoutPanel4.PerformLayout();
|
||||
this.tableLayoutPanel6.ResumeLayout(false);
|
||||
this.tableLayoutPanel6.PerformLayout();
|
||||
this.tableLayoutPanel7.ResumeLayout(false);
|
||||
this.tableLayoutPanel7.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
@ -538,5 +572,7 @@
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.CheckBox chkMarkOnEventViewer;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7;
|
||||
private System.Windows.Forms.CheckBox chkProcessDummyReadWrites;
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ namespace Mesen.GUI.Debugger
|
||||
AddBinding("MemoryType", cboBreakpointType);
|
||||
AddBinding("Enabled", chkEnabled);
|
||||
AddBinding("MarkEvent", chkMarkOnEventViewer);
|
||||
AddBinding("ProcessDummyReadWrites", chkProcessDummyReadWrites);
|
||||
AddBinding("Address", txtAddress);
|
||||
AddBinding("StartAddress", txtFrom);
|
||||
AddBinding("EndAddress", txtTo);
|
||||
@ -212,18 +213,38 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
radRange.Checked = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void cboBreakpointType_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
DebugMemoryType type = cboBreakpointType.GetEnumValue<DebugMemoryType>();
|
||||
|
||||
chkExec.Visible = Breakpoint.IsTypeCpuBreakpoint(type);
|
||||
chkProcessDummyReadWrites.Visible = Breakpoint.IsTypeCpuBreakpoint(type);
|
||||
|
||||
string maxValue = (InteropEmu.DebugGetMemorySize(type) - 1).ToString("X2");
|
||||
string minValue = "".PadLeft(maxValue.Length, '0');
|
||||
|
||||
lblRange.Text = $"(range: ${minValue}-${maxValue})";
|
||||
}
|
||||
|
||||
private void UpdateDummyReadWriteCheckbox()
|
||||
{
|
||||
if(chkRead.Checked || chkWrite.Checked) {
|
||||
chkProcessDummyReadWrites.Enabled = true;
|
||||
} else {
|
||||
chkProcessDummyReadWrites.Enabled = false;
|
||||
chkProcessDummyReadWrites.Checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void chkRead_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateDummyReadWriteCheckbox();
|
||||
}
|
||||
|
||||
private void chkWrite_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateDummyReadWriteCheckbox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +504,15 @@ namespace Mesen.GUI.Debugger
|
||||
if(breakpointId >= 0 && breakpointId < breakpoints.Count) {
|
||||
Breakpoint bp = breakpoints[breakpointId];
|
||||
if(bpType != BreakpointType.Global) {
|
||||
message += ": " + ResourceHelper.GetEnumText(bpType) + " ($" + bpAddress.ToString("X4") + ")";
|
||||
string prefix = "";
|
||||
if(bpType == BreakpointType.ReadRam || bpType == BreakpointType.WriteRam) {
|
||||
InstructionProgress progress = new InstructionProgress();
|
||||
InteropEmu.DebugGetInstructionProgress(ref progress);
|
||||
if(progress.OpMemoryOperationType == InteropMemoryOperationType.DummyRead || progress.OpMemoryOperationType == InteropMemoryOperationType.DummyWrite) {
|
||||
prefix = "(Dummy) ";
|
||||
}
|
||||
}
|
||||
message += ": " + prefix + ResourceHelper.GetEnumText(bpType) + " ($" + bpAddress.ToString("X4") + ")";
|
||||
}
|
||||
if(!string.IsNullOrWhiteSpace(bp.Condition)) {
|
||||
string cond = bp.Condition.Trim();
|
||||
|
@ -1963,6 +1963,9 @@ namespace Mesen.GUI
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool MarkEvent;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool ProcessDummyReadWrites;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
|
||||
public byte[] Condition;
|
||||
}
|
||||
@ -2342,7 +2345,8 @@ namespace Mesen.GUI
|
||||
ExecOperand = 3,
|
||||
PpuRenderingRead = 4,
|
||||
DummyRead = 5,
|
||||
DmcRead = 6
|
||||
DmcRead = 6,
|
||||
DummyWrite = 7
|
||||
}
|
||||
|
||||
public enum MemoryOperationType
|
||||
|
Loading…
Reference in New Issue
Block a user