Debugger: Added CDL flags for CX4/GSU
This commit is contained in:
parent
dade91a189
commit
e9e88da0cb
14 changed files with 98 additions and 30 deletions
|
@ -1,10 +1,8 @@
|
|||
#include "stdafx.h"
|
||||
#include "CodeDataLogger.h"
|
||||
#include "MemoryManager.h"
|
||||
|
||||
CodeDataLogger::CodeDataLogger(uint32_t prgSize, MemoryManager* memoryManager)
|
||||
CodeDataLogger::CodeDataLogger(uint32_t prgSize)
|
||||
{
|
||||
_memoryManager = memoryManager;
|
||||
_prgSize = prgSize;
|
||||
_cdlData = new uint8_t[prgSize];
|
||||
Reset();
|
||||
|
@ -125,6 +123,17 @@ uint8_t CodeDataLogger::GetCpuFlags(uint32_t absoluteAddr)
|
|||
return _cdlData[absoluteAddr] & (CdlFlags::MemoryMode8 | CdlFlags::IndexMode8);
|
||||
}
|
||||
|
||||
CpuType CodeDataLogger::GetCpuType(uint32_t absoluteAddr)
|
||||
{
|
||||
if(_cdlData[absoluteAddr] & CdlFlags::Gsu) {
|
||||
return CpuType::Gsu;
|
||||
} else if(_cdlData[absoluteAddr] & CdlFlags::Cx4) {
|
||||
return CpuType::Cx4;
|
||||
}
|
||||
|
||||
return CpuType::Cpu;
|
||||
}
|
||||
|
||||
void CodeDataLogger::SetCdlData(uint8_t *cdlData, uint32_t length)
|
||||
{
|
||||
if(length <= _prgSize) {
|
||||
|
@ -132,16 +141,14 @@ void CodeDataLogger::SetCdlData(uint8_t *cdlData, uint32_t length)
|
|||
}
|
||||
}
|
||||
|
||||
void CodeDataLogger::GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t *cdlData)
|
||||
void CodeDataLogger::GetCdlData(uint32_t offset, uint32_t length, uint8_t *cdlData)
|
||||
{
|
||||
if(memoryType == SnesMemoryType::PrgRom) {
|
||||
memcpy(cdlData, _cdlData + offset, length);
|
||||
} else if(memoryType == SnesMemoryType::CpuMemory) {
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _memoryManager->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
cdlData[i] = (info.Type == SnesMemoryType::PrgRom && info.Address >= 0) ? _cdlData[info.Address] : 0;
|
||||
}
|
||||
}
|
||||
memcpy(cdlData, _cdlData + offset, length);
|
||||
}
|
||||
|
||||
uint8_t CodeDataLogger::GetFlags(uint32_t addr)
|
||||
{
|
||||
return _cdlData[addr];
|
||||
}
|
||||
|
||||
void CodeDataLogger::MarkBytesAs(uint32_t start, uint32_t end, uint8_t flags)
|
||||
|
|
|
@ -2,12 +2,9 @@
|
|||
#include "stdafx.h"
|
||||
#include "DebugTypes.h"
|
||||
|
||||
class MemoryManager;
|
||||
|
||||
class CodeDataLogger
|
||||
{
|
||||
private:
|
||||
MemoryManager *_memoryManager;
|
||||
uint8_t *_cdlData = nullptr;
|
||||
uint32_t _prgSize = 0;
|
||||
uint32_t _codeSize = 0;
|
||||
|
@ -16,7 +13,7 @@ private:
|
|||
void CalculateStats();
|
||||
|
||||
public:
|
||||
CodeDataLogger(uint32_t prgSize, MemoryManager* memoryManager);
|
||||
CodeDataLogger(uint32_t prgSize);
|
||||
~CodeDataLogger();
|
||||
|
||||
void Reset();
|
||||
|
@ -33,9 +30,11 @@ public:
|
|||
bool IsSubEntryPoint(uint32_t absoluteAddr);
|
||||
bool IsData(uint32_t absoluteAddr);
|
||||
uint8_t GetCpuFlags(uint32_t absoluteAddr);
|
||||
CpuType GetCpuType(uint32_t absoluteAddr);
|
||||
|
||||
void SetCdlData(uint8_t *cdlData, uint32_t length);
|
||||
void GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t *cdlData);
|
||||
void GetCdlData(uint32_t offset, uint32_t length, uint8_t *cdlData);
|
||||
uint8_t GetFlags(uint32_t addr);
|
||||
|
||||
void MarkBytesAs(uint32_t start, uint32_t end, uint8_t flags);
|
||||
void StripData(uint8_t* romBuffer, CdlStripOption flag);
|
||||
|
|
|
@ -88,8 +88,7 @@ void Cx4::Run()
|
|||
}
|
||||
} else {
|
||||
uint16_t opCode = _prgRam[_state.Cache.Page][_state.PC];
|
||||
uint32_t addr = (_state.Cache.Address[_state.Cache.Page] + (_state.PC * 2)) & 0xFFFFFF;
|
||||
_console->ProcessMemoryRead<CpuType::Cx4>(addr, (uint8_t)opCode, MemoryOperationType::ExecOpCode);
|
||||
_console->ProcessMemoryRead<CpuType::Cx4>(0, 0, MemoryOperationType::ExecOpCode);
|
||||
_state.PC++;
|
||||
|
||||
if(_state.PC == 0) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "Console.h"
|
||||
#include "MemoryAccessCounter.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
#include "CodeDataLogger.h"
|
||||
#include "EmuSettings.h"
|
||||
#include "Cx4.h"
|
||||
#include "MemoryMappings.h"
|
||||
|
@ -19,9 +20,12 @@
|
|||
Cx4Debugger::Cx4Debugger(Debugger* debugger)
|
||||
{
|
||||
_debugger = debugger;
|
||||
_codeDataLogger = debugger->GetCodeDataLogger().get();
|
||||
_traceLogger = debugger->GetTraceLogger().get();
|
||||
_disassembler = debugger->GetDisassembler().get();
|
||||
_memoryAccessCounter = debugger->GetMemoryAccessCounter().get();
|
||||
_cx4 = debugger->GetConsole()->GetCartridge()->GetCx4();
|
||||
_memoryManager = debugger->GetConsole()->GetMemoryManager().get();
|
||||
_settings = debugger->GetConsole()->GetSettings().get();
|
||||
|
||||
_breakpointManager.reset(new BreakpointManager(debugger, CpuType::Cx4));
|
||||
|
@ -34,10 +38,19 @@ void Cx4Debugger::Reset()
|
|||
|
||||
void Cx4Debugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType type)
|
||||
{
|
||||
Cx4State state = _cx4->GetState();
|
||||
addr = (state.Cache.Address[state.Cache.Page] + (state.PC * 2)) & 0xFFFFFF;
|
||||
|
||||
AddressInfo addressInfo = _cx4->GetMemoryMappings()->GetAbsoluteAddress(addr);
|
||||
MemoryOperationInfo operation { (uint32_t)addr, value, type };
|
||||
|
||||
if(type == MemoryOperationType::ExecOpCode) {
|
||||
AddressInfo opCodeHighAddr = _cx4->GetMemoryMappings()->GetAbsoluteAddress(addr + 1);
|
||||
if(addressInfo.Type == SnesMemoryType::PrgRom) {
|
||||
_codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Code | CdlFlags::Cx4);
|
||||
_codeDataLogger->SetFlags(addressInfo.Address + 1, CdlFlags::Code | CdlFlags::Cx4);
|
||||
}
|
||||
|
||||
if(_traceLogger->IsCpuLogged(CpuType::Cx4) || _settings->CheckDebuggerFlag(DebuggerFlags::Cx4DebuggerEnabled)) {
|
||||
_disassembler->BuildCache(addressInfo, 0, CpuType::Cx4);
|
||||
|
||||
|
@ -55,6 +68,14 @@ void Cx4Debugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
if(_step->StepCount > 0) {
|
||||
_step->StepCount--;
|
||||
}
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
|
||||
_memoryAccessCounter->ProcessMemoryExec(opCodeHighAddr, _memoryManager->GetMasterClock());
|
||||
} else {
|
||||
if(addressInfo.Type == SnesMemoryType::PrgRom) {
|
||||
_codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Data | CdlFlags::Cx4);
|
||||
}
|
||||
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
_debugger->ProcessBreakConditions(_step->StepCount == 0, GetBreakpointManager(), operation, addressInfo);
|
||||
|
@ -65,6 +86,7 @@ void Cx4Debugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
AddressInfo addressInfo = _cx4->GetMemoryMappings()->GetAbsoluteAddress(addr);
|
||||
MemoryOperationInfo operation { (uint32_t)addr, value, type };
|
||||
_debugger->ProcessBreakConditions(_step->StepCount == 0, GetBreakpointManager(), operation, addressInfo);
|
||||
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void Cx4Debugger::Run()
|
||||
|
@ -92,11 +114,6 @@ void Cx4Debugger::Step(int32_t stepCount, StepType type)
|
|||
_step.reset(new StepRequest(step));
|
||||
}
|
||||
|
||||
shared_ptr<CallstackManager> Cx4Debugger::GetCallstackManager()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BreakpointManager* Cx4Debugger::GetBreakpointManager()
|
||||
{
|
||||
return _breakpointManager.get();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
class Disassembler;
|
||||
class Debugger;
|
||||
class TraceLogger;
|
||||
class CodeDataLogger;
|
||||
class Cx4;
|
||||
class CallstackManager;
|
||||
class MemoryAccessCounter;
|
||||
|
@ -18,6 +19,9 @@ class Cx4Debugger final : public IDebugger
|
|||
Debugger* _debugger;
|
||||
Disassembler* _disassembler;
|
||||
TraceLogger* _traceLogger;
|
||||
CodeDataLogger* _codeDataLogger;
|
||||
MemoryAccessCounter* _memoryAccessCounter;
|
||||
MemoryManager* _memoryManager;
|
||||
Cx4* _cx4;
|
||||
EmuSettings* _settings;
|
||||
|
||||
|
@ -35,6 +39,5 @@ public:
|
|||
void ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType type);
|
||||
void Run();
|
||||
void Step(int32_t stepCount, StepType type);
|
||||
shared_ptr<CallstackManager> GetCallstackManager();
|
||||
BreakpointManager* GetBreakpointManager();
|
||||
};
|
|
@ -102,6 +102,9 @@ namespace CdlFlags
|
|||
|
||||
IndexMode8 = 0x10,
|
||||
MemoryMode8 = 0x20,
|
||||
|
||||
Gsu = 0x40,
|
||||
Cx4 = 0x80
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ Debugger::Debugger(shared_ptr<Console> console)
|
|||
_watchExpEval[(int)CpuType::NecDsp].reset(new ExpressionEvaluator(this, CpuType::NecDsp));
|
||||
_watchExpEval[(int)CpuType::Cx4].reset(new ExpressionEvaluator(this, CpuType::Cx4));
|
||||
|
||||
_codeDataLogger.reset(new CodeDataLogger(_cart->DebugGetPrgRomSize(), _memoryManager.get()));
|
||||
_codeDataLogger.reset(new CodeDataLogger(_cart->DebugGetPrgRomSize()));
|
||||
_memoryDumper.reset(new MemoryDumper(this));
|
||||
_disassembler.reset(new Disassembler(console, _codeDataLogger, this));
|
||||
_traceLogger.reset(new TraceLogger(this, _console));
|
||||
|
@ -534,7 +534,27 @@ void Debugger::RefreshCodeCache()
|
|||
for(uint32_t i = 0; i < prgRomSize; i++) {
|
||||
if(_codeDataLogger->IsCode(i)) {
|
||||
addrInfo.Address = (int32_t)i;
|
||||
i += _disassembler->BuildCache(addrInfo, _codeDataLogger->GetCpuFlags(i), CpuType::Cpu) - 1;
|
||||
i += _disassembler->BuildCache(addrInfo, _codeDataLogger->GetCpuFlags(i), _codeDataLogger->GetCpuType(i)) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t* cdlData)
|
||||
{
|
||||
if(memoryType == SnesMemoryType::PrgRom) {
|
||||
_codeDataLogger->GetCdlData(offset, length, cdlData);
|
||||
} else {
|
||||
MemoryMappings* mappings = nullptr;
|
||||
switch(memoryType) {
|
||||
case SnesMemoryType::CpuMemory: mappings = _memoryManager->GetMemoryMappings(); break;
|
||||
case SnesMemoryType::GsuMemory: mappings = _cart->GetGsu()->GetMemoryMappings(); break;
|
||||
case SnesMemoryType::Cx4Memory: mappings = _cart->GetCx4()->GetMemoryMappings(); break;
|
||||
default: throw std::runtime_error("GetCdlData - Unsupported memory type");
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = mappings->GetAbsoluteAddress(offset + i);
|
||||
cdlData[i] = info.Type == SnesMemoryType::PrgRom ? _codeDataLogger->GetFlags(info.Address) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ public:
|
|||
AddressInfo GetAbsoluteAddress(AddressInfo relAddress);
|
||||
AddressInfo GetRelativeAddress(AddressInfo absAddress, CpuType cpuType);
|
||||
|
||||
void GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t* cdlData);
|
||||
void SetCdlData(uint8_t * cdlData, uint32_t length);
|
||||
void MarkBytesAs(uint32_t start, uint32_t end, uint8_t flags);
|
||||
void RefreshCodeCache();
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
#include "Console.h"
|
||||
#include "EmuSettings.h"
|
||||
#include "MemoryAccessCounter.h"
|
||||
#include "CodeDataLogger.h"
|
||||
|
||||
GsuDebugger::GsuDebugger(Debugger* debugger)
|
||||
{
|
||||
_debugger = debugger;
|
||||
_codeDataLogger = debugger->GetCodeDataLogger().get();
|
||||
_traceLogger = debugger->GetTraceLogger().get();
|
||||
_disassembler = debugger->GetDisassembler().get();
|
||||
_memoryAccessCounter = debugger->GetMemoryAccessCounter().get();
|
||||
|
@ -44,6 +46,10 @@ void GsuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
MemoryOperationInfo operation { addr, value, type };
|
||||
|
||||
if(type == MemoryOperationType::ExecOpCode) {
|
||||
if(addressInfo.Type == SnesMemoryType::PrgRom) {
|
||||
_codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Code | CdlFlags::Gsu);
|
||||
}
|
||||
|
||||
if(_traceLogger->IsCpuLogged(CpuType::Gsu) || _settings->CheckDebuggerFlag(DebuggerFlags::GsuDebuggerEnabled)) {
|
||||
GsuState gsuState = _gsu->GetState();
|
||||
_disassembler->BuildCache(addressInfo, gsuState.SFR.GetFlagsHigh() & 0x13, CpuType::Gsu);
|
||||
|
@ -66,6 +72,9 @@ void GsuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
}
|
||||
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
|
||||
} else {
|
||||
if(addressInfo.Type == SnesMemoryType::PrgRom) {
|
||||
_codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Data | CdlFlags::Gsu);
|
||||
}
|
||||
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
|
@ -79,7 +88,6 @@ void GsuDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
_debugger->ProcessBreakConditions(false, GetBreakpointManager(), operation, addressInfo);
|
||||
|
||||
_disassembler->InvalidateCache(addressInfo, CpuType::Gsu);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
class Disassembler;
|
||||
class Debugger;
|
||||
class TraceLogger;
|
||||
class CodeDataLogger;
|
||||
class Gsu;
|
||||
class MemoryAccessCounter;
|
||||
class MemoryManager;
|
||||
|
@ -17,6 +18,7 @@ class GsuDebugger final : public IDebugger
|
|||
Debugger* _debugger;
|
||||
Disassembler* _disassembler;
|
||||
TraceLogger* _traceLogger;
|
||||
CodeDataLogger* _codeDataLogger;
|
||||
MemoryAccessCounter* _memoryAccessCounter;
|
||||
MemoryManager* _memoryManager;
|
||||
Gsu* _gsu;
|
||||
|
|
|
@ -82,7 +82,7 @@ extern "C"
|
|||
DllExport void __stdcall ResetMemoryAccessCounts() { GetDebugger()->GetMemoryAccessCounter()->ResetCounts(); }
|
||||
DllExport void __stdcall GetMemoryAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, AddressCounters* counts) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(offset, length, memoryType, counts); }
|
||||
|
||||
DllExport void __stdcall GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t* cdlData) { GetDebugger()->GetCodeDataLogger()->GetCdlData(offset, length, memoryType, cdlData); }
|
||||
DllExport void __stdcall GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t* cdlData) { GetDebugger()->GetCdlData(offset, length, memoryType, cdlData); }
|
||||
DllExport void __stdcall SetCdlData(uint8_t* cdlData, uint32_t length) { GetDebugger()->SetCdlData(cdlData, length); }
|
||||
DllExport void __stdcall MarkBytesAs(uint32_t start, uint32_t end, uint8_t flags) { GetDebugger()->MarkBytesAs(start, end, flags); }
|
||||
|
||||
|
|
|
@ -347,6 +347,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
DebugApi.RefreshDisassembly(CpuType.Sa1);
|
||||
DebugApi.RefreshDisassembly(CpuType.Gsu);
|
||||
DebugApi.RefreshDisassembly(CpuType.NecDsp);
|
||||
DebugApi.RefreshDisassembly(CpuType.Cx4);
|
||||
}
|
||||
|
||||
_manager.RefreshCode(_inSourceView ? _symbolProvider : null, _inSourceView ? cboSourceFile.SelectedItem as SourceFileInfo : null);
|
||||
|
|
|
@ -73,6 +73,9 @@ namespace Mesen.GUI.Debugger
|
|||
if(_highlightDataBytes || _highlightCodeBytes) {
|
||||
switch(_memoryType) {
|
||||
case SnesMemoryType.CpuMemory:
|
||||
case SnesMemoryType.Sa1Memory:
|
||||
case SnesMemoryType.Cx4Memory:
|
||||
case SnesMemoryType.GsuMemory:
|
||||
case SnesMemoryType.PrgRom:
|
||||
_cdlData = DebugApi.GetCdlData((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType);
|
||||
break;
|
||||
|
|
|
@ -48,6 +48,8 @@ namespace Mesen.GUI.Debugger
|
|||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
|
||||
bool isPaused = EmuApi.IsPaused();
|
||||
|
||||
mnuUseAltSpcOpNames.Visible = false;
|
||||
|
||||
switch(_cpuType) {
|
||||
|
@ -174,7 +176,10 @@ namespace Mesen.GUI.Debugger
|
|||
toolTip.SetToolTip(picWatchHelp, ctrlWatch.GetTooltipText());
|
||||
|
||||
BreakpointManager.AddCpuType(_cpuType);
|
||||
DebugApi.Step(_cpuType, 10000, StepType.Step);
|
||||
|
||||
if(!isPaused) {
|
||||
DebugApi.Step(_cpuType, 10000, StepType.Step);
|
||||
}
|
||||
|
||||
base.OnLoad(e);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue