Core: Changed CPU cycle counter to be a 64-bit int (breaks save state compatibility)
This commit is contained in:
parent
8b12cd7815
commit
5b80d2fe21
24 changed files with 88 additions and 83 deletions
|
@ -12,7 +12,7 @@ private:
|
||||||
uint32_t _newBarcodeDigitCount = 0;
|
uint32_t _newBarcodeDigitCount = 0;
|
||||||
|
|
||||||
uint8_t _barcodeStream[BarcodeBattlerReader::StreamSize];
|
uint8_t _barcodeStream[BarcodeBattlerReader::StreamSize];
|
||||||
int32_t _insertCycle = 0;
|
uint64_t _insertCycle = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void StreamState(bool saving) override
|
void StreamState(bool saving) override
|
||||||
|
@ -88,10 +88,10 @@ public:
|
||||||
uint8_t ReadRAM(uint16_t addr) override
|
uint8_t ReadRAM(uint16_t addr) override
|
||||||
{
|
{
|
||||||
if(addr == 0x4017) {
|
if(addr == 0x4017) {
|
||||||
int32_t elapsedCycles = _console->GetCpu()->GetElapsedCycles(_insertCycle);
|
uint64_t elapsedCycles = _console->GetCpu()->GetCycleCount() - _insertCycle;
|
||||||
constexpr uint32_t cyclesPerBit = CPU::ClockRateNtsc / 1200;
|
constexpr uint32_t cyclesPerBit = CPU::ClockRateNtsc / 1200;
|
||||||
|
|
||||||
uint32_t streamPosition = elapsedCycles / cyclesPerBit;
|
uint32_t streamPosition = (uint32_t)(elapsedCycles / cyclesPerBit);
|
||||||
if(streamPosition < BarcodeBattlerReader::StreamSize) {
|
if(streamPosition < BarcodeBattlerReader::StreamSize) {
|
||||||
return _barcodeStream[streamPosition] << 2;
|
return _barcodeStream[streamPosition] << 2;
|
||||||
}
|
}
|
||||||
|
|
14
Core/CPU.h
14
Core/CPU.h
|
@ -31,7 +31,7 @@ public:
|
||||||
private:
|
private:
|
||||||
typedef void(CPU::*Func)();
|
typedef void(CPU::*Func)();
|
||||||
|
|
||||||
int32_t _cycleCount;
|
uint64_t _cycleCount;
|
||||||
uint16_t _operand;
|
uint16_t _operand;
|
||||||
|
|
||||||
Func _opTable[256];
|
Func _opTable[256];
|
||||||
|
@ -777,17 +777,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
CPU(shared_ptr<Console> console);
|
CPU(shared_ptr<Console> console);
|
||||||
|
|
||||||
int32_t GetCycleCount() { return _cycleCount; }
|
uint64_t GetCycleCount() { return _cycleCount; }
|
||||||
|
|
||||||
int32_t GetElapsedCycles(int32_t prevCycleCount)
|
|
||||||
{
|
|
||||||
if(prevCycleCount > _cycleCount) {
|
|
||||||
return 0xFFFFFFFF - prevCycleCount + _cycleCount + 1;
|
|
||||||
} else {
|
|
||||||
return _cycleCount - prevCycleCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetNmiFlag() { _state.NMIFlag = true; }
|
void SetNmiFlag() { _state.NMIFlag = true; }
|
||||||
void ClearNmiFlag() { _state.NMIFlag = false; }
|
void ClearNmiFlag() { _state.NMIFlag = false; }
|
||||||
void SetIrqMask(uint8_t mask) { _irqMask = mask; }
|
void SetIrqMask(uint8_t mask) { _irqMask = mask; }
|
||||||
|
|
|
@ -687,11 +687,11 @@ void Console::RunSingleFrame()
|
||||||
|
|
||||||
void Console::RunSlaveCpu()
|
void Console::RunSlaveCpu()
|
||||||
{
|
{
|
||||||
int32_t cycleGap;
|
int64_t cycleGap;
|
||||||
while(true) {
|
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)
|
//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();
|
cycleGap = (int64_t)(_cpu->GetCycleCount() - _slave->_cpu->GetCycleCount());
|
||||||
if(cycleGap > 5 || cycleGap < -10000 || _ppu->GetFrameCount() > _slave->_ppu->GetFrameCount()) {
|
if(cycleGap > 5 || _ppu->GetFrameCount() > _slave->_ppu->GetFrameCount()) {
|
||||||
_slave->_cpu->Exec();
|
_slave->_cpu->Exec();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,7 +9,7 @@ class DatachBarcodeReader : public BaseControlDevice, public IBarcodeReader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
vector<uint8_t> _data;
|
vector<uint8_t> _data;
|
||||||
int32_t _insertCycle = 0;
|
uint64_t _insertCycle = 0;
|
||||||
uint64_t _newBarcode = 0;
|
uint64_t _newBarcode = 0;
|
||||||
uint32_t _newBarcodeDigitCount = 0;
|
uint32_t _newBarcodeDigitCount = 0;
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ public:
|
||||||
|
|
||||||
uint8_t GetOutput()
|
uint8_t GetOutput()
|
||||||
{
|
{
|
||||||
int32_t elapsedCycles = _console->GetCpu()->GetElapsedCycles(_insertCycle);
|
uint64_t elapsedCycles = _console->GetCpu()->GetCycleCount() - _insertCycle;
|
||||||
int32_t bitNumber = elapsedCycles / 1000;
|
uint32_t bitNumber = (uint32_t)(elapsedCycles / 1000);
|
||||||
if(bitNumber < (int32_t)_data.size()) {
|
if(bitNumber < (uint32_t)_data.size()) {
|
||||||
return _data[bitNumber];
|
return _data[bitNumber];
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -130,13 +130,13 @@ private:
|
||||||
uint16_t _ppuScrollX;
|
uint16_t _ppuScrollX;
|
||||||
uint16_t _ppuScrollY;
|
uint16_t _ppuScrollY;
|
||||||
|
|
||||||
int32_t _prevInstructionCycle;
|
uint64_t _prevInstructionCycle;
|
||||||
int32_t _curInstructionCycle;
|
uint64_t _curInstructionCycle;
|
||||||
int32_t _runToCycle;
|
uint64_t _runToCycle;
|
||||||
bool _needRewind;
|
bool _needRewind;
|
||||||
|
|
||||||
vector<stringstream> _rewindCache;
|
vector<stringstream> _rewindCache;
|
||||||
vector<uint32_t> _rewindPrevInstructionCycleCache;
|
vector<uint64_t> _rewindPrevInstructionCycleCache;
|
||||||
|
|
||||||
uint32_t _inputOverride[4];
|
uint32_t _inputOverride[4];
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ private:
|
||||||
vector<uint8_t> _fileData;
|
vector<uint8_t> _fileData;
|
||||||
bool _enabled = false;
|
bool _enabled = false;
|
||||||
bool _isPlaying = false;
|
bool _isPlaying = false;
|
||||||
int32_t _cycle = -1;
|
uint64_t _cycle = 0;
|
||||||
|
|
||||||
bool _isRecording = false;
|
bool _isRecording = false;
|
||||||
string _recordFilePath;
|
string _recordFilePath;
|
||||||
|
@ -115,9 +115,9 @@ public:
|
||||||
uint8_t ReadRAM(uint16_t addr) override
|
uint8_t ReadRAM(uint16_t addr) override
|
||||||
{
|
{
|
||||||
if(addr == 0x4016 && _isPlaying) {
|
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;
|
uint8_t value = ((_data[readPos / 8] >> (readPos % 8)) & 0x01) << 1;
|
||||||
return _enabled ? value : 0;
|
return _enabled ? value : 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -133,7 +133,7 @@ public:
|
||||||
_enabled = (value & 0x04) != 0;
|
_enabled = (value & 0x04) != 0;
|
||||||
|
|
||||||
if(_isRecording) {
|
if(_isRecording) {
|
||||||
while(_console->GetCpu()->GetElapsedCycles(_cycle) > FamilyBasicDataRecorder::SamplingRate) {
|
while(_console->GetCpu()->GetCycleCount() - _cycle > FamilyBasicDataRecorder::SamplingRate) {
|
||||||
_data.push_back(value & 0x01);
|
_data.push_back(value & 0x01);
|
||||||
_cycle += 88;
|
_cycle += 88;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class MMC1 : public BaseMapper
|
||||||
uint8_t _chrReg1;
|
uint8_t _chrReg1;
|
||||||
uint8_t _prgReg;
|
uint8_t _prgReg;
|
||||||
|
|
||||||
int32_t _lastWriteCycle = -1;
|
uint64_t _lastWriteCycle = 0;
|
||||||
|
|
||||||
bool _forceWramOn;
|
bool _forceWramOn;
|
||||||
MMC1Registers _lastChrReg;
|
MMC1Registers _lastChrReg;
|
||||||
|
@ -195,10 +195,10 @@ class MMC1 : public BaseMapper
|
||||||
|
|
||||||
virtual void WriteRegister(uint16_t addr, uint8_t value) override
|
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)
|
//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)) {
|
if(IsBufferFull(value)) {
|
||||||
switch((MMC1Registers)((addr & 0x6000) >> 13)) {
|
switch((MMC1Registers)((addr & 0x6000) >> 13)) {
|
||||||
case MMC1Registers::Reg8000: _state.Reg8000 = _writeBuffer; break;
|
case MMC1Registers::Reg8000: _state.Reg8000 = _writeBuffer; break;
|
||||||
|
|
|
@ -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) {
|
switch(operationType) {
|
||||||
case MemoryOperationType::Read: return _readStamps[(int)addressType];
|
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];
|
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];
|
return operationType == MemoryOperationType::Write ? _ppuWriteStamps[(int)addressType] : _ppuReadStamps[(int)addressType];
|
||||||
}
|
}
|
||||||
|
@ -89,23 +89,23 @@ bool MemoryAccessCounter::IsAddressUninitialized(AddressTypeInfo &addressInfo)
|
||||||
return false;
|
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) {
|
if(addressInfo.Address >= 0) {
|
||||||
vector<int> &counts = GetPpuCountArray(operation, addressInfo.Type);
|
vector<int> &counts = GetPpuCountArray(operation, addressInfo.Type);
|
||||||
counts.data()[addressInfo.Address]++;
|
counts.data()[addressInfo.Address]++;
|
||||||
|
|
||||||
vector<int> &stamps = GetPpuStampArray(operation, addressInfo.Type);
|
vector<uint64_t> &stamps = GetPpuStampArray(operation, addressInfo.Type);
|
||||||
stamps.data()[addressInfo.Address] = cpuCycle;
|
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);
|
vector<int> &counts = GetCountArray(operation, addressInfo.Type);
|
||||||
counts.data()[addressInfo.Address]++;
|
counts.data()[addressInfo.Address]++;
|
||||||
|
|
||||||
vector<int> &stamps = GetStampArray(operation, addressInfo.Type);
|
vector<uint64_t> &stamps = GetStampArray(operation, addressInfo.Type);
|
||||||
stamps.data()[addressInfo.Address] = cpuCycle;
|
stamps.data()[addressInfo.Address] = cpuCycle;
|
||||||
|
|
||||||
if(operation == MemoryOperationType::Read && (addressInfo.Type == AddressType::InternalRam || addressInfo.Type == AddressType::WorkRam) && !_writeCounts[(int)addressInfo.Type][addressInfo.Address]) {
|
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(_writeCounts[i].data(), 0, _writeCounts[i].size() * sizeof(uint32_t));
|
||||||
memset(_execCounts[i].data(), 0, _execCounts[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(_readStamps[i].data(), 0, _readStamps[i].size() * sizeof(uint64_t));
|
||||||
memset(_writeStamps[i].data(), 0, _writeStamps[i].size() * sizeof(uint32_t));
|
memset(_writeStamps[i].data(), 0, _writeStamps[i].size() * sizeof(uint64_t));
|
||||||
memset(_execStamps[i].data(), 0, _execStamps[i].size() * sizeof(uint32_t));
|
memset(_execStamps[i].data(), 0, _execStamps[i].size() * sizeof(uint64_t));
|
||||||
|
|
||||||
memset(_ppuReadCounts[i].data(), 0, _ppuReadCounts[i].size() * sizeof(uint32_t));
|
memset(_ppuReadCounts[i].data(), 0, _ppuReadCounts[i].size() * sizeof(uint32_t));
|
||||||
memset(_ppuWriteCounts[i].data(), 0, _ppuWriteCounts[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) {
|
switch(memoryType) {
|
||||||
default: break;
|
default: break;
|
||||||
|
|
||||||
case DebugMemoryType::InternalRam:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::WorkRam:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::SaveRam:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::PrgRom:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::ChrRom:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::ChrRam:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::NametableRam:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::PaletteMemory:
|
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;
|
break;
|
||||||
|
|
||||||
case DebugMemoryType::CpuMemory:
|
case DebugMemoryType::CpuMemory:
|
||||||
|
@ -194,7 +194,7 @@ void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, Debu
|
||||||
void MemoryAccessCounter::GetNametableChangedData(bool ntChangedData[])
|
void MemoryAccessCounter::GetNametableChangedData(bool ntChangedData[])
|
||||||
{
|
{
|
||||||
PpuAddressTypeInfo addressInfo;
|
PpuAddressTypeInfo addressInfo;
|
||||||
int32_t cpuCycle = _debugger->GetConsole()->GetCpu()->GetCycleCount();
|
uint64_t cpuCycle = _debugger->GetConsole()->GetCpu()->GetCycleCount();
|
||||||
NesModel model = _debugger->GetConsole()->GetModel();
|
NesModel model = _debugger->GetConsole()->GetModel();
|
||||||
double frameRate = model == NesModel::NTSC ? 60.1 : 50.01;
|
double frameRate = model == NesModel::NTSC ? 60.1 : 50.01;
|
||||||
double overclockRate = _debugger->GetConsole()->GetPpu()->GetOverclockRate() * (_debugger->GetConsole()->GetSettings()->GetOverclockRate() / 100);
|
double overclockRate = _debugger->GetConsole()->GetPpu()->GetOverclockRate() * (_debugger->GetConsole()->GetSettings()->GetOverclockRate() / 100);
|
||||||
|
|
|
@ -13,28 +13,28 @@ private:
|
||||||
vector<int32_t> _writeCounts[4];
|
vector<int32_t> _writeCounts[4];
|
||||||
vector<int32_t> _execCounts[4];
|
vector<int32_t> _execCounts[4];
|
||||||
|
|
||||||
vector<int32_t> _readStamps[4];
|
vector<uint64_t> _readStamps[4];
|
||||||
vector<int32_t> _writeStamps[4];
|
vector<uint64_t> _writeStamps[4];
|
||||||
vector<int32_t> _execStamps[4];
|
vector<uint64_t> _execStamps[4];
|
||||||
|
|
||||||
vector<uint8_t> _uninitReads[4];
|
vector<uint8_t> _uninitReads[4];
|
||||||
|
|
||||||
vector<int32_t> _ppuReadCounts[4];
|
vector<int32_t> _ppuReadCounts[4];
|
||||||
vector<int32_t> _ppuWriteCounts[4];
|
vector<int32_t> _ppuWriteCounts[4];
|
||||||
vector<int32_t> _ppuReadStamps[4];
|
vector<uint64_t> _ppuReadStamps[4];
|
||||||
vector<int32_t> _ppuWriteStamps[4];
|
vector<uint64_t> _ppuWriteStamps[4];
|
||||||
|
|
||||||
vector<int32_t>& GetCountArray(MemoryOperationType operationType, AddressType addressType);
|
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>& GetPpuCountArray(MemoryOperationType operationType, PpuAddressType addressType);
|
||||||
vector<int32_t>& GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType);
|
vector<uint64_t>& GetPpuStampArray(MemoryOperationType operationType, PpuAddressType addressType);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MemoryAccessCounter(Debugger* debugger);
|
MemoryAccessCounter(Debugger* debugger);
|
||||||
|
|
||||||
void ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle);
|
void ProcessPpuMemoryAccess(PpuAddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle);
|
||||||
bool ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle);
|
bool ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, uint64_t cpuCycle);
|
||||||
void ResetCounts();
|
void ResetCounts();
|
||||||
|
|
||||||
bool IsAddressUninitialized(AddressTypeInfo &addressInfo);
|
bool IsAddressUninitialized(AddressTypeInfo &addressInfo);
|
||||||
|
@ -42,5 +42,5 @@ public:
|
||||||
void GetUninitMemoryReads(DebugMemoryType memoryType, int32_t counts[]);
|
void GetUninitMemoryReads(DebugMemoryType memoryType, int32_t counts[]);
|
||||||
void GetNametableChangedData(bool ntChangedData[]);
|
void GetNametableChangedData(bool ntChangedData[]);
|
||||||
void GetAccessCounts(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, int32_t counts[]);
|
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[]);
|
||||||
};
|
};
|
|
@ -1092,8 +1092,8 @@ uint8_t PPU::ReadSpriteRam(uint8_t addr)
|
||||||
if(!_enableOamDecay) {
|
if(!_enableOamDecay) {
|
||||||
return _spriteRAM[addr];
|
return _spriteRAM[addr];
|
||||||
} else {
|
} else {
|
||||||
int32_t elapsedCycle = _console->GetCpu()->GetElapsedCycles(_oamDecayCycles[addr >> 3]);
|
uint64_t elapsedCycles = _console->GetCpu()->GetCycleCount() - _oamDecayCycles[addr >> 3];
|
||||||
if(elapsedCycle <= PPU::OamDecayCycleCount) {
|
if(elapsedCycles <= PPU::OamDecayCycleCount) {
|
||||||
_oamDecayCycles[addr >> 3] = _console->GetCpu()->GetCycleCount();
|
_oamDecayCycles[addr >> 3] = _console->GetCpu()->GetCycleCount();
|
||||||
return _spriteRAM[addr];
|
return _spriteRAM[addr];
|
||||||
} else {
|
} else {
|
||||||
|
@ -1325,7 +1325,7 @@ uint8_t* PPU::GetSpriteRam()
|
||||||
if(_enableOamDecay) {
|
if(_enableOamDecay) {
|
||||||
for(int i = 0; i < 0x100; i++) {
|
for(int i = 0; i < 0x100; i++) {
|
||||||
//Apply OAM decay to sprite RAM before letting debugger access it
|
//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;
|
_spriteRAM[i] = 0x10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ class PPU : public IMemoryHandler, public Snapshotable
|
||||||
uint32_t _minimumDrawSpriteCycle;
|
uint32_t _minimumDrawSpriteCycle;
|
||||||
uint32_t _minimumDrawSpriteStandardCycle;
|
uint32_t _minimumDrawSpriteStandardCycle;
|
||||||
|
|
||||||
int32_t _oamDecayCycles[0x40];
|
uint64_t _oamDecayCycles[0x40];
|
||||||
bool _enableOamDecay;
|
bool _enableOamDecay;
|
||||||
|
|
||||||
void UpdateStatusFlag();
|
void UpdateStatusFlag();
|
||||||
|
|
|
@ -14,7 +14,7 @@ private:
|
||||||
string GetStateFilepath(int stateIndex);
|
string GetStateFilepath(int stateIndex);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr uint32_t FileFormatVersion = 10;
|
static constexpr uint32_t FileFormatVersion = 11;
|
||||||
|
|
||||||
SaveStateManager(shared_ptr<Console> console);
|
SaveStateManager(shared_ptr<Console> console);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
if(_logToFile && _options.ShowExtraInfo) {
|
||||||
//Flush current buffer
|
//Flush current buffer
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
void StartLogging(string filename);
|
void StartLogging(string filename);
|
||||||
void StopLogging();
|
void StopLogging();
|
||||||
|
|
||||||
void LogExtraInfo(const char *log, uint32_t cycleCount);
|
void LogExtraInfo(const char *log, uint64_t cycleCount);
|
||||||
|
|
||||||
const char* GetExecutionTrace(uint32_t lineCount);
|
const char* GetExecutionTrace(uint32_t lineCount);
|
||||||
};
|
};
|
|
@ -60,7 +60,7 @@ struct State
|
||||||
uint8_t Y = 0;
|
uint8_t Y = 0;
|
||||||
uint8_t PS = 0;
|
uint8_t PS = 0;
|
||||||
uint32_t IRQFlag = 0;
|
uint32_t IRQFlag = 0;
|
||||||
int32_t CycleCount = 0;
|
uint64_t CycleCount = 0;
|
||||||
bool NMIFlag = false;
|
bool NMIFlag = false;
|
||||||
|
|
||||||
//Used by debugger
|
//Used by debugger
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace Mesen.GUI.Debugger
|
||||||
public class ByteColorProvider : IByteColorProvider
|
public class ByteColorProvider : IByteColorProvider
|
||||||
{
|
{
|
||||||
DebugMemoryType _memoryType;
|
DebugMemoryType _memoryType;
|
||||||
Int32[] _readStamps;
|
UInt64[] _readStamps;
|
||||||
Int32[] _writeStamps;
|
UInt64[] _writeStamps;
|
||||||
Int32[] _execStamps;
|
UInt64[] _execStamps;
|
||||||
Int32[] _readCounts;
|
Int32[] _readCounts;
|
||||||
Int32[] _writeCounts;
|
Int32[] _writeCounts;
|
||||||
Int32[] _execCounts;
|
Int32[] _execCounts;
|
||||||
|
|
|
@ -9,8 +9,8 @@ namespace Mesen.GUI.Debugger
|
||||||
public class ChrByteColorProvider : IByteColorProvider
|
public class ChrByteColorProvider : IByteColorProvider
|
||||||
{
|
{
|
||||||
DebugMemoryType _memoryType;
|
DebugMemoryType _memoryType;
|
||||||
Int32[] _readStamps;
|
UInt64[] _readStamps;
|
||||||
Int32[] _writeStamps;
|
UInt64[] _writeStamps;
|
||||||
Int32[] _readCounts;
|
Int32[] _readCounts;
|
||||||
Int32[] _writeCounts;
|
Int32[] _writeCounts;
|
||||||
DebugState _state = new DebugState();
|
DebugState _state = new DebugState();
|
||||||
|
|
|
@ -1180,7 +1180,7 @@
|
||||||
this.txtCycleCount.Margin = new System.Windows.Forms.Padding(0);
|
this.txtCycleCount.Margin = new System.Windows.Forms.Padding(0);
|
||||||
this.txtCycleCount.MaxLength = 11;
|
this.txtCycleCount.MaxLength = 11;
|
||||||
this.txtCycleCount.Name = "txtCycleCount";
|
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.TabIndex = 9;
|
||||||
this.txtCycleCount.TextChanged += new System.EventHandler(this.OnOptionChanged);
|
this.txtCycleCount.TextChanged += new System.EventHandler(this.OnOptionChanged);
|
||||||
//
|
//
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace Mesen.GUI.Debugger
|
||||||
private bool _firstBreak = true;
|
private bool _firstBreak = true;
|
||||||
private bool _wasPaused = false;
|
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 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 InteropEmu.NotificationListener _notifListener;
|
||||||
private ICodeViewer _lastCodeWindow;
|
private ICodeViewer _lastCodeWindow;
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Mesen.GUI.Debugger
|
||||||
private bool _loggingEnabled = false;
|
private bool _loggingEnabled = false;
|
||||||
private string _lastFilename;
|
private string _lastFilename;
|
||||||
private EntityBinder _entityBinder = new EntityBinder();
|
private EntityBinder _entityBinder = new EntityBinder();
|
||||||
private int _previousCycleCount;
|
private UInt64 _previousCycleCount;
|
||||||
private string _previousTrace;
|
private string _previousTrace;
|
||||||
private volatile bool _refreshRunning;
|
private volatile bool _refreshRunning;
|
||||||
private bool _initialized;
|
private bool _initialized;
|
||||||
|
|
|
@ -532,7 +532,7 @@ namespace Mesen.GUI
|
||||||
return InteropEmu.DebugGetMemoryAccessCounts(0, (uint)size, type, operationType);
|
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);
|
int size = InteropEmu.DebugGetMemorySize(type);
|
||||||
return InteropEmu.DebugGetMemoryAccessStamps(0, (uint)size, type, operationType);
|
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);
|
[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);
|
GCHandle hStamps = GCHandle.Alloc(stamps, GCHandleType.Pinned);
|
||||||
try {
|
try {
|
||||||
|
@ -1448,7 +1448,7 @@ namespace Mesen.GUI
|
||||||
public Byte Y;
|
public Byte Y;
|
||||||
public Byte PS;
|
public Byte PS;
|
||||||
public IRQSource IRQFlag;
|
public IRQSource IRQFlag;
|
||||||
public Int32 CycleCount;
|
public UInt64 CycleCount;
|
||||||
|
|
||||||
[MarshalAs(UnmanagedType.I1)]
|
[MarshalAs(UnmanagedType.I1)]
|
||||||
public bool NMIFlag;
|
public bool NMIFlag;
|
||||||
|
|
|
@ -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 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 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 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 DebugGetUninitMemoryReads(DebugMemoryType memoryType, int32_t* counts) { GetDebugger()->GetMemoryAccessCounter()->GetUninitMemoryReads(memoryType, counts); }
|
||||||
DllExport void __stdcall DebugGetNametableChangedData(bool* ntChangedData) { GetDebugger()->GetMemoryAccessCounter()->GetNametableChangedData(ntChangedData); }
|
DllExport void __stdcall DebugGetNametableChangedData(bool* ntChangedData) { GetDebugger()->GetMemoryAccessCounter()->GetNametableChangedData(ntChangedData); }
|
||||||
|
|
|
@ -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 HexUtilities::ToHex(vector<uint8_t> &data)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
|
|
|
@ -10,6 +10,7 @@ public:
|
||||||
static string ToHex(uint8_t value);
|
static string ToHex(uint8_t value);
|
||||||
static string ToHex(uint16_t value);
|
static string ToHex(uint16_t value);
|
||||||
static string ToHex(uint32_t value, bool fullSize = false);
|
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(int32_t value, bool fullSize = false);
|
||||||
static string ToHex(vector<uint8_t> &data);
|
static string ToHex(vector<uint8_t> &data);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue