From 71d0ac693a5da9293dceae3fe5aa4cf700f18c1a Mon Sep 17 00:00:00 2001 From: Sour Date: Sun, 23 Feb 2020 15:58:14 -0500 Subject: [PATCH] Debugger: Improved GSU disassembly/debugger --- Core/Cx4.cpp | 5 ++ Core/Cx4.h | 1 + Core/Debugger.cpp | 35 +++++++++++-- Core/Debugger.h | 2 +- Core/Disassembler.cpp | 40 ++++++++------ Core/Disassembler.h | 2 + Core/DisassemblyInfo.cpp | 4 +- Core/ExpressionEvaluator.cpp | 4 +- Core/GsuDisUtils.cpp | 61 +++++++++++++++++----- Core/GsuDisUtils.h | 3 ++ Core/LabelManager.cpp | 4 +- Core/LabelManager.h | 2 +- Core/MemoryManager.cpp | 35 ------------- Core/MemoryManager.h | 2 +- Core/MemoryMappings.cpp | 25 +++++++++ Core/MemoryMappings.h | 1 + InteropDLL/DebugApiWrapper.cpp | 2 +- UI/Debugger/Breakpoints/Breakpoint.cs | 4 +- UI/Debugger/Code/CpuDisassemblyManager.cs | 8 +-- UI/Debugger/Code/SymbolCodeDataProvider.cs | 8 +-- UI/Debugger/Controls/ctrlWatch.cs | 2 +- UI/Debugger/Labels/CodeLabel.cs | 4 +- UI/Debugger/Labels/LabelManager.cs | 5 +- UI/Debugger/Labels/ctrlLabelList.cs | 10 ++-- UI/Debugger/MemoryTools/frmMemoryTools.cs | 2 +- UI/Debugger/Profiler/ctrlProfiler.cs | 2 +- UI/Debugger/frmDebugger.Designer.cs | 29 +++++----- UI/Debugger/frmDebugger.cs | 1 - UI/Debugger/frmGoToAll.cs | 4 +- UI/Interop/DebugApi.cs | 2 +- 30 files changed, 192 insertions(+), 117 deletions(-) diff --git a/Core/Cx4.cpp b/Core/Cx4.cpp index 14a1514..194fdcb 100644 --- a/Core/Cx4.cpp +++ b/Core/Cx4.cpp @@ -456,6 +456,11 @@ AddressInfo Cx4::GetAbsoluteAddress(uint32_t address) return { -1, SnesMemoryType::Register }; } +MemoryMappings* Cx4::GetMemoryMappings() +{ + return &_mappings; +} + uint8_t* Cx4::DebugGetDataRam() { return _dataRam; diff --git a/Core/Cx4.h b/Core/Cx4.h index 1e61f90..6a501b2 100644 --- a/Core/Cx4.h +++ b/Core/Cx4.h @@ -125,6 +125,7 @@ public: void PeekBlock(uint32_t addr, uint8_t* output) override; AddressInfo GetAbsoluteAddress(uint32_t address) override; + MemoryMappings* GetMemoryMappings(); uint8_t* DebugGetDataRam(); uint32_t DebugGetDataRamSize(); Cx4State GetState(); diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 0b7a1d0..ab7b707 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -460,13 +460,40 @@ AddressInfo Debugger::GetAbsoluteAddress(AddressInfo relAddress) throw std::runtime_error("Unsupported address type"); } -AddressInfo Debugger::GetRelativeAddress(AddressInfo absAddress) +AddressInfo Debugger::GetRelativeAddress(AddressInfo absAddress, CpuType cpuType) { + MemoryMappings* mappings = nullptr; + switch(cpuType) { + case CpuType::Cpu: mappings = _memoryManager->GetMemoryMappings(); break; + case CpuType::Sa1: mappings = _cart->GetSa1()->GetMemoryMappings(); break; + case CpuType::Gsu: mappings = _cart->GetGsu()->GetMemoryMappings(); break; + case CpuType::Cx4: mappings = _cart->GetCx4()->GetMemoryMappings(); break; + } + switch(absAddress.Type) { case SnesMemoryType::PrgRom: case SnesMemoryType::WorkRam: - case SnesMemoryType::SaveRam: - return { _memoryManager->GetRelativeAddress(absAddress), SnesMemoryType::CpuMemory }; + case SnesMemoryType::SaveRam: { + if(!mappings) { + throw std::runtime_error("Unsupported cpu type"); + } + + uint8_t startBank = 0; + //Try to find a mirror close to where the PC is + if(cpuType == CpuType::Cpu) { + if(absAddress.Type == SnesMemoryType::WorkRam) { + startBank = 0x7E; + } else { + startBank = (_cpu->GetState().K & 0xC0) << 4; + } + } else if(cpuType == CpuType::Sa1) { + startBank = (_cart->GetSa1()->GetCpuState().K & 0xC0); + } else if(cpuType == CpuType::Gsu) { + startBank = (_cart->GetGsu()->GetState().ProgramBank & 0xC0); + } + + return { mappings->GetRelativeAddress(absAddress, startBank), DebugUtilities::GetCpuMemoryType(cpuType) }; + } case SnesMemoryType::SpcRam: case SnesMemoryType::SpcRom: @@ -477,8 +504,6 @@ AddressInfo Debugger::GetRelativeAddress(AddressInfo absAddress) default: return { -1, SnesMemoryType::Register }; - - throw std::runtime_error("Unsupported address type"); } } diff --git a/Core/Debugger.h b/Core/Debugger.h index 140765e..488cdcf 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -118,7 +118,7 @@ public: void GetState(DebugState &state, bool partialPpuState); AddressInfo GetAbsoluteAddress(AddressInfo relAddress); - AddressInfo GetRelativeAddress(AddressInfo absAddress); + AddressInfo GetRelativeAddress(AddressInfo absAddress, CpuType cpuType); void SetCdlData(uint8_t * cdlData, uint32_t length); void MarkBytesAs(uint32_t start, uint32_t end, uint8_t flags); diff --git a/Core/Disassembler.cpp b/Core/Disassembler.cpp index 5b6323d..0a94c47 100644 --- a/Core/Disassembler.cpp +++ b/Core/Disassembler.cpp @@ -26,11 +26,14 @@ Disassembler::Disassembler(shared_ptr console, shared_ptr cdl, Debugger* debugger) { + shared_ptr cart = console->GetCartridge(); + _cdl = cdl; _debugger = debugger; _labelManager = debugger->GetLabelManager(); _console = console.get(); _spc = console->GetSpc().get(); + _gsu = cart->GetGsu(); _settings = console->GetSettings().get(); _memoryDumper = _debugger->GetMemoryDumper().get(); _memoryManager = console->GetMemoryManager().get(); @@ -42,24 +45,25 @@ Disassembler::Disassembler(shared_ptr console, shared_ptrDebugGetWorkRam(); _wramSize = MemoryManager::WorkRamSize; - _spcRam = console->GetSpc()->GetSpcRam(); + _spcRam = _spc->GetSpcRam(); _spcRamSize = Spc::SpcRamSize; - _spcRom = console->GetSpc()->GetSpcRom(); + _spcRom = _spc->GetSpcRom(); _spcRomSize = Spc::SpcRomSize; - _necDspProgramRom = console->GetCartridge()->GetDsp() ? console->GetCartridge()->GetDsp()->DebugGetProgramRom() : nullptr; - _necDspProgramRomSize = console->GetCartridge()->GetDsp() ? console->GetCartridge()->GetDsp()->DebugGetProgramRomSize() : 0; - _sa1InternalRam = console->GetCartridge()->GetSa1() ? console->GetCartridge()->GetSa1()->DebugGetInternalRam() : nullptr; - _sa1InternalRamSize = console->GetCartridge()->GetSa1() ? console->GetCartridge()->GetSa1()->DebugGetInternalRamSize() : 0; + _necDspProgramRom = cart->GetDsp() ? cart->GetDsp()->DebugGetProgramRom() : nullptr; + _necDspProgramRomSize = cart->GetDsp() ? cart->GetDsp()->DebugGetProgramRomSize() : 0; - _gsuWorkRam = console->GetCartridge()->GetGsu() ? console->GetCartridge()->GetGsu()->DebugGetWorkRam() : nullptr; - _gsuWorkRamSize = console->GetCartridge()->GetGsu() ? console->GetCartridge()->GetGsu()->DebugGetWorkRamSize() : 0; + _sa1InternalRam = cart->GetSa1() ? cart->GetSa1()->DebugGetInternalRam() : nullptr; + _sa1InternalRamSize = cart->GetSa1() ? cart->GetSa1()->DebugGetInternalRamSize() : 0; - _bsxPsRam = console->GetCartridge()->GetBsx() ? console->GetCartridge()->GetBsx()->DebugGetPsRam() : nullptr; - _bsxPsRamSize = console->GetCartridge()->GetBsx() ? console->GetCartridge()->GetBsx()->DebugGetPsRamSize() : 0; - _bsxMemPack = console->GetCartridge()->GetBsx() ? console->GetCartridge()->GetBsxMemoryPack()->DebugGetMemoryPack() : nullptr; - _bsxMemPackSize = console->GetCartridge()->GetBsx() ? console->GetCartridge()->GetBsxMemoryPack()->DebugGetMemoryPackSize() : 0; + _gsuWorkRam = cart->GetGsu() ? cart->GetGsu()->DebugGetWorkRam() : nullptr; + _gsuWorkRamSize = cart->GetGsu() ? cart->GetGsu()->DebugGetWorkRamSize() : 0; + + _bsxPsRam = cart->GetBsx() ? cart->GetBsx()->DebugGetPsRam() : nullptr; + _bsxPsRamSize = cart->GetBsx() ? cart->GetBsx()->DebugGetPsRamSize() : 0; + _bsxMemPack = cart->GetBsx() ? cart->GetBsxMemoryPack()->DebugGetMemoryPack() : nullptr; + _bsxMemPackSize = cart->GetBsx() ? cart->GetBsxMemoryPack()->DebugGetMemoryPackSize() : 0; _prgCache = vector(_prgRomSize); _sramCache = vector(_sramSize); @@ -494,7 +498,7 @@ bool Disassembler::GetLineData(CpuType type, uint32_t lineIndex, CodeLineData &d } case CpuType::Spc: { - SpcState state = _console->GetSpc()->GetState(); + SpcState state = _spc->GetState(); state.PC = (uint16_t)result.CpuAddress; if(!disInfo.IsInitialized()) { @@ -515,6 +519,7 @@ bool Disassembler::GetLineData(CpuType type, uint32_t lineIndex, CodeLineData &d } case CpuType::Gsu: { + GsuState state = _gsu->GetState(); if(!disInfo.IsInitialized()) { disInfo = DisassemblyInfo(src.Data + result.Address.Address, 0, CpuType::Gsu); } else { @@ -522,8 +527,13 @@ bool Disassembler::GetLineData(CpuType type, uint32_t lineIndex, CodeLineData &d } data.OpSize = disInfo.GetOpSize(); - data.EffectiveAddress = -1; - data.ValueSize = 0; + data.EffectiveAddress = disInfo.GetEffectiveAddress(_console, &state); + if(data.EffectiveAddress >= 0) { + data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType, data.ValueSize); + data.ValueSize = 2; + } else { + data.ValueSize = 0; + } break; } diff --git a/Core/Disassembler.h b/Core/Disassembler.h index 442de1f..c33f79a 100644 --- a/Core/Disassembler.h +++ b/Core/Disassembler.h @@ -8,6 +8,7 @@ class MemoryManager; class Console; class Spc; +class Gsu; class Debugger; class LabelManager; class CodeDataLogger; @@ -29,6 +30,7 @@ private: MemoryManager *_memoryManager; Console *_console; Spc* _spc; + Gsu* _gsu; EmuSettings* _settings; Debugger *_debugger; shared_ptr _cdl; diff --git a/Core/DisassemblyInfo.cpp b/Core/DisassemblyInfo.cpp index a8a0e6b..7026efc 100644 --- a/Core/DisassemblyInfo.cpp +++ b/Core/DisassemblyInfo.cpp @@ -69,8 +69,8 @@ int32_t DisassemblyInfo::GetEffectiveAddress(Console *console, void *cpuState) return CpuDisUtils::GetEffectiveAddress(*this, console, *(CpuState*)cpuState); case CpuType::Spc: return SpcDisUtils::GetEffectiveAddress(*this, console, *(SpcState*)cpuState); - - case CpuType::Gsu: + case CpuType::Gsu: return GsuDisUtils::GetEffectiveAddress(*this, console, *(GsuState*)cpuState); + case CpuType::Cx4: case CpuType::NecDsp: return -1; diff --git a/Core/ExpressionEvaluator.cpp b/Core/ExpressionEvaluator.cpp index 4109cc3..a167776 100644 --- a/Core/ExpressionEvaluator.cpp +++ b/Core/ExpressionEvaluator.cpp @@ -431,11 +431,11 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, DebugState &state, E if(token >= EvalValues::FirstLabelIndex) { int64_t labelIndex = token - EvalValues::FirstLabelIndex; if((size_t)labelIndex < data.Labels.size()) { - token = _labelManager->GetLabelRelativeAddress(data.Labels[(uint32_t)labelIndex]); + token = _labelManager->GetLabelRelativeAddress(data.Labels[(uint32_t)labelIndex], _cpuType); if(token < -1) { //Label doesn't exist, try to find a matching multi-byte label string label = data.Labels[(uint32_t)labelIndex] + "+0"; - token = _labelManager->GetLabelRelativeAddress(label); + token = _labelManager->GetLabelRelativeAddress(label, _cpuType); } } else { token = -2; diff --git a/Core/GsuDisUtils.cpp b/Core/GsuDisUtils.cpp index 3517b3e..b5473ee 100644 --- a/Core/GsuDisUtils.cpp +++ b/Core/GsuDisUtils.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "GsuDisUtils.h" #include "DisassemblyInfo.h" +#include "LabelManager.h" #include "EmuSettings.h" #include "../Utilities/FastString.h" #include "../Utilities/HexUtilities.h" @@ -15,8 +16,19 @@ void GsuDisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me uint8_t opCode = info.GetOpCode(); FastString str(settings->CheckDebuggerFlag(DebuggerFlags::UseLowerCaseDisassembly)); + + auto getJumpTarget = [&str, labelManager, memoryAddr, &info]() { + uint32_t jmpTarget = memoryAddr + (int8_t)info.GetByteCode()[1] + 2; + AddressInfo address = { (int32_t)jmpTarget, SnesMemoryType::GsuMemory }; + string label = labelManager->GetLabel(address); + if(label.empty()) { + str.WriteAll('$', HexUtilities::ToHex24(jmpTarget)); + } else { + str.Write(label, true); + } + }; + const char* reg = registerNames[opCode & 0x0F]; - uint32_t jmpTarget = memoryAddr + (int8_t)info.GetByteCode()[1]; switch(opCode) { case 0x00: str.Write("STOP"); break; @@ -25,17 +37,17 @@ void GsuDisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me case 0x03: str.Write("LSR"); break; case 0x04: str.Write("ROL"); break; - case 0x05: str.WriteAll("BRA $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x06: str.WriteAll("BLT $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x07: str.WriteAll("BGE $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x08: str.WriteAll("BNE $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x09: str.WriteAll("BEQ $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x0A: str.WriteAll("BPL $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x0B: str.WriteAll("BMI $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x0C: str.WriteAll("BCC $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x0D: str.WriteAll("BCS $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x0E: str.WriteAll("BCV $", HexUtilities::ToHex24(jmpTarget)); break; - case 0x0F: str.WriteAll("BVS $", HexUtilities::ToHex24(jmpTarget)); break; + case 0x05: str.WriteAll("BRA "); getJumpTarget(); break; + case 0x06: str.WriteAll("BLT "); getJumpTarget(); break; + case 0x07: str.WriteAll("BGE "); getJumpTarget(); break; + case 0x08: str.WriteAll("BNE "); getJumpTarget(); break; + case 0x09: str.WriteAll("BEQ "); getJumpTarget(); break; + case 0x0A: str.WriteAll("BPL "); getJumpTarget(); break; + case 0x0B: str.WriteAll("BMI "); getJumpTarget(); break; + case 0x0C: str.WriteAll("BCC "); getJumpTarget(); break; + case 0x0D: str.WriteAll("BCS "); getJumpTarget(); break; + case 0x0E: str.WriteAll("BCV "); getJumpTarget(); break; + case 0x0F: str.WriteAll("BVS "); getJumpTarget(); break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: @@ -197,3 +209,28 @@ void GsuDisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me out += str.ToString(); } + +int32_t GsuDisUtils::GetEffectiveAddress(DisassemblyInfo& info, Console* console, GsuState& state) +{ + uint8_t opCode = info.GetOpCode(); + bool alt1 = (info.GetFlags() & 0x01) != 0; + bool alt2 = (info.GetFlags() & 0x02) != 0; + + switch(opCode) { + case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7: + case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF: + if(alt1 || alt2) { + return 0x700000 | (info.GetByteCode()[1] << 1) | (state.RamBank << 16); + } + break; + + case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: + case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: + if(alt1 || alt2) { + return 0x700000 | info.GetByteCode()[1] | (info.GetByteCode()[2] << 8) | (state.RamBank << 16); + } + break; + } + + return -1; +} diff --git a/Core/GsuDisUtils.h b/Core/GsuDisUtils.h index 1ba2d11..47ea54e 100644 --- a/Core/GsuDisUtils.h +++ b/Core/GsuDisUtils.h @@ -4,9 +4,12 @@ class DisassemblyInfo; class LabelManager; class EmuSettings; +class Console; +struct GsuState; class GsuDisUtils { public: static void GetDisassembly(DisassemblyInfo &info, string &out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings); + static int32_t GetEffectiveAddress(DisassemblyInfo& info, Console* console, GsuState& state); }; diff --git a/Core/LabelManager.cpp b/Core/LabelManager.cpp index 5741d66..b91e022 100644 --- a/Core/LabelManager.cpp +++ b/Core/LabelManager.cpp @@ -132,14 +132,14 @@ bool LabelManager::ContainsLabel(string &label) return _codeLabelReverseLookup.find(label) != _codeLabelReverseLookup.end(); } -int32_t LabelManager::GetLabelRelativeAddress(string &label) +int32_t LabelManager::GetLabelRelativeAddress(string &label, CpuType cpuType) { auto result = _codeLabelReverseLookup.find(label); if(result != _codeLabelReverseLookup.end()) { uint64_t key = result->second; SnesMemoryType type = GetKeyMemoryType(key); AddressInfo addr { (int32_t)(key & 0xFFFFFFFF), type }; - return _debugger->GetRelativeAddress(addr).Address; + return _debugger->GetRelativeAddress(addr, cpuType).Address; } //Label doesn't exist return -2; diff --git a/Core/LabelManager.h b/Core/LabelManager.h index 6d4b70c..247da65 100644 --- a/Core/LabelManager.h +++ b/Core/LabelManager.h @@ -39,7 +39,7 @@ public: void SetLabel(uint32_t address, SnesMemoryType memType, string label, string comment); void ClearLabels(); - int32_t GetLabelRelativeAddress(string &label); + int32_t GetLabelRelativeAddress(string &label, CpuType cpuType = CpuType::Cpu); string GetLabel(AddressInfo address); string GetComment(AddressInfo absAddress); diff --git a/Core/MemoryManager.cpp b/Core/MemoryManager.cpp index 6aa5152..29bcd2c 100644 --- a/Core/MemoryManager.cpp +++ b/Core/MemoryManager.cpp @@ -415,41 +415,6 @@ bool MemoryManager::IsWorkRam(uint32_t cpuAddress) return handler && handler->GetMemoryType() == SnesMemoryType::WorkRam; } -int MemoryManager::GetRelativeAddress(AddressInfo &address, int32_t cpuAddress) -{ - if(address.Type == SnesMemoryType::WorkRam) { - return 0x7E0000 | address.Address; - } - - uint16_t startPosition; - if(cpuAddress < 0) { - uint8_t bank = _console->GetCpu()->GetState().K; - startPosition = ((bank & 0xC0) << 4); - } else { - startPosition = (cpuAddress >> 12) & 0xF00; - } - - for(int i = startPosition; i <= 0xFFF; i++) { - IMemoryHandler* handler = _mappings.GetHandler(i << 12); - if(handler) { - AddressInfo addrInfo = handler->GetAbsoluteAddress(address.Address & 0xFFF); - if(addrInfo.Type == address.Type && addrInfo.Address == address.Address) { - return (i << 12) | (address.Address & 0xFFF); - } - } - } - for(int i = 0; i < startPosition; i++) { - IMemoryHandler* handler = _mappings.GetHandler(i << 12); - if(handler) { - AddressInfo addrInfo = handler->GetAbsoluteAddress(address.Address & 0xFFF); - if(addrInfo.Type == address.Type && addrInfo.Address == address.Address) { - return (i << 12) | (address.Address & 0xFFF); - } - } - } - return -1; -} - void MemoryManager::Serialize(Serializer &s) { s.Stream(_masterClock, _openBus, _cpuSpeed, _hClock, _dramRefreshPosition, _hdmaInitPosition); diff --git a/Core/MemoryManager.h b/Core/MemoryManager.h index 9eb5782..5c6ea10 100644 --- a/Core/MemoryManager.h +++ b/Core/MemoryManager.h @@ -91,7 +91,7 @@ public: bool IsRegister(uint32_t cpuAddress); bool IsWorkRam(uint32_t cpuAddress); - int GetRelativeAddress(AddressInfo &address, int32_t cpuAddress = -1); + int GetRelativeAddress(AddressInfo &address, uint8_t startBank = 0); void Serialize(Serializer &s) override; }; diff --git a/Core/MemoryMappings.cpp b/Core/MemoryMappings.cpp index 900b128..6369fa5 100644 --- a/Core/MemoryMappings.cpp +++ b/Core/MemoryMappings.cpp @@ -56,6 +56,31 @@ AddressInfo MemoryMappings::GetAbsoluteAddress(uint32_t addr) } } +int MemoryMappings::GetRelativeAddress(AddressInfo& absAddress, uint8_t startBank) +{ + uint16_t startPosition = startBank << 4; + + for(int i = startPosition; i <= 0xFFF; i++) { + IMemoryHandler* handler = GetHandler(i << 12); + if(handler) { + AddressInfo addrInfo = handler->GetAbsoluteAddress(absAddress.Address & 0xFFF); + if(addrInfo.Type == absAddress.Type && addrInfo.Address == absAddress.Address) { + return (i << 12) | (absAddress.Address & 0xFFF); + } + } + } + for(int i = 0; i < startPosition; i++) { + IMemoryHandler* handler = GetHandler(i << 12); + if(handler) { + AddressInfo addrInfo = handler->GetAbsoluteAddress(absAddress.Address & 0xFFF); + if(addrInfo.Type == absAddress.Type && addrInfo.Address == absAddress.Address) { + return (i << 12) | (absAddress.Address & 0xFFF); + } + } + } + return -1; +} + uint8_t MemoryMappings::Peek(uint32_t addr) { //Read, without triggering side-effects diff --git a/Core/MemoryMappings.h b/Core/MemoryMappings.h index 81b169d..489f358 100644 --- a/Core/MemoryMappings.h +++ b/Core/MemoryMappings.h @@ -15,6 +15,7 @@ public: IMemoryHandler* GetHandler(uint32_t addr); AddressInfo GetAbsoluteAddress(uint32_t addr); + int GetRelativeAddress(AddressInfo& absAddress, uint8_t startBank = 0); uint8_t Peek(uint32_t addr); uint16_t PeekWord(uint32_t addr); diff --git a/InteropDLL/DebugApiWrapper.cpp b/InteropDLL/DebugApiWrapper.cpp index 69f40d9..5a0a605 100644 --- a/InteropDLL/DebugApiWrapper.cpp +++ b/InteropDLL/DebugApiWrapper.cpp @@ -74,7 +74,7 @@ extern "C" DllExport void __stdcall SetMemoryValues(SnesMemoryType type, uint32_t address, uint8_t* data, int32_t length) { return GetDebugger()->GetMemoryDumper()->SetMemoryValues(type, address, data, length); } DllExport AddressInfo __stdcall GetAbsoluteAddress(AddressInfo relAddress) { return GetDebugger()->GetAbsoluteAddress(relAddress); } - DllExport AddressInfo __stdcall GetRelativeAddress(AddressInfo absAddress) { return GetDebugger()->GetRelativeAddress(absAddress); } + DllExport AddressInfo __stdcall GetRelativeAddress(AddressInfo absAddress, CpuType cpuType) { return GetDebugger()->GetRelativeAddress(absAddress, cpuType); } DllExport void __stdcall SetLabel(uint32_t address, SnesMemoryType memType, char* label, char* comment) { GetDebugger()->GetLabelManager()->SetLabel(address, memType, label, comment); } DllExport void __stdcall ClearLabels() { GetDebugger()->GetLabelManager()->ClearLabels(); } diff --git a/UI/Debugger/Breakpoints/Breakpoint.cs b/UI/Debugger/Breakpoints/Breakpoint.cs index ca9b9f4..405e045 100644 --- a/UI/Debugger/Breakpoints/Breakpoint.cs +++ b/UI/Debugger/Breakpoints/Breakpoint.cs @@ -161,7 +161,7 @@ namespace Mesen.GUI.Debugger { UInt32 address = AddressType == BreakpointAddressType.SingleAddress ? this.Address : this.StartAddress; if(IsCpuBreakpoint && this.IsAbsoluteAddress) { - return DebugApi.GetRelativeAddress(new AddressInfo() { Address = (int)address, Type = this.MemoryType }).Address; + return DebugApi.GetRelativeAddress(new AddressInfo() { Address = (int)address, Type = this.MemoryType }, this.CpuType).Address; } else { return (int)address; } @@ -171,7 +171,7 @@ namespace Mesen.GUI.Debugger { if(this.AddressType == BreakpointAddressType.AddressRange){ if(IsCpuBreakpoint && this.IsAbsoluteAddress) { - return DebugApi.GetRelativeAddress(new AddressInfo() { Address = (int)this.EndAddress, Type = this.MemoryType }).Address; + return DebugApi.GetRelativeAddress(new AddressInfo() { Address = (int)this.EndAddress, Type = this.MemoryType }, this.CpuType).Address; } else { return (int)this.EndAddress; } diff --git a/UI/Debugger/Code/CpuDisassemblyManager.cs b/UI/Debugger/Code/CpuDisassemblyManager.cs index 73c735b..373d92c 100644 --- a/UI/Debugger/Code/CpuDisassemblyManager.cs +++ b/UI/Debugger/Code/CpuDisassemblyManager.cs @@ -69,9 +69,9 @@ namespace Mesen.GUI.Debugger.Code int address; if(location.Label != null) { - address = location.Label.GetRelativeAddress().Address; + address = location.Label.GetRelativeAddress(this.CpuType).Address; if(address >= 0) { - location.Address = location.Label.GetRelativeAddress().Address + (location.ArrayIndex ?? 0); + location.Address = location.Label.GetRelativeAddress(this.CpuType).Address + (location.ArrayIndex ?? 0); } else { location.Address = -1; } @@ -119,7 +119,7 @@ namespace Mesen.GUI.Debugger.Code AddressInfo? symbolAddress = _symbolProvider.GetSymbolAddressInfo(location.Symbol); if(symbolAddress != null && symbolAddress.Value.Address >= 0) { - int relativeAddress = DebugApi.GetRelativeAddress(symbolAddress.Value).Address; + int relativeAddress = DebugApi.GetRelativeAddress(symbolAddress.Value, this.CpuType).Address; byte byteValue = relativeAddress >= 0 ? DebugApi.GetMemoryValue(this.RelativeMemoryType, (UInt32)relativeAddress) : (byte)0; UInt16 wordValue = relativeAddress >= 0 ? (UInt16)(byteValue | (DebugApi.GetMemoryValue(this.RelativeMemoryType, (UInt32)relativeAddress + 1) << 8)) : (UInt16)0; @@ -157,7 +157,7 @@ namespace Mesen.GUI.Debugger.Code } else if(absAddress.Type == SnesMemoryType.Register) { relativeAddress = absAddress.Address; } else { - relativeAddress = location.Label.GetRelativeAddress().Address + (location.ArrayIndex ?? 0); + relativeAddress = location.Label.GetRelativeAddress(this.CpuType).Address + (location.ArrayIndex ?? 0); } byte byteValue = relativeAddress >= 0 ? DebugApi.GetMemoryValue(this.RelativeMemoryType, (UInt32)relativeAddress) : (byte)0; diff --git a/UI/Debugger/Code/SymbolCodeDataProvider.cs b/UI/Debugger/Code/SymbolCodeDataProvider.cs index 5918c57..ac80d3f 100644 --- a/UI/Debugger/Code/SymbolCodeDataProvider.cs +++ b/UI/Debugger/Code/SymbolCodeDataProvider.cs @@ -13,14 +13,14 @@ namespace Mesen.GUI.Debugger.Code //private byte[] _prgRom; private int _lineCount; private SourceFileInfo _file; - private CpuType _type; + private CpuType _cpuType; private bool _isC; private ISymbolProvider _symbolProvider; public SymbolCodeDataProvider(CpuType type, ISymbolProvider symbolProvider, SourceFileInfo file) { //_prgRom = DebugApi.GetMemoryState(SnesMemoryType.PrgRom); - _type = type; + _cpuType = type; _symbolProvider = symbolProvider; _file = file; _lineCount = file.Data.Length; @@ -33,7 +33,7 @@ namespace Mesen.GUI.Debugger.Code { AddressInfo? address = _symbolProvider.GetLineAddress(_file, lineIndex); - CodeLineData data = new CodeLineData(_type) { + CodeLineData data = new CodeLineData(_cpuType) { Address = GetLineAddress(lineIndex), AbsoluteAddress = address.HasValue ? address.Value.Address : -1, EffectiveAddress = -1, @@ -76,7 +76,7 @@ namespace Mesen.GUI.Debugger.Code { AddressInfo? absAddress = _symbolProvider.GetLineAddress(_file, lineIndex); if(absAddress != null) { - return DebugApi.GetRelativeAddress(absAddress.Value).Address; + return DebugApi.GetRelativeAddress(absAddress.Value, _cpuType).Address; } else { return -1; } diff --git a/UI/Debugger/Controls/ctrlWatch.cs b/UI/Debugger/Controls/ctrlWatch.cs index de3290d..48d2580 100644 --- a/UI/Debugger/Controls/ctrlWatch.cs +++ b/UI/Debugger/Controls/ctrlWatch.cs @@ -248,7 +248,7 @@ namespace Mesen.GUI.Debugger if(_selectedAddress >= 0) { DebugWindowManager.OpenDebugger(_cpuType).GoToAddress(_selectedAddress); } else if(_selectedLabel != null) { - AddressInfo relAddress = _selectedLabel.GetRelativeAddress(); + AddressInfo relAddress = _selectedLabel.GetRelativeAddress(_cpuType); if(relAddress.Address >= 0) { DebugWindowManager.OpenDebugger(_cpuType).GoToAddress(relAddress.Address); } diff --git a/UI/Debugger/Labels/CodeLabel.cs b/UI/Debugger/Labels/CodeLabel.cs index f552da8..a87c81e 100644 --- a/UI/Debugger/Labels/CodeLabel.cs +++ b/UI/Debugger/Labels/CodeLabel.cs @@ -124,9 +124,9 @@ namespace Mesen.GUI.Debugger.Labels return new AddressInfo() { Address = (int)this.Address, Type = this.MemoryType }; } - public AddressInfo GetRelativeAddress() + public AddressInfo GetRelativeAddress(CpuType cpuType) { - return DebugApi.GetRelativeAddress(GetAbsoluteAddress()); + return DebugApi.GetRelativeAddress(GetAbsoluteAddress(), cpuType); } public byte GetValue() diff --git a/UI/Debugger/Labels/LabelManager.cs b/UI/Debugger/Labels/LabelManager.cs index a33d37a..4aada45 100644 --- a/UI/Debugger/Labels/LabelManager.cs +++ b/UI/Debugger/Labels/LabelManager.cs @@ -60,8 +60,8 @@ namespace Mesen.GUI.Debugger.Labels public static List GetLabels(CpuType cpu) { - if(cpu == CpuType.Sa1) { - //Share label list between SNES CPU and SA1 + if(cpu == CpuType.Sa1 || cpu == CpuType.Gsu) { + //Share label list between SNES CPU, SA1 and GSU (since the share the same PRG ROM) cpu = CpuType.Cpu; } @@ -187,6 +187,7 @@ namespace Mesen.GUI.Debugger.Labels } else { DebugApi.RefreshDisassembly(CpuType.Cpu); DebugApi.RefreshDisassembly(CpuType.Sa1); + DebugApi.RefreshDisassembly(CpuType.Gsu); } } diff --git a/UI/Debugger/Labels/ctrlLabelList.cs b/UI/Debugger/Labels/ctrlLabelList.cs index a38b340..7b443a7 100644 --- a/UI/Debugger/Labels/ctrlLabelList.cs +++ b/UI/Debugger/Labels/ctrlLabelList.cs @@ -100,7 +100,7 @@ namespace Mesen.GUI.Debugger.Controls foreach(ListViewItem item in _listItems) { CodeLabel label = (CodeLabel)item.Tag; - Int32 relativeAddress = label.GetRelativeAddress().Address; + Int32 relativeAddress = label.GetRelativeAddress(_cpuType).Address; if(relativeAddress != (Int32)item.SubItems[1].Tag) { needUpdate = true; if(relativeAddress >= 0) { @@ -138,7 +138,7 @@ namespace Mesen.GUI.Debugger.Controls case SnesMemoryType.BsxMemoryPack: prefix = "MPACK: $"; break; default: throw new Exception("Unsupported type"); } - int relAddress = label.GetRelativeAddress().Address; + int relAddress = label.GetRelativeAddress(_cpuType).Address; item.SubItems.Add(relAddress >= 0 ? "$" + relAddress.ToString("X4") : "-"); item.SubItems.Add(prefix + label.Address.ToString("X4")); item.SubItems.Add(ConfigManager.Config.Debug.Debugger.ShowCommentsInLabelList ? label.Comment : ""); @@ -176,7 +176,7 @@ namespace Mesen.GUI.Debugger.Controls { if(lstLabels.SelectedIndices.Count > 0) { CodeLabel label = (CodeLabel)GetSelectedLabel(); - int relAddress = label.GetRelativeAddress().Address; + int relAddress = label.GetRelativeAddress(_cpuType).Address; if(relAddress >= 0) { DebugWindowManager.OpenDebugger(_cpuType).GoToAddress(relAddress); } @@ -194,7 +194,7 @@ namespace Mesen.GUI.Debugger.Controls if(lstLabels.SelectedIndices.Count == 1) { CodeLabel label = GetSelectedLabel(); - bool availableInCpuMemory = label.GetRelativeAddress().Address >= 0; + bool availableInCpuMemory = label.GetRelativeAddress(_cpuType).Address >= 0; mnuViewInCpuMemory.Enabled = availableInCpuMemory; bool showViewInMemoryType = label.MemoryType != SnesMemoryType.Register && label.MemoryType != SnesMemoryType.SpcRom && label.MemoryType != SnesMemoryType.SpcRam; @@ -324,7 +324,7 @@ namespace Mesen.GUI.Debugger.Controls { if(lstLabels.SelectedIndices.Count == 1) { CodeLabel label = GetSelectedLabel(); - AddressInfo relAddress = label.GetRelativeAddress(); + AddressInfo relAddress = label.GetRelativeAddress(_cpuType); if(relAddress.Address >= 0) { DebugWindowManager.OpenMemoryViewer(relAddress); } diff --git a/UI/Debugger/MemoryTools/frmMemoryTools.cs b/UI/Debugger/MemoryTools/frmMemoryTools.cs index dae01b3..0b62c9b 100644 --- a/UI/Debugger/MemoryTools/frmMemoryTools.cs +++ b/UI/Debugger/MemoryTools/frmMemoryTools.cs @@ -170,7 +170,7 @@ namespace Mesen.GUI.Debugger } else if(dest.AbsoluteAddress != null) { ShowAddress(dest.AbsoluteAddress.Value); } else if(dest.Label != null) { - AddressInfo relAddress = dest.Label.GetRelativeAddress(); + AddressInfo relAddress = dest.Label.GetRelativeAddress(_memoryType.ToCpuType()); if(relAddress.Type == _memoryType && relAddress.Address >= 0) { ShowAddress(relAddress); } else { diff --git a/UI/Debugger/Profiler/ctrlProfiler.cs b/UI/Debugger/Profiler/ctrlProfiler.cs index 5d99f6b..6b3beb1 100644 --- a/UI/Debugger/Profiler/ctrlProfiler.cs +++ b/UI/Debugger/Profiler/ctrlProfiler.cs @@ -84,7 +84,7 @@ namespace Mesen.GUI.Debugger.Controls private void lstFunctions_DoubleClick(object sender, EventArgs e) { if(lstFunctions.SelectedIndices.Count > 0) { - AddressInfo relativeAddress = DebugApi.GetRelativeAddress(_functions[lstFunctions.SelectedIndices[0]].Address); + AddressInfo relativeAddress = DebugApi.GetRelativeAddress(_functions[lstFunctions.SelectedIndices[0]].Address, this.CpuType); if(relativeAddress.Address >= 0) { frmDebugger debugger = DebugWindowManager.OpenDebugger(this.CpuType); debugger.GoToAddress(relativeAddress.Address); diff --git a/UI/Debugger/frmDebugger.Designer.cs b/UI/Debugger/frmDebugger.Designer.cs index 0614a71..aac6f40 100644 --- a/UI/Debugger/frmDebugger.Designer.cs +++ b/UI/Debugger/frmDebugger.Designer.cs @@ -34,6 +34,8 @@ this.ctrlDisassemblyView = new Mesen.GUI.Debugger.Controls.ctrlDisassemblyView(); this.ctrlMesenMenuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuReloadRom = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem16 = new System.Windows.Forms.ToolStripSeparator(); this.mnuSaveRomAs = new System.Windows.Forms.ToolStripMenuItem(); this.mnuSaveAsIps = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripSeparator(); @@ -143,8 +145,6 @@ this.grpCallstack = new System.Windows.Forms.GroupBox(); this.ctrlCallstack = new Mesen.GUI.Debugger.Controls.ctrlCallstack(); this.tsToolbar = new Mesen.GUI.Controls.ctrlMesenToolStrip(); - this.toolStripMenuItem16 = new System.Windows.Forms.ToolStripSeparator(); - this.mnuReloadRom = new System.Windows.Forms.ToolStripMenuItem(); this.ctrlMesenMenuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.ctrlSplitContainer)).BeginInit(); this.ctrlSplitContainer.Panel1.SuspendLayout(); @@ -196,6 +196,18 @@ this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); this.fileToolStripMenuItem.Text = "File"; // + // mnuReloadRom + // + this.mnuReloadRom.Image = global::Mesen.GUI.Properties.Resources.Refresh; + this.mnuReloadRom.Name = "mnuReloadRom"; + this.mnuReloadRom.Size = new System.Drawing.Size(201, 22); + this.mnuReloadRom.Text = "Reload ROM"; + // + // toolStripMenuItem16 + // + this.toolStripMenuItem16.Name = "toolStripMenuItem16"; + this.toolStripMenuItem16.Size = new System.Drawing.Size(198, 6); + // // mnuSaveRomAs // this.mnuSaveRomAs.Image = global::Mesen.GUI.Properties.Resources.SaveFloppy; @@ -926,6 +938,7 @@ this.ctrlLabelList.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlLabelList.Location = new System.Drawing.Point(0, 551); this.ctrlLabelList.Name = "ctrlLabelList"; + this.ctrlLabelList.Padding = new System.Windows.Forms.Padding(3); this.ctrlLabelList.Size = new System.Drawing.Size(348, 0); this.ctrlLabelList.TabIndex = 4; // @@ -1061,18 +1074,6 @@ this.tsToolbar.TabIndex = 3; this.tsToolbar.Text = "ctrlMesenToolStrip1"; // - // toolStripMenuItem16 - // - this.toolStripMenuItem16.Name = "toolStripMenuItem16"; - this.toolStripMenuItem16.Size = new System.Drawing.Size(198, 6); - // - // mnuReloadRom - // - this.mnuReloadRom.Image = global::Mesen.GUI.Properties.Resources.Refresh; - this.mnuReloadRom.Name = "mnuReloadRom"; - this.mnuReloadRom.Size = new System.Drawing.Size(201, 22); - this.mnuReloadRom.Text = "Reload ROM"; - // // frmDebugger // this.AllowDrop = true; diff --git a/UI/Debugger/frmDebugger.cs b/UI/Debugger/frmDebugger.cs index a3fc49b..bc7a554 100644 --- a/UI/Debugger/frmDebugger.cs +++ b/UI/Debugger/frmDebugger.cs @@ -73,7 +73,6 @@ namespace Mesen.GUI.Debugger ConfigApi.SetDebuggerFlag(DebuggerFlags.GsuDebuggerEnabled, true); this.Text = "GSU Debugger"; ctrlCallstack.Visible = false; - ctrlLabelList.Visible = false; mnuStepOver.Visible = false; mnuStepOut.Visible = false; mnuStepInto.Text = "Step"; diff --git a/UI/Debugger/frmGoToAll.cs b/UI/Debugger/frmGoToAll.cs index 7547b50..aed273d 100644 --- a/UI/Debugger/frmGoToAll.cs +++ b/UI/Debugger/frmGoToAll.cs @@ -195,7 +195,7 @@ namespace Mesen.GUI.Debugger if(addressInfo != null) { value = DebugApi.GetMemoryValue(addressInfo.Value.Type, (uint)addressInfo.Value.Address); - relAddress = DebugApi.GetRelativeAddress(addressInfo.Value); + relAddress = DebugApi.GetRelativeAddress(addressInfo.Value, CpuType.Cpu); //TODO } else { //For constants, the address field contains the constant's value value = symbol.Address ?? 0; @@ -238,7 +238,7 @@ namespace Mesen.GUI.Debugger } } - AddressInfo relAddress = label.GetRelativeAddress(); + AddressInfo relAddress = label.GetRelativeAddress(CpuType.Cpu); //TODO searchResults.Add(new SearchResultInfo() { Caption = label.Label, AbsoluteAddress = label.GetAbsoluteAddress(), diff --git a/UI/Interop/DebugApi.cs b/UI/Interop/DebugApi.cs index fa4444c..ece968e 100644 --- a/UI/Interop/DebugApi.cs +++ b/UI/Interop/DebugApi.cs @@ -70,7 +70,7 @@ namespace Mesen.GUI [DllImport(DllPath)] public static extern void SetMemoryState(SnesMemoryType type, [In] byte[] buffer, Int32 length); [DllImport(DllPath)] public static extern AddressInfo GetAbsoluteAddress(AddressInfo relAddress); - [DllImport(DllPath)] public static extern AddressInfo GetRelativeAddress(AddressInfo absAddress); + [DllImport(DllPath)] public static extern AddressInfo GetRelativeAddress(AddressInfo absAddress, CpuType cpuType); [DllImport(DllPath)] public static extern void SetLabel(uint address, SnesMemoryType memType, string label, string comment); [DllImport(DllPath)] public static extern void ClearLabels();