mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
Debugger: Refactor/fix logic to determine size of value to display along with the effective address
This commit is contained in:
parent
948aec1d3a
commit
5e31200cf3
23 changed files with 142 additions and 120 deletions
|
@ -171,10 +171,10 @@ protected:
|
|||
|
||||
void WriteEffectiveAddress(DisassemblyInfo& info, RowPart& rowPart, void* cpuState, string& output, MemoryType cpuMemoryType, CpuType cpuType)
|
||||
{
|
||||
int32_t effectiveAddress = info.GetEffectiveAddress(_debugger, cpuState, cpuType);
|
||||
if(effectiveAddress >= 0) {
|
||||
EffectiveAddressInfo effectiveAddress = info.GetEffectiveAddress(_debugger, cpuState, cpuType);
|
||||
if(effectiveAddress.Address >= 0) {
|
||||
if(_options.UseLabels) {
|
||||
AddressInfo addr { effectiveAddress, cpuMemoryType };
|
||||
AddressInfo addr { effectiveAddress.Address, cpuMemoryType };
|
||||
string label = _labelManager->GetLabel(addr);
|
||||
if(!label.empty()) {
|
||||
WriteStringValue(output, " [" + label + "]", rowPart);
|
||||
|
@ -182,19 +182,18 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
WriteStringValue(output, " [$" + DebugUtilities::AddressToHex(cpuType, effectiveAddress) + "]", rowPart);
|
||||
WriteStringValue(output, " [$" + DebugUtilities::AddressToHex(cpuType, effectiveAddress.Address) + "]", rowPart);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteMemoryValue(DisassemblyInfo& info, RowPart& rowPart, void* cpuState, string& output, MemoryType memType, CpuType cpuType)
|
||||
{
|
||||
int32_t address = info.GetEffectiveAddress(_debugger, cpuState, cpuType);
|
||||
if(address >= 0) {
|
||||
uint8_t valueSize;
|
||||
uint16_t value = info.GetMemoryValue(address, _memoryDumper, memType, valueSize);
|
||||
EffectiveAddressInfo effectiveAddress = info.GetEffectiveAddress(_debugger, cpuState, cpuType);
|
||||
if(effectiveAddress.Address >= 0 && effectiveAddress.ValueSize > 0) {
|
||||
uint16_t value = info.GetMemoryValue(effectiveAddress, _memoryDumper, memType);
|
||||
if(rowPart.DisplayInHex) {
|
||||
output += "= $";
|
||||
if(valueSize == 2) {
|
||||
if(effectiveAddress.ValueSize == 2) {
|
||||
WriteIntValue(output, (uint16_t)value, rowPart);
|
||||
} else {
|
||||
WriteIntValue(output, (uint8_t)value, rowPart);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "Core/MemoryOperationType.h"
|
||||
#include "Core/Shared/CpuType.h"
|
||||
#include "Core/Debugger/DisassemblyInfo.h"
|
||||
|
||||
enum class MemoryType;
|
||||
enum class CpuType : uint8_t;
|
||||
|
@ -157,9 +158,8 @@ struct CodeLineData
|
|||
uint8_t OpSize;
|
||||
uint16_t Flags;
|
||||
|
||||
int32_t EffectiveAddress;
|
||||
EffectiveAddressInfo EffectiveAddress;
|
||||
uint16_t Value;
|
||||
uint8_t ValueSize;
|
||||
CpuType LineCpuType;
|
||||
|
||||
uint8_t ByteCode[8];
|
||||
|
|
|
@ -294,8 +294,8 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
{
|
||||
data.Address = row.CpuAddress;
|
||||
data.AbsoluteAddress = row.Address;
|
||||
data.EffectiveAddress = -1;
|
||||
data.ValueSize = 0;
|
||||
data.EffectiveAddress = {};
|
||||
data.Value = 0;
|
||||
data.Flags = row.Flags;
|
||||
data.LineCpuType = type;
|
||||
|
||||
|
@ -375,11 +375,8 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType);
|
||||
|
||||
if(data.EffectiveAddress >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType, data.ValueSize);
|
||||
} else {
|
||||
data.ValueSize = 0;
|
||||
if(data.EffectiveAddress.Address >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -397,11 +394,8 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType);
|
||||
if(data.EffectiveAddress >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType, data.ValueSize);
|
||||
data.ValueSize = 1;
|
||||
} else {
|
||||
data.ValueSize = 0;
|
||||
if(data.EffectiveAddress.Address >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -420,11 +414,8 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType);
|
||||
if(data.EffectiveAddress >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType, data.ValueSize);
|
||||
data.ValueSize = 2;
|
||||
} else {
|
||||
data.ValueSize = 0;
|
||||
if(data.EffectiveAddress.Address >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -437,8 +428,6 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
}
|
||||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = -1;
|
||||
data.ValueSize = 0;
|
||||
break;
|
||||
|
||||
case CpuType::Cx4:
|
||||
|
@ -452,7 +441,9 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType);
|
||||
data.ValueSize = 0;
|
||||
if(data.EffectiveAddress.Address >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -470,7 +461,9 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType);
|
||||
data.ValueSize = 0;
|
||||
if(data.EffectiveAddress.Address >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -488,10 +481,8 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType);
|
||||
if(data.EffectiveAddress >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType, data.ValueSize);
|
||||
} else {
|
||||
data.ValueSize = 0;
|
||||
if(data.EffectiveAddress.Address >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -510,10 +501,8 @@ void Disassembler::GetLineData(DisassemblyResult& row, CpuType type, MemoryType
|
|||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = disInfo.GetEffectiveAddress(_debugger, &state, lineCpuType);
|
||||
if(data.EffectiveAddress >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType, data.ValueSize);
|
||||
} else {
|
||||
data.ValueSize = 0;
|
||||
if(data.EffectiveAddress.Address >= 0) {
|
||||
data.Value = disInfo.GetMemoryValue(data.EffectiveAddress, _memoryDumper, memType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ void DisassemblyInfo::GetDisassembly(string &out, uint32_t memoryAddr, LabelMana
|
|||
|
||||
}
|
||||
|
||||
int32_t DisassemblyInfo::GetEffectiveAddress(Debugger *debugger, void *cpuState, CpuType cpuType)
|
||||
EffectiveAddressInfo DisassemblyInfo::GetEffectiveAddress(Debugger *debugger, void *cpuState, CpuType cpuType)
|
||||
{
|
||||
switch(_cpuType) {
|
||||
case CpuType::Sa1:
|
||||
|
@ -91,7 +91,7 @@ int32_t DisassemblyInfo::GetEffectiveAddress(Debugger *debugger, void *cpuState,
|
|||
case CpuType::Cx4: return Cx4DisUtils::GetEffectiveAddress(*this, *(Cx4State*)cpuState, debugger->GetMemoryDumper());
|
||||
|
||||
case CpuType::NecDsp:
|
||||
return -1;
|
||||
return {};
|
||||
|
||||
case CpuType::Gameboy: return GameboyDisUtils::GetEffectiveAddress(*this, *(GbCpuState*)cpuState);
|
||||
|
||||
|
@ -259,14 +259,11 @@ void DisassemblyInfo::UpdateCpuFlags(uint8_t& cpuFlags)
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t DisassemblyInfo::GetMemoryValue(uint32_t effectiveAddress, MemoryDumper *memoryDumper, MemoryType memType, uint8_t &valueSize)
|
||||
uint16_t DisassemblyInfo::GetMemoryValue(EffectiveAddressInfo effectiveAddress, MemoryDumper *memoryDumper, MemoryType memType)
|
||||
{
|
||||
//TODO cleanup
|
||||
if((_cpuType == CpuType::Spc || _cpuType == CpuType::Gameboy || _cpuType == CpuType::Nes || _cpuType == CpuType::Pce) || (_flags & ProcFlags::MemoryMode8)) {
|
||||
valueSize = 1;
|
||||
return memoryDumper->GetMemoryValue(memType, effectiveAddress);
|
||||
if(effectiveAddress.ValueSize == 2) {
|
||||
return memoryDumper->GetMemoryValueWord(memType, effectiveAddress.Address);
|
||||
} else {
|
||||
valueSize = 2;
|
||||
return memoryDumper->GetMemoryValueWord(memType, effectiveAddress);
|
||||
return memoryDumper->GetMemoryValue(memType, effectiveAddress.Address);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@ class EmuSettings;
|
|||
enum class MemoryType;
|
||||
enum class CpuType : uint8_t;
|
||||
|
||||
struct EffectiveAddressInfo
|
||||
{
|
||||
int32_t Address = -1;
|
||||
uint8_t ValueSize = 0;
|
||||
};
|
||||
|
||||
class DisassemblyInfo
|
||||
{
|
||||
private:
|
||||
|
@ -49,7 +55,8 @@ public:
|
|||
bool IsJump();
|
||||
void UpdateCpuFlags(uint8_t& cpuFlags);
|
||||
|
||||
int32_t GetEffectiveAddress(Debugger* debugger, void *cpuState, CpuType type);
|
||||
uint16_t GetMemoryValue(uint32_t effectiveAddress, MemoryDumper *memoryDumper, MemoryType memType, uint8_t &valueSize);
|
||||
EffectiveAddressInfo GetEffectiveAddress(Debugger* debugger, void *cpuState, CpuType type);
|
||||
|
||||
uint16_t GetMemoryValue(EffectiveAddressInfo effectiveAddress, MemoryDumper *memoryDumper, MemoryType memType);
|
||||
};
|
||||
|
||||
|
|
|
@ -92,10 +92,10 @@ uint32_t DisassemblySearch::SearchDisassembly(CpuType cpuType, const char* searc
|
|||
}
|
||||
}
|
||||
|
||||
if(lineData.EffectiveAddress >= 0) {
|
||||
txt = _labelManager->GetLabel({ lineData.EffectiveAddress, memType });
|
||||
if(lineData.EffectiveAddress.Address >= 0) {
|
||||
txt = _labelManager->GetLabel({ lineData.EffectiveAddress.Address, memType });
|
||||
if(txt.empty()) {
|
||||
txt = "[$" + DebugUtilities::AddressToHex(lineData.LineCpuType, lineData.EffectiveAddress) + "]";
|
||||
txt = "[$" + DebugUtilities::AddressToHex(lineData.LineCpuType, lineData.EffectiveAddress.Address) + "]";
|
||||
} else {
|
||||
txt = "[" + txt + "]";
|
||||
}
|
||||
|
@ -108,8 +108,8 @@ uint32_t DisassemblySearch::SearchDisassembly(CpuType cpuType, const char* searc
|
|||
}
|
||||
}
|
||||
|
||||
if(maxResultCount == 1 && lineData.ValueSize > 0) {
|
||||
txt = "$" + (lineData.ValueSize == 2 ? HexUtilities::ToHex((uint16_t)lineData.Value) : HexUtilities::ToHex((uint8_t)lineData.Value));
|
||||
if(maxResultCount == 1 && lineData.EffectiveAddress.ValueSize > 0) {
|
||||
txt = "$" + (lineData.EffectiveAddress.ValueSize == 2 ? HexUtilities::ToHex((uint16_t)lineData.Value) : HexUtilities::ToHex((uint8_t)lineData.Value));
|
||||
if(TextContains(searchStr, txt.c_str(), (int)txt.size(), options)) {
|
||||
searchResults[resultCount] = lineData;
|
||||
if(maxResultCount == ++resultCount) {
|
||||
|
|
|
@ -136,21 +136,21 @@ void GameboyDisUtils::GetDisassembly(DisassemblyInfo& info, string& out, uint32_
|
|||
out += str.ToString();
|
||||
}
|
||||
|
||||
int32_t GameboyDisUtils::GetEffectiveAddress(DisassemblyInfo& info, GbCpuState& state)
|
||||
EffectiveAddressInfo GameboyDisUtils::GetEffectiveAddress(DisassemblyInfo& info, GbCpuState& state)
|
||||
{
|
||||
switch(_gbEffAddrType[info.GetOpCode()]) {
|
||||
default:
|
||||
case AddrType::None: return -1;
|
||||
case AddrType::None: return {};
|
||||
|
||||
case AddrType::BC: return (state.B << 8) | state.C;
|
||||
case AddrType::DE: return (state.D << 8) | state.E;
|
||||
case AddrType::HL: return (state.H << 8) | state.L;
|
||||
case AddrType::C: return 0xFF00 + state.C;
|
||||
case AddrType::BC: return { (state.B << 8) | state.C, 1 };
|
||||
case AddrType::DE: return { (state.D << 8) | state.E, 1 };
|
||||
case AddrType::HL: return { (state.H << 8) | state.L, 1 };
|
||||
case AddrType::C: return { 0xFF00 + state.C, 1 };
|
||||
case AddrType::Suff:
|
||||
if((info.GetByteCode()[1] & 0x07) == 0x06) {
|
||||
return (state.H << 8) | state.L;
|
||||
return { (state.H << 8) | state.L, 1 };
|
||||
}
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "Debugger/DebugTypes.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class LabelManager;
|
||||
class EmuSettings;
|
||||
struct GbCpuState;
|
||||
|
@ -11,7 +10,7 @@ class GameboyDisUtils
|
|||
{
|
||||
public:
|
||||
static void GetDisassembly(DisassemblyInfo& info, string& out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings);
|
||||
static int32_t GetEffectiveAddress(DisassemblyInfo& info, GbCpuState& state);
|
||||
static EffectiveAddressInfo GetEffectiveAddress(DisassemblyInfo& info, GbCpuState& state);
|
||||
static uint8_t GetOpSize(uint8_t opCode);
|
||||
static bool IsJumpToSub(uint8_t opCode);
|
||||
static bool IsReturnInstruction(uint8_t opCode);
|
||||
|
|
|
@ -163,25 +163,25 @@ uint32_t NesDisUtils::GetOperandAddress(DisassemblyInfo& info, uint32_t memoryAd
|
|||
return opAddr;
|
||||
}
|
||||
|
||||
int32_t NesDisUtils::GetEffectiveAddress(DisassemblyInfo& info, NesCpuState& state, MemoryDumper* memoryDumper)
|
||||
EffectiveAddressInfo NesDisUtils::GetEffectiveAddress(DisassemblyInfo& info, NesCpuState& state, MemoryDumper* memoryDumper)
|
||||
{
|
||||
uint8_t* byteCode = info.GetByteCode();
|
||||
switch(_opMode[info.GetOpCode()]) {
|
||||
default: break;
|
||||
|
||||
case NesAddrMode::ZeroX: return (uint8_t)(byteCode[1] + state.X); break;
|
||||
case NesAddrMode::ZeroY: return (uint8_t)(byteCode[1] + state.Y); break;
|
||||
case NesAddrMode::ZeroX: return { (uint8_t)(byteCode[1] + state.X), 1 }; break;
|
||||
case NesAddrMode::ZeroY: return { (uint8_t)(byteCode[1] + state.Y), 1 }; break;
|
||||
|
||||
case NesAddrMode::IndX: {
|
||||
uint8_t zeroAddr = byteCode[1] + state.X;
|
||||
return memoryDumper->GetMemoryValue(MemoryType::NesMemory, zeroAddr) | memoryDumper->GetMemoryValue(MemoryType::NesMemory, (uint8_t)(zeroAddr + 1)) << 8;
|
||||
return { memoryDumper->GetMemoryValue(MemoryType::NesMemory, zeroAddr) | memoryDumper->GetMemoryValue(MemoryType::NesMemory, (uint8_t)(zeroAddr + 1)) << 8, 1 };
|
||||
}
|
||||
|
||||
case NesAddrMode::IndY:
|
||||
case NesAddrMode::IndYW: {
|
||||
uint8_t zeroAddr = byteCode[1];
|
||||
uint16_t addr = memoryDumper->GetMemoryValue(MemoryType::NesMemory, zeroAddr) | memoryDumper->GetMemoryValue(MemoryType::NesMemory, (uint8_t)(zeroAddr + 1)) << 8;
|
||||
return (uint16_t)(addr + state.Y);
|
||||
return { (uint16_t)(addr + state.Y), 1 };
|
||||
}
|
||||
|
||||
case NesAddrMode::Ind: {
|
||||
|
@ -190,22 +190,22 @@ int32_t NesDisUtils::GetEffectiveAddress(DisassemblyInfo& info, NesCpuState& sta
|
|||
//CPU bug when indirect address starts at the end of a page
|
||||
uint8_t lo = memoryDumper->GetMemoryValue(MemoryType::NesMemory, addr);
|
||||
uint8_t hi = memoryDumper->GetMemoryValue(MemoryType::NesMemory, addr & 0xFF00);
|
||||
return lo | (hi << 8);
|
||||
return { lo | (hi << 8), 1 };
|
||||
} else {
|
||||
return memoryDumper->GetMemoryValue(MemoryType::NesMemory, addr);
|
||||
return { memoryDumper->GetMemoryValue(MemoryType::NesMemory, addr), 1 };
|
||||
}
|
||||
}
|
||||
|
||||
case NesAddrMode::AbsX:
|
||||
case NesAddrMode::AbsXW:
|
||||
return (uint16_t)((byteCode[1] | (byteCode[2] << 8)) + state.X) & 0xFFFF;
|
||||
return { (uint16_t)((byteCode[1] | (byteCode[2] << 8)) + state.X) & 0xFFFF, 1 };
|
||||
|
||||
case NesAddrMode::AbsY:
|
||||
case NesAddrMode::AbsYW:
|
||||
return (uint16_t)((byteCode[1] | (byteCode[2] << 8)) + state.Y) & 0xFFFF;
|
||||
return { (uint16_t)((byteCode[1] | (byteCode[2] << 8)) + state.Y) & 0xFFFF, 1 };
|
||||
}
|
||||
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
|
||||
uint8_t NesDisUtils::GetOpSize(NesAddrMode addrMode)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "Debugger/DebugTypes.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class LabelManager;
|
||||
class MemoryDumper;
|
||||
class EmuSettings;
|
||||
|
@ -17,7 +16,7 @@ private:
|
|||
|
||||
public:
|
||||
static void GetDisassembly(DisassemblyInfo& info, string& out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings);
|
||||
static int32_t GetEffectiveAddress(DisassemblyInfo& info, NesCpuState& state, MemoryDumper* memoryDumper);
|
||||
static EffectiveAddressInfo GetEffectiveAddress(DisassemblyInfo& info, NesCpuState& state, MemoryDumper* memoryDumper);
|
||||
|
||||
static uint8_t GetOpSize(uint8_t opCode);
|
||||
static char const* const GetOpName(uint8_t opCode);
|
||||
|
|
|
@ -57,8 +57,3 @@ MemoryOperationInfo DummyPceCpu::GetOperationInfo(uint32_t index)
|
|||
{
|
||||
return _memOperations[index];
|
||||
}
|
||||
|
||||
int32_t DummyPceCpu::GetLastOperand()
|
||||
{
|
||||
return _operand;
|
||||
}
|
|
@ -174,7 +174,7 @@ void PceDisUtils::GetDisassembly(DisassemblyInfo& info, string& out, uint32_t me
|
|||
out += str.ToString();
|
||||
}
|
||||
|
||||
int32_t PceDisUtils::GetEffectiveAddress(DisassemblyInfo& info, PceConsole* console, PceCpuState& state)
|
||||
EffectiveAddressInfo PceDisUtils::GetEffectiveAddress(DisassemblyInfo& info, PceConsole* console, PceCpuState& state)
|
||||
{
|
||||
switch(_opMode[info.GetOpCode()]) {
|
||||
default: break;
|
||||
|
@ -202,13 +202,13 @@ int32_t PceDisUtils::GetEffectiveAddress(DisassemblyInfo& info, PceConsole* cons
|
|||
for(int i = count - 1; i > 0; i--) {
|
||||
MemoryOperationInfo opInfo = pceCpu.GetOperationInfo(i);
|
||||
if(opInfo.Type != MemoryOperationType::ExecOperand) {
|
||||
return opInfo.Address;
|
||||
return { (int32_t)opInfo.Address, 1 };
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
|
||||
uint8_t PceDisUtils::GetOpSize(PceAddrMode addrMode)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "Debugger/DebugTypes.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class LabelManager;
|
||||
class MemoryDumper;
|
||||
class EmuSettings;
|
||||
|
@ -17,7 +16,7 @@ private:
|
|||
|
||||
public:
|
||||
static void GetDisassembly(DisassemblyInfo& info, string& out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings);
|
||||
static int32_t GetEffectiveAddress(DisassemblyInfo& info, PceConsole* console, PceCpuState& state);
|
||||
static EffectiveAddressInfo GetEffectiveAddress(DisassemblyInfo& info, PceConsole* console, PceCpuState& state);
|
||||
|
||||
static uint8_t GetOpSize(uint8_t opCode);
|
||||
static char const* const GetOpName(uint8_t opCode);
|
||||
|
|
|
@ -307,7 +307,6 @@ private:
|
|||
|
||||
public:
|
||||
void SetDummyState(PceCpuState& state);
|
||||
int32_t GetLastOperand();
|
||||
|
||||
uint32_t GetOperationCount();
|
||||
MemoryOperationInfo GetOperationInfo(uint32_t index);
|
||||
|
|
|
@ -210,14 +210,14 @@ void Cx4DisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me
|
|||
out += str.ToString();
|
||||
}
|
||||
|
||||
int32_t Cx4DisUtils::GetEffectiveAddress(DisassemblyInfo& info, Cx4State& state, MemoryDumper* memoryDumper)
|
||||
EffectiveAddressInfo 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;
|
||||
default: return {};
|
||||
|
||||
case 0x08:
|
||||
case 0x0C:
|
||||
|
@ -231,9 +231,9 @@ int32_t Cx4DisUtils::GetEffectiveAddress(DisassemblyInfo& info, Cx4State& state,
|
|||
case 0x38:
|
||||
//Show destination address for branches & JSR
|
||||
if(param1) {
|
||||
return (state.P << 9) | (param2 * 2);
|
||||
return { (state.P << 9) | (param2 * 2), 1 };
|
||||
} else {
|
||||
return state.Cache.Address[state.Cache.Page] | (param2 * 2);
|
||||
return { (int32_t)(state.Cache.Address[state.Cache.Page] | (param2 * 2)), 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "Debugger/DisassemblyInfo.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class LabelManager;
|
||||
class EmuSettings;
|
||||
class MemoryDumper;
|
||||
|
@ -11,7 +11,7 @@ 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);
|
||||
static EffectiveAddressInfo GetEffectiveAddress(DisassemblyInfo& info, Cx4State& state, MemoryDumper* memoryDumper);
|
||||
static bool IsConditionalJump(uint8_t opCode, uint8_t param);
|
||||
static bool IsUnconditionalJump(uint8_t opCode);
|
||||
static bool IsJumpToSub(uint8_t opCode);
|
||||
|
|
|
@ -212,7 +212,7 @@ void GsuDisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me
|
|||
out += str.ToString();
|
||||
}
|
||||
|
||||
int32_t GsuDisUtils::GetEffectiveAddress(DisassemblyInfo& info, SnesConsole* console, GsuState& state)
|
||||
EffectiveAddressInfo GsuDisUtils::GetEffectiveAddress(DisassemblyInfo& info, SnesConsole* console, GsuState& state)
|
||||
{
|
||||
uint8_t opCode = info.GetOpCode();
|
||||
bool alt1 = (info.GetFlags() & 0x01) != 0;
|
||||
|
@ -222,19 +222,19 @@ int32_t GsuDisUtils::GetEffectiveAddress(DisassemblyInfo& info, SnesConsole* con
|
|||
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);
|
||||
return { 0x700000 | (info.GetByteCode()[1] << 1) | (state.RamBank << 16), 2 };
|
||||
}
|
||||
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);
|
||||
return { 0x700000 | info.GetByteCode()[1] | (info.GetByteCode()[2] << 8) | (state.RamBank << 16), 2 };
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool GsuDisUtils::IsUnconditionalJump(uint8_t opCode)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "Debugger/DebugTypes.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class LabelManager;
|
||||
class EmuSettings;
|
||||
class SnesConsole;
|
||||
|
@ -11,7 +11,7 @@ class GsuDisUtils
|
|||
{
|
||||
public:
|
||||
static void GetDisassembly(DisassemblyInfo &info, string &out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings);
|
||||
static int32_t GetEffectiveAddress(DisassemblyInfo& info, SnesConsole* console, GsuState& state);
|
||||
static EffectiveAddressInfo GetEffectiveAddress(DisassemblyInfo& info, SnesConsole* console, GsuState& state);
|
||||
static bool IsUnconditionalJump(uint8_t opCode);
|
||||
static bool IsConditionalJump(uint8_t opCode);
|
||||
static uint8_t GetOpSize(uint8_t opCode);
|
||||
|
|
|
@ -103,17 +103,42 @@ uint32_t SnesDisUtils::GetOperandAddress(DisassemblyInfo &info, uint32_t memoryA
|
|||
return opAddr;
|
||||
}
|
||||
|
||||
int32_t SnesDisUtils::GetEffectiveAddress(DisassemblyInfo &info, SnesConsole *console, SnesCpuState &state, CpuType type)
|
||||
EffectiveAddressInfo SnesDisUtils::GetEffectiveAddress(DisassemblyInfo &info, SnesConsole *console, SnesCpuState &state, CpuType type)
|
||||
{
|
||||
if(HasEffectiveAddress(SnesDisUtils::OpMode[info.GetOpCode()])) {
|
||||
DummySnesCpu cpu(console, type);
|
||||
DummySnesCpu dummyCpu(console, type);
|
||||
state.PS &= ~(ProcFlags::IndexMode8 | ProcFlags::MemoryMode8);
|
||||
state.PS |= info.GetFlags();
|
||||
cpu.SetDummyState(state);
|
||||
cpu.Exec();
|
||||
return cpu.GetLastOperand();
|
||||
dummyCpu.SetDummyState(state);
|
||||
dummyCpu.Exec();
|
||||
|
||||
bool isJump = SnesDisUtils::IsUnconditionalJump(info.GetOpCode()) || SnesDisUtils::IsUnconditionalJump(info.GetOpCode());
|
||||
if(isJump) {
|
||||
//For jumps, return the target address, and show no value
|
||||
return { dummyCpu.GetLastOperand(), 0 };
|
||||
}
|
||||
|
||||
//For everything else, return the last read/write address
|
||||
uint32_t count = dummyCpu.GetOperationCount();
|
||||
for(int i = count - 1; i > 0; i--) {
|
||||
MemoryOperationInfo opInfo = dummyCpu.GetOperationInfo(i);
|
||||
|
||||
if(opInfo.Type != MemoryOperationType::ExecOperand) {
|
||||
MemoryOperationInfo prevOpInfo = dummyCpu.GetOperationInfo(i - 1);
|
||||
EffectiveAddressInfo result;
|
||||
if(prevOpInfo.Type == opInfo.Type) {
|
||||
//For 16-bit read/writes, return the first address
|
||||
result.Address = prevOpInfo.Address;
|
||||
result.ValueSize = 2;
|
||||
} else {
|
||||
result.Address = opInfo.Address;
|
||||
result.ValueSize = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool SnesDisUtils::CanDisassembleNextOp(uint8_t opCode)
|
||||
|
@ -268,7 +293,17 @@ CdlFlags::CdlFlags SnesDisUtils::GetOpFlags(uint8_t opCode, uint32_t pc, uint32_
|
|||
|
||||
bool SnesDisUtils::IsJumpToSub(uint8_t opCode)
|
||||
{
|
||||
return opCode == 0x20 || opCode == 0x22 || opCode == 0xFC; //JSR, JSL
|
||||
switch(opCode) {
|
||||
case 0x00: //BRK
|
||||
case 0x02: //COP
|
||||
case 0x20: //JSR
|
||||
case 0x22: //JSL
|
||||
case 0xFC: //JSR
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SnesDisUtils::IsReturnInstruction(uint8_t opCode)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "Debugger/DebugTypes.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class SnesConsole;
|
||||
class LabelManager;
|
||||
class EmuSettings;
|
||||
|
@ -30,7 +29,7 @@ public:
|
|||
static CdlFlags::CdlFlags GetOpFlags(uint8_t opCode, uint32_t pc, uint32_t prevPc);
|
||||
static bool IsJumpToSub(uint8_t opCode);
|
||||
static bool IsReturnInstruction(uint8_t opCode);
|
||||
static int32_t GetEffectiveAddress(DisassemblyInfo &info, SnesConsole* console, SnesCpuState &state, CpuType type);
|
||||
static EffectiveAddressInfo GetEffectiveAddress(DisassemblyInfo& info, SnesConsole* console, SnesCpuState& state, CpuType type);
|
||||
|
||||
static bool CanDisassembleNextOp(uint8_t opCode);
|
||||
static void UpdateCpuFlags(uint8_t opCode, uint8_t* byteCode, uint8_t& cpuFlags);
|
||||
|
|
|
@ -129,7 +129,7 @@ void SpcDisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me
|
|||
out += str.ToString();
|
||||
}
|
||||
|
||||
int32_t SpcDisUtils::GetEffectiveAddress(DisassemblyInfo &info, SnesConsole *console, SpcState &state)
|
||||
EffectiveAddressInfo SpcDisUtils::GetEffectiveAddress(DisassemblyInfo &info, SnesConsole *console, SpcState &state)
|
||||
{
|
||||
if(_needAddress[info.GetOpCode()]) {
|
||||
Spc* spc = console->GetSpc();
|
||||
|
@ -141,11 +141,11 @@ int32_t SpcDisUtils::GetEffectiveAddress(DisassemblyInfo &info, SnesConsole *con
|
|||
for(int i = count - 1; i > 0; i--) {
|
||||
MemoryOperationInfo opInfo = dummySpc.GetOperationInfo(i);
|
||||
if(opInfo.Type != MemoryOperationType::ExecOperand) {
|
||||
return opInfo.Address;
|
||||
return { (int32_t)opInfo.Address, 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return {};
|
||||
}
|
||||
|
||||
uint8_t SpcDisUtils::GetOpSize(uint8_t opCode)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "Debugger/DisassemblyInfo.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class SnesConsole;
|
||||
class LabelManager;
|
||||
class EmuSettings;
|
||||
|
@ -11,7 +11,7 @@ class SpcDisUtils
|
|||
{
|
||||
public:
|
||||
static void GetDisassembly(DisassemblyInfo &info, string &out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings);
|
||||
static int32_t GetEffectiveAddress(DisassemblyInfo &info, SnesConsole *console, SpcState &state);
|
||||
static EffectiveAddressInfo GetEffectiveAddress(DisassemblyInfo &info, SnesConsole *console, SpcState &state);
|
||||
static uint8_t GetOpSize(uint8_t opCode);
|
||||
static bool IsUnconditionalJump(uint8_t opCode);
|
||||
static bool IsConditionalJump(uint8_t opCode);
|
||||
|
|
|
@ -113,10 +113,10 @@ namespace Mesen.Debugger
|
|||
|
||||
this.Address = data.Address;
|
||||
this.AbsoluteAddress = data.AbsoluteAddress;
|
||||
this.EffectiveAddress = data.EffectiveAddress;
|
||||
this.EffectiveAddress = data.EffectiveAddress.Address;
|
||||
this.Flags = (LineFlags)data.Flags;
|
||||
this.Value = data.Value;
|
||||
this.ValueSize = data.ValueSize;
|
||||
this.ValueSize = data.EffectiveAddress.ValueSize;
|
||||
}
|
||||
|
||||
private string ConvertString(byte[] stringArray)
|
||||
|
@ -158,7 +158,13 @@ namespace Mesen.Debugger
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct EffectiveAddressInfo
|
||||
{
|
||||
public Int32 Address;
|
||||
public byte ValueSize;
|
||||
}
|
||||
|
||||
public struct InteropCodeLineData
|
||||
{
|
||||
public Int32 Address;
|
||||
|
@ -166,9 +172,8 @@ namespace Mesen.Debugger
|
|||
public byte OpSize;
|
||||
public UInt16 Flags;
|
||||
|
||||
public Int32 EffectiveAddress;
|
||||
public EffectiveAddressInfo EffectiveAddress;
|
||||
public UInt16 Value;
|
||||
public byte ValueSize;
|
||||
public CpuType LineCpuType;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
|
|
Loading…
Add table
Reference in a new issue