Debugger: Added CDL flags for CX4/GSU

This commit is contained in:
Sour 2020-02-25 23:56:55 -05:00
parent dade91a189
commit e9e88da0cb
14 changed files with 98 additions and 30 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -102,6 +102,9 @@ namespace CdlFlags
IndexMode8 = 0x10,
MemoryMode8 = 0x20,
Gsu = 0x40,
Cx4 = 0x80
};
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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