Debugger: Refactor memory counters (simplifies code & improves debugger performance)
This commit is contained in:
parent
55db5e9fb7
commit
c6c2e5b319
10 changed files with 130 additions and 193 deletions
|
@ -128,21 +128,23 @@ void CpuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
}
|
||||
}
|
||||
}
|
||||
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
|
||||
} else if(type == MemoryOperationType::ExecOperand) {
|
||||
if(addressInfo.Type == SnesMemoryType::PrgRom && addressInfo.Address >= 0) {
|
||||
_codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Code | (state.PS & (CdlFlags::IndexMode8 | CdlFlags::MemoryMode8)));
|
||||
}
|
||||
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
|
||||
} else {
|
||||
if(addressInfo.Type == SnesMemoryType::PrgRom && addressInfo.Address >= 0) {
|
||||
_codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Data | (state.PS & (CdlFlags::IndexMode8 | CdlFlags::MemoryMode8)));
|
||||
}
|
||||
}
|
||||
|
||||
if(_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock())) {
|
||||
//Memory access was a read on an uninitialized memory address
|
||||
if(_enableBreakOnUninitRead && _settings->CheckDebuggerFlag(DebuggerFlags::BreakOnUninitRead)) {
|
||||
breakSource = BreakSource::BreakOnUninitMemoryRead;
|
||||
_step->StepCount = 0;
|
||||
if(_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock())) {
|
||||
//Memory access was a read on an uninitialized memory address
|
||||
if(_enableBreakOnUninitRead && _settings->CheckDebuggerFlag(DebuggerFlags::BreakOnUninitRead)) {
|
||||
breakSource = BreakSource::BreakOnUninitMemoryRead;
|
||||
_step->StepCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +169,7 @@ void CpuDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
_eventManager->AddEvent(DebugEventType::Register, operation);
|
||||
}
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock());
|
||||
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
|
||||
|
||||
_debugger->ProcessBreakConditions(false, _breakpointManager.get(), operation, addressInfo);
|
||||
|
||||
|
|
|
@ -143,7 +143,8 @@ void Debugger::ProcessMemoryWrite(uint32_t addr, uint8_t value, MemoryOperationT
|
|||
void Debugger::ProcessWorkRamRead(uint32_t addr, uint8_t value)
|
||||
{
|
||||
AddressInfo addressInfo { (int32_t)addr, SnesMemoryType::WorkRam };
|
||||
//TODO Make this more flexible/accurate
|
||||
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
|
||||
|
||||
MemoryOperationInfo operation { 0x7E0000 | addr, value, MemoryOperationType::Read };
|
||||
ProcessBreakConditions(false, _cpuDebugger->GetBreakpointManager(), operation, addressInfo);
|
||||
}
|
||||
|
@ -151,7 +152,8 @@ void Debugger::ProcessWorkRamRead(uint32_t addr, uint8_t value)
|
|||
void Debugger::ProcessWorkRamWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
AddressInfo addressInfo { (int32_t)addr, SnesMemoryType::WorkRam };
|
||||
//TODO Make this more flexible/accurate
|
||||
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
|
||||
|
||||
MemoryOperationInfo operation { 0x7E0000 | addr, value, MemoryOperationType::Write };
|
||||
ProcessBreakConditions(false, _cpuDebugger->GetBreakpointManager(), operation, addressInfo);
|
||||
}
|
||||
|
@ -162,7 +164,7 @@ void Debugger::ProcessPpuRead(uint16_t addr, uint8_t value, SnesMemoryType memor
|
|||
MemoryOperationInfo operation { addr, value, MemoryOperationType::Read };
|
||||
ProcessBreakConditions(false, _cpuDebugger->GetBreakpointManager(), operation, addressInfo);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, MemoryOperationType::Read, _memoryManager->GetMasterClock());
|
||||
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void Debugger::ProcessPpuWrite(uint16_t addr, uint8_t value, SnesMemoryType memoryType)
|
||||
|
@ -171,7 +173,7 @@ void Debugger::ProcessPpuWrite(uint16_t addr, uint8_t value, SnesMemoryType memo
|
|||
MemoryOperationInfo operation { addr, value, MemoryOperationType::Write };
|
||||
ProcessBreakConditions(false, _cpuDebugger->GetBreakpointManager(), operation, addressInfo);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, MemoryOperationType::Write, _memoryManager->GetMasterClock());
|
||||
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void Debugger::ProcessPpuCycle()
|
||||
|
|
|
@ -64,11 +64,12 @@ void GsuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
if(_step->StepCount > 0) {
|
||||
_step->StepCount--;
|
||||
}
|
||||
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
|
||||
} else {
|
||||
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
_debugger->ProcessBreakConditions(_step->StepCount == 0, GetBreakpointManager(), operation, addressInfo);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void GsuDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType type)
|
||||
|
@ -79,7 +80,7 @@ void GsuDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
|
||||
_disassembler->InvalidateCache(addressInfo, CpuType::Gsu);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock());
|
||||
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void GsuDebugger::Run()
|
||||
|
|
|
@ -611,16 +611,33 @@ int LuaApi::GetAccessCounters(lua_State *lua)
|
|||
checkparams();
|
||||
|
||||
uint32_t size = 0;
|
||||
vector<uint32_t> counts;
|
||||
counts.resize(_memoryDumper->GetMemorySize(memoryType), 0);
|
||||
_debugger->GetMemoryAccessCounter()->GetAccessCounts(0, size, memoryType, operationType, counts.data());
|
||||
vector<AddressCounters> counts;
|
||||
counts.resize(_memoryDumper->GetMemorySize(memoryType), {});
|
||||
_debugger->GetMemoryAccessCounter()->GetAccessCounts(0, size, memoryType, counts.data());
|
||||
|
||||
lua_newtable(lua);
|
||||
for(uint32_t i = 0; i < size; i++) {
|
||||
lua_pushinteger(lua, counts[i]);
|
||||
lua_rawseti(lua, -2, i);
|
||||
}
|
||||
switch(operationType) {
|
||||
case MemoryOperationType::Read:
|
||||
for(uint32_t i = 0; i < size; i++) {
|
||||
lua_pushinteger(lua, counts[i].ReadCount);
|
||||
lua_rawseti(lua, -2, i);
|
||||
}
|
||||
break;
|
||||
|
||||
case MemoryOperationType::Write:
|
||||
for(uint32_t i = 0; i < size; i++) {
|
||||
lua_pushinteger(lua, counts[i].WriteCount);
|
||||
lua_rawseti(lua, -2, i);
|
||||
}
|
||||
break;
|
||||
|
||||
case MemoryOperationType::ExecOpCode:
|
||||
for(uint32_t i = 0; i < size; i++) {
|
||||
lua_pushinteger(lua, counts[i].ExecCount);
|
||||
lua_rawseti(lua, -2, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,102 +19,73 @@ MemoryAccessCounter::MemoryAccessCounter(Debugger* debugger, Console *console)
|
|||
|
||||
for(int i = (int)SnesMemoryType::PrgRom; i < (int)SnesMemoryType::Register; i++) {
|
||||
uint32_t memSize = _debugger->GetMemoryDumper()->GetMemorySize((SnesMemoryType)i);
|
||||
|
||||
_readCounts[i].insert(_readCounts[i].end(), memSize, 0);
|
||||
_writeCounts[i].insert(_writeCounts[i].end(), memSize, 0);
|
||||
_execCounts[i].insert(_execCounts[i].end(), memSize, 0);
|
||||
|
||||
_readStamps[i].insert(_readStamps[i].end(), memSize, 0);
|
||||
_writeStamps[i].insert(_writeStamps[i].end(), memSize, 0);
|
||||
_execStamps[i].insert(_execStamps[i].end(), memSize, 0);
|
||||
|
||||
_uninitReads[i].insert(_uninitReads[i].end(), memSize, false);
|
||||
}
|
||||
}
|
||||
|
||||
vector<uint32_t>& MemoryAccessCounter::GetCountArray(MemoryOperationType operationType, SnesMemoryType memType)
|
||||
{
|
||||
switch(operationType) {
|
||||
case MemoryOperationType::DmaRead:
|
||||
case MemoryOperationType::Read: return _readCounts[(int)memType];
|
||||
|
||||
case MemoryOperationType::DmaWrite:
|
||||
case MemoryOperationType::Write: return _writeCounts[(int)memType];
|
||||
|
||||
default:
|
||||
case MemoryOperationType::ExecOpCode:
|
||||
case MemoryOperationType::ExecOperand: return _execCounts[(int)memType];
|
||||
}
|
||||
}
|
||||
|
||||
vector<uint64_t>& MemoryAccessCounter::GetStampArray(MemoryOperationType operationType, SnesMemoryType memType)
|
||||
{
|
||||
switch(operationType) {
|
||||
case MemoryOperationType::DmaRead:
|
||||
case MemoryOperationType::Read: return _readStamps[(int)memType];
|
||||
|
||||
case MemoryOperationType::DmaWrite:
|
||||
case MemoryOperationType::Write: return _writeStamps[(int)memType];
|
||||
|
||||
default:
|
||||
case MemoryOperationType::ExecOpCode:
|
||||
case MemoryOperationType::ExecOperand: return _execStamps[(int)memType];
|
||||
_counters[i].insert(_counters[i].end(), memSize, {});
|
||||
}
|
||||
}
|
||||
|
||||
bool MemoryAccessCounter::IsAddressUninitialized(AddressInfo &addressInfo)
|
||||
{
|
||||
if(addressInfo.Type != SnesMemoryType::PrgRom && addressInfo.Type != SnesMemoryType::SaveRam) {
|
||||
return _writeCounts[(int)addressInfo.Type][addressInfo.Address] == 0;
|
||||
return _counters[(int)addressInfo.Type][addressInfo.Address].WriteCount == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemoryAccessCounter::ProcessMemoryAccess(AddressInfo &addressInfo, MemoryOperationType operation, uint64_t masterClock)
|
||||
bool MemoryAccessCounter::ProcessMemoryRead(AddressInfo &addressInfo, uint64_t masterClock)
|
||||
{
|
||||
if(addressInfo.Address < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<uint32_t> &counts = GetCountArray(operation, addressInfo.Type);
|
||||
counts[addressInfo.Address]++;
|
||||
|
||||
vector<uint64_t> &stamps = GetStampArray(operation, addressInfo.Type);
|
||||
stamps[addressInfo.Address] = masterClock;
|
||||
|
||||
if(operation == MemoryOperationType::Read && IsAddressUninitialized(addressInfo)) {
|
||||
AddressCounters& counts = _counters[(int)addressInfo.Type][addressInfo.Address];
|
||||
counts.ReadCount++;
|
||||
counts.ReadStamp = masterClock;
|
||||
if(counts.WriteCount == 0 && IsAddressUninitialized(addressInfo)) {
|
||||
//Mark address as read before being written to (if trying to read/execute)
|
||||
_uninitReads[(int)addressInfo.Type][addressInfo.Address] = true;
|
||||
counts.UninitRead = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MemoryAccessCounter::ProcessMemoryWrite(AddressInfo& addressInfo, uint64_t masterClock)
|
||||
{
|
||||
if(addressInfo.Address < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddressCounters& counts = _counters[(int)addressInfo.Type][addressInfo.Address];
|
||||
counts.WriteCount++;
|
||||
counts.WriteStamp = masterClock;
|
||||
}
|
||||
|
||||
void MemoryAccessCounter::ProcessMemoryExec(AddressInfo& addressInfo, uint64_t masterClock)
|
||||
{
|
||||
if(addressInfo.Address < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddressCounters& counts = _counters[(int)addressInfo.Type][addressInfo.Address];
|
||||
counts.ExecCount++;
|
||||
counts.ExecStamp = masterClock;
|
||||
}
|
||||
|
||||
void MemoryAccessCounter::ResetCounts()
|
||||
{
|
||||
DebugBreakHelper helper(_debugger);
|
||||
for(int i = 0; i < (int)SnesMemoryType::Register; i++) {
|
||||
memset(_readCounts[i].data(), 0, _readCounts[i].size() * sizeof(uint32_t));
|
||||
memset(_writeCounts[i].data(), 0, _writeCounts[i].size() * sizeof(uint32_t));
|
||||
memset(_execCounts[i].data(), 0, _execCounts[i].size() * sizeof(uint32_t));
|
||||
|
||||
memset(_readStamps[i].data(), 0, _readStamps[i].size() * sizeof(uint64_t));
|
||||
memset(_writeStamps[i].data(), 0, _writeStamps[i].size() * sizeof(uint64_t));
|
||||
memset(_execStamps[i].data(), 0, _execStamps[i].size() * sizeof(uint64_t));
|
||||
|
||||
memset(_uninitReads[i].data(), 0, _uninitReads[i].size() * sizeof(uint8_t));
|
||||
memset(_counters[i].data(), 0, _counters[i].size() * sizeof(AddressCounters));
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, SnesMemoryType memoryType, MemoryOperationType operationType, uint64_t stamps[])
|
||||
void MemoryAccessCounter::GetAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, AddressCounters counts[])
|
||||
{
|
||||
switch(memoryType) {
|
||||
case SnesMemoryType::CpuMemory:
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _memoryManager->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
stamps[i] = GetStampArray(operationType, info.Type)[info.Address];
|
||||
counts[i] = _counters[(int)info.Type][info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -123,7 +94,7 @@ void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, Snes
|
|||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _spc->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
stamps[i] = GetStampArray(operationType, info.Type)[info.Address];
|
||||
counts[i] = _counters[(int)info.Type][info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -132,7 +103,7 @@ void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, Snes
|
|||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _sa1->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
stamps[i] = GetStampArray(operationType, info.Type)[info.Address];
|
||||
counts[i] = _counters[(int)info.Type][info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -141,65 +112,13 @@ void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, Snes
|
|||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _gsu->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
stamps[i] = GetStampArray(operationType, info.Type)[info.Address];
|
||||
counts[i] = _counters[(int)info.Type][info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
memcpy(stamps, GetStampArray(operationType, memoryType).data() + offset, length * sizeof(uint64_t));
|
||||
memcpy(counts, &_counters[(int)memoryType] + offset, length * sizeof(AddressCounters));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryAccessCounter::GetAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, MemoryOperationType operationType, uint32_t counts[])
|
||||
{
|
||||
switch(memoryType) {
|
||||
case SnesMemoryType::CpuMemory:
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _memoryManager->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
counts[i] = GetCountArray(operationType, info.Type)[info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SnesMemoryType::SpcMemory:
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _spc->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
counts[i] = GetCountArray(operationType, info.Type)[info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SnesMemoryType::Sa1Memory:
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _sa1->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
counts[i] = GetCountArray(operationType, info.Type)[info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SnesMemoryType::GsuMemory:
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _gsu->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
counts[i] = GetCountArray(operationType, info.Type)[info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
memcpy(counts, GetCountArray(operationType, memoryType).data() + offset, length * sizeof(uint32_t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryAccessCounter::GetUninitMemoryReads(SnesMemoryType memoryType, bool uninitReads[])
|
||||
{
|
||||
for(size_t i = 0, len = _uninitReads[(int)memoryType].size(); i < len; i++) {
|
||||
uninitReads[i] = _uninitReads[(int)memoryType][i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,18 +9,21 @@ class Console;
|
|||
class Sa1;
|
||||
class Gsu;
|
||||
|
||||
struct AddressCounters
|
||||
{
|
||||
uint32_t ReadCount;
|
||||
uint64_t ReadStamp;
|
||||
uint32_t WriteCount;
|
||||
bool UninitRead;
|
||||
uint64_t WriteStamp;
|
||||
uint32_t ExecCount;
|
||||
uint64_t ExecStamp;
|
||||
};
|
||||
|
||||
class MemoryAccessCounter
|
||||
{
|
||||
private:
|
||||
vector<uint32_t> _readCounts[(int)SnesMemoryType::Register];
|
||||
vector<uint32_t> _writeCounts[(int)SnesMemoryType::Register];
|
||||
vector<uint32_t> _execCounts[(int)SnesMemoryType::Register];
|
||||
|
||||
vector<uint64_t> _readStamps[(int)SnesMemoryType::Register];
|
||||
vector<uint64_t> _writeStamps[(int)SnesMemoryType::Register];
|
||||
vector<uint64_t> _execStamps[(int)SnesMemoryType::Register];
|
||||
|
||||
vector<uint8_t> _uninitReads[(int)SnesMemoryType::Register];
|
||||
vector<AddressCounters> _counters[(int)SnesMemoryType::Register];
|
||||
|
||||
Debugger* _debugger;
|
||||
MemoryManager* _memoryManager;
|
||||
|
@ -28,17 +31,16 @@ private:
|
|||
Sa1* _sa1;
|
||||
Gsu* _gsu;
|
||||
|
||||
vector<uint32_t>& GetCountArray(MemoryOperationType operationType, SnesMemoryType memType);
|
||||
vector<uint64_t>& GetStampArray(MemoryOperationType operationType, SnesMemoryType memType);
|
||||
bool IsAddressUninitialized(AddressInfo &addressInfo);
|
||||
|
||||
public:
|
||||
MemoryAccessCounter(Debugger *debugger, Console *console);
|
||||
|
||||
bool ProcessMemoryAccess(AddressInfo &addressInfo, MemoryOperationType operation, uint64_t masterClock);
|
||||
bool ProcessMemoryRead(AddressInfo& addressInfo, uint64_t masterClock);
|
||||
void ProcessMemoryWrite(AddressInfo& addressInfo, uint64_t masterClock);
|
||||
void ProcessMemoryExec(AddressInfo& addressInfo, uint64_t masterClock);
|
||||
|
||||
void ResetCounts();
|
||||
|
||||
void GetAccessStamps(uint32_t offset, uint32_t length, SnesMemoryType memoryType, MemoryOperationType operationType, uint64_t stamps[]);
|
||||
void GetAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, MemoryOperationType operationType, uint32_t counts[]);
|
||||
void GetUninitMemoryReads(SnesMemoryType memoryType, bool uninitReads[]);
|
||||
void GetAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, AddressCounters counts[]);
|
||||
};
|
|
@ -95,11 +95,14 @@ void SpcDebugger::ProcessRead(uint16_t addr, uint8_t value, MemoryOperationType
|
|||
_step->StepCount = 0;
|
||||
}
|
||||
}
|
||||
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
|
||||
} else if(type == MemoryOperationType::ExecOperand) {
|
||||
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
|
||||
} else {
|
||||
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
_debugger->ProcessBreakConditions(_step->StepCount == 0, GetBreakpointManager(), operation, addressInfo, breakSource);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void SpcDebugger::ProcessWrite(uint16_t addr, uint8_t value, MemoryOperationType type)
|
||||
|
@ -110,7 +113,7 @@ void SpcDebugger::ProcessWrite(uint16_t addr, uint8_t value, MemoryOperationType
|
|||
|
||||
_disassembler->InvalidateCache(addressInfo, CpuType::Spc);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock());
|
||||
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void SpcDebugger::Run()
|
||||
|
|
|
@ -79,8 +79,7 @@ extern "C"
|
|||
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(); }
|
||||
|
||||
DllExport void __stdcall GetMemoryAccessStamps(uint32_t offset, uint32_t length, SnesMemoryType memoryType, MemoryOperationType operationType, uint64_t* stamps) { GetDebugger()->GetMemoryAccessCounter()->GetAccessStamps(offset, length, memoryType, operationType, stamps); }
|
||||
DllExport void __stdcall GetMemoryAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, MemoryOperationType operationType, uint32_t* counts) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(offset, length, memoryType, operationType, counts); }
|
||||
DllExport void __stdcall GetMemoryAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, AddressCounters* counts) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(offset, length, memoryType, counts); }
|
||||
|
||||
DllExport void __stdcall GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t* cdlData) { GetDebugger()->GetCodeDataLogger()->GetCdlData(offset, length, memoryType, cdlData); }
|
||||
DllExport void __stdcall SetCdlData(uint8_t* cdlData, uint32_t length) { GetDebugger()->SetCdlData(cdlData, length); }
|
||||
|
|
|
@ -10,12 +10,7 @@ namespace Mesen.GUI.Debugger
|
|||
public class ByteColorProvider : IByteColorProvider
|
||||
{
|
||||
SnesMemoryType _memoryType;
|
||||
UInt64[] _readStamps;
|
||||
UInt64[] _writeStamps;
|
||||
UInt64[] _execStamps;
|
||||
UInt32[] _readCounts;
|
||||
UInt32[] _writeCounts;
|
||||
UInt32[] _execCounts;
|
||||
AddressCounters[] _counters;
|
||||
byte[] _cdlData;
|
||||
bool[] _hasLabel;
|
||||
DebugState _state = new DebugState();
|
||||
|
@ -72,13 +67,7 @@ namespace Mesen.GUI.Debugger
|
|||
_breakpointTypes = null;
|
||||
}
|
||||
|
||||
_readStamps = DebugApi.GetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Read);
|
||||
_writeStamps = DebugApi.GetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Write);
|
||||
_execStamps = DebugApi.GetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.ExecOpCode);
|
||||
|
||||
_readCounts = DebugApi.GetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Read);
|
||||
_writeCounts = DebugApi.GetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Write);
|
||||
_execCounts = DebugApi.GetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.ExecOpCode);
|
||||
_counters = DebugApi.GetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType);
|
||||
|
||||
_cdlData = null;
|
||||
if(_highlightDataBytes || _highlightCodeBytes) {
|
||||
|
@ -128,13 +117,13 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
const int CyclesPerFrame = 357368;
|
||||
long index = byteIndex - firstByteIndex;
|
||||
double framesSinceExec = (double)(_state.MasterClock - _execStamps[index]) / CyclesPerFrame;
|
||||
double framesSinceWrite = (double)(_state.MasterClock - _writeStamps[index]) / CyclesPerFrame;
|
||||
double framesSinceRead = (double)(_state.MasterClock - _readStamps[index]) / CyclesPerFrame;
|
||||
double framesSinceExec = (double)(_state.MasterClock - _counters[index].ExecStamp) / CyclesPerFrame;
|
||||
double framesSinceWrite = (double)(_state.MasterClock - _counters[index].WriteStamp) / CyclesPerFrame;
|
||||
double framesSinceRead = (double)(_state.MasterClock - _counters[index].ReadStamp) / CyclesPerFrame;
|
||||
|
||||
bool isRead = _readCounts[index] > 0;
|
||||
bool isWritten = _writeCounts[index] > 0;
|
||||
bool isExecuted = _execCounts[index] > 0;
|
||||
bool isRead = _counters[index].ReadCount > 0;
|
||||
bool isWritten = _counters[index].WriteCount > 0;
|
||||
bool isExecuted = _counters[index].ExecCount > 0;
|
||||
bool isUnused = !isRead && !isWritten && !isExecuted;
|
||||
|
||||
int alpha = 0;
|
||||
|
@ -176,11 +165,11 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
}
|
||||
|
||||
if(_showExec && _execStamps[index] != 0 && framesSinceExec >= 0 && (framesSinceExec < _framesToFade || _framesToFade == 0)) {
|
||||
if(_showExec && _counters[index].ExecStamp != 0 && framesSinceExec >= 0 && (framesSinceExec < _framesToFade || _framesToFade == 0)) {
|
||||
_colors.ForeColor = Color.FromArgb(alpha, DarkerColor(cfg.ExecColor, (_framesToFade - framesSinceExec) / _framesToFade));
|
||||
} else if(_showWrite && _writeStamps[index] != 0 && framesSinceWrite >= 0 && (framesSinceWrite < _framesToFade || _framesToFade == 0)) {
|
||||
} else if(_showWrite && _counters[index].WriteStamp != 0 && framesSinceWrite >= 0 && (framesSinceWrite < _framesToFade || _framesToFade == 0)) {
|
||||
_colors.ForeColor = Color.FromArgb(alpha, DarkerColor(cfg.WriteColor, (_framesToFade - framesSinceWrite) / _framesToFade));
|
||||
} else if(_showRead && _readStamps[index] != 0 && framesSinceRead >= 0 && (framesSinceRead < _framesToFade || _framesToFade == 0)) {
|
||||
} else if(_showRead && _counters[index].ReadStamp != 0 && framesSinceRead >= 0 && (framesSinceRead < _framesToFade || _framesToFade == 0)) {
|
||||
_colors.ForeColor = Color.FromArgb(alpha, DarkerColor(cfg.ReadColor, (_framesToFade - framesSinceRead) / _framesToFade));
|
||||
} else {
|
||||
_colors.ForeColor = Color.FromArgb(alpha, Color.Black);
|
||||
|
|
|
@ -145,19 +145,11 @@ namespace Mesen.GUI
|
|||
return profilerData;
|
||||
}
|
||||
|
||||
[DllImport(DllPath, EntryPoint = "GetMemoryAccessStamps")] private static extern void GetMemoryAccessStampsWrapper(UInt32 offset, UInt32 length, SnesMemoryType type, MemoryOperationType operationType, [In,Out]UInt64[] stamps);
|
||||
public static UInt64[] GetMemoryAccessStamps(UInt32 offset, UInt32 length, SnesMemoryType type, MemoryOperationType operationType)
|
||||
[DllImport(DllPath, EntryPoint = "GetMemoryAccessCounts")] private static extern void GetMemoryAccessCountsWrapper(UInt32 offset, UInt32 length, SnesMemoryType type, [In,Out]AddressCounters[] counts);
|
||||
public static AddressCounters[] GetMemoryAccessCounts(UInt32 offset, UInt32 length, SnesMemoryType type)
|
||||
{
|
||||
UInt64[] stamps = new UInt64[length];
|
||||
DebugApi.GetMemoryAccessStampsWrapper(offset, length, type, operationType, stamps);
|
||||
return stamps;
|
||||
}
|
||||
|
||||
[DllImport(DllPath, EntryPoint = "GetMemoryAccessCounts")] private static extern void GetMemoryAccessCountsWrapper(UInt32 offset, UInt32 length, SnesMemoryType type, MemoryOperationType operationType, [In,Out]UInt32[] counts);
|
||||
public static UInt32[] GetMemoryAccessCounts(UInt32 offset, UInt32 length, SnesMemoryType type, MemoryOperationType operationType)
|
||||
{
|
||||
UInt32[] counts = new UInt32[length];
|
||||
DebugApi.GetMemoryAccessCountsWrapper(offset, length, type, operationType, counts);
|
||||
AddressCounters[] counts = new AddressCounters[length];
|
||||
DebugApi.GetMemoryAccessCountsWrapper(offset, length, type, counts);
|
||||
return counts;
|
||||
}
|
||||
|
||||
|
@ -276,6 +268,17 @@ namespace Mesen.GUI
|
|||
}
|
||||
}
|
||||
|
||||
public struct AddressCounters
|
||||
{
|
||||
public UInt32 ReadCount;
|
||||
public UInt64 ReadStamp;
|
||||
public UInt32 WriteCount;
|
||||
public bool UninitRead;
|
||||
public UInt64 WriteStamp;
|
||||
public UInt32 ExecCount;
|
||||
public UInt64 ExecStamp;
|
||||
}
|
||||
|
||||
public struct AddressInfo
|
||||
{
|
||||
public Int32 Address;
|
||||
|
|
Loading…
Add table
Reference in a new issue