From 6de42fb21014ac18ff2a94fc74d7f10994b3f14c Mon Sep 17 00:00:00 2001 From: Sour Date: Sun, 20 Feb 2022 18:22:33 -0500 Subject: [PATCH] Debugger: CX4 debugger refactoring/improvements --- Core/Debugger/Debugger.cpp | 4 +-- Core/Debugger/Disassembler.cpp | 17 +++++++++- Core/Debugger/DisassemblyInfo.cpp | 4 +-- Core/SNES/Coprocessors/CX4/Cx4.cpp | 13 ++------ Core/SNES/Coprocessors/CX4/Cx4.h | 2 -- Core/SNES/Debugger/Cx4Debugger.cpp | 50 ++++++++++++++++++------------ Core/SNES/Debugger/Cx4Debugger.h | 1 + Core/SNES/Debugger/Cx4DisUtils.cpp | 29 +++++++++++++++++ Core/SNES/Debugger/Cx4DisUtils.h | 3 ++ 9 files changed, 85 insertions(+), 38 deletions(-) diff --git a/Core/Debugger/Debugger.cpp b/Core/Debugger/Debugger.cpp index d625f0e8..4b7b271d 100644 --- a/Core/Debugger/Debugger.cpp +++ b/Core/Debugger/Debugger.cpp @@ -147,8 +147,8 @@ void Debugger::ProcessInstruction() case CpuType::NecDsp: GetDebugger()->ProcessInstruction(); break; case CpuType::Sa1: GetDebugger()->ProcessInstruction(); break; case CpuType::Gsu: GetDebugger()->ProcessInstruction(); break; - /*case CpuType::Cx4: GetDebugger()->ProcessInstruction(); break; - case CpuType::Gameboy: GetDebugger()->ProcessInstruction(); break;*/ + case CpuType::Cx4: GetDebugger()->ProcessInstruction(); break; + //case CpuType::Gameboy: GetDebugger()->ProcessInstruction(); break; case CpuType::Nes: GetDebugger()->ProcessInstruction(); break; } } diff --git a/Core/Debugger/Disassembler.cpp b/Core/Debugger/Disassembler.cpp index 5b2c5d34..d8c24231 100644 --- a/Core/Debugger/Disassembler.cpp +++ b/Core/Debugger/Disassembler.cpp @@ -11,6 +11,7 @@ #include "SNES/SnesCpuTypes.h" #include "SNES/SpcTypes.h" #include "SNES/Coprocessors/GSU/GsuTypes.h" +#include "SNES/Coprocessors/CX4/Cx4Types.h" #include "Gameboy/GbTypes.h" #include "NES/NesTypes.h" #include "Shared/EmuSettings.h" @@ -402,7 +403,6 @@ CodeLineData Disassembler::GetLineData(DisassemblyResult& row, CpuType type, Mem } case CpuType::NecDsp: - case CpuType::Cx4: if(!disInfo.IsInitialized()) { disInfo = DisassemblyInfo(row.Address.Address, 0, type, row.Address.Type, _memoryDumper); } else { @@ -414,6 +414,21 @@ CodeLineData Disassembler::GetLineData(DisassemblyResult& row, CpuType type, Mem data.ValueSize = 0; break; + case CpuType::Cx4: + { + Cx4State state = (Cx4State&)_debugger->GetCpuStateRef(lineCpuType); + if(!disInfo.IsInitialized()) { + disInfo = DisassemblyInfo(row.Address.Address, 0, type, row.Address.Type, _memoryDumper); + } else { + data.Flags |= LineFlags::VerifiedCode; + } + + data.OpSize = disInfo.GetOpSize(); + data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType); + data.ValueSize = 0; + break; + } + case CpuType::Gameboy: { GbCpuState state = (GbCpuState&)_debugger->GetCpuStateRef(lineCpuType); diff --git a/Core/Debugger/DisassemblyInfo.cpp b/Core/Debugger/DisassemblyInfo.cpp index 416bd419..a73f5a06 100644 --- a/Core/Debugger/DisassemblyInfo.cpp +++ b/Core/Debugger/DisassemblyInfo.cpp @@ -86,8 +86,8 @@ int32_t DisassemblyInfo::GetEffectiveAddress(Debugger *debugger, void *cpuState, case CpuType::Spc: return SpcDisUtils::GetEffectiveAddress(*this, (SnesConsole*)debugger->GetConsole(), *(SpcState*)cpuState); case CpuType::Gsu: return GsuDisUtils::GetEffectiveAddress(*this, (SnesConsole*)debugger->GetConsole(), *(GsuState*)cpuState); - - case CpuType::Cx4: + case CpuType::Cx4: return Cx4DisUtils::GetEffectiveAddress(*this, *(Cx4State*)cpuState, debugger->GetMemoryDumper()); + case CpuType::NecDsp: return -1; diff --git a/Core/SNES/Coprocessors/CX4/Cx4.cpp b/Core/SNES/Coprocessors/CX4/Cx4.cpp index aff8f872..44692d7b 100644 --- a/Core/SNES/Coprocessors/CX4/Cx4.cpp +++ b/Core/SNES/Coprocessors/CX4/Cx4.cpp @@ -91,8 +91,9 @@ void Cx4::Run() Stop(); } } else { + _emu->ProcessInstruction(); + uint16_t opCode = _prgRam[_state.Cache.Page][_state.PC]; - _emu->ProcessMemoryRead(0, 0, MemoryOperationType::ExecOpCode); _state.PC++; if(_state.PC == 0) { @@ -469,16 +470,6 @@ MemoryMappings* Cx4::GetMemoryMappings() return &_mappings; } -uint8_t* Cx4::DebugGetDataRam() -{ - return _dataRam; -} - -uint32_t Cx4::DebugGetDataRamSize() -{ - return Cx4::DataRamSize; -} - Cx4State& Cx4::GetState() { return _state; diff --git a/Core/SNES/Coprocessors/CX4/Cx4.h b/Core/SNES/Coprocessors/CX4/Cx4.h index ed9168d3..8ee78da5 100644 --- a/Core/SNES/Coprocessors/CX4/Cx4.h +++ b/Core/SNES/Coprocessors/CX4/Cx4.h @@ -128,7 +128,5 @@ public: AddressInfo GetAbsoluteAddress(uint32_t address) override; MemoryMappings* GetMemoryMappings(); - uint8_t* DebugGetDataRam(); - uint32_t DebugGetDataRamSize(); Cx4State& GetState(); }; \ No newline at end of file diff --git a/Core/SNES/Debugger/Cx4Debugger.cpp b/Core/SNES/Debugger/Cx4Debugger.cpp index 86b69518..0a218ce9 100644 --- a/Core/SNES/Debugger/Cx4Debugger.cpp +++ b/Core/SNES/Debugger/Cx4Debugger.cpp @@ -40,6 +40,34 @@ void Cx4Debugger::Reset() { } +void Cx4Debugger::ProcessInstruction() +{ + Cx4State& state = _cx4->GetState(); + uint32_t addr = (state.Cache.Address[state.Cache.Page] + (state.PC * 2)) & 0xFFFFFF; + uint16_t value = _cx4->GetMemoryMappings()->PeekWord(addr); + AddressInfo addressInfo = _cx4->GetMemoryMappings()->GetAbsoluteAddress(addr); + MemoryOperationInfo operation(addr, value, MemoryOperationType::ExecOpCode, MemoryType::Cx4Memory); + + if(addressInfo.Type == MemoryType::SnesPrgRom) { + _codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Code | CdlFlags::Cx4); + _codeDataLogger->SetFlags(addressInfo.Address + 1, CdlFlags::Code | CdlFlags::Cx4); + } + + if(_traceLogger->IsEnabled() || _settings->CheckDebuggerFlag(DebuggerFlags::Cx4DebuggerEnabled)) { + _disassembler->BuildCache(addressInfo, 0, CpuType::Cx4); + + if(_traceLogger->IsEnabled()) { + DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, 0, CpuType::Cx4); + _traceLogger->Log(state, disInfo, operation); + } + } + + _prevProgramCounter = addr; + + _step->ProcessCpuExec(); + _debugger->ProcessBreakConditions(CpuType::Cx4, *_step.get(), _breakpointManager.get(), operation, addressInfo); +} + void Cx4Debugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType type) { Cx4State& state = _cx4->GetState(); @@ -50,24 +78,6 @@ void Cx4Debugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType if(type == MemoryOperationType::ExecOpCode) { AddressInfo opCodeHighAddr = _cx4->GetMemoryMappings()->GetAbsoluteAddress(addr + 1); - if(addressInfo.Type == MemoryType::SnesPrgRom) { - _codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Code | CdlFlags::Cx4); - _codeDataLogger->SetFlags(addressInfo.Address + 1, CdlFlags::Code | CdlFlags::Cx4); - } - - if(_traceLogger->IsEnabled() || _settings->CheckDebuggerFlag(DebuggerFlags::Cx4DebuggerEnabled)) { - _disassembler->BuildCache(addressInfo, 0, CpuType::Cx4); - - if(_traceLogger->IsEnabled()) { - DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, 0, CpuType::Cx4); - _traceLogger->Log(state, disInfo, operation); - } - } - - _prevProgramCounter = addr; - - _step->ProcessCpuExec(); - _memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock()); _memoryAccessCounter->ProcessMemoryExec(opCodeHighAddr, _memoryManager->GetMasterClock()); } else { @@ -78,9 +88,9 @@ void Cx4Debugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType _traceLogger->LogNonExec(operation); } _memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock()); - } - _debugger->ProcessBreakConditions(CpuType::Cx4, *_step.get(), _breakpointManager.get(), operation, addressInfo); + _debugger->ProcessBreakConditions(CpuType::Cx4, *_step.get(), _breakpointManager.get(), operation, addressInfo); + } } void Cx4Debugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType type) diff --git a/Core/SNES/Debugger/Cx4Debugger.h b/Core/SNES/Debugger/Cx4Debugger.h index 43044ad3..f69eafec 100644 --- a/Core/SNES/Debugger/Cx4Debugger.h +++ b/Core/SNES/Debugger/Cx4Debugger.h @@ -37,6 +37,7 @@ public: void Reset() override; + void ProcessInstruction(); void ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType type); void ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType type); diff --git a/Core/SNES/Debugger/Cx4DisUtils.cpp b/Core/SNES/Debugger/Cx4DisUtils.cpp index fc1a5ba4..8af2602c 100644 --- a/Core/SNES/Debugger/Cx4DisUtils.cpp +++ b/Core/SNES/Debugger/Cx4DisUtils.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "SNES/Debugger/Cx4DisUtils.h" +#include "SNES/Coprocessors/CX4/Cx4Types.h" #include "Debugger/DisassemblyInfo.h" #include "Shared/EmuSettings.h" #include "Utilities/HexUtilities.h" @@ -208,3 +209,31 @@ void Cx4DisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me out += str.ToString(); } + +int32_t Cx4DisUtils::GetEffectiveAddress(DisassemblyInfo& info, Cx4State& state, MemoryDumper* memoryDumper) +{ + uint8_t op = info.GetByteCode()[1] & 0xFC; + uint8_t param1 = info.GetByteCode()[1] & 0x03; + uint8_t param2 = info.GetByteCode()[0] & 0xFF; + + switch(op) { + default: return -1; + + case 0x08: + case 0x0C: + case 0x10: + case 0x14: + case 0x18: + case 0x28: + case 0x2C: + case 0x30: + case 0x34: + case 0x38: + //Show destination address for branches & JSR + if(param1) { + return (state.P << 9) | (param2 * 2); + } else { + return state.Cache.Address[state.Cache.Page] | (param2 * 2); + } + } +} diff --git a/Core/SNES/Debugger/Cx4DisUtils.h b/Core/SNES/Debugger/Cx4DisUtils.h index c04b2b72..34a5e390 100644 --- a/Core/SNES/Debugger/Cx4DisUtils.h +++ b/Core/SNES/Debugger/Cx4DisUtils.h @@ -4,9 +4,12 @@ class DisassemblyInfo; class LabelManager; class EmuSettings; +class MemoryDumper; +struct Cx4State; class Cx4DisUtils { public: static void GetDisassembly(DisassemblyInfo &info, string &out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings); + static int32_t GetEffectiveAddress(DisassemblyInfo& info, Cx4State& state, MemoryDumper* memoryDumper); };