Core: Changed CPU cycle counter to be a 64-bit int (breaks save state compatibility)

This commit is contained in:
Sour 2019-05-12 12:28:01 -04:00
parent 8b12cd7815
commit 5b80d2fe21
24 changed files with 88 additions and 83 deletions

View file

@ -12,7 +12,7 @@ private:
uint32_t _newBarcodeDigitCount = 0;
uint8_t _barcodeStream[BarcodeBattlerReader::StreamSize];
int32_t _insertCycle = 0;
uint64_t _insertCycle = 0;
protected:
void StreamState(bool saving) override
@ -88,10 +88,10 @@ public:
uint8_t ReadRAM(uint16_t addr) override
{
if(addr == 0x4017) {
int32_t elapsedCycles = _console->GetCpu()->GetElapsedCycles(_insertCycle);
uint64_t elapsedCycles = _console->GetCpu()->GetCycleCount() - _insertCycle;
constexpr uint32_t cyclesPerBit = CPU::ClockRateNtsc / 1200;
uint32_t streamPosition = elapsedCycles / cyclesPerBit;
uint32_t streamPosition = (uint32_t)(elapsedCycles / cyclesPerBit);
if(streamPosition < BarcodeBattlerReader::StreamSize) {
return _barcodeStream[streamPosition] << 2;
}

View file

@ -31,7 +31,7 @@ public:
private:
typedef void(CPU::*Func)();
int32_t _cycleCount;
uint64_t _cycleCount;
uint16_t _operand;
Func _opTable[256];
@ -777,17 +777,7 @@ protected:
public:
CPU(shared_ptr<Console> console);
int32_t GetCycleCount() { return _cycleCount; }
int32_t GetElapsedCycles(int32_t prevCycleCount)
{
if(prevCycleCount > _cycleCount) {
return 0xFFFFFFFF - prevCycleCount + _cycleCount + 1;
} else {
return _cycleCount - prevCycleCount;
}
}
uint64_t GetCycleCount() { return _cycleCount; }
void SetNmiFlag() { _state.NMIFlag = true; }
void ClearNmiFlag() { _state.NMIFlag = false; }
void SetIrqMask(uint8_t mask) { _irqMask = mask; }

View file

@ -687,11 +687,11 @@ void Console::RunSingleFrame()
void Console::RunSlaveCpu()
{
int32_t cycleGap;
int64_t cycleGap;
while(true) {
//Run the slave until it catches up to the master CPU (and take into account the CPU count overflow that occurs every ~20mins)
cycleGap = _cpu->GetCycleCount() - _slave->_cpu->GetCycleCount();
if(cycleGap > 5 || cycleGap < -10000 || _ppu->GetFrameCount() > _slave->_ppu->GetFrameCount()) {
cycleGap = (int64_t)(_cpu->GetCycleCount() - _slave->_cpu->GetCycleCount());
if(cycleGap > 5 || _ppu->GetFrameCount() > _slave->_ppu->GetFrameCount()) {
_slave->_cpu->Exec();
} else {
break;

View file

@ -9,7 +9,7 @@ class DatachBarcodeReader : public BaseControlDevice, public IBarcodeReader
{
private:
vector<uint8_t> _data;
int32_t _insertCycle = 0;
uint64_t _insertCycle = 0;
uint64_t _newBarcode = 0;
uint32_t _newBarcodeDigitCount = 0;
@ -53,9 +53,9 @@ public:
uint8_t GetOutput()
{
int32_t elapsedCycles = _console->GetCpu()->GetElapsedCycles(_insertCycle);
int32_t bitNumber = elapsedCycles / 1000;
if(bitNumber < (int32_t)_data.size()) {
uint64_t elapsedCycles = _console->GetCpu()->GetCycleCount() - _insertCycle;
uint32_t bitNumber = (uint32_t)(elapsedCycles / 1000);
if(bitNumber < (uint32_t)_data.size()) {
return _data[bitNumber];
} else {
return 0;

View file

@ -130,13 +130,13 @@ private:
uint16_t _ppuScrollX;
uint16_t _ppuScrollY;
int32_t _prevInstructionCycle;
int32_t _curInstructionCycle;
int32_t _runToCycle;
uint64_t _prevInstructionCycle;
uint64_t _curInstructionCycle;
uint64_t _runToCycle;
bool _needRewind;
vector<stringstream> _rewindCache;
vector<uint32_t> _rewindPrevInstructionCycleCache;
vector<uint64_t> _rewindPrevInstructionCycleCache;
uint32_t _inputOverride[4];

View file

@ -13,7 +13,7 @@ private:
vector<uint8_t> _fileData;
bool _enabled = false;
bool _isPlaying = false;
int32_t _cycle = -1;
uint64_t _cycle = 0;
bool _isRecording = false;
string _recordFilePath;
@ -115,9 +115,9 @@ public:
uint8_t ReadRAM(uint16_t addr) override
{
if(addr == 0x4016 && _isPlaying) {
int32_t readPos = _console->GetCpu()->GetElapsedCycles(_cycle) / FamilyBasicDataRecorder::SamplingRate;
uint32_t readPos = (uint32_t)((_console->GetCpu()->GetCycleCount() / _cycle) / FamilyBasicDataRecorder::SamplingRate);
if((int32_t)_data.size() > readPos / 8) {
if((uint32_t)_data.size() > readPos / 8) {
uint8_t value = ((_data[readPos / 8] >> (readPos % 8)) & 0x01) << 1;
return _enabled ? value : 0;
} else {
@ -133,7 +133,7 @@ public:
_enabled = (value & 0x04) != 0;
if(_isRecording) {
while(_console->GetCpu()->GetElapsedCycles(_cycle) > FamilyBasicDataRecorder::SamplingRate) {
while(_console->GetCpu()->GetCycleCount() - _cycle > FamilyBasicDataRecorder::SamplingRate) {
_data.push_back(value & 0x01);
_cycle += 88;
}

View file

@ -44,7 +44,7 @@ class MMC1 : public BaseMapper
uint8_t _chrReg1;
uint8_t _prgReg;
int32_t _lastWriteCycle = -1;
uint64_t _lastWriteCycle = 0;
bool _forceWramOn;
MMC1Registers _lastChrReg;
@ -195,10 +195,10 @@ class MMC1 : public BaseMapper
virtual void WriteRegister(uint16_t addr, uint8_t value) override
{
int32_t currentCycle = _console->GetCpu()->GetCycleCount();
uint64_t currentCycle = _console->GetCpu()->GetCycleCount();
//Ignore write if within 2 cycles of another write (i.e the real write after a dummy write)
if(abs(currentCycle - _lastWriteCycle) >= 2) {
if(currentCycle - _lastWriteCycle >= 2) {
if(IsBufferFull(value)) {
switch((MMC1Registers)((addr & 0x6000) >> 13)) {
case MMC1Registers::Reg8000: _state.Reg8000 = _writeBuffer; break;

View file

@ -58,7 +58,7 @@ vector<int32_t>& MemoryAccessCounter::GetCountArray(MemoryOperationType operatio
}
}
vector<int32_t>& MemoryAccessCounter::GetStampArray(MemoryOperationType operationType, AddressType addressType)
vector<uint64_t>& MemoryAccessCounter::GetStampArray(MemoryOperationType operationType, AddressType addressType)
{
switch(operationType) {
case MemoryOperationType::Read: return _readStamps[(int)addressType];
@ -75,7 +75,7 @@ vector<int32_t>& MemoryAccessCounter::GetPpuCountArray(MemoryOperationType opera
return operationType == MemoryOperationType::Write ? _ppuWriteCounts[(int)addressType] : _ppuReadCounts[(int)addressType];
}
vector<int32_t>& MemoryAccessCounter::GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType)
vector<uint64_t>& MemoryAccessCounter::GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType)
{
return operationType == MemoryOperationType::Write ? _ppuWriteStamps[(int)addressType] : _ppuReadStamps[(int)addressType];
}
@ -89,23 +89,23 @@ bool MemoryAccessCounter::IsAddressUninitialized(AddressTypeInfo &addressInfo)
return false;
}
void MemoryAccessCounter::ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle)
void MemoryAccessCounter::ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle)
{
if(addressInfo.Address >= 0) {
vector<int> &counts = GetPpuCountArray(operation, addressInfo.Type);
counts.data()[addressInfo.Address]++;
vector<int> &stamps = GetPpuStampArray(operation, addressInfo.Type);
vector<uint64_t> &stamps = GetPpuStampArray(operation, addressInfo.Type);
stamps.data()[addressInfo.Address] = cpuCycle;
}
}
bool MemoryAccessCounter::ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle)
bool MemoryAccessCounter::ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle)
{
vector<int> &counts = GetCountArray(operation, addressInfo.Type);
counts.data()[addressInfo.Address]++;
vector<int> &stamps = GetStampArray(operation, addressInfo.Type);
vector<uint64_t> &stamps = GetStampArray(operation, addressInfo.Type);
stamps.data()[addressInfo.Address] = cpuCycle;
if(operation == MemoryOperationType::Read && (addressInfo.Type == AddressType::InternalRam || addressInfo.Type == AddressType::WorkRam) && !_writeCounts[(int)addressInfo.Type][addressInfo.Address]) {
@ -125,9 +125,9 @@ void MemoryAccessCounter::ResetCounts()
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(uint32_t));
memset(_writeStamps[i].data(), 0, _writeStamps[i].size() * sizeof(uint32_t));
memset(_execStamps[i].data(), 0, _execStamps[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));
@ -136,41 +136,41 @@ void MemoryAccessCounter::ResetCounts()
}
}
void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint32_t stamps[])
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(uint32_t));
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(uint32_t));
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(uint32_t));
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(uint32_t));
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(uint32_t));
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(uint32_t));
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(uint32_t));
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(uint32_t));
memcpy(stamps, GetPpuStampArray(operationType, PpuAddressType::PaletteRam).data() + offset, length * sizeof(uint64_t));
break;
case DebugMemoryType::CpuMemory:
@ -194,7 +194,7 @@ void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, Debu
void MemoryAccessCounter::GetNametableChangedData(bool ntChangedData[])
{
PpuAddressTypeInfo addressInfo;
int32_t cpuCycle = _debugger->GetConsole()->GetCpu()->GetCycleCount();
uint64_t cpuCycle = _debugger->GetConsole()->GetCpu()->GetCycleCount();
NesModel model = _debugger->GetConsole()->GetModel();
double frameRate = model == NesModel::NTSC ? 60.1 : 50.01;
double overclockRate = _debugger->GetConsole()->GetPpu()->GetOverclockRate() * (_debugger->GetConsole()->GetSettings()->GetOverclockRate() / 100);

View file

@ -13,28 +13,28 @@ private:
vector<int32_t> _writeCounts[4];
vector<int32_t> _execCounts[4];
vector<int32_t> _readStamps[4];
vector<int32_t> _writeStamps[4];
vector<int32_t> _execStamps[4];
vector<uint64_t> _readStamps[4];
vector<uint64_t> _writeStamps[4];
vector<uint64_t> _execStamps[4];
vector<uint8_t> _uninitReads[4];
vector<int32_t> _ppuReadCounts[4];
vector<int32_t> _ppuWriteCounts[4];
vector<int32_t> _ppuReadStamps[4];
vector<int32_t> _ppuWriteStamps[4];
vector<uint64_t> _ppuReadStamps[4];
vector<uint64_t> _ppuWriteStamps[4];
vector<int32_t>& GetCountArray(MemoryOperationType operationType, AddressType addressType);
vector<int32_t>& GetStampArray(MemoryOperationType operationType, AddressType addressType);
vector<uint64_t>& GetStampArray(MemoryOperationType operationType, AddressType addressType);
vector<int32_t>& GetPpuCountArray(MemoryOperationType operationType, PpuAddressType addressType);
vector<int32_t>& GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType);
vector<uint64_t>& GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType);
public:
MemoryAccessCounter(Debugger* debugger);
void ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle);
bool ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle);
void ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle);
bool ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle);
void ResetCounts();
bool IsAddressUninitialized(AddressTypeInfo &addressInfo);
@ -42,5 +42,5 @@ public:
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, uint32_t stamps[]);
void GetAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint64_t stamps[]);
};

View file

@ -1092,8 +1092,8 @@ uint8_t PPU::ReadSpriteRam(uint8_t addr)
if(!_enableOamDecay) {
return _spriteRAM[addr];
} else {
int32_t elapsedCycle = _console->GetCpu()->GetElapsedCycles(_oamDecayCycles[addr >> 3]);
if(elapsedCycle <= PPU::OamDecayCycleCount) {
uint64_t elapsedCycles = _console->GetCpu()->GetCycleCount() - _oamDecayCycles[addr >> 3];
if(elapsedCycles <= PPU::OamDecayCycleCount) {
_oamDecayCycles[addr >> 3] = _console->GetCpu()->GetCycleCount();
return _spriteRAM[addr];
} else {
@ -1325,7 +1325,7 @@ uint8_t* PPU::GetSpriteRam()
if(_enableOamDecay) {
for(int i = 0; i < 0x100; i++) {
//Apply OAM decay to sprite RAM before letting debugger access it
if(_console->GetCpu()->GetElapsedCycles(_oamDecayCycles[i >> 3]) > PPU::OamDecayCycleCount) {
if((_console->GetCpu()->GetCycleCount() - _oamDecayCycles[i >> 3]) > PPU::OamDecayCycleCount) {
_spriteRAM[i] = 0x10;
}
}

View file

@ -101,7 +101,7 @@ class PPU : public IMemoryHandler, public Snapshotable
uint32_t _minimumDrawSpriteCycle;
uint32_t _minimumDrawSpriteStandardCycle;
int32_t _oamDecayCycles[0x40];
uint64_t _oamDecayCycles[0x40];
bool _enableOamDecay;
void UpdateStatusFlag();

View file

@ -14,7 +14,7 @@ private:
string GetStateFilepath(int stateIndex);
public:
static constexpr uint32_t FileFormatVersion = 10;
static constexpr uint32_t FileFormatVersion = 11;
SaveStateManager(shared_ptr<Console> console);

View file

@ -151,7 +151,7 @@ void TraceLogger::StopLogging()
}
}
void TraceLogger::LogExtraInfo(const char *log, uint32_t cycleCount)
void TraceLogger::LogExtraInfo(const char *log, uint64_t cycleCount)
{
if(_logToFile && _options.ShowExtraInfo) {
//Flush current buffer

View file

@ -104,7 +104,7 @@ public:
void StartLogging(string filename);
void StopLogging();
void LogExtraInfo(const char *log, uint32_t cycleCount);
void LogExtraInfo(const char *log, uint64_t cycleCount);
const char* GetExecutionTrace(uint32_t lineCount);
};

View file

@ -60,7 +60,7 @@ struct State
uint8_t Y = 0;
uint8_t PS = 0;
uint32_t IRQFlag = 0;
int32_t CycleCount = 0;
uint64_t CycleCount = 0;
bool NMIFlag = false;
//Used by debugger

View file

@ -9,9 +9,9 @@ namespace Mesen.GUI.Debugger
public class ByteColorProvider : IByteColorProvider
{
DebugMemoryType _memoryType;
Int32[] _readStamps;
Int32[] _writeStamps;
Int32[] _execStamps;
UInt64[] _readStamps;
UInt64[] _writeStamps;
UInt64[] _execStamps;
Int32[] _readCounts;
Int32[] _writeCounts;
Int32[] _execCounts;

View file

@ -9,8 +9,8 @@ namespace Mesen.GUI.Debugger
public class ChrByteColorProvider : IByteColorProvider
{
DebugMemoryType _memoryType;
Int32[] _readStamps;
Int32[] _writeStamps;
UInt64[] _readStamps;
UInt64[] _writeStamps;
Int32[] _readCounts;
Int32[] _writeCounts;
DebugState _state = new DebugState();

View file

@ -1180,7 +1180,7 @@
this.txtCycleCount.Margin = new System.Windows.Forms.Padding(0);
this.txtCycleCount.MaxLength = 11;
this.txtCycleCount.Name = "txtCycleCount";
this.txtCycleCount.Size = new System.Drawing.Size(77, 20);
this.txtCycleCount.Size = new System.Drawing.Size(85, 20);
this.txtCycleCount.TabIndex = 9;
this.txtCycleCount.TextChanged += new System.EventHandler(this.OnOptionChanged);
//

View file

@ -23,7 +23,7 @@ namespace Mesen.GUI.Debugger
private bool _firstBreak = true;
private bool _wasPaused = false;
private bool _executionIsStopped = false; //Flag used to break on the first instruction after power cycle/reset if execution was stopped before the reset
private int _previousCycle = 0;
private UInt64 _previousCycle = 0;
private InteropEmu.NotificationListener _notifListener;
private ICodeViewer _lastCodeWindow;

View file

@ -20,7 +20,7 @@ namespace Mesen.GUI.Debugger
private bool _loggingEnabled = false;
private string _lastFilename;
private EntityBinder _entityBinder = new EntityBinder();
private int _previousCycleCount;
private UInt64 _previousCycleCount;
private string _previousTrace;
private volatile bool _refreshRunning;
private bool _initialized;

View file

@ -532,7 +532,7 @@ namespace Mesen.GUI
return InteropEmu.DebugGetMemoryAccessCounts(0, (uint)size, type, operationType);
}
public static Int32[] DebugGetMemoryAccessStamps(DebugMemoryType type, MemoryOperationType operationType)
public static UInt64[] DebugGetMemoryAccessStamps(DebugMemoryType type, MemoryOperationType operationType)
{
int size = InteropEmu.DebugGetMemorySize(type);
return InteropEmu.DebugGetMemoryAccessStamps(0, (uint)size, type, operationType);
@ -561,9 +561,9 @@ namespace Mesen.GUI
}
[DllImport(DLLPath, EntryPoint = "DebugGetMemoryAccessStamps")] private static extern void DebugGetMemoryAccessStampsWrapper(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType, IntPtr stamps);
public static Int32[] DebugGetMemoryAccessStamps(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType)
public static UInt64[] DebugGetMemoryAccessStamps(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType)
{
Int32[] stamps = new Int32[length];
UInt64[] stamps = new UInt64[length];
GCHandle hStamps = GCHandle.Alloc(stamps, GCHandleType.Pinned);
try {
@ -1448,7 +1448,7 @@ namespace Mesen.GUI
public Byte Y;
public Byte PS;
public IRQSource IRQFlag;
public Int32 CycleCount;
public UInt64 CycleCount;
[MarshalAs(UnmanagedType.I1)]
public bool NMIFlag;

View file

@ -112,7 +112,7 @@ 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, uint32_t* stamps) { GetDebugger()->GetMemoryAccessCounter()->GetAccessStamps(offset, length, memoryType, operationType, stamps); }
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 DebugGetNametableChangedData(bool* ntChangedData) { GetDebugger()->GetMemoryAccessCounter()->GetNametableChangedData(ntChangedData); }

View file

@ -64,6 +64,20 @@ string HexUtilities::ToHex(uint32_t value, bool fullSize)
}
}
string HexUtilities::ToHex(uint64_t value, bool fullSize)
{
if(fullSize) {
return ToHex((uint32_t)(value >> 32), true) + ToHex((uint32_t)value, true);
} else {
string result;
while(value > 0) {
result = _hexCache[value & 0xFF] + result;
value >>= 8;
}
return result;
}
}
string HexUtilities::ToHex(vector<uint8_t> &data)
{
string result;

View file

@ -10,6 +10,7 @@ public:
static string ToHex(uint8_t value);
static string ToHex(uint16_t value);
static string ToHex(uint32_t value, bool fullSize = false);
static string ToHex(uint64_t value, bool fullSize = false);
static string ToHex(int32_t value, bool fullSize = false);
static string ToHex(vector<uint8_t> &data);