Debugger: Improved GSU disassembly/debugger
This commit is contained in:
parent
08e0820164
commit
71d0ac693a
30 changed files with 192 additions and 117 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -26,11 +26,14 @@
|
|||
|
||||
Disassembler::Disassembler(shared_ptr<Console> console, shared_ptr<CodeDataLogger> cdl, Debugger* debugger)
|
||||
{
|
||||
shared_ptr<BaseCartridge> 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> console, shared_ptr<CodeDataLogge
|
|||
_wram = _memoryManager->DebugGetWorkRam();
|
||||
_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<DisassemblyInfo>(_prgRomSize);
|
||||
_sramCache = vector<DisassemblyInfo>(_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<CodeDataLogger> _cdl;
|
||||
|
|
|
@ -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: return GsuDisUtils::GetEffectiveAddress(*this, console, *(GsuState*)cpuState);
|
||||
|
||||
case CpuType::Gsu:
|
||||
case CpuType::Cx4:
|
||||
case CpuType::NecDsp:
|
||||
return -1;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -60,8 +60,8 @@ namespace Mesen.GUI.Debugger.Labels
|
|||
|
||||
public static List<CodeLabel> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
29
UI/Debugger/frmDebugger.Designer.cs
generated
29
UI/Debugger/frmDebugger.Designer.cs
generated
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue