diff --git a/Core/BaseMapper.cpp b/Core/BaseMapper.cpp index 6f041294..9cc586a9 100644 --- a/Core/BaseMapper.cpp +++ b/Core/BaseMapper.cpp @@ -973,7 +973,7 @@ void BaseMapper::SetMemoryValue(DebugMemoryType memoryType, uint32_t address, ui void BaseMapper::GetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info) { if(relativeAddr < 0x2000) { - info->Address = relativeAddr; + info->Address = relativeAddr & 0x7FF; info->Type = AddressType::InternalRam; } else { uint8_t *prgAddr = _prgPages[relativeAddr >> 8] + (uint8_t)relativeAddr; diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 495ecd2c..a774b045 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -585,6 +585,7 @@ void Debugger::UpdateCallstack(uint8_t instruction, uint32_t addr) for(int j = (int)_callstack.size() - i - 1; j >= 0; j--) { _callstack.pop_back(); _subReturnAddresses.pop_back(); + _profiler->UnstackFunction(); } break; } @@ -604,7 +605,9 @@ void Debugger::UpdateCallstack(uint8_t instruction, uint32_t addr) AddCallstackFrame(addr, targetAddr, StackFrameFlags::None); _subReturnAddresses.push_back(addr + 3); - _profiler->StackFunction(_mapper->ToAbsoluteAddress(addr), _mapper->ToAbsoluteAddress(targetAddr)); + AddressTypeInfo dest; + _mapper->GetAbsoluteAddressAndType(targetAddr, &dest); + _profiler->StackFunction(dest, StackFrameFlags::None); } } @@ -633,7 +636,9 @@ void Debugger::ProcessInterrupt(uint16_t cpuAddr, uint16_t destCpuAddr, bool for AddCallstackFrame(cpuAddr, destCpuAddr, forNmi ? StackFrameFlags::Nmi : StackFrameFlags::Irq); _subReturnAddresses.push_back(cpuAddr); - _profiler->StackFunction(-1, _mapper->ToAbsoluteAddress(destCpuAddr)); + AddressTypeInfo addressInfo; + _mapper->GetAbsoluteAddressAndType(destCpuAddr, &addressInfo); + _profiler->StackFunction(addressInfo, forNmi ? StackFrameFlags::Nmi : StackFrameFlags::Irq); ProcessEvent(forNmi ? EventType::Nmi : EventType::Irq); } @@ -762,30 +767,13 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin AddressTypeInfo addressInfo; GetAbsoluteAddressAndType(addr, &addressInfo); int32_t absoluteAddr = addressInfo.Type == AddressType::PrgRom ? addressInfo.Address : -1; - if(addressInfo.Address >= 0 && type != MemoryOperationType::DummyRead && type != MemoryOperationType::DummyWrite && _runToCycle == -1) { - //Ignore dummy read/writes and do not change counters while using the step back feature - if(type == MemoryOperationType::Write && CheckFlag(DebuggerFlags::IgnoreRedundantWrites)) { - if(_memoryManager->DebugRead(addr) != value) { - _memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _cpu->GetCycleCount()); - } - } else { - if(_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _cpu->GetCycleCount())) { - if(!_breakOnFirstCycle && _enableBreakOnUninitRead && CheckFlag(DebuggerFlags::BreakOnUninitMemoryRead)) { - //Break on uninit memory read - Step(1); - breakDone = SleepUntilResume(BreakSource::BreakOnUninitMemoryRead, 0, BreakpointType::Global, operationInfo.Address, (uint8_t)operationInfo.Value, operationInfo.OperationType); - } - } - } - - if(addressInfo.Type == AddressType::PrgRom) { - if(type == MemoryOperationType::ExecOperand) { - _codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::Code); - } else if(type == MemoryOperationType::Read) { - _codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::Data); - if(isDmcRead) { - _codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::PcmData); - } + if(addressInfo.Type == AddressType::PrgRom && addressInfo.Address >= 0 && type != MemoryOperationType::DummyRead && type != MemoryOperationType::DummyWrite && _runToCycle == -1) { + if(type == MemoryOperationType::ExecOperand) { + _codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::Code); + } else if(type == MemoryOperationType::Read) { + _codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::Data); + if(isDmcRead) { + _codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::PcmData); } } } @@ -821,7 +809,6 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin ProcessStepConditions(addr); _performanceTracker->ProcessCpuExec(addressInfo); - _profiler->ProcessInstructionStart(absoluteAddr); BreakSource breakSource = BreakSource::Unspecified; if(value == 0 && CheckFlag(DebuggerFlags::BreakOnBrk)) { @@ -864,7 +851,6 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin } else { _opCodeCycle++; _traceLogger->LogNonExec(operationInfo); - _profiler->ProcessCycle(); } if(!breakDone && _stepCycleCount > 0) { @@ -904,6 +890,10 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin _currentReadValue = nullptr; if(type == MemoryOperationType::Write) { + if(_runToCycle == -1 && !CheckFlag(DebuggerFlags::IgnoreRedundantWrites) || _memoryManager->DebugRead(addr) != value) { + _memoryAccessCounter->ProcessMemoryWrite(addressInfo, _cpu->GetCycleCount()); + } + _disassembler->InvalidateCache(addressInfo); if(addr >= 0x2000 && addr <= 0x3FFF) { @@ -926,8 +916,20 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin } else if(addr >= 0x4018 && _mapper->IsReadRegister(addr)) { _eventManager->AddDebugEvent(DebugEventType::MapperRegisterRead, addr, value); } - } else if(type == MemoryOperationType::ExecOpCode) { - if(!_needRewind) { + + //Ignore dummy read/writes and do not change counters while using the step back feature + if(_runToCycle == -1 && _memoryAccessCounter->ProcessMemoryRead(addressInfo, _cpu->GetCycleCount())) { + if(!breakDone && !_breakOnFirstCycle && _enableBreakOnUninitRead && CheckFlag(DebuggerFlags::BreakOnUninitMemoryRead)) { + //Break on uninit memory read + Step(1); + SleepUntilResume(BreakSource::BreakOnUninitMemoryRead, 0, BreakpointType::Global, operationInfo.Address, (uint8_t)operationInfo.Value, operationInfo.OperationType); + } + } + } else { + if(_runToCycle == -1 && (type == MemoryOperationType::ExecOpCode || type == MemoryOperationType::ExecOperand)) { + _memoryAccessCounter->ProcessMemoryExec(addressInfo, _cpu->GetCycleCount()); + } + if(!_needRewind && type == MemoryOperationType::ExecOpCode) { UpdateCallstack(_lastInstruction, addr); } } @@ -1006,7 +1008,7 @@ void Debugger::ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, OperationInfo operationInfo{ addr, value, type }; ProcessBreakpoints(BreakpointType::ReadVram, operationInfo, !_breakOnFirstCycle, true); } - _memoryAccessCounter->ProcessPpuMemoryAccess(addressInfo, type, _cpu->GetCycleCount()); + _memoryAccessCounter->ProcessPpuMemoryRead(addressInfo, _cpu->GetCycleCount()); ProcessPpuOperation(addr, value, MemoryOperationType::Read); } @@ -1019,7 +1021,7 @@ void Debugger::ProcessVramWriteOperation(uint16_t addr, uint8_t &value) OperationInfo operationInfo{ addr, value, MemoryOperationType::Write }; ProcessBreakpoints(BreakpointType::WriteVram, operationInfo, !_breakOnFirstCycle, true); } - _memoryAccessCounter->ProcessPpuMemoryAccess(addressInfo, MemoryOperationType::Write, _cpu->GetCycleCount()); + _memoryAccessCounter->ProcessPpuMemoryWrite(addressInfo, _cpu->GetCycleCount()); ProcessPpuOperation(addr, value, MemoryOperationType::Write); } diff --git a/Core/LuaApi.cpp b/Core/LuaApi.cpp index f2272d47..90233d2d 100644 --- a/Core/LuaApi.cpp +++ b/Core/LuaApi.cpp @@ -775,7 +775,7 @@ int LuaApi::GetAccessCounters(lua_State *lua) case AddressType::InternalRam: debugMemoryType = DebugMemoryType::InternalRam; - size = 0x2000; + size = 0x800; break; case AddressType::PrgRom: @@ -794,14 +794,32 @@ int LuaApi::GetAccessCounters(lua_State *lua) break; } - vector counts; - counts.resize(size, 0); - _debugger->GetMemoryAccessCounter()->GetAccessCounts(0, size, debugMemoryType, operationType, counts.data()); + vector counts; + counts.resize(size, {}); + _debugger->GetMemoryAccessCounter()->GetAccessCounts(0, size, debugMemoryType, 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; diff --git a/Core/MemoryAccessCounter.cpp b/Core/MemoryAccessCounter.cpp index cf450c8e..892a2226 100644 --- a/Core/MemoryAccessCounter.cpp +++ b/Core/MemoryAccessCounter.cpp @@ -13,22 +13,17 @@ MemoryAccessCounter::MemoryAccessCounter(Debugger* debugger) _debugger = debugger; uint32_t memorySizes[4] = { - 0x2000, + _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::InternalRam), _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::PrgRom), _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::WorkRam), _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::SaveRam) }; for(int i = 0; i < 4; i++) { - _readCounts[i].insert(_readCounts[i].end(), memorySizes[i], 0); - _writeCounts[i].insert(_writeCounts[i].end(), memorySizes[i], 0); - _execCounts[i].insert(_execCounts[i].end(), memorySizes[i], 0); - - _readStamps[i].insert(_readStamps[i].end(), memorySizes[i], 0); - _writeStamps[i].insert(_writeStamps[i].end(), memorySizes[i], 0); - _execStamps[i].insert(_execStamps[i].end(), memorySizes[i], 0); - - _uninitReads[i].insert(_uninitReads[i].end(), memorySizes[i], 0); + _counters[i].reserve(memorySizes[i]); + for(int j = 0; j < memorySizes[i]; j++) { + _counters[i].push_back({ (uint32_t)j }); + } } uint32_t ppuMemorySizes[4] = { @@ -39,155 +34,94 @@ MemoryAccessCounter::MemoryAccessCounter(Debugger* debugger) }; for(int i = 0; i < 4; i++) { - _ppuReadCounts[i].insert(_ppuReadCounts[i].end(), ppuMemorySizes[i], 0); - _ppuWriteCounts[i].insert(_ppuWriteCounts[i].end(), ppuMemorySizes[i], 0); - _ppuReadStamps[i].insert(_ppuReadStamps[i].end(), ppuMemorySizes[i], 0); - _ppuWriteStamps[i].insert(_ppuWriteStamps[i].end(), ppuMemorySizes[i], 0); + _ppuCounters[i].reserve(ppuMemorySizes[i]); + for(int j = 0; j < ppuMemorySizes[i]; j++) { + _ppuCounters[i].push_back({ (uint32_t)j }); + } } } -vector& MemoryAccessCounter::GetCountArray(MemoryOperationType operationType, AddressType addressType) -{ - switch(operationType) { - case MemoryOperationType::Read: return _readCounts[(int)addressType]; - case MemoryOperationType::Write: return _writeCounts[(int)addressType]; - - default: - case MemoryOperationType::ExecOpCode: - case MemoryOperationType::ExecOperand: return _execCounts[(int)addressType]; - } -} - -vector& MemoryAccessCounter::GetStampArray(MemoryOperationType operationType, AddressType addressType) -{ - switch(operationType) { - case MemoryOperationType::Read: return _readStamps[(int)addressType]; - case MemoryOperationType::Write: return _writeStamps[(int)addressType]; - - default: - case MemoryOperationType::ExecOpCode: - case MemoryOperationType::ExecOperand: return _execStamps[(int)addressType]; - } -} - -vector& MemoryAccessCounter::GetPpuCountArray(MemoryOperationType operationType, PpuAddressType addressType) -{ - return operationType == MemoryOperationType::Write ? _ppuWriteCounts[(int)addressType] : _ppuReadCounts[(int)addressType]; -} - -vector& MemoryAccessCounter::GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType) -{ - return operationType == MemoryOperationType::Write ? _ppuWriteStamps[(int)addressType] : _ppuReadStamps[(int)addressType]; -} - bool MemoryAccessCounter::IsAddressUninitialized(AddressTypeInfo &addressInfo) { if(addressInfo.Type == AddressType::InternalRam || addressInfo.Type == AddressType::WorkRam) { - int index = (int)addressInfo.Type; - return _writeCounts[index][addressInfo.Address] == 0; + return _counters[(int)addressInfo.Type][addressInfo.Address].WriteCount == 0; } return false; } -void MemoryAccessCounter::ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle) +void MemoryAccessCounter::ProcessPpuMemoryRead(PpuAddressTypeInfo &addressInfo, uint64_t cpuCycle) { - if(addressInfo.Address >= 0) { - vector &counts = GetPpuCountArray(operation, addressInfo.Type); - counts.data()[addressInfo.Address]++; - - vector &stamps = GetPpuStampArray(operation, addressInfo.Type); - stamps.data()[addressInfo.Address] = cpuCycle; + if(addressInfo.Address < 0) { + return; } + + AddressCounters& counts = _ppuCounters[(int)addressInfo.Type][addressInfo.Address]; + counts.ReadCount++; + counts.ReadStamp = cpuCycle; } -bool MemoryAccessCounter::ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle) +void MemoryAccessCounter::ProcessPpuMemoryWrite(PpuAddressTypeInfo& addressInfo, uint64_t cpuCycle) { - vector &counts = GetCountArray(operation, addressInfo.Type); - counts.data()[addressInfo.Address]++; + if(addressInfo.Address < 0) { + return; + } - vector &stamps = GetStampArray(operation, addressInfo.Type); - stamps.data()[addressInfo.Address] = cpuCycle; + AddressCounters& counts = _ppuCounters[(int)addressInfo.Type][addressInfo.Address]; + counts.WriteCount++; + counts.WriteStamp = cpuCycle; +} - if(operation == MemoryOperationType::Read && (addressInfo.Type == AddressType::InternalRam || addressInfo.Type == AddressType::WorkRam) && !_writeCounts[(int)addressInfo.Type][addressInfo.Address]) { +bool MemoryAccessCounter::ProcessMemoryRead(AddressTypeInfo &addressInfo, uint64_t cpuCycle) +{ + if(addressInfo.Address < 0) { + return false; + } + + AddressCounters& counts = _counters[(int)addressInfo.Type][addressInfo.Address]; + counts.ReadCount++; + counts.ReadStamp = cpuCycle; + + if(counts.WriteCount == 0 && (addressInfo.Type == AddressType::InternalRam || addressInfo.Type == AddressType::WorkRam)) { //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(AddressTypeInfo& addressInfo, uint64_t cpuCycle) +{ + if(addressInfo.Address < 0) { + return; + } + + AddressCounters& counts = _counters[(int)addressInfo.Type][addressInfo.Address]; + counts.WriteCount++; + counts.WriteStamp = cpuCycle; +} + +void MemoryAccessCounter::ProcessMemoryExec(AddressTypeInfo& addressInfo, uint64_t cpuCycle) +{ + if(addressInfo.Address < 0) { + return; + } + + AddressCounters& counts = _counters[(int)addressInfo.Type][addressInfo.Address]; + counts.ExecCount++; + counts.ExecStamp = cpuCycle; +} + void MemoryAccessCounter::ResetCounts() { DebugBreakHelper helper(_debugger); for(int i = 0; i < 4; 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(_ppuReadCounts[i].data(), 0, _ppuReadCounts[i].size() * sizeof(uint32_t)); - memset(_ppuWriteCounts[i].data(), 0, _ppuWriteCounts[i].size() * sizeof(uint32_t)); - memset(_ppuReadStamps[i].data(), 0, _ppuReadStamps[i].size() * sizeof(uint32_t)); - memset(_ppuWriteStamps[i].data(), 0, _ppuWriteStamps[i].size() * sizeof(uint32_t)); - } -} - -void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint64_t stamps[]) -{ - switch(memoryType) { - default: break; - - case DebugMemoryType::InternalRam: - memcpy(stamps, GetStampArray(operationType, AddressType::InternalRam).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::WorkRam: - memcpy(stamps, GetStampArray(operationType, AddressType::WorkRam).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::SaveRam: - memcpy(stamps, GetStampArray(operationType, AddressType::SaveRam).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::PrgRom: - memcpy(stamps, GetStampArray(operationType, AddressType::PrgRom).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::ChrRom: - memcpy(stamps, GetPpuStampArray(operationType, PpuAddressType::ChrRom).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::ChrRam: - memcpy(stamps, GetPpuStampArray(operationType, PpuAddressType::ChrRam).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::NametableRam: - memcpy(stamps, GetPpuStampArray(operationType, PpuAddressType::NametableRam).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::PaletteMemory: - memcpy(stamps, GetPpuStampArray(operationType, PpuAddressType::PaletteRam).data() + offset, length * sizeof(uint64_t)); - break; - - case DebugMemoryType::CpuMemory: - for(uint32_t i = 0; i < length; i++) { - AddressTypeInfo info; - _debugger->GetAbsoluteAddressAndType(offset + i, &info); - stamps[i] = GetStampArray(operationType, info.Type).data()[info.Address]; - } - break; - - case DebugMemoryType::PpuMemory: - for(uint32_t i = 0; i < length; i++) { - PpuAddressTypeInfo info; - _debugger->GetPpuAbsoluteAddressAndType(offset + i, &info); - stamps[i] = GetPpuStampArray(operationType, info.Type).data()[info.Address]; - } - break; + for(int j = 0; j < _counters[i].size(); j++) { + _counters[i][j] = { (uint32_t)j }; + } + for(int j = 0; j < _ppuCounters[i].size(); j++) { + _ppuCounters[i][j] = { (uint32_t)j }; + } } } @@ -203,71 +137,37 @@ void MemoryAccessCounter::GetNametableChangedData(bool ntChangedData[]) for(int i = 0; i < 0x1000; i++) { _debugger->GetPpuAbsoluteAddressAndType(0x2000+i, &addressInfo); if(addressInfo.Type != PpuAddressType::None) { - ntChangedData[i] = (cpuCycle - _ppuWriteStamps[(int)addressInfo.Type][addressInfo.Address]) < cyclesPerFrame; + ntChangedData[i] = (cpuCycle - _ppuCounters[(int)addressInfo.Type][addressInfo.Address].WriteStamp) < cyclesPerFrame; } else { ntChangedData[i] = false; } } } -void MemoryAccessCounter::GetUninitMemoryReads(DebugMemoryType memoryType, int32_t counts[]) -{ - AddressType addressType; - switch(memoryType) { - default: return; - case DebugMemoryType::InternalRam: addressType = AddressType::InternalRam; break; - case DebugMemoryType::WorkRam: addressType = AddressType::WorkRam; break; - case DebugMemoryType::SaveRam: addressType = AddressType::SaveRam; break; - case DebugMemoryType::PrgRom: addressType = AddressType::PrgRom; break; - } - - for(size_t i = 0, len = _uninitReads[(int)addressType].size(); i < len; i++) { - counts[i] = _uninitReads[(int)addressType][i]; - } -} - -void MemoryAccessCounter::GetAccessCounts(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, int32_t counts[]) +void MemoryAccessCounter::GetAccessCounts(uint32_t offset, uint32_t length, DebugMemoryType memoryType, AddressCounters counts[]) { switch(memoryType) { default: break; - case DebugMemoryType::InternalRam: - memcpy(counts, GetCountArray(operationType, AddressType::InternalRam).data() + offset, length * sizeof(uint32_t)); - break; + case DebugMemoryType::PrgRom: memcpy(counts, _counters[(int)AddressType::PrgRom].data() + offset, length * sizeof(AddressCounters)); break; + case DebugMemoryType::WorkRam: memcpy(counts, _counters[(int)AddressType::WorkRam].data() + offset, length * sizeof(AddressCounters)); break; + case DebugMemoryType::SaveRam: memcpy(counts, _counters[(int)AddressType::SaveRam].data() + offset, length * sizeof(AddressCounters)); break; + case DebugMemoryType::InternalRam: memcpy(counts, _counters[(int)AddressType::InternalRam].data() + offset, length * sizeof(AddressCounters)); break; - case DebugMemoryType::WorkRam: - memcpy(counts, GetCountArray(operationType, AddressType::WorkRam).data() + offset, length * sizeof(uint32_t)); - break; - - case DebugMemoryType::SaveRam: - memcpy(counts, GetCountArray(operationType, AddressType::SaveRam).data() + offset, length * sizeof(uint32_t)); - break; - - case DebugMemoryType::PrgRom: - memcpy(counts, GetCountArray(operationType, AddressType::PrgRom).data() + offset, length * sizeof(uint32_t)); - break; - - case DebugMemoryType::ChrRom: - memcpy(counts, GetPpuCountArray(operationType, PpuAddressType::ChrRom).data() + offset, length * sizeof(uint32_t)); - break; - - case DebugMemoryType::ChrRam: - memcpy(counts, GetPpuCountArray(operationType, PpuAddressType::ChrRam).data() + offset, length * sizeof(uint32_t)); - break; - - case DebugMemoryType::NametableRam: - memcpy(counts, GetPpuCountArray(operationType, PpuAddressType::NametableRam).data() + offset, length * sizeof(uint32_t)); - break; - - case DebugMemoryType::PaletteMemory: - memcpy(counts, GetPpuCountArray(operationType, PpuAddressType::PaletteRam).data() + offset, length * sizeof(uint32_t)); - break; + case DebugMemoryType::ChrRom: memcpy(counts, _ppuCounters[(int)PpuAddressType::ChrRom].data() + offset, length * sizeof(AddressCounters)); break; + case DebugMemoryType::ChrRam: memcpy(counts, _ppuCounters[(int)PpuAddressType::ChrRam].data() + offset, length * sizeof(AddressCounters)); break; + case DebugMemoryType::NametableRam: memcpy(counts, _ppuCounters[(int)PpuAddressType::NametableRam].data() + offset, length * sizeof(AddressCounters)); break; + case DebugMemoryType::PaletteMemory: memcpy(counts, _ppuCounters[(int)PpuAddressType::PaletteRam].data() + offset, length * sizeof(AddressCounters)); break; case DebugMemoryType::CpuMemory: for(uint32_t i = 0; i < length; i++) { AddressTypeInfo info; _debugger->GetAbsoluteAddressAndType(offset + i, &info); - counts[i] = GetCountArray(operationType, info.Type).data()[info.Address]; + if(info.Address >= 0) { + counts[i] = _counters[(int)info.Type][info.Address]; + } else { + counts[i] = {}; + } } break; @@ -275,7 +175,11 @@ void MemoryAccessCounter::GetAccessCounts(uint32_t offset, uint32_t length, Debu for(uint32_t i = 0; i < length; i++) { PpuAddressTypeInfo info; _debugger->GetPpuAbsoluteAddressAndType(offset + i, &info); - counts[i] = GetPpuCountArray(operationType, info.Type).data()[info.Address]; + if(info.Address >= 0) { + counts[i] = _ppuCounters[(int)info.Type][info.Address]; + } else { + counts[i] = {}; + } } break; } diff --git a/Core/MemoryAccessCounter.h b/Core/MemoryAccessCounter.h index daa2c18b..f99da787 100644 --- a/Core/MemoryAccessCounter.h +++ b/Core/MemoryAccessCounter.h @@ -5,42 +5,39 @@ #include class Debugger; +struct AddressCounters +{ + uint32_t Address; + uint32_t ReadCount; + uint64_t ReadStamp; + bool UninitRead; + uint32_t WriteCount; + uint64_t WriteStamp; + uint32_t ExecCount; + uint64_t ExecStamp; +}; + class MemoryAccessCounter { private: Debugger* _debugger; - vector _readCounts[4]; - vector _writeCounts[4]; - vector _execCounts[4]; - - vector _readStamps[4]; - vector _writeStamps[4]; - vector _execStamps[4]; - - vector _uninitReads[4]; - - vector _ppuReadCounts[4]; - vector _ppuWriteCounts[4]; - vector _ppuReadStamps[4]; - vector _ppuWriteStamps[4]; - - vector& GetCountArray(MemoryOperationType operationType, AddressType addressType); - vector& GetStampArray(MemoryOperationType operationType, AddressType addressType); - - vector& GetPpuCountArray(MemoryOperationType operationType, PpuAddressType addressType); - vector& GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType); + + vector _counters[4]; + vector _ppuCounters[4]; public: MemoryAccessCounter(Debugger* debugger); - void ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle); - bool ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle); + void ProcessPpuMemoryRead(PpuAddressTypeInfo& addressInfo, uint64_t cpuCycle); + void ProcessPpuMemoryWrite(PpuAddressTypeInfo &addressInfo, uint64_t cpuCycle); + bool ProcessMemoryRead(AddressTypeInfo& addressInfo, uint64_t cpuCycle); + void ProcessMemoryWrite(AddressTypeInfo& addressInfo, uint64_t cpuCycle); + void ProcessMemoryExec(AddressTypeInfo &addressInfo, uint64_t cpuCycle); + void ResetCounts(); bool IsAddressUninitialized(AddressTypeInfo &addressInfo); - void GetUninitMemoryReads(DebugMemoryType memoryType, int32_t counts[]); void GetNametableChangedData(bool ntChangedData[]); - void GetAccessCounts(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, int32_t counts[]); - void GetAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint64_t stamps[]); + void GetAccessCounts(uint32_t offset, uint32_t length, DebugMemoryType memoryType, AddressCounters counts[]); }; \ No newline at end of file diff --git a/Core/Profiler.cpp b/Core/Profiler.cpp index f8129154..b2961dd6 100644 --- a/Core/Profiler.cpp +++ b/Core/Profiler.cpp @@ -3,79 +3,87 @@ #include "Profiler.h" #include "DebugBreakHelper.h" #include "Debugger.h" +#include "Console.h" +#include "MemoryManager.h" #include "MemoryDumper.h" +#include "DebuggerTypes.h" +#include "Cpu.h" -Profiler::Profiler(Debugger * debugger) +static constexpr int32_t ResetFunctionIndex = -1; + +Profiler::Profiler(Debugger* debugger) { _debugger = debugger; + _cpu = debugger->GetConsole()->GetCpu(); InternalReset(); } -void Profiler::ProcessCycle() +Profiler::~Profiler() { - _cyclesByFunction[_currentFunction]++; - _cyclesByFunctionInclusive[_currentFunction]++; - _cyclesByInstruction[_currentInstruction]++; - _currentCycleCount++; } -void Profiler::StackFunction(int32_t instructionAddr, int32_t functionAddr) +void Profiler::StackFunction(AddressTypeInfo& addr, StackFrameFlags stackFlag) { - if(functionAddr >= 0) { - _nextFunctionAddr = functionAddr; - _jsrStack.push(instructionAddr); + if(addr.Address >= 0) { + uint32_t key = addr.Address | ((uint8_t)addr.Type << 24); + if(_functions.find(key) == _functions.end()) { + _functions[key] = ProfiledFunction(); + _functions[key].Address = addr; + } + + UpdateCycles(); + + _stackFlags.push_back(stackFlag); + _cycleCountStack.push_back(_currentCycleCount); + _functionStack.push_back(_currentFunction); + + ProfiledFunction& func = _functions[key]; + func.CallCount++; + + _currentFunction = key; + _currentCycleCount = 0; } } +void Profiler::UpdateCycles() +{ + uint64_t masterClock = _cpu->GetCycleCount(); + + ProfiledFunction& func = _functions[_currentFunction]; + uint64_t clockGap = masterClock - _prevMasterClock; + func.ExclusiveCycles += clockGap; + func.InclusiveCycles += clockGap; + + int32_t len = (int32_t)_functionStack.size(); + for(int32_t i = len - 1; i >= 0; i--) { + _functions[_functionStack[i]].InclusiveCycles += clockGap; + if(_stackFlags[i] != StackFrameFlags::None) { + //Don't apply inclusive times to stack frames before an IRQ/NMI + break; + } + } + + _currentCycleCount += clockGap; + _prevMasterClock = masterClock; +} + void Profiler::UnstackFunction() { if(!_functionStack.empty()) { + UpdateCycles(); + //Return to the previous function - _minCycles[_currentFunction] = std::min(_minCycles[_currentFunction], _currentCycleCount); - _maxCycles[_currentFunction] = std::max(_maxCycles[_currentFunction], _currentCycleCount); + ProfiledFunction& func = _functions[_currentFunction]; + func.MinCycles = std::min(func.MinCycles, _currentCycleCount); + func.MaxCycles = std::max(func.MaxCycles, _currentCycleCount); - _currentFunction = _functionStack.top(); - _functionStack.pop(); - - int32_t jsrAddr = _jsrStack.top(); - _jsrStack.pop(); - - if(jsrAddr >= 0) { - //Prevent IRQ/NMI from adding cycles to the calling function - - //Add the subroutine's cycle count to the JSR instruction - _cyclesByInstruction[jsrAddr] += _currentCycleCount; - - if(_currentFunction >= 0) { - //Add the subroutine's cycle count to the function's inclusive cycle count - _cyclesByFunctionInclusive[_currentFunction] += _currentCycleCount; - } - } + _currentFunction = _functionStack.back(); + _functionStack.pop_back(); + _stackFlags.pop_back(); //Add the subroutine's cycle count to the current routine's cycle count - _currentCycleCount = _cycleCountStack.top() + _currentCycleCount; - _cycleCountStack.pop(); - } -} - -void Profiler::ProcessInstructionStart(int32_t absoluteAddr) -{ - if(_nextFunctionAddr >= 0) { - _cycleCountStack.push(_currentCycleCount); - _functionStack.push(_currentFunction); - - _currentFunction = _nextFunctionAddr; - _currentCycleCount = 0; - _functionCallCount[_nextFunctionAddr]++; - - _nextFunctionAddr = -1; - } - - if(absoluteAddr >= 0) { - _currentInstruction = absoluteAddr; - ProcessCycle(); - } else { - _currentFunction = _inMemoryFunctionIndex; + _currentCycleCount = _cycleCountStack.back() + _currentCycleCount; + _cycleCountStack.pop_back(); } } @@ -87,43 +95,31 @@ void Profiler::Reset() void Profiler::InternalReset() { - _nextFunctionAddr = -1; + _prevMasterClock = _cpu->GetCycleCount(); _currentCycleCount = 0; - _currentInstruction = 0; + _currentFunction = ResetFunctionIndex; + _functionStack.clear(); + _stackFlags.clear(); + _cycleCountStack.clear(); - int size = _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::PrgRom); - _resetFunctionIndex = size; - _inMemoryFunctionIndex = size + 1; - _currentFunction = _resetFunctionIndex; - - _cyclesByInstruction.clear(); - _cyclesByFunction.clear(); - _cyclesByFunctionInclusive.clear(); - _functionCallCount.clear(); - _minCycles.clear(); - _maxCycles.clear(); - - _cyclesByInstruction.insert(_cyclesByInstruction.end(), size + 2, 0); - _cyclesByFunction.insert(_cyclesByFunction.end(), size + 2, 0); - _cyclesByFunctionInclusive.insert(_cyclesByFunctionInclusive.end(), size + 2, 0); - _functionCallCount.insert(_functionCallCount.end(), size + 2, 0); - _minCycles.insert(_minCycles.end(), size + 2, std::numeric_limits().max()); - _maxCycles.insert(_maxCycles.end(), size + 2, 0); + _functions.clear(); + _functions[ResetFunctionIndex] = ProfiledFunction(); + _functions[ResetFunctionIndex].Address = { ResetFunctionIndex, AddressType::Register }; } -void Profiler::GetProfilerData(uint64_t * profilerData, ProfilerDataType type) +void Profiler::GetProfilerData(ProfiledFunction* profilerData, uint32_t& functionCount) { - vector *dataArray = nullptr; + DebugBreakHelper helper(_debugger); - switch(type) { - default: - case ProfilerDataType::FunctionExclusive: dataArray = &_cyclesByFunction; break; - case ProfilerDataType::FunctionInclusive: dataArray = &_cyclesByFunctionInclusive; break; - case ProfilerDataType::Instructions: dataArray = &_cyclesByInstruction; break; - case ProfilerDataType::FunctionCallCount: dataArray = &_functionCallCount; break; - case ProfilerDataType::MinCycles: dataArray = &_minCycles; break; - case ProfilerDataType::MaxCycles: dataArray = &_maxCycles; break; + UpdateCycles(); + + functionCount = 0; + for(auto func : _functions) { + profilerData[functionCount] = func.second; + functionCount++; + + if(functionCount >= 100000) { + break; + } } - - memcpy(profilerData, (*dataArray).data(), (*dataArray).size() * sizeof(uint64_t)); } diff --git a/Core/Profiler.h b/Core/Profiler.h index a09fc580..48928353 100644 --- a/Core/Profiler.h +++ b/Core/Profiler.h @@ -1,55 +1,46 @@ #pragma once #include "stdafx.h" -#include -#include +#include "DebuggerTypes.h" class Debugger; +class CPU; -enum class ProfilerDataType +struct ProfiledFunction { - FunctionExclusive = 0, - FunctionInclusive = 1, - Instructions = 2, - FunctionCallCount = 3, - MinCycles = 4, - MaxCycles = 5, + uint64_t ExclusiveCycles = 0; + uint64_t InclusiveCycles = 0; + uint64_t CallCount = 0; + uint64_t MinCycles = UINT64_MAX; + uint64_t MaxCycles = 0; + AddressTypeInfo Address; }; class Profiler { private: Debugger* _debugger; + CPU* _cpu; - vector _cyclesByInstruction; - vector _cyclesByFunction; - vector _cyclesByFunctionInclusive; - vector _functionCallCount; - vector _minCycles; - vector _maxCycles; - - std::stack _functionStack; - std::stack _jsrStack; - std::stack _cycleCountStack; + unordered_map _functions; + + deque _functionStack; + deque _stackFlags; + deque _cycleCountStack; uint64_t _currentCycleCount; - + uint64_t _prevMasterClock; int32_t _currentFunction; - int32_t _currentInstruction; - int32_t _nextFunctionAddr; - - uint32_t _resetFunctionIndex; - uint32_t _inMemoryFunctionIndex; void InternalReset(); + void UpdateCycles(); public: Profiler(Debugger* debugger); + ~Profiler(); - void ProcessInstructionStart(int32_t absoluteAddr); - void ProcessCycle(); - void StackFunction(int32_t instructionAddr, int32_t functionAddr); + void StackFunction(AddressTypeInfo& addr, StackFrameFlags stackFlag); void UnstackFunction(); void Reset(); - void GetProfilerData(uint64_t* profilerData, ProfilerDataType type); + void GetProfilerData(ProfiledFunction* profilerData, uint32_t& functionCount); }; \ No newline at end of file diff --git a/Core/stdafx.h b/Core/stdafx.h index 50386d69..7e96009e 100644 --- a/Core/stdafx.h +++ b/Core/stdafx.h @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "../Utilities/UTF8Util.h" @@ -37,6 +39,8 @@ using std::ios; using std::istream; using std::ostream; using std::stringstream; +using std::unordered_map; +using std::deque; using utf8::ifstream; using utf8::ofstream; using std::list; diff --git a/GUI.NET/Debugger/ByteColorProvider.cs b/GUI.NET/Debugger/ByteColorProvider.cs index 0ab5d9fc..25db6316 100644 --- a/GUI.NET/Debugger/ByteColorProvider.cs +++ b/GUI.NET/Debugger/ByteColorProvider.cs @@ -9,12 +9,7 @@ namespace Mesen.GUI.Debugger public class ByteColorProvider : IByteColorProvider { DebugMemoryType _memoryType; - UInt64[] _readStamps; - UInt64[] _writeStamps; - UInt64[] _execStamps; - Int32[] _readCounts; - Int32[] _writeCounts; - Int32[] _execCounts; + AddressCounters[] _counts; bool[] _freezeState; byte[] _cdlData; bool[] _hasLabel; @@ -74,17 +69,11 @@ namespace Mesen.GUI.Debugger _breakpointTypes = null; } - _readStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Read); - _writeStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Write); - _execStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Exec); + _counts = InteropEmu.DebugGetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType); if(_memoryType == DebugMemoryType.CpuMemory) { _freezeState = InteropEmu.DebugGetFreezeState((UInt16)firstByteIndex, (UInt16)visibleByteCount); } - _readCounts = InteropEmu.DebugGetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Read); - _writeCounts = InteropEmu.DebugGetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Write); - _execCounts = InteropEmu.DebugGetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Exec); - _cdlData = null; if(_highlightDmcDataBytes || _highlightDataBytes || _highlightCodeBytes) { switch(_memoryType) { @@ -133,13 +122,13 @@ namespace Mesen.GUI.Debugger { const int CyclesPerFrame = 29780; long index = byteIndex - firstByteIndex; - double framesSinceExec = (double)(_state.CPU.CycleCount - _execStamps[index]) / CyclesPerFrame; - double framesSinceWrite = (double)(_state.CPU.CycleCount - _writeStamps[index]) / CyclesPerFrame; - double framesSinceRead = (double)(_state.CPU.CycleCount - _readStamps[index]) / CyclesPerFrame; + double framesSinceExec = (double)(_state.CPU.CycleCount - _counts[index].ExecStamp) / CyclesPerFrame; + double framesSinceWrite = (double)(_state.CPU.CycleCount - _counts[index].WriteStamp) / CyclesPerFrame; + double framesSinceRead = (double)(_state.CPU.CycleCount - _counts[index].ReadStamp) / CyclesPerFrame; - bool isRead = _readCounts[index] > 0; - bool isWritten = _writeCounts[index] > 0; - bool isExecuted = _execCounts[index] > 0; + bool isRead = _counts[index].ReadCount > 0; + bool isWritten = _counts[index].WriteCount > 0; + bool isExecuted = _counts[index].ExecCount > 0; bool isUnused = !isRead && !isWritten && !isExecuted; int alpha = 0; @@ -180,11 +169,11 @@ namespace Mesen.GUI.Debugger if(_freezeState != null && _freezeState[index]) { _colors.ForeColor = Color.Magenta; - } else if(_showExec && _execStamps[index] != 0 && framesSinceExec >= 0 && (framesSinceExec < _framesToFade || _framesToFade == 0)) { + } else if(_showExec && _counts[index].ExecStamp != 0 && framesSinceExec >= 0 && (framesSinceExec < _framesToFade || _framesToFade == 0)) { _colors.ForeColor = Color.FromArgb(alpha, DarkerColor(ConfigManager.Config.DebugInfo.RamExecColor, (_framesToFade - framesSinceExec) / _framesToFade)); - } else if(_showWrite && _writeStamps[index] != 0 && framesSinceWrite >= 0 && (framesSinceWrite < _framesToFade || _framesToFade == 0)) { + } else if(_showWrite && _counts[index].WriteStamp != 0 && framesSinceWrite >= 0 && (framesSinceWrite < _framesToFade || _framesToFade == 0)) { _colors.ForeColor = Color.FromArgb(alpha, DarkerColor(ConfigManager.Config.DebugInfo.RamWriteColor, (_framesToFade - framesSinceWrite) / _framesToFade)); - } else if(_showRead && _readStamps[index] != 0 && framesSinceRead >= 0 && (framesSinceRead < _framesToFade || _framesToFade == 0)) { + } else if(_showRead && _counts[index].ReadStamp != 0 && framesSinceRead >= 0 && (framesSinceRead < _framesToFade || _framesToFade == 0)) { _colors.ForeColor = Color.FromArgb(alpha, DarkerColor(ConfigManager.Config.DebugInfo.RamReadColor, (_framesToFade - framesSinceRead) / _framesToFade)); } else { _colors.ForeColor = Color.FromArgb(alpha, Color.Black); diff --git a/GUI.NET/Debugger/ChrByteColorProvider.cs b/GUI.NET/Debugger/ChrByteColorProvider.cs index f4a5b46f..a7070e4d 100644 --- a/GUI.NET/Debugger/ChrByteColorProvider.cs +++ b/GUI.NET/Debugger/ChrByteColorProvider.cs @@ -9,10 +9,7 @@ namespace Mesen.GUI.Debugger public class ChrByteColorProvider : IByteColorProvider { DebugMemoryType _memoryType; - UInt64[] _readStamps; - UInt64[] _writeStamps; - Int32[] _readCounts; - Int32[] _writeCounts; + AddressCounters[] _counts; DebugState _state = new DebugState(); bool _showWrite; bool _showRead; @@ -65,10 +62,7 @@ namespace Mesen.GUI.Debugger InteropEmu.DebugGetState(ref _state); - _readStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Read); - _writeStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Write); - _readCounts = InteropEmu.DebugGetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Read); - _writeCounts = InteropEmu.DebugGetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType, MemoryOperationType.Write); + _counts = InteropEmu.DebugGetMemoryAccessCounts((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType); if(_memoryType == DebugMemoryType.ChrRom && (_highlightDrawnBytes || _highlightReadBytes)) { _cdlData = InteropEmu.DebugGetCdlData((UInt32)firstByteIndex, (UInt32)visibleByteCount, _memoryType); @@ -81,11 +75,11 @@ namespace Mesen.GUI.Debugger { const int CyclesPerFrame = 29780; long index = byteIndex - firstByteIndex; - double framesSinceWrite = (double)(_state.CPU.CycleCount - _writeStamps[index]) / CyclesPerFrame; - double framesSinceRead = (double)(_state.CPU.CycleCount - _readStamps[index]) / CyclesPerFrame; + double framesSinceWrite = (double)(_state.CPU.CycleCount - _counts[index].WriteStamp) / CyclesPerFrame; + double framesSinceRead = (double)(_state.CPU.CycleCount - _counts[index].ReadStamp) / CyclesPerFrame; - bool isRead = _readCounts[index] > 0; - bool isWritten = _writeCounts[index] > 0; + bool isRead = _counts[index].ReadCount > 0; + bool isWritten = _counts[index].WriteCount > 0; bool isUnused = !isRead && !isWritten; int alpha = 0; @@ -115,9 +109,9 @@ namespace Mesen.GUI.Debugger } } - if(_showWrite && _writeStamps[index] != 0 && framesSinceWrite >= 0 && (framesSinceWrite < _framesToFade || _framesToFade == 0)) { + if(_showWrite && _counts[index].WriteStamp != 0 && framesSinceWrite >= 0 && (framesSinceWrite < _framesToFade || _framesToFade == 0)) { _colors.ForeColor = Color.FromArgb(alpha, ByteColorProvider.DarkerColor(ConfigManager.Config.DebugInfo.RamWriteColor, (_framesToFade - framesSinceWrite) / _framesToFade)); - } else if(_showRead && _readStamps[index] != 0 && framesSinceRead >= 0 && (framesSinceRead < _framesToFade || _framesToFade == 0)) { + } else if(_showRead && _counts[index].ReadStamp != 0 && framesSinceRead >= 0 && (framesSinceRead < _framesToFade || _framesToFade == 0)) { _colors.ForeColor = Color.FromArgb(alpha, ByteColorProvider.DarkerColor(ConfigManager.Config.DebugInfo.RamReadColor, (_framesToFade - framesSinceRead) / _framesToFade)); } else { _colors.ForeColor = Color.FromArgb(alpha, Color.Black); diff --git a/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.Designer.cs b/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.Designer.cs index e2238040..d4829e0c 100644 --- a/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.Designer.cs +++ b/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.Designer.cs @@ -32,27 +32,27 @@ this.lblViewMemoryType = new System.Windows.Forms.Label(); this.cboMemoryType = new System.Windows.Forms.ComboBox(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.ctrlScrollableTextbox = new Mesen.GUI.Debugger.ctrlScrollableTextbox(); this.btnReset = new System.Windows.Forms.Button(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); - this.picHelp = new System.Windows.Forms.PictureBox(); - this.chkHighlightUninitRead = new System.Windows.Forms.CheckBox(); - this.chkHideUnusedAddresses = new System.Windows.Forms.CheckBox(); + this.picWatchHelp = new System.Windows.Forms.PictureBox(); + this.lblHint = new System.Windows.Forms.Label(); this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); - this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); - this.lblSort = new System.Windows.Forms.Label(); - this.cboSort = new System.Windows.Forms.ComboBox(); + this.lstCounters = new Mesen.GUI.Controls.DoubleBufferedListView(); + this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader7 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader8 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.toolTip = new System.Windows.Forms.ToolTip(this.components); - this.ctxMenu = new System.Windows.Forms.ContextMenuStrip(this.components); - this.mnuCopy = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.columnHeader9 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.flowLayoutPanel1.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.picHelp)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).BeginInit(); this.tableLayoutPanel2.SuspendLayout(); - this.flowLayoutPanel2.SuspendLayout(); - this.ctxMenu.SuspendLayout(); this.SuspendLayout(); // // flowLayoutPanel1 @@ -93,10 +93,10 @@ this.tableLayoutPanel1.ColumnCount = 2; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.Controls.Add(this.ctrlScrollableTextbox, 0, 1); this.tableLayoutPanel1.Controls.Add(this.btnReset, 1, 2); this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 0, 2); this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.lstCounters, 0, 1); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); @@ -106,95 +106,60 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(514, 307); + this.tableLayoutPanel1.Size = new System.Drawing.Size(641, 343); this.tableLayoutPanel1.TabIndex = 3; // - // ctrlScrollableTextbox - // - this.ctrlScrollableTextbox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.ctrlScrollableTextbox.CodeHighlightingEnabled = true; - this.tableLayoutPanel1.SetColumnSpan(this.ctrlScrollableTextbox, 2); - this.ctrlScrollableTextbox.ContextMenuStrip = this.ctxMenu; - this.ctrlScrollableTextbox.Dock = System.Windows.Forms.DockStyle.Fill; - this.ctrlScrollableTextbox.HideSelection = false; - this.ctrlScrollableTextbox.Location = new System.Drawing.Point(0, 27); - this.ctrlScrollableTextbox.Margin = new System.Windows.Forms.Padding(0); - this.ctrlScrollableTextbox.Name = "ctrlScrollableTextbox"; - this.ctrlScrollableTextbox.ShowCompactPrgAddresses = false; - this.ctrlScrollableTextbox.ShowContentNotes = false; - this.ctrlScrollableTextbox.ShowLineNumberNotes = false; - this.ctrlScrollableTextbox.ShowMemoryValues = false; - this.ctrlScrollableTextbox.ShowScrollbars = true; - this.ctrlScrollableTextbox.ShowSingleContentLineNotes = true; - this.ctrlScrollableTextbox.ShowSingleLineLineNumberNotes = false; - this.ctrlScrollableTextbox.Size = new System.Drawing.Size(514, 233); - this.ctrlScrollableTextbox.TabIndex = 0; - // // btnReset // this.btnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnReset.Location = new System.Drawing.Point(436, 281); + this.btnReset.Location = new System.Drawing.Point(566, 320); + this.btnReset.Margin = new System.Windows.Forms.Padding(0); this.btnReset.Name = "btnReset"; this.btnReset.Size = new System.Drawing.Size(75, 23); this.btnReset.TabIndex = 5; - this.btnReset.Text = "Reset Counts"; + this.btnReset.Text = "Reset"; this.btnReset.UseVisualStyleBackColor = true; this.btnReset.Click += new System.EventHandler(this.btnReset_Click); // // tableLayoutPanel3 // - this.tableLayoutPanel3.ColumnCount = 3; - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel3.ColumnCount = 2; this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel3.Controls.Add(this.picHelp, 1, 1); - this.tableLayoutPanel3.Controls.Add(this.chkHighlightUninitRead, 0, 1); - this.tableLayoutPanel3.Controls.Add(this.chkHideUnusedAddresses, 0, 0); + this.tableLayoutPanel3.Controls.Add(this.picWatchHelp, 0, 0); + this.tableLayoutPanel3.Controls.Add(this.lblHint, 1, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 260); + this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 320); this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; - this.tableLayoutPanel3.RowCount = 3; - this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel3.RowCount = 2; this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel3.Size = new System.Drawing.Size(433, 47); + this.tableLayoutPanel3.Size = new System.Drawing.Size(566, 23); this.tableLayoutPanel3.TabIndex = 2; // - // picHelp + // picWatchHelp // - this.picHelp.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.picHelp.Image = global::Mesen.GUI.Properties.Resources.Help; - this.picHelp.Location = new System.Drawing.Point(201, 26); - this.picHelp.Name = "picHelp"; - this.picHelp.Size = new System.Drawing.Size(16, 16); - this.picHelp.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; - this.picHelp.TabIndex = 5; - this.picHelp.TabStop = false; + this.picWatchHelp.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.picWatchHelp.Image = global::Mesen.GUI.Properties.Resources.Warning; + this.picWatchHelp.Location = new System.Drawing.Point(3, 3); + this.picWatchHelp.Name = "picWatchHelp"; + this.picWatchHelp.Size = new System.Drawing.Size(16, 16); + this.picWatchHelp.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.picWatchHelp.TabIndex = 2; + this.picWatchHelp.TabStop = false; // - // chkHighlightUninitRead + // lblHint // - this.chkHighlightUninitRead.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.chkHighlightUninitRead.AutoSize = true; - this.chkHighlightUninitRead.Location = new System.Drawing.Point(3, 26); - this.chkHighlightUninitRead.Name = "chkHighlightUninitRead"; - this.chkHighlightUninitRead.Size = new System.Drawing.Size(192, 17); - this.chkHighlightUninitRead.TabIndex = 4; - this.chkHighlightUninitRead.Text = "Highlight uninitialized memory reads"; - this.chkHighlightUninitRead.UseVisualStyleBackColor = true; - this.chkHighlightUninitRead.CheckedChanged += new System.EventHandler(this.chkOption_CheckedChanged); - // - // chkHideUnusedAddresses - // - this.chkHideUnusedAddresses.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.chkHideUnusedAddresses.AutoSize = true; - this.chkHideUnusedAddresses.Location = new System.Drawing.Point(3, 3); - this.chkHideUnusedAddresses.Name = "chkHideUnusedAddresses"; - this.chkHideUnusedAddresses.Size = new System.Drawing.Size(137, 17); - this.chkHideUnusedAddresses.TabIndex = 6; - this.chkHideUnusedAddresses.Text = "Hide unused addresses"; - this.chkHideUnusedAddresses.UseVisualStyleBackColor = true; - this.chkHideUnusedAddresses.CheckedChanged += new System.EventHandler(this.chkOption_CheckedChanged); + this.lblHint.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblHint.AutoSize = true; + this.lblHint.Location = new System.Drawing.Point(25, 4); + this.lblHint.Name = "lblHint"; + this.lblHint.Size = new System.Drawing.Size(530, 13); + this.lblHint.TabIndex = 0; + this.lblHint.Text = "Uninitialized read column is only accurate if the debugger was active when the ga" + + "me was loaded/power cycled"; + this.lblHint.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // tableLayoutPanel2 // @@ -205,55 +170,79 @@ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel1, 0, 0); - this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 1, 0); this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; this.tableLayoutPanel2.RowCount = 1; this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel2.Size = new System.Drawing.Size(514, 27); + this.tableLayoutPanel2.Size = new System.Drawing.Size(641, 27); this.tableLayoutPanel2.TabIndex = 6; // - // flowLayoutPanel2 + // lstCounters // - this.flowLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.flowLayoutPanel2.AutoSize = true; - this.flowLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.flowLayoutPanel2.Controls.Add(this.lblSort); - this.flowLayoutPanel2.Controls.Add(this.cboSort); - this.flowLayoutPanel2.Location = new System.Drawing.Point(338, 0); - this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); - this.flowLayoutPanel2.Name = "flowLayoutPanel2"; - this.flowLayoutPanel2.Size = new System.Drawing.Size(176, 27); - this.flowLayoutPanel2.TabIndex = 3; - this.flowLayoutPanel2.WrapContents = false; + this.lstCounters.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeader1, + this.columnHeader9, + this.columnHeader2, + this.columnHeader6, + this.columnHeader3, + this.columnHeader7, + this.columnHeader4, + this.columnHeader8, + this.columnHeader5}); + this.tableLayoutPanel1.SetColumnSpan(this.lstCounters, 2); + this.lstCounters.Dock = System.Windows.Forms.DockStyle.Fill; + this.lstCounters.FullRowSelect = true; + this.lstCounters.Location = new System.Drawing.Point(3, 30); + this.lstCounters.Name = "lstCounters"; + this.lstCounters.Size = new System.Drawing.Size(635, 287); + this.lstCounters.TabIndex = 7; + this.lstCounters.UseCompatibleStateImageBehavior = false; + this.lstCounters.View = System.Windows.Forms.View.Details; + this.lstCounters.VirtualMode = true; + this.lstCounters.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lstCounters_ColumnClick); + this.lstCounters.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lstCounters_RetrieveVirtualItem); // - // lblSort + // columnHeader1 // - this.lblSort.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.lblSort.AutoSize = true; - this.lblSort.Location = new System.Drawing.Point(3, 7); - this.lblSort.Name = "lblSort"; - this.lblSort.Size = new System.Drawing.Size(43, 13); - this.lblSort.TabIndex = 0; - this.lblSort.Text = "Sort by:"; + this.columnHeader1.Text = "Address"; + this.columnHeader1.Width = 60; // - // cboSort + // columnHeader2 // - this.cboSort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboSort.FormattingEnabled = true; - this.cboSort.Items.AddRange(new object[] { - "Address", - "Read Count", - "Write Count", - "Execute Count", - "Uninitialized Reads"}); - this.cboSort.Location = new System.Drawing.Point(52, 3); - this.cboSort.Name = "cboSort"; - this.cboSort.Size = new System.Drawing.Size(121, 21); - this.cboSort.TabIndex = 1; - this.cboSort.SelectedIndexChanged += new System.EventHandler(this.cboSort_SelectedIndexChanged); + this.columnHeader2.Text = "Reads"; + this.columnHeader2.Width = 70; + // + // columnHeader6 + // + this.columnHeader6.Text = "Last Read"; + this.columnHeader6.Width = 70; + // + // columnHeader3 + // + this.columnHeader3.Text = "Writes"; + this.columnHeader3.Width = 70; + // + // columnHeader7 + // + this.columnHeader7.Text = "Last Write"; + this.columnHeader7.Width = 70; + // + // columnHeader4 + // + this.columnHeader4.Text = "Executes"; + this.columnHeader4.Width = 70; + // + // columnHeader8 + // + this.columnHeader8.Text = "Last Exec"; + this.columnHeader8.Width = 70; + // + // columnHeader5 + // + this.columnHeader5.Text = "Uninit Read"; + this.columnHeader5.Width = 70; // // toolTip // @@ -262,29 +251,10 @@ this.toolTip.InitialDelay = 10; this.toolTip.ReshowDelay = 10; // - // ctxMenu + // columnHeader9 // - this.ctxMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuCopy, - this.mnuSelectAll}); - this.ctxMenu.Name = "ctxMenu"; - this.ctxMenu.Size = new System.Drawing.Size(123, 48); - // - // mnuCopy - // - this.mnuCopy.Image = global::Mesen.GUI.Properties.Resources.Copy; - this.mnuCopy.Name = "mnuCopy"; - this.mnuCopy.Size = new System.Drawing.Size(122, 22); - this.mnuCopy.Text = "Copy"; - this.mnuCopy.Click += new System.EventHandler(this.mnuCopy_Click); - // - // mnuSelectAll - // - this.mnuSelectAll.Image = global::Mesen.GUI.Properties.Resources.SelectAll; - this.mnuSelectAll.Name = "mnuSelectAll"; - this.mnuSelectAll.Size = new System.Drawing.Size(122, 22); - this.mnuSelectAll.Text = "Select All"; - this.mnuSelectAll.Click += new System.EventHandler(this.mnuSelectAll_Click); + this.columnHeader9.Text = "Value"; + this.columnHeader9.Width = 40; // // ctrlMemoryAccessCounters // @@ -293,42 +263,40 @@ this.Controls.Add(this.tableLayoutPanel1); this.Margin = new System.Windows.Forms.Padding(0); this.Name = "ctrlMemoryAccessCounters"; - this.Size = new System.Drawing.Size(514, 307); + this.Size = new System.Drawing.Size(641, 343); this.flowLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.PerformLayout(); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); this.tableLayoutPanel3.ResumeLayout(false); this.tableLayoutPanel3.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.picHelp)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).EndInit(); this.tableLayoutPanel2.ResumeLayout(false); this.tableLayoutPanel2.PerformLayout(); - this.flowLayoutPanel2.ResumeLayout(false); - this.flowLayoutPanel2.PerformLayout(); - this.ctxMenu.ResumeLayout(false); this.ResumeLayout(false); } #endregion - - private ctrlScrollableTextbox ctrlScrollableTextbox; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Label lblViewMemoryType; private System.Windows.Forms.ComboBox cboMemoryType; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; - private System.Windows.Forms.Label lblSort; - private System.Windows.Forms.ComboBox cboSort; - private System.Windows.Forms.CheckBox chkHighlightUninitRead; private System.Windows.Forms.Button btnReset; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; - private System.Windows.Forms.PictureBox picHelp; private System.Windows.Forms.ToolTip toolTip; - private System.Windows.Forms.CheckBox chkHideUnusedAddresses; - private System.Windows.Forms.ContextMenuStrip ctxMenu; - private System.Windows.Forms.ToolStripMenuItem mnuCopy; - private System.Windows.Forms.ToolStripMenuItem mnuSelectAll; + private Mesen.GUI.Controls.DoubleBufferedListView lstCounters; + private System.Windows.Forms.ColumnHeader columnHeader1; + private System.Windows.Forms.ColumnHeader columnHeader2; + private System.Windows.Forms.ColumnHeader columnHeader3; + private System.Windows.Forms.ColumnHeader columnHeader4; + private System.Windows.Forms.ColumnHeader columnHeader5; + private System.Windows.Forms.ColumnHeader columnHeader6; + private System.Windows.Forms.ColumnHeader columnHeader7; + private System.Windows.Forms.ColumnHeader columnHeader8; + private System.Windows.Forms.Label lblHint; + private System.Windows.Forms.PictureBox picWatchHelp; + private System.Windows.Forms.ColumnHeader columnHeader9; } } diff --git a/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.cs b/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.cs index 502a4dec..21098a0f 100644 --- a/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.cs +++ b/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.cs @@ -15,15 +15,16 @@ namespace Mesen.GUI.Debugger.Controls { public partial class ctrlMemoryAccessCounters : BaseControl { - private MemoryCountData[] _data; + private bool _sorting = false; + private UInt64 _cycleCount = 0; + private AddressCounters[] _counts = new AddressCounters[0]; + private AddressCounters[] _newCounts = new AddressCounters[0]; private DebugMemoryType _memoryType = DebugMemoryType.InternalRam; private SortType _sortType = SortType.Address; public ctrlMemoryAccessCounters() { InitializeComponent(); - - this.toolTip.SetToolTip(chkHighlightUninitRead, "The uninitialized memory reads highlight will only be accurate if the debugger was active when the game was loaded (or if the game has been power cycled since)"); } protected override void OnLoad(EventArgs e) @@ -31,17 +32,9 @@ namespace Mesen.GUI.Debugger.Controls base.OnLoad(e); if(!IsDesignMode) { InitMemoryTypeDropdown(); - cboSort.SelectedIndex = 0; - InitShortcuts(); } } - private void InitShortcuts() - { - mnuCopy.InitShortcut(this, nameof(DebuggerShortcutsConfig.Copy)); - mnuSelectAll.InitShortcut(this, nameof(DebuggerShortcutsConfig.SelectAll)); - } - public void InitMemoryTypeDropdown() { cboMemoryType.SelectedIndexChanged -= cboMemoryType_SelectedIndexChanged; @@ -79,97 +72,43 @@ namespace Mesen.GUI.Debugger.Controls UpdateMemoryType(); } - public Font BaseFont { get { return ctrlScrollableTextbox.BaseFont; } set { ctrlScrollableTextbox.BaseFont = value; } } - public int TextZoom { get { return ctrlScrollableTextbox.TextZoom; } set { ctrlScrollableTextbox.TextZoom = value; } } - public void RefreshData() { - bool isPpu = ( - _memoryType == DebugMemoryType.ChrRom || - _memoryType == DebugMemoryType.ChrRam || - _memoryType == DebugMemoryType.PaletteMemory || - _memoryType == DebugMemoryType.NametableRam - ); + if(_sorting) { + return; + } + + InteropEmu.DebugGetMemoryAccessCounts(_memoryType, ref _counts); - int[] readCounts = InteropEmu.DebugGetMemoryAccessCounts(_memoryType, MemoryOperationType.Read); - int[] writeCounts = InteropEmu.DebugGetMemoryAccessCounts(_memoryType, MemoryOperationType.Write); - int[] execCounts = isPpu ? new int[readCounts.Length] : InteropEmu.DebugGetMemoryAccessCounts(_memoryType, MemoryOperationType.Exec); + DebugState state = new DebugState(); + InteropEmu.DebugGetState(ref state); + _cycleCount = state.CPU.CycleCount; - int[] uninitReads = isPpu ? new int[readCounts.Length] : InteropEmu.DebugGetUninitMemoryReads(_memoryType); - - List addresses = new List(readCounts.Length); - List content = new List(readCounts.Length); - - if(_data == null || _data.Length != readCounts.Length) { - _data = new MemoryCountData[readCounts.Length]; - for(int i = 0; i < readCounts.Length; i++) { - _data[i] = new MemoryCountData(); + _sorting = true; + Task.Run(() => { + switch(_sortType) { + case SortType.Address: break; + case SortType.Value: break; + case SortType.Read: Array.Sort(_newCounts, new SortReadComparer()); break; + case SortType.ReadStamp: Array.Sort(_newCounts, new SortReadStampComparer()); break; + case SortType.Write: Array.Sort(_newCounts, new SortWriteComparer()); break; + case SortType.WriteStamp: Array.Sort(_newCounts, new SortWriteStampComparer()); break; + case SortType.Exec: Array.Sort(_newCounts, new SortExecComparer()); break; + case SortType.ExecStamp: Array.Sort(_newCounts, new SortExecStampComparer()); break; + case SortType.UninitRead: Array.Sort(_newCounts, new SortUninitComparer()); break; } - } - for(int i = 0; i < readCounts.Length; i++) { - _data[i].Address = i; - _data[i].ReadCount = readCounts[i]; - _data[i].WriteCount = writeCounts[i]; - _data[i].ExecCount = execCounts[i]; - _data[i].UninitRead = uninitReads[i] > 0; - _data[i].IsPpu = isPpu; - } + AddressCounters[] counts = _counts; + _counts = _newCounts; + _newCounts = counts; - MemoryCountData[] data = new MemoryCountData[readCounts.Length]; - Array.Copy(_data, data, readCounts.Length); - - switch(_sortType) { - case SortType.Address: break; - case SortType.Read: Array.Sort(data.Select((e) => -e.ReadCount).ToArray(), data); break; - case SortType.Write: Array.Sort(data.Select((e) => -e.WriteCount).ToArray(), data); break; - case SortType.Exec: Array.Sort(data.Select((e) => -e.ExecCount).ToArray(), data); break; - case SortType.UninitRead: Array.Sort(data.Select((e) => e.UninitRead ? -e.ReadCount : (Int32.MaxValue - e.ReadCount)).ToArray(), data); break; - } - - bool hideUnusedAddresses = chkHideUnusedAddresses.Checked; - for(int i = 0; i < readCounts.Length; i++) { - if(!hideUnusedAddresses || !data[i].Empty) { - addresses.Add(data[i].Address); - content.Add(data[i].Content); - } - } - - if(chkHighlightUninitRead.Checked) { - ctrlScrollableTextbox.StyleProvider = new LineStyleProvider(new HashSet(data.Where((e) => e.UninitRead).Select((e) => e.Address))); - } else { - ctrlScrollableTextbox.StyleProvider = null; - } - if(isPpu) { - ctrlScrollableTextbox.Header = " " + "Read".PadRight(12) + "Write"; - } else { - ctrlScrollableTextbox.Header = " " + "Read".PadRight(12) + "Write".PadRight(12) + "Execute"; - } - ctrlScrollableTextbox.LineNumbers = addresses.ToArray(); - ctrlScrollableTextbox.TextLines = content.ToArray(); - } - - private class LineStyleProvider : ctrlTextbox.ILineStyleProvider - { - HashSet _addresses = new HashSet(); - - public LineStyleProvider(HashSet addresses) - { - _addresses = addresses; - } - - public string GetLineComment(int lineIndex) - { - return null; - } - - public LineProperties GetLineStyle(int cpuAddress, int lineIndex) - { - if(_addresses.Contains(cpuAddress)) { - return new LineProperties() { TextBgColor = Color.LightCoral }; - } - return null; - } + this.BeginInvoke((Action)(() => { + _sorting = false; + lstCounters.BeginUpdate(); + lstCounters.VirtualListSize = _counts.Length; + lstCounters.EndUpdate(); + })); + }); } private void cboMemoryType_SelectedIndexChanged(object sender, EventArgs e) @@ -183,111 +122,101 @@ namespace Mesen.GUI.Debugger.Controls RefreshData(); } - private void cboSort_SelectedIndexChanged(object sender, EventArgs e) - { - _sortType = (SortType)cboSort.SelectedIndex; - RefreshData(); - } - - private void chkOption_CheckedChanged(object sender, EventArgs e) - { - RefreshData(); - } - private void btnReset_Click(object sender, EventArgs e) { InteropEmu.DebugResetMemoryAccessCounts(); RefreshData(); } + private string FormatNumber(UInt64 value) + { + if(value >= 1000000000000) { + return ((double)value / 1000000000000).ToString("0.00") + " T"; + } else if(value >= 1000000000) { + return ((double)value / 1000000000).ToString("0.00") + " G"; + } else if(value >= 1000000) { + return ((double)value / 1000000).ToString("0.00") + " M"; + } else if(value >= 1000) { + return ((double)value / 1000).ToString("0.00") + " K"; + } + return value.ToString(); + } + + private void lstCounters_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) + { + AddressCounters counts = _counts[e.ItemIndex]; + ListViewItem item = new ListViewItem("$" + counts.Address.ToString("X4")); + item.Selected = false; + item.Focused = false; + + item.SubItems.Add("$" + InteropEmu.DebugGetMemoryValue(_memoryType, counts.Address).ToString("X2")); + item.SubItems.Add(FormatNumber(counts.ReadCount)); + item.SubItems.Add(counts.ReadStamp > 0 ? FormatNumber(_cycleCount - counts.ReadStamp) : "n/a"); + item.SubItems.Add(FormatNumber(counts.WriteCount)); + item.SubItems.Add(counts.WriteStamp > 0 ? FormatNumber(_cycleCount - counts.WriteStamp) : "n/a"); + item.SubItems.Add(FormatNumber(counts.ExecCount)); + item.SubItems.Add(counts.ExecStamp > 0 ? FormatNumber(_cycleCount - counts.ExecStamp) : "n/a"); + item.SubItems.Add(counts.UninitRead != 0 ? "☑" : "☐"); + + if(counts.ReadCount == 0 && counts.WriteCount == 0 && counts.ExecCount == 0) { + item.ForeColor = Color.Gray; + } + + e.Item = item; + } + public void GoToAddress() { - ctrlScrollableTextbox.GoToAddress(); + GoToAddress address = new GoToAddress(); + address.Address = 0; + + using(frmGoToLine frm = new frmGoToLine(address, 8)) { + frm.StartPosition = FormStartPosition.Manual; + Point topLeft = this.PointToScreen(new Point(0, 0)); + frm.Location = new Point(topLeft.X + (this.Width - frm.Width) / 2, topLeft.Y + (this.Height - frm.Height) / 2); + if(frm.ShowDialog() == DialogResult.OK) { + int index = -1; + for(int i = 0; i < _counts.Length; i++) { + if(_counts[i].Address == address.Address) { + index = i; + break; + } + } + + if(index >= 0) { + lstCounters.EnsureVisible(index); + lstCounters.SelectedIndices.Clear(); + lstCounters.SelectedIndices.Add(index); + } + } + } } + private void lstCounters_ColumnClick(object sender, ColumnClickEventArgs e) + { + _sortType = (SortType)e.Column; + RefreshData(); + } + + private class SortReadComparer : IComparer { public int Compare(AddressCounters a, AddressCounters b) { return a.ReadCount.CompareTo(b.ReadCount) * -2 + a.Address.CompareTo(b.Address); } } + private class SortReadStampComparer : IComparer { public int Compare(AddressCounters a, AddressCounters b) { return a.ReadStamp.CompareTo(b.ReadStamp) * -2 + a.Address.CompareTo(b.Address); } } + private class SortWriteComparer : IComparer { public int Compare(AddressCounters a, AddressCounters b) { return a.WriteCount.CompareTo(b.WriteCount) * -2 + a.Address.CompareTo(b.Address); } } + private class SortWriteStampComparer : IComparer { public int Compare(AddressCounters a, AddressCounters b) { return a.WriteStamp.CompareTo(b.WriteStamp) * -2 + a.Address.CompareTo(b.Address); } } + private class SortExecComparer : IComparer { public int Compare(AddressCounters a, AddressCounters b) { return a.ExecCount.CompareTo(b.ExecCount) * -2 + a.Address.CompareTo(b.Address); } } + private class SortExecStampComparer : IComparer { public int Compare(AddressCounters a, AddressCounters b) { return a.ExecStamp.CompareTo(b.ExecStamp) * -2 + a.Address.CompareTo(b.Address); } } + private class SortUninitComparer : IComparer { public int Compare(AddressCounters a, AddressCounters b) { return a.UninitRead.CompareTo(b.UninitRead) * -2 + a.Address.CompareTo(b.Address); } } + private enum SortType { Address = 0, - Read = 1, - Write = 2, - Exec = 3, - UninitRead = 4, - } - - private class MemoryCountData - { - private bool _needRecalc = true; - private int _readCount = 0; - private int _writeCount = 0; - private int _execCount = 0; - private string _content = string.Empty; - - public int Address { get; set; } - - public int ReadCount - { - get { return _readCount; } - set - { - if(this._readCount!=value) { - this._readCount = value; - this._needRecalc = true; - }; - } - } - - public int WriteCount - { - get { return _writeCount; } - set - { - if(this._writeCount!=value) { - this._writeCount = value; - this._needRecalc = true; - }; - } - } - - public int ExecCount - { - get { return _execCount; } - set - { - if(this._execCount!=value) { - this._execCount = value; - this._needRecalc = true; - }; - } - } - - public bool Empty { get { return ReadCount == 0 && WriteCount == 0 && ExecCount == 0; } } - - public string Content - { - get - { - if(this._needRecalc) { - _content = " " + (_readCount == 0 ? "0" : _readCount.ToString()).PadRight(12) + - (_writeCount == 0 ? "0" : _writeCount.ToString()).PadRight(12) + - (IsPpu ? "" : (_execCount == 0 ? "0" : _execCount.ToString())); - _needRecalc = false; - } - return _content; - } - } - - public bool UninitRead { get; set; } - public bool IsPpu { get; set; } - } - - private void mnuCopy_Click(object sender, EventArgs e) - { - ctrlScrollableTextbox.CopySelection(true, false, false); - } - - private void mnuSelectAll_Click(object sender, EventArgs e) - { - ctrlScrollableTextbox.SelectAll(); + Value, + Read, + ReadStamp, + Write, + WriteStamp, + Exec, + ExecStamp, + UninitRead, } } } diff --git a/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.resx b/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.resx index c9c6e6d3..8766f298 100644 --- a/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.resx +++ b/GUI.NET/Debugger/Controls/ctrlMemoryAccessCounters.resx @@ -117,9 +117,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 107, 17 - 17, 17 diff --git a/GUI.NET/Debugger/Controls/ctrlProfiler.Designer.cs b/GUI.NET/Debugger/Controls/ctrlProfiler.Designer.cs index ea83a953..9fa60d2c 100644 --- a/GUI.NET/Debugger/Controls/ctrlProfiler.Designer.cs +++ b/GUI.NET/Debugger/Controls/ctrlProfiler.Designer.cs @@ -95,7 +95,9 @@ this.lstFunctions.TabIndex = 7; this.lstFunctions.UseCompatibleStateImageBehavior = false; this.lstFunctions.View = System.Windows.Forms.View.Details; + this.lstFunctions.VirtualMode = true; this.lstFunctions.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lstFunctions_ColumnClick); + this.lstFunctions.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lstFunctions_RetrieveVirtualItem); this.lstFunctions.DoubleClick += new System.EventHandler(this.lstFunctions_DoubleClick); // // colFunction diff --git a/GUI.NET/Debugger/Controls/ctrlProfiler.cs b/GUI.NET/Debugger/Controls/ctrlProfiler.cs index 898c49b1..0230555a 100644 --- a/GUI.NET/Debugger/Controls/ctrlProfiler.cs +++ b/GUI.NET/Debugger/Controls/ctrlProfiler.cs @@ -15,13 +15,10 @@ namespace Mesen.GUI.Debugger.Controls public partial class ctrlProfiler : BaseControl { public static event EventHandler OnFunctionSelected; - private UInt64[] _exclusiveTime; - private UInt64[] _inclusiveTime; - private UInt64[] _callCount; - private UInt64[] _minCycles; - private UInt64[] _maxCycles; - private object _resetLock = new object(); + private ProfiledFunction[] _newData = new ProfiledFunction[0]; + private ProfiledFunction[] _functions = new ProfiledFunction[0]; + UInt64 _exclusiveTotal = 0; private int _sortColumn = 5; private bool _sortOrder = true; @@ -45,137 +42,32 @@ namespace Mesen.GUI.Debugger.Controls public void RefreshData() { - lock(_resetLock) { - _exclusiveTime = InteropEmu.DebugGetProfilerData(ProfilerDataType.FunctionExclusive); - _inclusiveTime = InteropEmu.DebugGetProfilerData(ProfilerDataType.FunctionInclusive); - _callCount = InteropEmu.DebugGetProfilerData(ProfilerDataType.FunctionCallCount); - _minCycles = InteropEmu.DebugGetProfilerData(ProfilerDataType.MinCycles); - _maxCycles = InteropEmu.DebugGetProfilerData(ProfilerDataType.MaxCycles); - } - RefreshList(); + _newData = InteropEmu.DebugGetProfilerData(); } - private int GetMaxAddrHexSize() + public void RefreshList() { - int size = _exclusiveTime.Length - 2; - int bitCount = 0; - int hexCount = 1; - while(size > 0) { - size /= 2; - if(bitCount == 4) { - hexCount++; - } - } - - return hexCount; - } - - private void RefreshList() - { - UInt64 exclusiveTotal = 0; - foreach(UInt64 time in _exclusiveTime) { - exclusiveTotal += time; - } - - int hexCount = GetMaxAddrHexSize(); - lstFunctions.BeginUpdate(); - lstFunctions.ListViewItemSorter = null; - int? topItemIndex = lstFunctions.TopItem?.Index; - int selectedIndex = lstFunctions.SelectedIndices.Count > 0 ? lstFunctions.SelectedIndices[0] : -1; - - int itemNumber = 0; - for(UInt32 i = 0; i < _exclusiveTime.Length; i++) { - if(_exclusiveTime[i] > 0) { - string functionName; - - if(i == _exclusiveTime.Length - 2) { - functionName = "[Reset]"; - } else if(i == _exclusiveTime.Length - 1) { - functionName = "[In-Memory Function]"; - } else { - CodeLabel label = LabelManager.GetLabel((UInt32)i, AddressType.PrgRom); - functionName = "$" + i.ToString("X" + hexCount.ToString()); - if(label != null) { - functionName = label.Label + " (" + functionName + ")"; - } - } - - ListViewItem item; - if(itemNumber >= lstFunctions.Items.Count) { - item = lstFunctions.Items.Add(""); - item.SubItems.Add(""); - item.SubItems.Add(""); - item.SubItems.Add(""); - item.SubItems.Add(""); - item.SubItems.Add(""); - item.SubItems.Add(""); - item.SubItems.Add(""); - item.SubItems.Add(""); - } else { - item = lstFunctions.Items[itemNumber]; - } - - item.Text = functionName; - - item.Tag = i; - item.Selected = false; - item.Focused = false; - - item.SubItems[1].Text = _callCount[i].ToString(); - item.SubItems[1].Tag = _callCount[i]; - - item.SubItems[2].Text = _inclusiveTime[i].ToString(); - item.SubItems[2].Tag = _inclusiveTime[i]; - - double ratio = ((double)_inclusiveTime[i] / exclusiveTotal) *100; - item.SubItems[3].Text = ratio.ToString("0.00"); - item.SubItems[3].Tag = (UInt64)(ratio*100); - - item.SubItems[4].Text = _exclusiveTime[i].ToString(); - item.SubItems[4].Tag = _exclusiveTime[i]; - - ratio = ((double)_exclusiveTime[i] / exclusiveTotal)*100; - item.SubItems[5].Text = ratio.ToString("0.00"); - item.SubItems[5].Tag = (UInt64)(ratio*100); - - UInt64 avgCycles = _callCount[i] == 0 ? 0 : (_inclusiveTime[i] / _callCount[i]); - item.SubItems[6].Text = avgCycles.ToString(); - item.SubItems[6].Tag = avgCycles; - - item.SubItems[7].Text = _minCycles[i] == UInt64.MaxValue ? "n/a" : _minCycles[i].ToString(); - item.SubItems[7].Tag = _minCycles[i]; - - item.SubItems[8].Text = _maxCycles[i] == 0 ? "n/a" : _maxCycles[i].ToString(); - item.SubItems[8].Tag = _maxCycles[i]; - - itemNumber++; - } + _functions = _newData; + _exclusiveTotal = 0; + foreach(ProfiledFunction func in _functions) { + _exclusiveTotal += func.ExclusiveCycles; } - lstFunctions.ListViewItemSorter = new ListComparer(_sortColumn, _sortOrder); + Array.Sort(_functions, new ListComparer(this, _sortColumn, _sortOrder)); + lstFunctions.VirtualListSize = _functions.Length; + lstFunctions.EndUpdate(); - - if(topItemIndex.HasValue) { - lstFunctions.TopItem = lstFunctions.Items[topItemIndex.Value]; - } - - if(selectedIndex >= 0) { - lstFunctions.Items[selectedIndex].Selected = true; - lstFunctions.Items[selectedIndex].Focused = true; - } } private void btnReset_Click(object sender, EventArgs e) { - lock(_resetLock) { - InteropEmu.DebugResetProfiler(); - } + InteropEmu.DebugResetProfiler(); lstFunctions.Items.Clear(); RefreshData(); } - + private void lstFunctions_ColumnClick(object sender, ColumnClickEventArgs e) { if(_sortColumn == e.Column) { @@ -187,40 +79,112 @@ namespace Mesen.GUI.Debugger.Controls RefreshList(); } - + private void lstFunctions_DoubleClick(object sender, EventArgs e) { - if(lstFunctions.SelectedItems.Count > 0) { - OnFunctionSelected?.Invoke(lstFunctions.SelectedItems[0].Tag, EventArgs.Empty); + if(lstFunctions.SelectedIndices.Count > 0) { + AddressTypeInfo addr = _functions[lstFunctions.SelectedIndices[0]].Address; + int relativeAddress = InteropEmu.DebugGetRelativeAddress((uint)addr.Address, addr.Type); + if(relativeAddress >= 0) { + OnFunctionSelected?.Invoke(relativeAddress, EventArgs.Empty); + } } } - private class ListComparer : IComparer + private void lstFunctions_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) + { + e.Item = GetListItem(_functions[e.ItemIndex]); + } + + private ListViewItem GetListItem(ProfiledFunction func) + { + ListViewItem item = new ListViewItem(GetFunctionName(func)); + item.Selected = false; + item.Focused = false; + + item.SubItems.Add(GetColumnContent(func, 1).ToString()); + item.SubItems.Add(GetColumnContent(func, 2).ToString()); + item.SubItems.Add(((double)GetColumnContent(func, 3)).ToString("0.00")); + item.SubItems.Add(GetColumnContent(func, 4).ToString()); + item.SubItems.Add(((double)GetColumnContent(func, 5)).ToString("0.00")); + item.SubItems.Add(GetColumnContent(func, 6).ToString()); + item.SubItems.Add((UInt64)GetColumnContent(func, 7) == UInt64.MaxValue ? "n/a" : GetColumnContent(func, 7).ToString()); + item.SubItems.Add((UInt64)GetColumnContent(func, 8) == 0 ? "n/a" : GetColumnContent(func, 8).ToString()); + + return item; + } + + private string GetFunctionName(ProfiledFunction func) + { + string functionName; + + if(func.Address.Address == -1) { + functionName = "[Reset]"; + } else { + CodeLabel label = LabelManager.GetLabel((UInt32)func.Address.Address, func.Address.Type); + + switch(func.Address.Type) { + case AddressType.PrgRom: functionName = "PRG: $"; break; + case AddressType.Register: functionName = "REG: $"; break; + case AddressType.SaveRam: functionName = "SRAM: $"; break; + case AddressType.WorkRam: functionName = "WRAM: $"; break; + case AddressType.InternalRam: functionName = "RAM: $"; break; + default: throw new Exception("Unsupported type"); + } + + functionName += func.Address.Address.ToString("X4"); + if(label != null) { + functionName = label.Label + " (" + functionName + ")"; + } + } + + return functionName; + } + + private object GetColumnContent(ProfiledFunction func, int columnIndex) + { + switch(columnIndex) { + case 0: return GetFunctionName(func); + case 1: return func.CallCount; + case 2: return func.InclusiveCycles; + case 3: return (double)func.InclusiveCycles / _exclusiveTotal * 100; + case 4: return func.ExclusiveCycles; + case 5: return (double)func.ExclusiveCycles / _exclusiveTotal * 100; + case 6: return func.CallCount == 0 ? 0 : (func.InclusiveCycles / func.CallCount); + case 7: return func.MinCycles; + case 8: return func.MaxCycles; + } + throw new Exception("Invalid column index"); + } + + private class ListComparer : IComparer { private int _columnIndex; private bool _sortOrder; + private ctrlProfiler _profiler; - public ListComparer(int columnIndex, bool sortOrder) + public ListComparer(ctrlProfiler profiler, int columnIndex, bool sortOrder) { + _profiler = profiler; _columnIndex = columnIndex; _sortOrder = sortOrder; } - public int Compare(object x, object y) + public int Compare(ProfiledFunction x, ProfiledFunction y) { if(_columnIndex == 0) { if(_sortOrder) { - return String.Compare(((ListViewItem)y).SubItems[0].Text, ((ListViewItem)x).SubItems[0].Text); + return String.Compare(_profiler.GetFunctionName(y), _profiler.GetFunctionName(x)); } else { - return String.Compare(((ListViewItem)x).SubItems[0].Text, ((ListViewItem)y).SubItems[0].Text); + return String.Compare(_profiler.GetFunctionName(x), _profiler.GetFunctionName(y)); } } else { - UInt64 columnValueY = (UInt64)((ListViewItem)y).SubItems[_columnIndex].Tag; - UInt64 columnValueX = (UInt64)((ListViewItem)x).SubItems[_columnIndex].Tag; + IComparable columnValueY = (IComparable)_profiler.GetColumnContent(x, _columnIndex); + IComparable columnValueX = (IComparable)_profiler.GetColumnContent(y, _columnIndex); if(_sortOrder) { - return (int)(columnValueY - columnValueX); + return columnValueX.CompareTo(columnValueY); } else { - return (int)(columnValueX - columnValueY); + return columnValueY.CompareTo(columnValueX); } } } diff --git a/GUI.NET/Debugger/frmDebugger.Designer.cs b/GUI.NET/Debugger/frmDebugger.Designer.cs index 24adcef9..620c870f 100644 --- a/GUI.NET/Debugger/frmDebugger.Designer.cs +++ b/GUI.NET/Debugger/frmDebugger.Designer.cs @@ -268,7 +268,7 @@ namespace Mesen.GUI.Debugger this.splitContainer.Panel2.Controls.Add(this.tableLayoutPanel10); this.splitContainer.Panel2MinSize = 100; this.splitContainer.Size = new System.Drawing.Size(1075, 570); - this.splitContainer.SplitterDistance = 410; + this.splitContainer.SplitterDistance = 407; this.splitContainer.SplitterWidth = 7; this.splitContainer.TabIndex = 1; this.splitContainer.TabStop = false; @@ -292,8 +292,8 @@ namespace Mesen.GUI.Debugger // this.ctrlSplitContainerTop.Panel2.Controls.Add(this.tlpFunctionLabelLists); this.ctrlSplitContainerTop.Panel2MinSize = 150; - this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1075, 410); - this.ctrlSplitContainerTop.SplitterDistance = 824; + this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1075, 407); + this.ctrlSplitContainerTop.SplitterDistance = 821; this.ctrlSplitContainerTop.SplitterWidth = 7; this.ctrlSplitContainerTop.TabIndex = 3; this.ctrlSplitContainerTop.PanelCollapsed += new System.EventHandler(this.ctrlSplitContainerTop_PanelCollapsed); @@ -313,8 +313,8 @@ namespace Mesen.GUI.Debugger this.tlpTop.Name = "tlpTop"; this.tlpTop.RowCount = 1; this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 410F)); - this.tlpTop.Size = new System.Drawing.Size(824, 410); + this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 407F)); + this.tlpTop.Size = new System.Drawing.Size(821, 407); this.tlpTop.TabIndex = 2; // // panel1 @@ -325,7 +325,7 @@ namespace Mesen.GUI.Debugger this.panel1.Location = new System.Drawing.Point(3, 0); this.panel1.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(360, 410); + this.panel1.Size = new System.Drawing.Size(357, 407); this.panel1.TabIndex = 5; // // ctrlSourceViewer @@ -334,7 +334,7 @@ namespace Mesen.GUI.Debugger this.ctrlSourceViewer.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlSourceViewer.Location = new System.Drawing.Point(0, 0); this.ctrlSourceViewer.Name = "ctrlSourceViewer"; - this.ctrlSourceViewer.Size = new System.Drawing.Size(360, 410); + this.ctrlSourceViewer.Size = new System.Drawing.Size(357, 407); this.ctrlSourceViewer.SymbolProvider = null; this.ctrlSourceViewer.TabIndex = 7; this.ctrlSourceViewer.Visible = false; @@ -347,7 +347,7 @@ namespace Mesen.GUI.Debugger this.ctrlDebuggerCode.Location = new System.Drawing.Point(0, 0); this.ctrlDebuggerCode.Name = "ctrlDebuggerCode"; this.ctrlDebuggerCode.ShowMemoryValues = false; - this.ctrlDebuggerCode.Size = new System.Drawing.Size(360, 410); + this.ctrlDebuggerCode.Size = new System.Drawing.Size(357, 407); this.ctrlDebuggerCode.SymbolProvider = null; this.ctrlDebuggerCode.TabIndex = 2; this.ctrlDebuggerCode.OnEditCode += new Mesen.GUI.Debugger.ctrlDebuggerCode.AssemblerEventHandler(this.ctrlDebuggerCode_OnEditCode); @@ -358,10 +358,10 @@ namespace Mesen.GUI.Debugger this.panel2.Controls.Add(this.ctrlSourceViewerSplit); this.panel2.Controls.Add(this.ctrlDebuggerCodeSplit); this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; - this.panel2.Location = new System.Drawing.Point(366, 0); + this.panel2.Location = new System.Drawing.Point(363, 0); this.panel2.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0); this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(1, 410); + this.panel2.Size = new System.Drawing.Size(1, 407); this.panel2.TabIndex = 6; // // ctrlSourceViewerSplit @@ -370,7 +370,7 @@ namespace Mesen.GUI.Debugger this.ctrlSourceViewerSplit.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlSourceViewerSplit.Location = new System.Drawing.Point(0, 0); this.ctrlSourceViewerSplit.Name = "ctrlSourceViewerSplit"; - this.ctrlSourceViewerSplit.Size = new System.Drawing.Size(1, 410); + this.ctrlSourceViewerSplit.Size = new System.Drawing.Size(1, 407); this.ctrlSourceViewerSplit.SymbolProvider = null; this.ctrlSourceViewerSplit.TabIndex = 8; this.ctrlSourceViewerSplit.Visible = false; @@ -383,7 +383,7 @@ namespace Mesen.GUI.Debugger this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(0, 0); this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit"; this.ctrlDebuggerCodeSplit.ShowMemoryValues = false; - this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 410); + this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 407); this.ctrlDebuggerCodeSplit.SymbolProvider = null; this.ctrlDebuggerCodeSplit.TabIndex = 4; this.ctrlDebuggerCodeSplit.Visible = false; @@ -397,13 +397,13 @@ namespace Mesen.GUI.Debugger this.tableLayoutPanel1.Controls.Add(this.ctrlConsoleStatus, 0, 0); this.tableLayoutPanel1.Controls.Add(this.tlpVerticalLayout, 0, 1); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(366, 0); + this.tableLayoutPanel1.Location = new System.Drawing.Point(363, 0); this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 2; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(458, 410); + this.tableLayoutPanel1.Size = new System.Drawing.Size(458, 407); this.tableLayoutPanel1.TabIndex = 7; // // ctrlConsoleStatus @@ -427,7 +427,7 @@ namespace Mesen.GUI.Debugger this.tlpVerticalLayout.Name = "tlpVerticalLayout"; this.tlpVerticalLayout.RowCount = 1; this.tlpVerticalLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tlpVerticalLayout.Size = new System.Drawing.Size(458, 10); + this.tlpVerticalLayout.Size = new System.Drawing.Size(458, 7); this.tlpVerticalLayout.TabIndex = 4; // // tlpFunctionLabelLists @@ -443,16 +443,16 @@ namespace Mesen.GUI.Debugger this.tlpFunctionLabelLists.RowCount = 2; this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tlpFunctionLabelLists.Size = new System.Drawing.Size(244, 410); + this.tlpFunctionLabelLists.Size = new System.Drawing.Size(247, 407); this.tlpFunctionLabelLists.TabIndex = 5; // // grpLabels // this.grpLabels.Controls.Add(this.ctrlLabelList); this.grpLabels.Dock = System.Windows.Forms.DockStyle.Fill; - this.grpLabels.Location = new System.Drawing.Point(3, 208); + this.grpLabels.Location = new System.Drawing.Point(3, 206); this.grpLabels.Name = "grpLabels"; - this.grpLabels.Size = new System.Drawing.Size(238, 199); + this.grpLabels.Size = new System.Drawing.Size(241, 198); this.grpLabels.TabIndex = 6; this.grpLabels.TabStop = false; this.grpLabels.Text = "Labels"; @@ -462,7 +462,7 @@ namespace Mesen.GUI.Debugger this.ctrlLabelList.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlLabelList.Location = new System.Drawing.Point(3, 16); this.ctrlLabelList.Name = "ctrlLabelList"; - this.ctrlLabelList.Size = new System.Drawing.Size(232, 180); + this.ctrlLabelList.Size = new System.Drawing.Size(235, 179); this.ctrlLabelList.TabIndex = 0; this.ctrlLabelList.OnFindOccurrence += new System.EventHandler(this.ctrlLabelList_OnFindOccurrence); this.ctrlLabelList.OnLabelSelected += new Mesen.GUI.Debugger.GoToDestinationEventHandler(this.ctrlLabelList_OnLabelSelected); @@ -473,7 +473,7 @@ namespace Mesen.GUI.Debugger this.grpFunctions.Dock = System.Windows.Forms.DockStyle.Fill; this.grpFunctions.Location = new System.Drawing.Point(3, 3); this.grpFunctions.Name = "grpFunctions"; - this.grpFunctions.Size = new System.Drawing.Size(238, 199); + this.grpFunctions.Size = new System.Drawing.Size(241, 197); this.grpFunctions.TabIndex = 5; this.grpFunctions.TabStop = false; this.grpFunctions.Text = "Functions"; @@ -483,7 +483,7 @@ namespace Mesen.GUI.Debugger this.ctrlFunctionList.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlFunctionList.Location = new System.Drawing.Point(3, 16); this.ctrlFunctionList.Name = "ctrlFunctionList"; - this.ctrlFunctionList.Size = new System.Drawing.Size(232, 180); + this.ctrlFunctionList.Size = new System.Drawing.Size(235, 178); this.ctrlFunctionList.TabIndex = 0; this.ctrlFunctionList.OnFindOccurrence += new System.EventHandler(this.ctrlFunctionList_OnFindOccurrence); this.ctrlFunctionList.OnFunctionSelected += new Mesen.GUI.Debugger.GoToDestinationEventHandler(this.ctrlFunctionList_OnFunctionSelected); @@ -514,7 +514,7 @@ namespace Mesen.GUI.Debugger this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel10.Size = new System.Drawing.Size(1075, 153); + this.tableLayoutPanel10.Size = new System.Drawing.Size(1075, 156); this.tableLayoutPanel10.TabIndex = 0; // // grpWatch @@ -523,7 +523,7 @@ namespace Mesen.GUI.Debugger this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill; this.grpWatch.Location = new System.Drawing.Point(3, 3); this.grpWatch.Name = "grpWatch"; - this.grpWatch.Size = new System.Drawing.Size(352, 147); + this.grpWatch.Size = new System.Drawing.Size(352, 150); this.grpWatch.TabIndex = 2; this.grpWatch.TabStop = false; this.grpWatch.Text = "Watch"; @@ -533,7 +533,7 @@ namespace Mesen.GUI.Debugger this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlWatch.Location = new System.Drawing.Point(3, 16); this.ctrlWatch.Name = "ctrlWatch"; - this.ctrlWatch.Size = new System.Drawing.Size(346, 128); + this.ctrlWatch.Size = new System.Drawing.Size(346, 131); this.ctrlWatch.TabIndex = 0; // // grpBreakpoints @@ -542,7 +542,7 @@ namespace Mesen.GUI.Debugger this.grpBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill; this.grpBreakpoints.Location = new System.Drawing.Point(361, 3); this.grpBreakpoints.Name = "grpBreakpoints"; - this.grpBreakpoints.Size = new System.Drawing.Size(352, 147); + this.grpBreakpoints.Size = new System.Drawing.Size(352, 150); this.grpBreakpoints.TabIndex = 3; this.grpBreakpoints.TabStop = false; this.grpBreakpoints.Text = "Breakpoints"; @@ -552,7 +552,7 @@ namespace Mesen.GUI.Debugger this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16); this.ctrlBreakpoints.Name = "ctrlBreakpoints"; - this.ctrlBreakpoints.Size = new System.Drawing.Size(346, 128); + this.ctrlBreakpoints.Size = new System.Drawing.Size(346, 131); this.ctrlBreakpoints.TabIndex = 0; this.ctrlBreakpoints.BreakpointNavigation += new System.EventHandler(this.ctrlBreakpoints_BreakpointNavigation); // @@ -562,7 +562,7 @@ namespace Mesen.GUI.Debugger this.grpCallstack.Dock = System.Windows.Forms.DockStyle.Fill; this.grpCallstack.Location = new System.Drawing.Point(719, 3); this.grpCallstack.Name = "grpCallstack"; - this.grpCallstack.Size = new System.Drawing.Size(353, 147); + this.grpCallstack.Size = new System.Drawing.Size(353, 150); this.grpCallstack.TabIndex = 4; this.grpCallstack.TabStop = false; this.grpCallstack.Text = "Call Stack"; @@ -572,7 +572,7 @@ namespace Mesen.GUI.Debugger this.ctrlCallstack.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlCallstack.Location = new System.Drawing.Point(3, 16); this.ctrlCallstack.Name = "ctrlCallstack"; - this.ctrlCallstack.Size = new System.Drawing.Size(347, 128); + this.ctrlCallstack.Size = new System.Drawing.Size(347, 131); this.ctrlCallstack.TabIndex = 0; this.ctrlCallstack.FunctionSelected += new System.EventHandler(this.ctrlCallstack_FunctionSelected); // @@ -948,33 +948,33 @@ namespace Mesen.GUI.Debugger // mnuGoToAll // this.mnuGoToAll.Name = "mnuGoToAll"; - this.mnuGoToAll.Size = new System.Drawing.Size(198, 22); + this.mnuGoToAll.Size = new System.Drawing.Size(183, 22); this.mnuGoToAll.Text = "Go to All"; this.mnuGoToAll.Click += new System.EventHandler(this.mnuGoToAll_Click); // // mnuGoToAddress // this.mnuGoToAddress.Name = "mnuGoToAddress"; - this.mnuGoToAddress.Size = new System.Drawing.Size(198, 22); + this.mnuGoToAddress.Size = new System.Drawing.Size(183, 22); this.mnuGoToAddress.Text = "Go to Address"; this.mnuGoToAddress.Click += new System.EventHandler(this.mnuGoToAddress_Click); // // mnuGoTo // this.mnuGoTo.Name = "mnuGoTo"; - this.mnuGoTo.Size = new System.Drawing.Size(198, 22); + this.mnuGoTo.Size = new System.Drawing.Size(183, 22); this.mnuGoTo.Text = "Go to..."; // // toolStripMenuItem29 // this.toolStripMenuItem29.Name = "toolStripMenuItem29"; - this.toolStripMenuItem29.Size = new System.Drawing.Size(195, 6); + this.toolStripMenuItem29.Size = new System.Drawing.Size(180, 6); // // mnuFind // this.mnuFind.Image = global::Mesen.GUI.Properties.Resources.Find; this.mnuFind.Name = "mnuFind"; - this.mnuFind.Size = new System.Drawing.Size(198, 22); + this.mnuFind.Size = new System.Drawing.Size(183, 22); this.mnuFind.Text = "Find..."; this.mnuFind.Click += new System.EventHandler(this.mnuFind_Click); // @@ -982,7 +982,7 @@ namespace Mesen.GUI.Debugger // this.mnuFindNext.Image = global::Mesen.GUI.Properties.Resources.NextArrow; this.mnuFindNext.Name = "mnuFindNext"; - this.mnuFindNext.Size = new System.Drawing.Size(198, 22); + this.mnuFindNext.Size = new System.Drawing.Size(183, 22); this.mnuFindNext.Text = "Find Next"; this.mnuFindNext.Click += new System.EventHandler(this.mnuFindNext_Click); // @@ -990,19 +990,19 @@ namespace Mesen.GUI.Debugger // this.mnuFindPrev.Image = global::Mesen.GUI.Properties.Resources.PreviousArrow; this.mnuFindPrev.Name = "mnuFindPrev"; - this.mnuFindPrev.Size = new System.Drawing.Size(198, 22); + this.mnuFindPrev.Size = new System.Drawing.Size(183, 22); this.mnuFindPrev.Text = "Find Previous"; this.mnuFindPrev.Click += new System.EventHandler(this.mnuFindPrev_Click); // // toolStripMenuItem9 // this.toolStripMenuItem9.Name = "toolStripMenuItem9"; - this.toolStripMenuItem9.Size = new System.Drawing.Size(195, 6); + this.toolStripMenuItem9.Size = new System.Drawing.Size(180, 6); // // mnuFindAllOccurrences // this.mnuFindAllOccurrences.Name = "mnuFindAllOccurrences"; - this.mnuFindAllOccurrences.Size = new System.Drawing.Size(198, 22); + this.mnuFindAllOccurrences.Size = new System.Drawing.Size(183, 22); this.mnuFindAllOccurrences.Text = "Find All Occurrences"; this.mnuFindAllOccurrences.Click += new System.EventHandler(this.mnuFindAllOccurrences_Click); // @@ -1674,7 +1674,7 @@ namespace Mesen.GUI.Debugger this.toolStripMenuItem30, this.mnuCodeDataLogger}); this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; - this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20); + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20); this.toolsToolStripMenuItem.Text = "Tools"; // // mnuApuViewer @@ -1929,7 +1929,7 @@ namespace Mesen.GUI.Debugger this.lblPrgAnalysisResult.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right; this.lblPrgAnalysisResult.BorderStyle = System.Windows.Forms.Border3DStyle.Etched; this.lblPrgAnalysisResult.Name = "lblPrgAnalysisResult"; - this.lblPrgAnalysisResult.Size = new System.Drawing.Size(243, 19); + this.lblPrgAnalysisResult.Size = new System.Drawing.Size(235, 19); this.lblPrgAnalysisResult.Text = "xx% (Code: xx%, Data: xx%, Unknown: xx%)"; // // lblChrAnalysis @@ -1941,13 +1941,13 @@ namespace Mesen.GUI.Debugger // lblChrAnalysisResult // this.lblChrAnalysisResult.Name = "lblChrAnalysisResult"; - this.lblChrAnalysisResult.Size = new System.Drawing.Size(247, 19); + this.lblChrAnalysisResult.Size = new System.Drawing.Size(239, 19); this.lblChrAnalysisResult.Text = "xx% (Drawn: xx%, Read: xx%, Unknown: xx%)"; // // toolStripStatusLabel1 // this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.Size = new System.Drawing.Size(324, 19); + this.toolStripStatusLabel1.Size = new System.Drawing.Size(340, 19); this.toolStripStatusLabel1.Spring = true; // // lblCyclesElapsedCount diff --git a/GUI.NET/Debugger/frmDebugger.cs b/GUI.NET/Debugger/frmDebugger.cs index de0fac26..56c866af 100644 --- a/GUI.NET/Debugger/frmDebugger.cs +++ b/GUI.NET/Debugger/frmDebugger.cs @@ -343,13 +343,10 @@ namespace Mesen.GUI.Debugger UpdateDebugger(false, false); } - private void ctrlProfiler_OnFunctionSelected(object sender, EventArgs e) + private void ctrlProfiler_OnFunctionSelected(object relativeAddress, EventArgs e) { - int relativeAddress = InteropEmu.DebugGetRelativeAddress((UInt32)sender, AddressType.PrgRom); - if(relativeAddress >= 0) { - BringToFront(); - LastCodeWindow.ScrollToLineNumber(relativeAddress); - } + BringToFront(); + LastCodeWindow.ScrollToLineNumber((int)relativeAddress); } private void mnuFile_DropDownOpening(object sender, EventArgs e) diff --git a/GUI.NET/Debugger/frmMemoryViewer.Designer.cs b/GUI.NET/Debugger/frmMemoryViewer.Designer.cs index 46969519..4f300d01 100644 --- a/GUI.NET/Debugger/frmMemoryViewer.Designer.cs +++ b/GUI.NET/Debugger/frmMemoryViewer.Designer.cs @@ -775,14 +775,12 @@ // // ctrlMemoryAccessCounters // - this.ctrlMemoryAccessCounters.BaseFont = new System.Drawing.Font("Consolas", 12F); this.ctrlMemoryAccessCounters.Dock = System.Windows.Forms.DockStyle.Fill; this.ctrlMemoryAccessCounters.Location = new System.Drawing.Point(0, 0); this.ctrlMemoryAccessCounters.Margin = new System.Windows.Forms.Padding(0); this.ctrlMemoryAccessCounters.Name = "ctrlMemoryAccessCounters"; this.ctrlMemoryAccessCounters.Size = new System.Drawing.Size(606, 343); this.ctrlMemoryAccessCounters.TabIndex = 0; - this.ctrlMemoryAccessCounters.TextZoom = 100; // // frmMemoryViewer // diff --git a/GUI.NET/Debugger/frmMemoryViewer.cs b/GUI.NET/Debugger/frmMemoryViewer.cs index dfe06853..4fe25d51 100644 --- a/GUI.NET/Debugger/frmMemoryViewer.cs +++ b/GUI.NET/Debugger/frmMemoryViewer.cs @@ -59,9 +59,6 @@ namespace Mesen.GUI.Debugger this.ctrlHexViewer.TextZoom = config.RamTextZoom; this.ctrlHexViewer.BaseFont = new Font(config.RamFontFamily, config.RamFontSize, config.RamFontStyle); - this.ctrlMemoryAccessCounters.BaseFont = new Font(config.RamFontFamily, config.RamFontSize, config.RamFontStyle); - this.ctrlMemoryAccessCounters.TextZoom = config.RamTextZoom; - this.mnuHighlightExecution.Checked = config.RamHighlightExecution; this.mnuHightlightReads.Checked = config.RamHighlightReads; this.mnuHighlightWrites.Checked = config.RamHighlightWrites; @@ -400,9 +397,9 @@ namespace Mesen.GUI.Debugger private void mnuGoTo_Click(object sender, EventArgs e) { if(_selectedTab == tpgMemoryViewer) { - this.ctrlHexViewer.GoToAddress(); + ctrlHexViewer.GoToAddress(); } else if(_selectedTab == tpgAccessCounters) { - this.ctrlMemoryAccessCounters.GoToAddress(); + ctrlMemoryAccessCounters.GoToAddress(); } } @@ -414,21 +411,18 @@ namespace Mesen.GUI.Debugger private void mnuIncreaseFontSize_Click(object sender, EventArgs e) { this.ctrlHexViewer.TextZoom += 10; - this.ctrlMemoryAccessCounters.TextZoom += 10; this.UpdateConfig(); } private void mnuDecreaseFontSize_Click(object sender, EventArgs e) { this.ctrlHexViewer.TextZoom -= 10; - this.ctrlMemoryAccessCounters.TextZoom -= 10; this.UpdateConfig(); } private void mnuResetFontSize_Click(object sender, EventArgs e) { this.ctrlHexViewer.TextZoom = 100; - this.ctrlMemoryAccessCounters.TextZoom = 100; this.UpdateConfig(); } @@ -739,7 +733,6 @@ namespace Mesen.GUI.Debugger private void mnuSelectFont_Click(object sender, EventArgs e) { ctrlHexViewer.BaseFont = FontDialogHelper.SelectFont(ctrlHexViewer.BaseFont); - ctrlMemoryAccessCounters.BaseFont = ctrlHexViewer.BaseFont; } private void mnuByteEditingMode_CheckedChanged(object sender, EventArgs e) diff --git a/GUI.NET/Debugger/frmProfiler.Designer.cs b/GUI.NET/Debugger/frmProfiler.Designer.cs index da7a76f9..1beffb27 100644 --- a/GUI.NET/Debugger/frmProfiler.Designer.cs +++ b/GUI.NET/Debugger/frmProfiler.Designer.cs @@ -43,7 +43,7 @@ // // tmrRefresh // - this.tmrRefresh.Interval = 1000; + this.tmrRefresh.Interval = 300; this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick); // // frmProfiler diff --git a/GUI.NET/Debugger/frmProfiler.cs b/GUI.NET/Debugger/frmProfiler.cs index 96e1b76b..7d07de0f 100644 --- a/GUI.NET/Debugger/frmProfiler.cs +++ b/GUI.NET/Debugger/frmProfiler.cs @@ -22,6 +22,7 @@ namespace Mesen.GUI.Debugger DebugWorkspaceManager.AutoLoadDbgFiles(true); ctrlProfiler.RefreshData(); + ctrlProfiler.RefreshList(); tmrRefresh.Start(); RestoreLocation(ConfigManager.Config.DebugInfo.ProfilerLocation, ConfigManager.Config.DebugInfo.ProfilerSize); @@ -40,6 +41,7 @@ namespace Mesen.GUI.Debugger private void tmrRefresh_Tick(object sender, EventArgs e) { ctrlProfiler.RefreshData(); + ctrlProfiler.RefreshList(); } } } diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index d23a749a..e23c6d4b 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -535,82 +535,30 @@ namespace Mesen.GUI return buffer; } - [DllImport(DLLPath, EntryPoint = "DebugGetProfilerData")] private static extern void DebugGetProfilerDataWrapper(IntPtr profilerData, ProfilerDataType dataType); - public static UInt64[] DebugGetProfilerData(ProfilerDataType dataType) + [DllImport(DLLPath, EntryPoint = "DebugGetProfilerData")] private static extern void GetProfilerDataWrapper([In, Out]ProfiledFunction[] profilerData, ref UInt32 functionCount); + public static ProfiledFunction[] DebugGetProfilerData() { - UInt64[] profileData = new UInt64[InteropEmu.DebugGetMemorySize(DebugMemoryType.PrgRom) + 2]; + ProfiledFunction[] profilerData = new ProfiledFunction[100000]; + UInt32 functionCount = 0; - GCHandle hProfilerData = GCHandle.Alloc(profileData, GCHandleType.Pinned); - try { - InteropEmu.DebugGetProfilerDataWrapper(hProfilerData.AddrOfPinnedObject(), dataType); - } finally { - hProfilerData.Free(); - } + InteropEmu.GetProfilerDataWrapper(profilerData, ref functionCount); + Array.Resize(ref profilerData, (int)functionCount); - return profileData; + return profilerData; } - public static Int32[] DebugGetMemoryAccessCounts(DebugMemoryType type, MemoryOperationType operationType) + public static void DebugGetMemoryAccessCounts(DebugMemoryType type, ref AddressCounters[] counters) { int size = InteropEmu.DebugGetMemorySize(type); - return InteropEmu.DebugGetMemoryAccessCounts(0, (uint)size, type, operationType); + Array.Resize(ref counters, size); + InteropEmu.DebugGetMemoryAccessCountsWrapper(0, (uint)size, type, counters); } - public static UInt64[] DebugGetMemoryAccessStamps(DebugMemoryType type, MemoryOperationType operationType) + [DllImport(DLLPath, EntryPoint = "DebugGetMemoryAccessCounts")] private static extern void DebugGetMemoryAccessCountsWrapper(UInt32 offset, UInt32 length, DebugMemoryType type, [In,Out]AddressCounters[] counts); + public static AddressCounters[] DebugGetMemoryAccessCounts(UInt32 offset, UInt32 length, DebugMemoryType type) { - int size = InteropEmu.DebugGetMemorySize(type); - return InteropEmu.DebugGetMemoryAccessStamps(0, (uint)size, type, operationType); - } - - [DllImport(DLLPath, EntryPoint = "DebugGetUninitMemoryReads")] private static extern void DebugGetUninitMemoryReadsWrapper(DebugMemoryType type, IntPtr counts); - public static Int32[] DebugGetUninitMemoryReads(DebugMemoryType type) - { - int size = InteropEmu.DebugGetMemorySize(type); - if(type == DebugMemoryType.InternalRam) { - size = 0x2000; - } - - Int32[] counts = new Int32[size]; - - if(size > 0) { - GCHandle hCounts = GCHandle.Alloc(counts, GCHandleType.Pinned); - try { - InteropEmu.DebugGetUninitMemoryReadsWrapper(type, hCounts.AddrOfPinnedObject()); - } finally { - hCounts.Free(); - } - } - - return counts; - } - - [DllImport(DLLPath, EntryPoint = "DebugGetMemoryAccessStamps")] private static extern void DebugGetMemoryAccessStampsWrapper(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType, IntPtr stamps); - public static UInt64[] DebugGetMemoryAccessStamps(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType) - { - UInt64[] stamps = new UInt64[length]; - - GCHandle hStamps = GCHandle.Alloc(stamps, GCHandleType.Pinned); - try { - InteropEmu.DebugGetMemoryAccessStampsWrapper(offset, length, type, operationType, hStamps.AddrOfPinnedObject()); - } finally { - hStamps.Free(); - } - - return stamps; - } - - [DllImport(DLLPath, EntryPoint = "DebugGetMemoryAccessCounts")] private static extern void DebugGetMemoryAccessCountsWrapper(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType, IntPtr counts); - public static Int32[] DebugGetMemoryAccessCounts(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType) - { - Int32[] counts = new Int32[length]; - - GCHandle hResult = GCHandle.Alloc(counts, GCHandleType.Pinned); - try { - InteropEmu.DebugGetMemoryAccessCountsWrapper(offset, length, type, operationType, hResult.AddrOfPinnedObject()); - } finally { - hResult.Free(); - } - + AddressCounters[] counts = new AddressCounters[length]; + InteropEmu.DebugGetMemoryAccessCountsWrapper(offset, length, type, counts); return counts; } @@ -2153,6 +2101,29 @@ namespace Mesen.GUI } } + public struct ProfiledFunction + { + public UInt64 ExclusiveCycles; + public UInt64 InclusiveCycles; + public UInt64 CallCount; + public UInt64 MinCycles; + public UInt64 MaxCycles; + public AddressTypeInfo Address; + } + + [StructLayout(LayoutKind.Sequential)] + public struct AddressCounters + { + public UInt32 Address; + public UInt32 ReadCount; + public UInt64 ReadStamp; + public byte UninitRead; + public UInt32 WriteCount; + public UInt64 WriteStamp; + public UInt32 ExecCount; + public UInt64 ExecStamp; + } + public enum RecordMovieFrom { StartWithoutSaveData, diff --git a/InteropDLL/DebugWrapper.cpp b/InteropDLL/DebugWrapper.cpp index e14be2c5..e6ce2ef5 100644 --- a/InteropDLL/DebugWrapper.cpp +++ b/InteropDLL/DebugWrapper.cpp @@ -114,12 +114,10 @@ extern "C" DllExport void __stdcall DebugSetMemoryValues(DebugMemoryType type, uint32_t address, uint8_t* data, int32_t length) { return GetDebugger()->GetMemoryDumper()->SetMemoryValues(type, address, data, length); } DllExport void __stdcall DebugResetMemoryAccessCounts() { GetDebugger()->GetMemoryAccessCounter()->ResetCounts(); } - DllExport void __stdcall DebugGetMemoryAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint64_t* stamps) { GetDebugger()->GetMemoryAccessCounter()->GetAccessStamps(offset, length, memoryType, operationType, stamps); } - DllExport void __stdcall DebugGetMemoryAccessCounts(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, int32_t* counts) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(offset, length, memoryType, operationType, counts); } - DllExport void __stdcall DebugGetUninitMemoryReads(DebugMemoryType memoryType, int32_t* counts) { GetDebugger()->GetMemoryAccessCounter()->GetUninitMemoryReads(memoryType, counts); } + DllExport void __stdcall DebugGetMemoryAccessCounts(uint32_t offset, uint32_t length, DebugMemoryType memoryType, AddressCounters* counts) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(offset, length, memoryType, counts); } DllExport void __stdcall DebugGetNametableChangedData(bool* ntChangedData) { GetDebugger()->GetMemoryAccessCounter()->GetNametableChangedData(ntChangedData); } - DllExport void __stdcall DebugGetProfilerData(uint64_t* profilerData, ProfilerDataType dataType) { GetDebugger()->GetProfiler()->GetProfilerData(profilerData, dataType); } + DllExport void __stdcall DebugGetProfilerData(ProfiledFunction* profilerData, uint32_t &functionCount) { GetDebugger()->GetProfiler()->GetProfilerData(profilerData, functionCount); } DllExport void __stdcall DebugResetProfiler() { GetDebugger()->GetProfiler()->Reset(); } DllExport void __stdcall DebugSetFreezeState(uint16_t address, bool frozen) { GetDebugger()->SetFreezeState(address, frozen); }