SPC: Fixed potential overflow problem when running for a very long time
This commit is contained in:
parent
75150cb133
commit
7e4a141b7b
3 changed files with 12 additions and 6 deletions
|
@ -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());
|
||||
|
||||
|
|
13
Core/Spc.cpp
13
Core/Spc.cpp
|
@ -9,6 +9,7 @@
|
|||
Spc::Spc(shared_ptr<Console> console, vector<uint8_t> &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> console, vector<uint8_t> &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<uint8_t> 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);
|
||||
|
|
|
@ -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> _console;
|
||||
shared_ptr<MemoryManager> _memoryManager;
|
||||
unique_ptr<SPC_DSP> _dsp;
|
||||
|
||||
bool _immediateMode;
|
||||
uint16_t _operandA;
|
||||
uint16_t _operandB;
|
||||
double _clockRatio;
|
||||
|
||||
SpcState _state;
|
||||
uint8_t _ram[Spc::SpcRamSize];
|
||||
|
|
Loading…
Add table
Reference in a new issue