From 7e4a141b7ba7b6890ab03ad647aa9e58a55edddc Mon Sep 17 00:00:00 2001 From: Sour Date: Fri, 29 Mar 2019 22:13:22 -0400 Subject: [PATCH] SPC: Fixed potential overflow problem when running for a very long time --- Core/Console.cpp | 2 +- Core/Spc.cpp | 13 ++++++++----- Core/Spc.h | 3 +++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Core/Console.cpp b/Core/Console.cpp index 602c6d2..345b520 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -230,10 +230,10 @@ bool Console::LoadRom(VirtualFile romFile, VirtualFile patchFile, bool stopRom) _internalRegisters.reset(new InternalRegisters(shared_from_this())); _ppu.reset(new Ppu(shared_from_this())); - _spc.reset(new Spc(shared_from_this(), spcRomData)); _controlManager.reset(new ControlManager(shared_from_this())); _memoryManager.reset(new MemoryManager()); _dmaController.reset(new DmaController(_memoryManager.get())); + _spc.reset(new Spc(shared_from_this(), spcRomData)); _memoryManager->Initialize(shared_from_this()); diff --git a/Core/Spc.cpp b/Core/Spc.cpp index ae91d60..2881925 100644 --- a/Core/Spc.cpp +++ b/Core/Spc.cpp @@ -9,6 +9,7 @@ Spc::Spc(shared_ptr console, vector &spcRomData) { _console = console; + _memoryManager = console->GetMemoryManager(); _soundBuffer = new int16_t[Spc::SampleBufferSize]; _immediateMode = false; _operandA = 0; @@ -28,6 +29,8 @@ Spc::Spc(shared_ptr console, vector &spcRomData) _state.RomEnabled = true; _state.SP = 0xFF; _state.PC = ReadWord(Spc::ResetVector); + + _clockRatio = (double)2048000 / _console->GetMasterClockRate(); } Spc::~Spc() @@ -202,9 +205,7 @@ void Spc::CpuWriteRegister(uint32_t addr, uint8_t value) void Spc::Run() { - int64_t masterClock = _console->GetMemoryManager()->GetMasterClock(); - //TODO: This will overflow after 100+ hours, needs to be fixed - uint64_t targetCycle = (masterClock * (uint64_t)1024000 / (uint64_t)_console->GetMasterClockRate()) * 2; + uint64_t targetCycle = (uint64_t)(_memoryManager->GetMasterClock() * _clockRatio); while(_state.Cycle < targetCycle) { Exec(); } @@ -214,6 +215,8 @@ void Spc::ProcessEndFrame() { Run(); + _clockRatio = (double)2048000 / _console->GetMasterClockRate(); + int sampleCount = _dsp->sample_count(); if(sampleCount != 0) { _console->GetSoundMixer()->PlayAudioBuffer(_soundBuffer, sampleCount / 2); @@ -233,14 +236,14 @@ void Spc::Serialize(Serializer &s) s.Stream(_state.OutputReg[0], _state.OutputReg[1], _state.OutputReg[2], _state.OutputReg[3]); s.Stream(_state.RamReg[0], _state.RamReg[1]); s.Stream(_state.ExternalSpeed, _state.InternalSpeed, _state.WriteEnabled, _state.TimersEnabled); - s.Stream(_state.DspReg, _state.RomEnabled); + s.Stream(_state.DspReg, _state.RomEnabled, _clockRatio); _state.Timer0.Serialize(s); _state.Timer1.Serialize(s); _state.Timer2.Serialize(s); ArrayInfo ram { _ram, Spc::SpcRamSize }; - s.Stream(ram, _state.DspReg, _state.RomEnabled); + s.Stream(ram); uint8_t dspState[SPC_DSP::state_size]; memset(dspState, 0, SPC_DSP::state_size); diff --git a/Core/Spc.h b/Core/Spc.h index d8adf94..98e5294 100644 --- a/Core/Spc.h +++ b/Core/Spc.h @@ -6,6 +6,7 @@ #include "../Utilities/ISerializable.h" class Console; +class MemoryManager; class SPC_DSP; class Spc : public ISerializable @@ -18,11 +19,13 @@ private: static constexpr uint16_t ResetVector = 0xFFFE; shared_ptr _console; + shared_ptr _memoryManager; unique_ptr _dsp; bool _immediateMode; uint16_t _operandA; uint16_t _operandB; + double _clockRatio; SpcState _state; uint8_t _ram[Spc::SpcRamSize];