Debugger: Allow editing memory values for all memory types
This commit is contained in:
parent
62a5c7b437
commit
ee6585aa5c
12 changed files with 97 additions and 24 deletions
|
@ -794,9 +794,10 @@ uint8_t* BaseMapper::GetWorkRam()
|
|||
|
||||
uint32_t BaseMapper::CopyMemory(DebugMemoryType type, uint8_t* buffer)
|
||||
{
|
||||
uint32_t chrRomSize = _onlyChrRam ? 0 : _chrRomSize;
|
||||
switch(type) {
|
||||
case DebugMemoryType::ChrRam: memcpy(buffer, _chrRam, _chrRamSize); return _chrRamSize;
|
||||
case DebugMemoryType::ChrRom: memcpy(buffer, _chrRom, _chrRomSize); return _chrRomSize;
|
||||
case DebugMemoryType::ChrRom: memcpy(buffer, _chrRom, chrRomSize); return chrRomSize;
|
||||
case DebugMemoryType::PrgRom: memcpy(buffer, _prgRom, _prgSize); return _prgSize;
|
||||
case DebugMemoryType::SaveRam: memcpy(buffer, _saveRam, _saveRamSize); return _saveRamSize;
|
||||
case DebugMemoryType::WorkRam: memcpy(buffer, _workRam, _workRamSize); return _workRamSize;
|
||||
|
@ -818,12 +819,23 @@ uint32_t BaseMapper::GetMemorySize(DebugMemoryType type)
|
|||
{
|
||||
switch(type) {
|
||||
default: return 0;
|
||||
case DebugMemoryType::ChrRom: return _chrRomSize;
|
||||
case DebugMemoryType::ChrRom: return _onlyChrRam ? 0 : _chrRomSize;
|
||||
case DebugMemoryType::ChrRam: return _chrRamSize;
|
||||
case DebugMemoryType::SaveRam: return _saveRamSize;
|
||||
case DebugMemoryType::PrgRom: return _prgSize;
|
||||
case DebugMemoryType::WorkRam: return _workRamSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseMapper::SetMemoryValue(DebugMemoryType memoryType, uint32_t address, uint8_t value)
|
||||
{
|
||||
switch(memoryType) {
|
||||
case DebugMemoryType::ChrRom: _chrRom[address] = value; break;
|
||||
case DebugMemoryType::ChrRam: _chrRam[address] = value; break;
|
||||
case DebugMemoryType::SaveRam: _saveRam[address] = value; break;
|
||||
case DebugMemoryType::PrgRom: _prgRom[address] = value; break;
|
||||
case DebugMemoryType::WorkRam: _workRam[address] = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t BaseMapper::ToAbsoluteAddress(uint16_t addr)
|
||||
|
|
|
@ -226,6 +226,7 @@ public:
|
|||
uint8_t* GetPrgRom();
|
||||
uint8_t* GetWorkRam();
|
||||
|
||||
void SetMemoryValue(DebugMemoryType memoryType, uint32_t address, uint8_t value);
|
||||
uint32_t GetMemorySize(DebugMemoryType type);
|
||||
|
||||
uint32_t CopyMemory(DebugMemoryType type, uint8_t* buffer);
|
||||
|
|
|
@ -30,7 +30,7 @@ Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<
|
|||
_labelManager.reset(new LabelManager(_mapper));
|
||||
_disassembler.reset(new Disassembler(memoryManager->GetInternalRAM(), mapper->GetPrgRom(), mapper->GetMemorySize(DebugMemoryType::PrgRom), mapper->GetWorkRam(), mapper->GetMemorySize(DebugMemoryType::WorkRam), this));
|
||||
_codeDataLogger.reset(new CodeDataLogger(mapper->GetMemorySize(DebugMemoryType::PrgRom), mapper->GetMemorySize(DebugMemoryType::ChrRom)));
|
||||
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, _mapper, _codeDataLogger));
|
||||
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, _mapper, _codeDataLogger, this));
|
||||
_memoryAccessCounter.reset(new MemoryAccessCounter(this));
|
||||
_profiler.reset(new Profiler(this));
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "stdafx.h"
|
||||
#include "Debugger.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "PPU.h"
|
||||
#include "CodeDataLogger.h"
|
||||
|
@ -6,8 +7,9 @@
|
|||
#include "MemoryDumper.h"
|
||||
#include "VideoDecoder.h"
|
||||
|
||||
MemoryDumper::MemoryDumper(shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper, shared_ptr<CodeDataLogger> codeDataLogger)
|
||||
MemoryDumper::MemoryDumper(shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper, shared_ptr<CodeDataLogger> codeDataLogger, Debugger* debugger)
|
||||
{
|
||||
_debugger = debugger;
|
||||
_ppu = ppu;
|
||||
_memoryManager = memoryManager;
|
||||
_mapper = mapper;
|
||||
|
@ -40,6 +42,40 @@ void MemoryDumper::SetMemoryState(DebugMemoryType type, uint8_t *buffer)
|
|||
}
|
||||
}
|
||||
|
||||
void MemoryDumper::SetMemoryValue(DebugMemoryType memoryType, uint32_t address, uint8_t value)
|
||||
{
|
||||
switch(memoryType) {
|
||||
case DebugMemoryType::CpuMemory:
|
||||
AddressTypeInfo info;
|
||||
_debugger->GetAbsoluteAddressAndType(address, &info);
|
||||
if(info.Address >= 0) {
|
||||
switch(info.Type) {
|
||||
case AddressType::InternalRam: SetMemoryValue(DebugMemoryType::InternalRam, info.Address, value); break;
|
||||
case AddressType::PrgRom: SetMemoryValue(DebugMemoryType::PrgRom, info.Address, value); break;
|
||||
case AddressType::WorkRam: SetMemoryValue(DebugMemoryType::WorkRam, info.Address, value); break;
|
||||
case AddressType::SaveRam: SetMemoryValue(DebugMemoryType::SaveRam, info.Address, value); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DebugMemoryType::InternalRam: _memoryManager->DebugWrite(address, value); break;
|
||||
|
||||
case DebugMemoryType::PaletteMemory: _ppu->WritePaletteRAM(address, value); break;
|
||||
case DebugMemoryType::SpriteMemory: _ppu->GetSpriteRam()[address] = value; break;
|
||||
case DebugMemoryType::SecondarySpriteMemory: _ppu->GetSecondarySpriteRam()[address] = value; break;
|
||||
|
||||
case DebugMemoryType::PpuMemory: _mapper->WriteVRAM(address, value); break;
|
||||
|
||||
case DebugMemoryType::ChrRam:
|
||||
case DebugMemoryType::WorkRam:
|
||||
case DebugMemoryType::SaveRam:
|
||||
case DebugMemoryType::PrgRom:
|
||||
case DebugMemoryType::ChrRom:
|
||||
_mapper->SetMemoryValue(memoryType, address, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t MemoryDumper::GetMemoryState(DebugMemoryType type, uint8_t *buffer)
|
||||
{
|
||||
switch(type) {
|
||||
|
|
|
@ -6,17 +6,19 @@ class PPU;
|
|||
class MemoryManager;
|
||||
class BaseMapper;
|
||||
class CodeDataLogger;
|
||||
class Debugger;
|
||||
|
||||
class MemoryDumper
|
||||
{
|
||||
private:
|
||||
Debugger* _debugger;
|
||||
shared_ptr<PPU> _ppu;
|
||||
shared_ptr<MemoryManager> _memoryManager;
|
||||
shared_ptr<BaseMapper> _mapper;
|
||||
shared_ptr<CodeDataLogger> _codeDataLogger;
|
||||
|
||||
public:
|
||||
MemoryDumper(shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper, shared_ptr<CodeDataLogger> codeDataLogger);
|
||||
MemoryDumper(shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper, shared_ptr<CodeDataLogger> codeDataLogger, Debugger *debugger);
|
||||
|
||||
uint32_t GetMemoryState(DebugMemoryType type, uint8_t *buffer);
|
||||
void GetNametable(int nametableIndex, uint32_t* frameBuffer, uint8_t* tileData, uint8_t* paletteData);
|
||||
|
@ -24,5 +26,6 @@ public:
|
|||
void GetSprites(uint32_t* frameBuffer);
|
||||
void GetPalette(uint32_t* frameBuffer);
|
||||
|
||||
void SetMemoryValue(DebugMemoryType memoryType, uint32_t address, uint8_t value);
|
||||
void SetMemoryState(DebugMemoryType type, uint8_t *buffer);
|
||||
};
|
|
@ -42,8 +42,8 @@
|
|||
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.chkTextSearch = new System.Windows.Forms.CheckBox();
|
||||
this.chkMatchCase = new System.Windows.Forms.CheckBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.ctrlHexBox = new Be.Windows.Forms.HexBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.flowLayoutPanel1.SuspendLayout();
|
||||
this.panelSearch.SuspendLayout();
|
||||
|
@ -241,7 +241,7 @@
|
|||
this.chkMatchCase.Text = "Match Case";
|
||||
this.chkMatchCase.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ctrlDataViewer
|
||||
// ctrlHexBox
|
||||
//
|
||||
this.ctrlHexBox.ColumnInfoVisible = true;
|
||||
this.ctrlHexBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
|
@ -250,7 +250,6 @@
|
|||
this.ctrlHexBox.LineInfoVisible = true;
|
||||
this.ctrlHexBox.Location = new System.Drawing.Point(3, 30);
|
||||
this.ctrlHexBox.Name = "ctrlHexBox";
|
||||
this.ctrlHexBox.ReadOnly = true;
|
||||
this.ctrlHexBox.SelectionBackColor = System.Drawing.Color.RoyalBlue;
|
||||
this.ctrlHexBox.ShadowSelectionColor = System.Drawing.Color.Orange;
|
||||
this.ctrlHexBox.Size = new System.Drawing.Size(537, 248);
|
||||
|
|
|
@ -10,6 +10,7 @@ using System.Windows.Forms;
|
|||
using Mesen.GUI.Config;
|
||||
using Be.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using static Be.Windows.Forms.DynamicByteProvider;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
|
@ -57,6 +58,9 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
if(changed) {
|
||||
_byteProvider = new StaticByteProvider(data);
|
||||
_byteProvider.ByteChanged += (int byteIndex, byte newValue, byte oldValue) => {
|
||||
ByteChanged?.Invoke(byteIndex, newValue, oldValue);
|
||||
};
|
||||
this.ctrlHexBox.ByteProvider = _byteProvider;
|
||||
if(clearHistory) {
|
||||
this.ctrlHexBox.ClearHistory();
|
||||
|
@ -270,16 +274,18 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
}
|
||||
}
|
||||
|
||||
public event EventHandler RequiredWidthChanged
|
||||
private void chkTextSearch_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.UpdateSearchOptions();
|
||||
}
|
||||
|
||||
public event EventHandler RequiredWidthChanged
|
||||
{
|
||||
add { this.ctrlHexBox.RequiredWidthChanged += value; }
|
||||
remove { this.ctrlHexBox.RequiredWidthChanged -= value; }
|
||||
}
|
||||
|
||||
private void chkTextSearch_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.UpdateSearchOptions();
|
||||
}
|
||||
public event ByteChangedHandler ByteChanged;
|
||||
|
||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public IByteCharConverter ByteCharConverter
|
||||
|
@ -294,5 +300,12 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
get { return this.ctrlHexBox.StringViewVisible; }
|
||||
set { this.ctrlHexBox.StringViewVisible = value; }
|
||||
}
|
||||
|
||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public bool ReadOnly
|
||||
{
|
||||
get { return this.ctrlHexBox.ReadOnly; }
|
||||
set { this.ctrlHexBox.ReadOnly = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,8 @@ namespace Be.Windows.Forms
|
|||
/// </summary>
|
||||
public event EventHandler LengthChanged;
|
||||
|
||||
public event EventHandler ByteChanged;
|
||||
public delegate void ByteChangedHandler(int byteIndex, byte newValue, byte oldValue);
|
||||
public event ByteChangedHandler ByteChanged;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -108,8 +109,8 @@ namespace Be.Windows.Forms
|
|||
public void WriteByte(long index, byte value)
|
||||
{
|
||||
if(_bytes[(int)index] != value) {
|
||||
ByteChanged?.Invoke((int)index, value, _bytes[(int)index]);
|
||||
_bytes[(int)index] = value;
|
||||
ByteChanged?.Invoke((int)index, EventArgs.Empty);
|
||||
OnChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
|
17
GUI.NET/Debugger/frmMemoryViewer.Designer.cs
generated
17
GUI.NET/Debugger/frmMemoryViewer.Designer.cs
generated
|
@ -41,8 +41,8 @@
|
|||
this.mnuImport = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuExport = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuResetTblMappings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuLoadTblFile = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuResetTblMappings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuView = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -86,6 +86,7 @@
|
|||
this.ctrlHexViewer.Size = new System.Drawing.Size(665, 346);
|
||||
this.ctrlHexViewer.TabIndex = 0;
|
||||
this.ctrlHexViewer.RequiredWidthChanged += new System.EventHandler(this.ctrlHexViewer_RequiredWidthChanged);
|
||||
this.ctrlHexViewer.ByteChanged += new Be.Windows.Forms.DynamicByteProvider.ByteChangedHandler(this.ctrlHexViewer_ByteChanged);
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
|
@ -175,13 +176,6 @@
|
|||
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
|
||||
this.toolStripMenuItem3.Size = new System.Drawing.Size(178, 6);
|
||||
//
|
||||
// mnuResetTblMappings
|
||||
//
|
||||
this.mnuResetTblMappings.Name = "mnuResetTblMappings";
|
||||
this.mnuResetTblMappings.Size = new System.Drawing.Size(181, 22);
|
||||
this.mnuResetTblMappings.Text = "Reset TBL mappings";
|
||||
this.mnuResetTblMappings.Click += new System.EventHandler(this.mnuResetTblMappings_Click);
|
||||
//
|
||||
// mnuLoadTblFile
|
||||
//
|
||||
this.mnuLoadTblFile.Name = "mnuLoadTblFile";
|
||||
|
@ -189,6 +183,13 @@
|
|||
this.mnuLoadTblFile.Text = "Load TBL file";
|
||||
this.mnuLoadTblFile.Click += new System.EventHandler(this.mnuLoadTblFile_Click);
|
||||
//
|
||||
// mnuResetTblMappings
|
||||
//
|
||||
this.mnuResetTblMappings.Name = "mnuResetTblMappings";
|
||||
this.mnuResetTblMappings.Size = new System.Drawing.Size(181, 22);
|
||||
this.mnuResetTblMappings.Text = "Reset TBL mappings";
|
||||
this.mnuResetTblMappings.Click += new System.EventHandler(this.mnuResetTblMappings_Click);
|
||||
//
|
||||
// toolStripMenuItem4
|
||||
//
|
||||
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
|
||||
|
|
|
@ -170,6 +170,11 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
}
|
||||
|
||||
private void ctrlHexViewer_ByteChanged(int byteIndex, byte newValue, byte oldValue)
|
||||
{
|
||||
InteropEmu.DebugSetMemoryValue(_memoryType, (UInt32)byteIndex, newValue);
|
||||
}
|
||||
|
||||
private void mnuImport_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog();
|
||||
|
|
|
@ -187,6 +187,7 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] public static extern Int32 DebugGetRelativeAddress(UInt32 absoluteAddr, AddressType type);
|
||||
[DllImport(DLLPath)] public static extern Int32 DebugGetAbsoluteAddress(UInt32 relativeAddr);
|
||||
[DllImport(DLLPath)] public static extern Int32 DebugGetMemorySize(DebugMemoryType type);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetMemoryValue(DebugMemoryType type, UInt32 address, byte value);
|
||||
[DllImport(DLLPath)] public static extern void DebugGetAbsoluteAddressAndType(UInt32 relativeAddr, ref AddressTypeInfo addressTypeInfo);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetPpuViewerScanlineCycle(Int32 scanline, Int32 cycle);
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ extern "C"
|
|||
DllExport void __stdcall DebugStartTraceLogger(TraceLoggerOptions options) { GetDebugger()->StartTraceLogger(options); }
|
||||
DllExport void __stdcall DebugStopTraceLogger() { GetDebugger()->StopTraceLogger(); }
|
||||
|
||||
DllExport void __stdcall DebugSetMemoryValue(DebugMemoryType type, uint32_t address, uint8_t value) { return GetDebugger()->GetMemoryDumper()->SetMemoryValue(type, address, value); }
|
||||
DllExport int32_t __stdcall DebugGetMemorySize(DebugMemoryType type) { return GetDebugger()->GetMemorySize(type); }
|
||||
DllExport void __stdcall DebugGetMemoryAccessCounts(AddressType memoryType, MemoryOperationType operationType, uint32_t* counts, bool forUninitReads) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(memoryType, operationType, counts, forUninitReads); }
|
||||
DllExport void __stdcall DebugResetMemoryAccessCounts() { GetDebugger()->GetMemoryAccessCounter()->ResetCounts(); }
|
||||
|
|
Loading…
Add table
Reference in a new issue