Debugger: Allow editing memory values for all memory types

This commit is contained in:
Souryo 2017-02-26 20:47:39 -05:00
parent 62a5c7b437
commit ee6585aa5c
12 changed files with 97 additions and 24 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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