mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-23 17:19:39 +00:00
Debugger: Labels/comments now work with built-in ram, work ram and save ram
This commit is contained in:
parent
502cc47c70
commit
512e37c6af
@ -783,7 +783,7 @@ int32_t BaseMapper::ToAbsoluteAddress(uint16_t addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t BaseMapper::ToAbsoluteRamAddress(uint16_t addr)
|
||||
int32_t BaseMapper::ToAbsoluteWorkRamAddress(uint16_t addr)
|
||||
{
|
||||
uint8_t *prgRamAddr = _prgPages[addr >> 8] + (addr & 0xFF);
|
||||
if(prgRamAddr >= _workRam && prgRamAddr < _workRam + _workRamSize) {
|
||||
@ -792,6 +792,15 @@ int32_t BaseMapper::ToAbsoluteRamAddress(uint16_t addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t BaseMapper::ToAbsoluteSaveRamAddress(uint16_t addr)
|
||||
{
|
||||
uint8_t *prgRamAddr = _prgPages[addr >> 8] + (addr & 0xFF);
|
||||
if(prgRamAddr >= _saveRam && prgRamAddr < _saveRam + _saveRamSize) {
|
||||
return (uint32_t)(prgRamAddr - _saveRam);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t BaseMapper::ToAbsoluteChrAddress(uint16_t addr)
|
||||
{
|
||||
uint8_t *chrAddr = _chrPages[addr >> 8] + (addr & 0xFF);
|
||||
@ -801,9 +810,17 @@ int32_t BaseMapper::ToAbsoluteChrAddress(uint16_t addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t BaseMapper::FromAbsoluteAddress(uint32_t addr)
|
||||
int32_t BaseMapper::FromAbsoluteAddress(uint32_t addr, AddressType type)
|
||||
{
|
||||
uint8_t* ptrAddress = _prgRom + addr;
|
||||
uint8_t* ptrAddress;
|
||||
|
||||
switch(type) {
|
||||
case AddressType::PrgRom: ptrAddress = _prgRom; break;
|
||||
case AddressType::WorkRam: ptrAddress = _workRam; break;
|
||||
case AddressType::SaveRam: ptrAddress = _saveRam; break;
|
||||
default: return -1;
|
||||
}
|
||||
ptrAddress += addr;
|
||||
|
||||
for(int i = 0; i < 256; i++) {
|
||||
uint8_t* pageAddress = _prgPages[i];
|
||||
@ -811,7 +828,7 @@ int32_t BaseMapper::FromAbsoluteAddress(uint32_t addr)
|
||||
return (i << 8) + (uint32_t)(ptrAddress - pageAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Address is currently not mapped
|
||||
return -1;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "MessageManager.h"
|
||||
#include "RomLoader.h"
|
||||
#include "EmulationSettings.h"
|
||||
#include "DebuggerTypes.h"
|
||||
|
||||
enum class DebugMemoryType;
|
||||
|
||||
@ -232,7 +233,8 @@ public:
|
||||
uint32_t CopyMemory(DebugMemoryType type, uint8_t* buffer);
|
||||
void WriteMemory(DebugMemoryType type, uint8_t* buffer);
|
||||
int32_t ToAbsoluteAddress(uint16_t addr);
|
||||
int32_t ToAbsoluteRamAddress(uint16_t addr);
|
||||
int32_t ToAbsoluteSaveRamAddress(uint16_t addr);
|
||||
int32_t ToAbsoluteWorkRamAddress(uint16_t addr);
|
||||
int32_t ToAbsoluteChrAddress(uint16_t addr);
|
||||
int32_t FromAbsoluteAddress(uint32_t addr);
|
||||
int32_t FromAbsoluteAddress(uint32_t addr, AddressType type = AddressType::PrgRom);
|
||||
};
|
@ -435,6 +435,8 @@
|
||||
<ClInclude Include="Cc21.h" />
|
||||
<ClInclude Include="ColorDreams46.h" />
|
||||
<ClInclude Include="DaouInfosys.h" />
|
||||
<ClInclude Include="DebuggerTypes.h" />
|
||||
<ClInclude Include="LabelManager.h" />
|
||||
<ClInclude Include="MemoryDumper.h" />
|
||||
<ClInclude Include="DebugState.h" />
|
||||
<ClInclude Include="DefaultVideoFilter.h" />
|
||||
@ -748,6 +750,7 @@
|
||||
<ClCompile Include="Console.cpp" />
|
||||
<ClCompile Include="ControlManager.cpp" />
|
||||
<ClCompile Include="Debugger.cpp" />
|
||||
<ClCompile Include="LabelManager.cpp" />
|
||||
<ClCompile Include="MemoryDumper.cpp" />
|
||||
<ClCompile Include="DefaultVideoFilter.cpp" />
|
||||
<ClCompile Include="DeltaModulationChannel.cpp" />
|
||||
|
@ -1090,6 +1090,12 @@
|
||||
<ClInclude Include="MemoryDumper.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LabelManager.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DebuggerTypes.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@ -1269,5 +1275,8 @@
|
||||
<ClCompile Include="MemoryDumper.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LabelManager.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -10,6 +10,7 @@
|
||||
#include "SoundMixer.h"
|
||||
#include "CodeDataLogger.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
#include "LabelManager.h"
|
||||
|
||||
Debugger* Debugger::Instance = nullptr;
|
||||
const int Debugger::BreakpointTypeCount;
|
||||
@ -23,6 +24,7 @@ Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<
|
||||
_memoryManager = memoryManager;
|
||||
_mapper = mapper;
|
||||
|
||||
_labelManager.reset(new LabelManager(_mapper));
|
||||
_disassembler.reset(new Disassembler(memoryManager->GetInternalRAM(), mapper->GetPrgRom(), mapper->GetPrgSize(), mapper->GetWorkRam(), mapper->GetPrgSize(true)));
|
||||
_codeDataLogger.reset(new CodeDataLogger(mapper->GetPrgSize(), mapper->GetChrSize()));
|
||||
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, _mapper, _codeDataLogger));
|
||||
@ -127,25 +129,9 @@ CdlRatios Debugger::GetCdlRatios()
|
||||
return _codeDataLogger->GetRatios();
|
||||
}
|
||||
|
||||
void Debugger::SetLabel(uint32_t address, string label, string comment)
|
||||
shared_ptr<LabelManager> Debugger::GetLabelManager()
|
||||
{
|
||||
ExpressionEvaluator::ResetCustomCache();
|
||||
|
||||
auto existingLabel = _codeLabels.find(address);
|
||||
if(existingLabel != _codeLabels.end()) {
|
||||
_codeLabelReverseLookup.erase(existingLabel->second);
|
||||
}
|
||||
|
||||
_codeLabels.erase(address);
|
||||
if(!label.empty()) {
|
||||
_codeLabels.emplace(address, label);
|
||||
_codeLabelReverseLookup.emplace(label, address);
|
||||
}
|
||||
|
||||
_codeComments.erase(address);
|
||||
if(!comment.empty()) {
|
||||
_codeComments.emplace(address, comment);
|
||||
}
|
||||
return _labelManager;
|
||||
}
|
||||
|
||||
void Debugger::SetBreakpoints(Breakpoint breakpoints[], uint32_t length)
|
||||
@ -311,7 +297,7 @@ void Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
|
||||
//Check if a breakpoint has been hit and freeze execution if one has
|
||||
bool breakDone = false;
|
||||
int32_t absoluteAddr = _mapper->ToAbsoluteAddress(addr);
|
||||
int32_t absoluteRamAddr = _mapper->ToAbsoluteRamAddress(addr);
|
||||
int32_t absoluteRamAddr = _mapper->ToAbsoluteWorkRamAddress(addr);
|
||||
|
||||
if(absoluteAddr >= 0) {
|
||||
if(type == MemoryOperationType::ExecOperand) {
|
||||
@ -489,34 +475,29 @@ string Debugger::GenerateOutput()
|
||||
bool showOnlyDiassembledCode = CheckFlag(DebuggerFlags::ShowOnlyDisassembledCode);
|
||||
|
||||
//Get code in internal RAM
|
||||
output << _disassembler->GetCode(0x0000, 0x1FFF, 0x0000, PrgMemoryType::PrgRom, showEffectiveAddresses, showOnlyDiassembledCode, cpuState, _memoryManager, _codeLabels, _codeComments);
|
||||
output << _disassembler->GetCode(0x0000, 0x1FFF, 0x0000, PrgMemoryType::PrgRom, showEffectiveAddresses, showOnlyDiassembledCode, cpuState, _memoryManager, _labelManager);
|
||||
output << "2000\x1\x1\x1--End of internal RAM--\n";
|
||||
|
||||
for(uint32_t i = 0x2000; i < 0x10000; i += 0x100) {
|
||||
//Merge all sequential ranges into 1 chunk
|
||||
int32_t romAddr = _mapper->ToAbsoluteAddress(i);
|
||||
int32_t ramAddr = _mapper->ToAbsoluteRamAddress(i);
|
||||
PrgMemoryType memoryType = PrgMemoryType::PrgRom;
|
||||
int32_t addr = _mapper->ToAbsoluteAddress(i);
|
||||
if(addr < 0) {
|
||||
addr = _mapper->ToAbsoluteWorkRamAddress(i);
|
||||
memoryType = PrgMemoryType::WorkRam;
|
||||
}
|
||||
uint32_t startMemoryAddr = i;
|
||||
int32_t startAddr, endAddr;
|
||||
|
||||
if(romAddr >= 0) {
|
||||
startAddr = romAddr;
|
||||
if(addr >= 0) {
|
||||
startAddr = addr;
|
||||
endAddr = startAddr + 0xFF;
|
||||
while(romAddr + 0x100 == _mapper->ToAbsoluteAddress(i + 0x100) && i < 0x10000) {
|
||||
while(addr + 0x100 == (memoryType == PrgMemoryType::PrgRom ? _mapper->ToAbsoluteAddress(i + 0x100) : _mapper->ToAbsoluteWorkRamAddress(i + 0x100)) && i < 0x10000) {
|
||||
endAddr += 0x100;
|
||||
romAddr += 0x100;
|
||||
addr += 0x100;
|
||||
i+=0x100;
|
||||
}
|
||||
output << _disassembler->GetCode(startAddr, endAddr, startMemoryAddr, PrgMemoryType::PrgRom, showEffectiveAddresses, showOnlyDiassembledCode, cpuState, _memoryManager, _codeLabels, _codeComments);
|
||||
} else if(ramAddr >= 0) {
|
||||
startAddr = ramAddr;
|
||||
endAddr = startAddr + 0xFF;
|
||||
while(ramAddr + 0x100 == _mapper->ToAbsoluteRamAddress(i + 0x100) && i < 0x10000) {
|
||||
endAddr += 0x100;
|
||||
ramAddr += 0x100;
|
||||
i += 0x100;
|
||||
}
|
||||
output << _disassembler->GetCode(startAddr, endAddr, startMemoryAddr, PrgMemoryType::WorkRam, showEffectiveAddresses, showOnlyDiassembledCode, cpuState, _memoryManager, _codeLabels, _codeComments);
|
||||
output << _disassembler->GetCode(startAddr, endAddr, startMemoryAddr, memoryType, showEffectiveAddresses, showOnlyDiassembledCode, cpuState, _memoryManager, _labelManager);
|
||||
}
|
||||
}
|
||||
|
||||
@ -533,9 +514,19 @@ uint8_t Debugger::GetMemoryValue(uint32_t addr)
|
||||
return _memoryManager->DebugRead(addr);
|
||||
}
|
||||
|
||||
int32_t Debugger::GetRelativeAddress(uint32_t addr)
|
||||
int32_t Debugger::GetRelativeAddress(uint32_t addr, AddressType type)
|
||||
{
|
||||
return _mapper->FromAbsoluteAddress(addr);
|
||||
switch(type) {
|
||||
case AddressType::InternalRam:
|
||||
return addr;
|
||||
|
||||
case AddressType::PrgRom:
|
||||
case AddressType::WorkRam:
|
||||
case AddressType::SaveRam:
|
||||
return _mapper->FromAbsoluteAddress(addr, type);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t Debugger::GetAbsoluteAddress(uint32_t addr)
|
||||
@ -615,11 +606,32 @@ shared_ptr<MemoryDumper> Debugger::GetMemoryDumper()
|
||||
return _memoryDumper;
|
||||
}
|
||||
|
||||
int32_t Debugger::GetCodeLabelAddress(string label)
|
||||
void Debugger::GetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info)
|
||||
{
|
||||
auto result = _codeLabelReverseLookup.find(label);
|
||||
if(result != _codeLabelReverseLookup.end()) {
|
||||
return _mapper->FromAbsoluteAddress(result->second);
|
||||
if(relativeAddr < 0x2000) {
|
||||
info->Address = relativeAddr;
|
||||
info->Type = AddressType::InternalRam;
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t addr = _mapper->ToAbsoluteAddress(relativeAddr);
|
||||
if(addr >= 0) {
|
||||
info->Address = addr;
|
||||
info->Type = AddressType::PrgRom;
|
||||
return;
|
||||
}
|
||||
|
||||
addr = _mapper->ToAbsoluteWorkRamAddress(relativeAddr);
|
||||
if(addr >= 0) {
|
||||
info->Address = addr;
|
||||
info->Type = AddressType::WorkRam;
|
||||
return;
|
||||
}
|
||||
|
||||
addr = _mapper->ToAbsoluteSaveRamAddress(relativeAddr);
|
||||
if(addr >= 0) {
|
||||
info->Address = addr;
|
||||
info->Type = AddressType::SaveRam;
|
||||
return;
|
||||
}
|
||||
return -1;
|
||||
}
|
@ -4,11 +4,9 @@
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
using std::atomic;
|
||||
using std::deque;
|
||||
using std::unordered_set;
|
||||
using std::unordered_map;
|
||||
|
||||
#include "DebugState.h"
|
||||
#include "Breakpoint.h"
|
||||
@ -16,19 +14,14 @@ using std::unordered_map;
|
||||
#include "../Utilities/SimpleLock.h"
|
||||
#include "CodeDataLogger.h"
|
||||
#include "MemoryDumper.h"
|
||||
#include "DebuggerTypes.h"
|
||||
|
||||
class CPU;
|
||||
class PPU;
|
||||
class MemoryManager;
|
||||
class Console;
|
||||
class Disassembler;
|
||||
|
||||
enum class DebuggerFlags
|
||||
{
|
||||
PpuPartialDraw = 1,
|
||||
ShowEffectiveAddresses = 2,
|
||||
ShowOnlyDisassembledCode = 4
|
||||
};
|
||||
class LabelManager;
|
||||
|
||||
class Debugger
|
||||
{
|
||||
@ -57,10 +50,6 @@ private:
|
||||
vector<Breakpoint> _breakpoints[BreakpointTypeCount];
|
||||
bool _hasBreakpoint[BreakpointTypeCount];
|
||||
|
||||
unordered_map<uint32_t, string> _codeLabels;
|
||||
unordered_map<string, uint32_t> _codeLabelReverseLookup;
|
||||
unordered_map<uint32_t, string> _codeComments;
|
||||
|
||||
deque<uint32_t> _callstackAbsolute;
|
||||
deque<uint32_t> _callstackRelative;
|
||||
|
||||
@ -70,6 +59,7 @@ private:
|
||||
|
||||
SimpleLock _breakLock;
|
||||
|
||||
shared_ptr<LabelManager> _labelManager;
|
||||
shared_ptr<TraceLogger> _traceLogger;
|
||||
|
||||
//Used to alter the executing address via "Set Next Statement"
|
||||
@ -109,9 +99,8 @@ public:
|
||||
bool CheckFlag(DebuggerFlags flag);
|
||||
|
||||
void SetBreakpoints(Breakpoint breakpoints[], uint32_t length);
|
||||
void SetLabel(uint32_t address, string label, string comment);
|
||||
|
||||
int32_t GetCodeLabelAddress(string label);
|
||||
|
||||
shared_ptr<LabelManager> GetLabelManager();
|
||||
|
||||
void GetFunctionEntryPoints(int32_t* entryPoints);
|
||||
void GetCallstack(int32_t* callstackAbsolute, int32_t* callstackRelative);
|
||||
@ -139,8 +128,9 @@ public:
|
||||
string* GetCode();
|
||||
|
||||
uint8_t GetMemoryValue(uint32_t addr);
|
||||
int32_t GetRelativeAddress(uint32_t addr);
|
||||
int32_t GetAbsoluteAddress(uint32_t addr);
|
||||
int32_t GetRelativeAddress(uint32_t addr, AddressType type);
|
||||
int32_t GetAbsoluteAddress(uint32_t addr);
|
||||
void GetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info);
|
||||
|
||||
void StartTraceLogger(TraceLoggerOptions options);
|
||||
void StopTraceLogger();
|
||||
|
22
Core/DebuggerTypes.h
Normal file
22
Core/DebuggerTypes.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
enum class DebuggerFlags
|
||||
{
|
||||
PpuPartialDraw = 1,
|
||||
ShowEffectiveAddresses = 2,
|
||||
ShowOnlyDisassembledCode = 4
|
||||
};
|
||||
|
||||
enum class AddressType
|
||||
{
|
||||
InternalRam = 0,
|
||||
PrgRom = 1,
|
||||
WorkRam = 2,
|
||||
SaveRam = 3,
|
||||
};
|
||||
|
||||
struct AddressTypeInfo
|
||||
{
|
||||
int32_t Address;
|
||||
AddressType Type;
|
||||
};
|
@ -4,6 +4,7 @@
|
||||
#include "BaseMapper.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "CPU.h"
|
||||
#include "LabelManager.h"
|
||||
|
||||
Disassembler::Disassembler(uint8_t* internalRam, uint8_t* prgRom, uint32_t prgSize, uint8_t* prgRam, uint32_t prgRamSize)
|
||||
{
|
||||
@ -186,7 +187,8 @@ vector<string> Disassembler::SplitComment(string input)
|
||||
return result;
|
||||
}
|
||||
|
||||
string Disassembler::GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memoryAddr, PrgMemoryType memoryType, bool showEffectiveAddresses, bool showOnlyDiassembledCode, State& cpuState, shared_ptr<MemoryManager> memoryManager, unordered_map<uint32_t, string> &codeLabels, unordered_map<uint32_t, string> &codeComments) {
|
||||
string Disassembler::GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memoryAddr, PrgMemoryType memoryType, bool showEffectiveAddresses, bool showOnlyDiassembledCode, State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
{
|
||||
std::ostringstream output;
|
||||
|
||||
uint16_t resetVector = memoryManager->DebugReadWord(CPU::ResetVector);
|
||||
@ -212,11 +214,9 @@ string Disassembler::GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memo
|
||||
uint32_t byteCount = 0;
|
||||
bool skippingCode = false;
|
||||
while(addr <= endAddr) {
|
||||
auto labelSearch = codeLabels.find(addr);
|
||||
auto commentSearch = codeComments.find(addr);
|
||||
string label = labelSearch != codeLabels.end() ? labelSearch->second : "";
|
||||
string labelString = label.empty() ? "" : ("\x1\x1\x1" + labelSearch->second + ":\n");
|
||||
string commentString = commentSearch != codeComments.end() ? commentSearch->second : "";
|
||||
string label = labelManager->GetLabel(memoryAddr);
|
||||
string commentString = labelManager->GetComment(memoryAddr);
|
||||
string labelString = label.empty() ? "" : ("\x1\x1\x1" + label + ":\n");
|
||||
bool multilineComment = commentString.find_first_of('\n') != string::npos;
|
||||
string singleLineComment = "";
|
||||
string multiLineComment = "";
|
||||
@ -245,7 +245,7 @@ string Disassembler::GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memo
|
||||
skippingCode = false;
|
||||
}
|
||||
|
||||
string effectiveAddress = showEffectiveAddresses ? info->GetEffectiveAddressString(cpuState, memoryManager, &codeLabels) : "";
|
||||
string effectiveAddress = showEffectiveAddresses ? info->GetEffectiveAddressString(cpuState, memoryManager, labelManager) : "";
|
||||
|
||||
if(info->IsSubEntryPoint()) {
|
||||
if(label.empty()) {
|
||||
@ -263,7 +263,7 @@ string Disassembler::GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memo
|
||||
|
||||
output << multiLineComment;
|
||||
output << labelString;
|
||||
output << std::hex << std::uppercase << memoryAddr << "\x1" << addr << "\x1" << info->GetByteCode() << "\x1 " << info->ToString(memoryAddr, memoryManager, &codeLabels) << "\x2" << effectiveAddress;
|
||||
output << std::hex << std::uppercase << memoryAddr << "\x1" << addr << "\x1" << info->GetByteCode() << "\x1 " << info->ToString(memoryAddr, memoryManager, labelManager) << "\x2" << effectiveAddress;
|
||||
output << singleLineComment;
|
||||
|
||||
output << "\n";
|
||||
|
@ -1,12 +1,11 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "BaseMapper.h"
|
||||
#include <unordered_map>
|
||||
using std::unordered_map;
|
||||
|
||||
struct State;
|
||||
class MemoryManager;
|
||||
class DisassemblyInfo;
|
||||
class LabelManager;
|
||||
|
||||
class Disassembler
|
||||
{
|
||||
@ -29,7 +28,7 @@ public:
|
||||
uint32_t BuildCache(int32_t absoluteAddr, int32_t absoluteRamAddr, uint16_t memoryAddr, bool isSubEntryPoint);
|
||||
void InvalidateCache(uint16_t memoryAddr, int32_t absoluteRamAddr);
|
||||
|
||||
string GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memoryAddr, PrgMemoryType memoryType, bool showEffectiveAddresses, bool showOnlyDiassembledCode, State& cpuState, shared_ptr<MemoryManager> memoryManager, unordered_map<uint32_t, string> &codeLabels, unordered_map<uint32_t, string> &codeComments);
|
||||
string GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memoryAddr, PrgMemoryType memoryType, bool showEffectiveAddresses, bool showOnlyDiassembledCode, State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
|
||||
shared_ptr<DisassemblyInfo> GetDisassemblyInfo(int32_t absoluteAddress, int32_t absoluteRamAddress, uint16_t memoryAddress);
|
||||
};
|
||||
|
@ -1,12 +1,13 @@
|
||||
#include "stdafx.h"
|
||||
#include "DisassemblyInfo.h"
|
||||
#include "CPU.h"
|
||||
#include "LabelManager.h"
|
||||
|
||||
string DisassemblyInfo::OPName[256];
|
||||
AddrMode DisassemblyInfo::OPMode[256];
|
||||
uint32_t DisassemblyInfo::OPSize[256];
|
||||
|
||||
string DisassemblyInfo::ToString(uint32_t memoryAddr, shared_ptr<MemoryManager> memoryManager, std::unordered_map<uint32_t, string> *codeLabels)
|
||||
string DisassemblyInfo::ToString(uint32_t memoryAddr, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
{
|
||||
std::ostringstream output;
|
||||
uint8_t opCode = *_opPointer;
|
||||
@ -24,11 +25,8 @@ string DisassemblyInfo::ToString(uint32_t memoryAddr, shared_ptr<MemoryManager>
|
||||
}
|
||||
|
||||
string operandValue;
|
||||
if(codeLabels) {
|
||||
auto result = codeLabels->find(memoryManager->ToAbsolutePrgAddress(_opAddr));
|
||||
if(result != codeLabels->end()) {
|
||||
operandValue = result->second;
|
||||
}
|
||||
if(labelManager && _opMode != AddrMode::Imm) {
|
||||
operandValue = labelManager->GetLabel(_opAddr);
|
||||
}
|
||||
|
||||
if(operandValue.empty()) {
|
||||
@ -110,17 +108,17 @@ void DisassemblyInfo::SetSubEntryPoint()
|
||||
_isSubEntryPoint = true;
|
||||
}
|
||||
|
||||
string DisassemblyInfo::GetEffectiveAddressString(State& cpuState, shared_ptr<MemoryManager> memoryManager, std::unordered_map<uint32_t, string> *codeLabels)
|
||||
string DisassemblyInfo::GetEffectiveAddressString(State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
{
|
||||
int32_t effectiveAddress = GetEffectiveAddress(cpuState, memoryManager);
|
||||
if(effectiveAddress < 0) {
|
||||
return "";
|
||||
} else {
|
||||
bool empty = true;
|
||||
if(codeLabels) {
|
||||
auto result = codeLabels->find(memoryManager->ToAbsolutePrgAddress(effectiveAddress));
|
||||
if(result != codeLabels->end()) {
|
||||
return " @ " + result->second;
|
||||
if(labelManager) {
|
||||
string label = labelManager->GetLabel(effectiveAddress);
|
||||
if(!label.empty()) {
|
||||
return " @ " + label;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <unordered_map>
|
||||
#include "CPU.h"
|
||||
|
||||
class LabelManager;
|
||||
|
||||
class DisassemblyInfo
|
||||
{
|
||||
public:
|
||||
@ -26,9 +28,9 @@ public:
|
||||
void SetSubEntryPoint();
|
||||
|
||||
int32_t GetEffectiveAddress(State& cpuState, shared_ptr<MemoryManager> memoryManager);
|
||||
string GetEffectiveAddressString(State& cpuState, shared_ptr<MemoryManager> memoryManager, std::unordered_map<uint32_t, string> *codeLabels);
|
||||
string GetEffectiveAddressString(State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
|
||||
string ToString(uint32_t memoryAddr, shared_ptr<MemoryManager> memoryManager, std::unordered_map<uint32_t, string> *codeLabels = nullptr);
|
||||
string ToString(uint32_t memoryAddr, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
string GetByteCode();
|
||||
uint32_t GetSize();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "ExpressionEvaluator.h"
|
||||
#include "Console.h"
|
||||
#include "Debugger.h"
|
||||
#include "LabelManager.h"
|
||||
|
||||
std::unordered_map<string, std::vector<int>, StringHasher> ExpressionEvaluator::_outputCache;
|
||||
std::unordered_map<string, std::vector<int>, StringHasher> ExpressionEvaluator::_customOutputCache;
|
||||
@ -88,7 +89,7 @@ bool ExpressionEvaluator::CheckSpecialTokens(string expression, size_t &pos, str
|
||||
output += std::to_string(EvalValues::AbsoluteAddress);
|
||||
} else {
|
||||
string originalExpression = expression.substr(initialPos, pos - initialPos);
|
||||
int32_t address = _debugger->GetCodeLabelAddress(originalExpression);
|
||||
int32_t address = _debugger->GetLabelManager()->GetLabelRelativeAddress(originalExpression);
|
||||
if(address >= 0) {
|
||||
_containsCustomLabels = true;
|
||||
output += std::to_string(address);
|
||||
|
100
Core/LabelManager.cpp
Normal file
100
Core/LabelManager.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "stdafx.h"
|
||||
#include "LabelManager.h"
|
||||
#include "Debugger.h"
|
||||
|
||||
LabelManager::LabelManager(shared_ptr<BaseMapper> mapper)
|
||||
{
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
void LabelManager::SetLabel(uint32_t address, AddressType addressType, string label, string comment)
|
||||
{
|
||||
ExpressionEvaluator::ResetCustomCache();
|
||||
|
||||
switch(addressType) {
|
||||
case AddressType::InternalRam: address |= 0x40000000; break;
|
||||
case AddressType::PrgRom: address |= 0x20000000; break;
|
||||
case AddressType::WorkRam: address |= 0x10000000; break;
|
||||
case AddressType::SaveRam: address |= 0x08000000; break;
|
||||
}
|
||||
|
||||
auto existingLabel = _codeLabels.find(address);
|
||||
if(existingLabel != _codeLabels.end()) {
|
||||
_codeLabelReverseLookup.erase(existingLabel->second);
|
||||
}
|
||||
|
||||
_codeLabels.erase(address);
|
||||
if(!label.empty()) {
|
||||
_codeLabels.emplace(address, label);
|
||||
_codeLabelReverseLookup.emplace(label, address);
|
||||
}
|
||||
|
||||
_codeComments.erase(address);
|
||||
if(!comment.empty()) {
|
||||
_codeComments.emplace(address, comment);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t LabelManager::GetLabelAddress(uint16_t relativeAddr)
|
||||
{
|
||||
if(relativeAddr < 0x2000) {
|
||||
return relativeAddr | 0x40000000;
|
||||
} else {
|
||||
int32_t addr = _mapper->ToAbsoluteAddress(relativeAddr);
|
||||
if(addr >= 0) {
|
||||
//PRG ROM
|
||||
return addr | 0x20000000;
|
||||
}
|
||||
|
||||
addr = _mapper->ToAbsoluteWorkRamAddress(relativeAddr);
|
||||
if(addr >= 0) {
|
||||
//Work RAM
|
||||
return addr | 0x10000000;
|
||||
}
|
||||
|
||||
addr = _mapper->ToAbsoluteSaveRamAddress(relativeAddr);
|
||||
if(addr >= 0) {
|
||||
//Save RAM
|
||||
return addr | 0x08000000;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
string LabelManager::GetLabel(uint16_t relativeAddr)
|
||||
{
|
||||
uint32_t labelAddr = GetLabelAddress(relativeAddr);
|
||||
|
||||
if(labelAddr >= 0) {
|
||||
auto result = _codeLabels.find(labelAddr);
|
||||
if(result != _codeLabels.end()) {
|
||||
return result->second;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
string LabelManager::GetComment(uint16_t relativeAddr)
|
||||
{
|
||||
uint32_t labelAddr = GetLabelAddress(relativeAddr);
|
||||
|
||||
if(labelAddr >= 0) {
|
||||
auto result = _codeComments.find(labelAddr);
|
||||
if(result != _codeComments.end()) {
|
||||
return result->second;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
int32_t LabelManager::GetLabelRelativeAddress(string label)
|
||||
{
|
||||
auto result = _codeLabelReverseLookup.find(label);
|
||||
if(result != _codeLabelReverseLookup.end()) {
|
||||
return _mapper->FromAbsoluteAddress(result->second);
|
||||
}
|
||||
return -1;
|
||||
}
|
30
Core/LabelManager.h
Normal file
30
Core/LabelManager.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include <unordered_map>
|
||||
using std::unordered_map;
|
||||
|
||||
class BaseMapper;
|
||||
class ExpressionEvaluator;
|
||||
enum class AddressType;
|
||||
|
||||
class LabelManager
|
||||
{
|
||||
private:
|
||||
unordered_map<uint32_t, string> _codeLabels;
|
||||
unordered_map<string, uint32_t> _codeLabelReverseLookup;
|
||||
unordered_map<uint32_t, string> _codeComments;
|
||||
|
||||
shared_ptr<BaseMapper> _mapper;
|
||||
|
||||
int32_t GetLabelAddress(uint16_t relativeAddr);
|
||||
|
||||
public:
|
||||
LabelManager(shared_ptr<BaseMapper> mapper);
|
||||
|
||||
void SetLabel(uint32_t address, AddressType addressType, string label, string comment);
|
||||
|
||||
int32_t GetLabelRelativeAddress(string label);
|
||||
|
||||
string GetLabel(uint16_t relativeAddr);
|
||||
string GetComment(uint16_t relativeAddr);
|
||||
};
|
@ -42,7 +42,7 @@ void TraceLogger::Log(DebugState &state, shared_ptr<DisassemblyInfo> disassembly
|
||||
State &cpuState = state.CPU;
|
||||
PPUDebugState &ppuState = state.PPU;
|
||||
|
||||
string disassembly = disassemblyInfo->ToString(cpuState.DebugPC, _memoryManager);
|
||||
string disassembly = disassemblyInfo->ToString(cpuState.DebugPC, _memoryManager, nullptr);
|
||||
|
||||
//Roughly adjust PPU cycle & scanline to take into account the PPU already ran 3 cycles by the time we get here
|
||||
short ppuCycle = (short)ppuState.Cycle - 3;
|
||||
|
@ -43,7 +43,7 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
}
|
||||
|
||||
relSubEntryAddr = i == 0 ? -1 : _relativeCallstack[i-1] & 0xFFFF;
|
||||
absSubEntryAddr = i == 0 ? -1 : _absoluteCallstack[i-1] & 0xFFFF;
|
||||
absSubEntryAddr = i == 0 ? -1 : _absoluteCallstack[i-1];
|
||||
|
||||
bool currentAddrUnmapped = (_relativeCallstack[i] & 0x10000) == 0x10000;
|
||||
relCurrentAddr = _relativeCallstack[i] & 0xFFFF;
|
||||
@ -79,7 +79,7 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
}
|
||||
|
||||
string funcName;
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)absSubEntryAddr);
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)absSubEntryAddr, AddressType.PrgRom);
|
||||
if(label != null) {
|
||||
funcName = label.Label + (relSubEntryAddr >= 0 ? (" ($" + relSubEntryAddr.ToString("X4") + ")") : "");
|
||||
} else {
|
||||
|
@ -185,11 +185,12 @@ namespace Mesen.GUI.Debugger
|
||||
if(label == null) {
|
||||
toolTip.Hide(ctrlCodeViewer);
|
||||
} else {
|
||||
Byte memoryValue = InteropEmu.DebugGetMemoryValue(label.Address);
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
||||
Int32 memoryValue = relativeAddress >= 0 ? InteropEmu.DebugGetMemoryValue((UInt32)relativeAddress) : -1;
|
||||
toolTip.Show(
|
||||
"Label: " + label.Label + Environment.NewLine +
|
||||
"Address: $" + InteropEmu.DebugGetRelativeAddress(label.Address).ToString("X4") + Environment.NewLine +
|
||||
"Value: $" + memoryValue.ToString("X2") + Environment.NewLine +
|
||||
"Address: $" + InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType).ToString("X4") + Environment.NewLine +
|
||||
"Value: " + (memoryValue >= 0 ? ("$" + memoryValue.ToString("X2")) : "n/a") + Environment.NewLine +
|
||||
"Comment: " + (label.Comment.Contains(Environment.NewLine) ? (Environment.NewLine + label.Comment) : label.Comment)
|
||||
, ctrlCodeViewer, e.Location.X + 5, e.Location.Y - 60 - label.Comment.Split('\n').Length * 14, 3000);
|
||||
}
|
||||
@ -239,19 +240,23 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void ctrlCodeViewer_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
int address = ctrlCodeViewer.GetLineNumberAtPosition(e.Y);
|
||||
int relativeAddress = ctrlCodeViewer.GetLineNumberAtPosition(e.Y);
|
||||
|
||||
if(address >= 0 && e.Location.X > this.ctrlCodeViewer.CodeMargin / 2 && e.Location.X < this.ctrlCodeViewer.CodeMargin) {
|
||||
UInt32 absoluteAddr = (UInt32)InteropEmu.DebugGetAbsoluteAddress((UInt32)address);
|
||||
CodeLabel existingLabel = LabelManager.GetLabel(absoluteAddr);
|
||||
CodeLabel newLabel = new CodeLabel() { Label = existingLabel?.Label, Comment = existingLabel?.Comment };
|
||||
if(relativeAddress >= 0 && e.Location.X > this.ctrlCodeViewer.CodeMargin / 2 && e.Location.X < this.ctrlCodeViewer.CodeMargin) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)relativeAddress, ref info);
|
||||
|
||||
frmEditLabel frm = new frmEditLabel(absoluteAddr, newLabel);
|
||||
if(frm.ShowDialog() == DialogResult.OK) {
|
||||
if(string.IsNullOrWhiteSpace(newLabel.Label) && string.IsNullOrWhiteSpace(newLabel.Comment)) {
|
||||
LabelManager.DeleteLabel(absoluteAddr);
|
||||
} else {
|
||||
LabelManager.SetLabel(absoluteAddr, newLabel.Label, newLabel.Comment);
|
||||
if(info.Address >= 0) {
|
||||
CodeLabel existingLabel = LabelManager.GetLabel((UInt32)info.Address, info.Type);
|
||||
CodeLabel newLabel = new CodeLabel() { Address = (UInt32)info.Address, AddressType = info.Type, Label = existingLabel?.Label, Comment = existingLabel?.Comment };
|
||||
|
||||
frmEditLabel frm = new frmEditLabel(newLabel);
|
||||
if(frm.ShowDialog() == DialogResult.OK) {
|
||||
if(string.IsNullOrWhiteSpace(newLabel.Label) && string.IsNullOrWhiteSpace(newLabel.Comment)) {
|
||||
LabelManager.DeleteLabel(newLabel.Address, newLabel.AddressType);
|
||||
} else {
|
||||
LabelManager.SetLabel(newLabel.Address, newLabel.AddressType, newLabel.Label, newLabel.Comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,10 +53,10 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
lstFunctions.ListViewItemSorter = null;
|
||||
lstFunctions.Items.Clear();
|
||||
for(int i = 0; entryPoints[i] >= 0; i++) {
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)entryPoints[i]);
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)entryPoints[i], AddressType.PrgRom);
|
||||
ListViewItem item = lstFunctions.Items.Add(label?.Label);
|
||||
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress((UInt32)entryPoints[i]);
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress((UInt32)entryPoints[i], AddressType.PrgRom);
|
||||
if(relativeAddress >= 0) {
|
||||
item.SubItems.Add("$" + relativeAddress.ToString("X4"));
|
||||
} else {
|
||||
|
@ -25,11 +25,11 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
|
||||
lstLabels.BeginUpdate();
|
||||
lstLabels.Items.Clear();
|
||||
foreach(KeyValuePair<UInt32, CodeLabel> kvp in LabelManager.GetLabels()) {
|
||||
foreach(KeyValuePair<string, CodeLabel> kvp in LabelManager.GetLabels()) {
|
||||
if(kvp.Value.Label.Length > 0) {
|
||||
ListViewItem item = lstLabels.Items.Add(kvp.Value.Label);
|
||||
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(kvp.Value.Address);
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(kvp.Value.Address, kvp.Value.AddressType);
|
||||
if(relativeAddress >= 0) {
|
||||
item.SubItems.Add("$" + relativeAddress.ToString("X4"));
|
||||
} else {
|
||||
@ -38,7 +38,7 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
item.Font = new Font(item.Font, FontStyle.Italic);
|
||||
}
|
||||
item.SubItems.Add("$" + kvp.Value.Address.ToString("X4"));
|
||||
item.SubItems[1].Tag = kvp.Value.Address;
|
||||
item.SubItems[1].Tag = kvp.Value;
|
||||
|
||||
item.Tag = relativeAddress;
|
||||
}
|
||||
@ -66,7 +66,7 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
private void mnuDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach(ListViewItem item in lstLabels.SelectedItems) {
|
||||
LabelManager.DeleteLabel((UInt32)item.SubItems[1].Tag);
|
||||
LabelManager.DeleteLabel(((CodeLabel)item.SubItems[1].Tag).Address, ((CodeLabel)item.SubItems[1].Tag).AddressType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,20 +9,27 @@ namespace Mesen.GUI.Debugger
|
||||
public class CodeLabel
|
||||
{
|
||||
public UInt32 Address;
|
||||
public AddressType AddressType;
|
||||
public string Label;
|
||||
public string Comment;
|
||||
}
|
||||
|
||||
public class LabelManager
|
||||
{
|
||||
private static Dictionary<UInt32, CodeLabel> _labels = new Dictionary<uint, CodeLabel>();
|
||||
private static Dictionary<string, CodeLabel> _labels = new Dictionary<string, CodeLabel>();
|
||||
private static Dictionary<string, CodeLabel> _reverseLookup = new Dictionary<string, CodeLabel>();
|
||||
|
||||
public static event EventHandler OnLabelUpdated;
|
||||
|
||||
public static CodeLabel GetLabel(UInt32 address)
|
||||
public static void ResetLabels()
|
||||
{
|
||||
return _labels.ContainsKey(address) ? _labels[address] : null;
|
||||
_labels.Clear();
|
||||
_reverseLookup.Clear();
|
||||
}
|
||||
|
||||
public static CodeLabel GetLabel(UInt32 address, AddressType type)
|
||||
{
|
||||
return _labels.ContainsKey(GetKey(address, type)) ? _labels[GetKey(address, type)] : null;
|
||||
}
|
||||
|
||||
public static CodeLabel GetLabel(string label)
|
||||
@ -30,40 +37,40 @@ namespace Mesen.GUI.Debugger
|
||||
return _reverseLookup.ContainsKey(label) ? _reverseLookup[label] : null;
|
||||
}
|
||||
|
||||
public static Dictionary<UInt32, CodeLabel> GetLabels()
|
||||
public static Dictionary<string, CodeLabel> GetLabels()
|
||||
{
|
||||
return _labels;
|
||||
}
|
||||
|
||||
public static bool SetLabel(UInt32 address, string label, string comment)
|
||||
private static string GetKey(UInt32 address, AddressType addressType)
|
||||
{
|
||||
if(_reverseLookup.ContainsKey(label) && _reverseLookup[label].Address != address) {
|
||||
//Label already exists
|
||||
return false;
|
||||
return address.ToString() + addressType.ToString();
|
||||
}
|
||||
|
||||
public static bool SetLabel(UInt32 address, AddressType type, string label, string comment)
|
||||
{
|
||||
if(_labels.ContainsKey(GetKey(address, type))) {
|
||||
_reverseLookup.Remove(_labels[GetKey(address, type)].Label);
|
||||
}
|
||||
|
||||
if(_labels.ContainsKey(address)) {
|
||||
_reverseLookup.Remove(_labels[address].Label);
|
||||
}
|
||||
|
||||
_labels[address] = new CodeLabel() { Address = address, Label = label, Comment = comment };
|
||||
_labels[GetKey(address, type)] = new CodeLabel() { Address = address, AddressType = type, Label = label, Comment = comment };
|
||||
if(label.Length > 0) {
|
||||
_reverseLookup[label] = _labels[address];
|
||||
_reverseLookup[label] = _labels[GetKey(address, type)];
|
||||
}
|
||||
|
||||
InteropEmu.DebugSetLabel(address, label, comment);
|
||||
InteropEmu.DebugSetLabel(address, type, label, comment);
|
||||
OnLabelUpdated?.Invoke(null, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void DeleteLabel(UInt32 address)
|
||||
public static void DeleteLabel(UInt32 address, AddressType type)
|
||||
{
|
||||
if(_labels.ContainsKey(address)) {
|
||||
_reverseLookup.Remove(_labels[address].Label);
|
||||
if(_labels.ContainsKey(GetKey(address, type))) {
|
||||
_reverseLookup.Remove(_labels[GetKey(address, type)].Label);
|
||||
}
|
||||
if(_labels.Remove(address)) {
|
||||
InteropEmu.DebugSetLabel(address, string.Empty, string.Empty);
|
||||
if(_labels.Remove(GetKey(address, type))) {
|
||||
InteropEmu.DebugSetLabel(address, type, string.Empty, string.Empty);
|
||||
OnLabelUpdated?.Invoke(null, null);
|
||||
}
|
||||
}
|
||||
|
1
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
1
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
@ -16,6 +16,7 @@
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
LabelManager.OnLabelUpdated -= LabelManager_OnLabelUpdated;
|
||||
if(_notifListener != null) {
|
||||
_notifListener.Dispose();
|
||||
_notifListener = null;
|
||||
|
@ -38,6 +38,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.mnuShowOnlyDisassembledCode.Checked = ConfigManager.Config.DebugInfo.ShowOnlyDisassembledCode;
|
||||
this.mnuShowFunctionLabelLists.Checked = ConfigManager.Config.DebugInfo.ShowFunctionLabelLists;
|
||||
|
||||
LabelManager.ResetLabels();
|
||||
LabelManager.OnLabelUpdated += LabelManager_OnLabelUpdated;
|
||||
|
||||
_lastCodeWindow = ctrlDebuggerCode;
|
||||
|
74
GUI.NET/Debugger/frmEditLabel.Designer.cs
generated
74
GUI.NET/Debugger/frmEditLabel.Designer.cs
generated
@ -32,12 +32,16 @@
|
||||
this.lblLabel = new System.Windows.Forms.Label();
|
||||
this.lblComment = new System.Windows.Forms.Label();
|
||||
this.txtLabel = new System.Windows.Forms.TextBox();
|
||||
this.lblRegion = new System.Windows.Forms.Label();
|
||||
this.lblAddress = new System.Windows.Forms.Label();
|
||||
this.cboRegion = new System.Windows.Forms.ComboBox();
|
||||
this.txtAddress = new System.Windows.Forms.TextBox();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// baseConfigPanel
|
||||
//
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 165);
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 210);
|
||||
this.baseConfigPanel.Size = new System.Drawing.Size(352, 29);
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
@ -45,23 +49,29 @@
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtComment, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblLabel, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblComment, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtLabel, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtComment, 1, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblLabel, 0, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblComment, 0, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtLabel, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblRegion, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.cboRegion, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtAddress, 1, 1);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowCount = 4;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(352, 165);
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(352, 210);
|
||||
this.tableLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// txtComment
|
||||
//
|
||||
this.txtComment.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtComment.Location = new System.Drawing.Point(63, 29);
|
||||
this.txtComment.Location = new System.Drawing.Point(63, 82);
|
||||
this.txtComment.Multiline = true;
|
||||
this.txtComment.Name = "txtComment";
|
||||
this.txtComment.Size = new System.Drawing.Size(286, 133);
|
||||
@ -71,7 +81,7 @@
|
||||
//
|
||||
this.lblLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblLabel.AutoSize = true;
|
||||
this.lblLabel.Location = new System.Drawing.Point(3, 6);
|
||||
this.lblLabel.Location = new System.Drawing.Point(3, 59);
|
||||
this.lblLabel.Name = "lblLabel";
|
||||
this.lblLabel.Size = new System.Drawing.Size(36, 13);
|
||||
this.lblLabel.TabIndex = 0;
|
||||
@ -81,7 +91,7 @@
|
||||
//
|
||||
this.lblComment.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblComment.AutoSize = true;
|
||||
this.lblComment.Location = new System.Drawing.Point(3, 89);
|
||||
this.lblComment.Location = new System.Drawing.Point(3, 142);
|
||||
this.lblComment.Name = "lblComment";
|
||||
this.lblComment.Size = new System.Drawing.Size(54, 13);
|
||||
this.lblComment.TabIndex = 1;
|
||||
@ -90,17 +100,53 @@
|
||||
// txtLabel
|
||||
//
|
||||
this.txtLabel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtLabel.Location = new System.Drawing.Point(63, 3);
|
||||
this.txtLabel.Location = new System.Drawing.Point(63, 56);
|
||||
this.txtLabel.Name = "txtLabel";
|
||||
this.txtLabel.Size = new System.Drawing.Size(286, 20);
|
||||
this.txtLabel.TabIndex = 2;
|
||||
//
|
||||
// lblRegion
|
||||
//
|
||||
this.lblRegion.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblRegion.AutoSize = true;
|
||||
this.lblRegion.Location = new System.Drawing.Point(3, 7);
|
||||
this.lblRegion.Name = "lblRegion";
|
||||
this.lblRegion.Size = new System.Drawing.Size(44, 13);
|
||||
this.lblRegion.TabIndex = 4;
|
||||
this.lblRegion.Text = "Region:";
|
||||
//
|
||||
// lblAddress
|
||||
//
|
||||
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblAddress.AutoSize = true;
|
||||
this.lblAddress.Location = new System.Drawing.Point(3, 33);
|
||||
this.lblAddress.Name = "lblAddress";
|
||||
this.lblAddress.Size = new System.Drawing.Size(48, 13);
|
||||
this.lblAddress.TabIndex = 5;
|
||||
this.lblAddress.Text = "Address:";
|
||||
//
|
||||
// cboRegion
|
||||
//
|
||||
this.cboRegion.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboRegion.FormattingEnabled = true;
|
||||
this.cboRegion.Location = new System.Drawing.Point(63, 3);
|
||||
this.cboRegion.Name = "cboRegion";
|
||||
this.cboRegion.Size = new System.Drawing.Size(121, 21);
|
||||
this.cboRegion.TabIndex = 6;
|
||||
//
|
||||
// txtAddress
|
||||
//
|
||||
this.txtAddress.Location = new System.Drawing.Point(63, 30);
|
||||
this.txtAddress.Name = "txtAddress";
|
||||
this.txtAddress.Size = new System.Drawing.Size(57, 20);
|
||||
this.txtAddress.TabIndex = 7;
|
||||
//
|
||||
// frmEditLabel
|
||||
//
|
||||
this.AcceptButton = null;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(352, 194);
|
||||
this.ClientSize = new System.Drawing.Size(352, 239);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "frmEditLabel";
|
||||
@ -121,5 +167,9 @@
|
||||
private System.Windows.Forms.Label lblLabel;
|
||||
private System.Windows.Forms.Label lblComment;
|
||||
private System.Windows.Forms.TextBox txtLabel;
|
||||
private System.Windows.Forms.Label lblRegion;
|
||||
private System.Windows.Forms.Label lblAddress;
|
||||
private System.Windows.Forms.ComboBox cboRegion;
|
||||
private System.Windows.Forms.TextBox txtAddress;
|
||||
}
|
||||
}
|
@ -14,26 +14,35 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmEditLabel : BaseConfigForm
|
||||
{
|
||||
UInt32 _address;
|
||||
private UInt32 _originalAddress;
|
||||
private AddressType _originalMemoryType;
|
||||
|
||||
public frmEditLabel(UInt32 address, CodeLabel label)
|
||||
public frmEditLabel(CodeLabel label)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_address = address;
|
||||
this.Text = "Edit Label: $" + address.ToString("X4");
|
||||
_originalAddress = label.Address;
|
||||
_originalMemoryType = label.AddressType;
|
||||
|
||||
Entity = label;
|
||||
|
||||
AddBinding("AddressType", cboRegion);
|
||||
AddBinding("Address", txtAddress);
|
||||
AddBinding("Label", txtLabel);
|
||||
AddBinding("Comment", txtComment);
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
txtLabel.Focus();
|
||||
}
|
||||
|
||||
protected override bool ValidateInput()
|
||||
{
|
||||
CodeLabel existingLabel = LabelManager.GetLabel(txtLabel.Text);
|
||||
|
||||
return (existingLabel == null || existingLabel.Address == _address)
|
||||
return (existingLabel == null || (existingLabel.Address == _originalAddress && existingLabel.AddressType == _originalMemoryType))
|
||||
&& !txtComment.Text.Contains('\x1') && !txtComment.Text.Contains('\x2')
|
||||
&& (txtLabel.Text.Length == 0 || Regex.IsMatch(txtLabel.Text, "^[_a-zA-Z]+[_a-zA-Z0-9]*"));
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ namespace Mesen.GUI
|
||||
[DllImport(DLLPath)] public static extern void DebugSetFlags(DebuggerFlags flags);
|
||||
[DllImport(DLLPath)] public static extern void DebugGetState(ref DebugState state);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetBreakpoints([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]InteropBreakpoint[] breakpoints, UInt32 length);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetLabel(UInt32 address, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string label, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string comment);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetLabel(UInt32 address, AddressType addressType, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string label, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string comment);
|
||||
[DllImport(DLLPath)] public static extern void DebugStep(UInt32 count);
|
||||
[DllImport(DLLPath)] public static extern void DebugPpuStep(UInt32 count);
|
||||
[DllImport(DLLPath)] public static extern void DebugStepCycles(UInt32 count);
|
||||
@ -175,8 +175,10 @@ namespace Mesen.GUI
|
||||
[DllImport(DLLPath)] public static extern void DebugRun();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool DebugIsCodeChanged();
|
||||
[DllImport(DLLPath)] public static extern Byte DebugGetMemoryValue(UInt32 addr);
|
||||
[DllImport(DLLPath)] public static extern Int32 DebugGetRelativeAddress(UInt32 absoluteAddr);
|
||||
[DllImport(DLLPath)] public static extern Int32 DebugGetRelativeAddress(UInt32 absoluteAddr, AddressType type);
|
||||
[DllImport(DLLPath)] public static extern Int32 DebugGetAbsoluteAddress(UInt32 relativeAddr);
|
||||
[DllImport(DLLPath)] public static extern void DebugGetAbsoluteAddressAndType(UInt32 relativeAddr, ref AddressTypeInfo addressTypeInfo);
|
||||
|
||||
[DllImport(DLLPath)] public static extern void DebugSetNextStatement(UInt16 addr);
|
||||
[DllImport(DLLPath)] public static extern Int32 DebugEvaluateExpression([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string expression, out EvalResultType resultType);
|
||||
|
||||
@ -1029,6 +1031,20 @@ namespace Mesen.GUI
|
||||
InternalRam = 10
|
||||
}
|
||||
|
||||
public enum AddressType
|
||||
{
|
||||
InternalRam = 0,
|
||||
PrgRom = 1,
|
||||
WorkRam = 2,
|
||||
SaveRam = 3,
|
||||
}
|
||||
|
||||
public struct AddressTypeInfo
|
||||
{
|
||||
public Int32 Address;
|
||||
public AddressType Type;
|
||||
}
|
||||
|
||||
public class MD5Helper
|
||||
{
|
||||
public static string GetMD5Hash(string filename)
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "../Core/Console.h"
|
||||
#include "../Core/Debugger.h"
|
||||
#include "../Core/CodeDataLogger.h"
|
||||
#include "../Core/LabelManager.h"
|
||||
|
||||
shared_ptr<Debugger> GetDebugger()
|
||||
{
|
||||
@ -31,7 +32,7 @@ extern "C"
|
||||
DllExport void __stdcall DebugGetState(DebugState *state) { GetDebugger()->GetState(state); }
|
||||
|
||||
DllExport void __stdcall DebugSetBreakpoints(Breakpoint breakpoints[], uint32_t length) { GetDebugger()->SetBreakpoints(breakpoints, length); }
|
||||
DllExport void __stdcall DebugSetLabel(uint32_t address, char* label, char* comment) { GetDebugger()->SetLabel(address, label, comment); }
|
||||
DllExport void __stdcall DebugSetLabel(uint32_t address, AddressType addressType, char* label, char* comment) { GetDebugger()->GetLabelManager()->SetLabel(address, addressType, label, comment); }
|
||||
|
||||
DllExport void __stdcall DebugRun() { GetDebugger()->Run(); }
|
||||
DllExport void __stdcall DebugStep(uint32_t count) { GetDebugger()->Step(count); }
|
||||
@ -55,8 +56,9 @@ extern "C"
|
||||
DllExport void __stdcall DebugGetFunctionEntryPoints(int32_t *entryPoints) { GetDebugger()->GetFunctionEntryPoints(entryPoints); }
|
||||
|
||||
DllExport uint8_t __stdcall DebugGetMemoryValue(uint32_t addr) { return GetDebugger()->GetMemoryValue(addr); }
|
||||
DllExport int32_t __stdcall DebugGetRelativeAddress(uint32_t addr) { return GetDebugger()->GetRelativeAddress(addr); }
|
||||
DllExport int32_t __stdcall DebugGetRelativeAddress(uint32_t addr, AddressType type) { return GetDebugger()->GetRelativeAddress(addr, type); }
|
||||
DllExport int32_t __stdcall DebugGetAbsoluteAddress(uint32_t addr) { return GetDebugger()->GetAbsoluteAddress(addr); }
|
||||
DllExport void __stdcall DebugGetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info) { return GetDebugger()->GetAbsoluteAddressAndType(relativeAddr, info); }
|
||||
|
||||
DllExport bool __stdcall DebugLoadCdlFile(char* cdlFilepath) { return GetDebugger()->LoadCdlFile(cdlFilepath); }
|
||||
DllExport bool __stdcall DebugSaveCdlFile(char* cdlFilepath) { return GetDebugger()->SaveCdlFile(cdlFilepath); }
|
||||
|
Loading…
Reference in New Issue
Block a user