APU: Fixed "catch up" bug that caused the frame counter's pacing to be incorrect
This commit is contained in:
parent
d528e6110b
commit
bf86f5458a
2 changed files with 9 additions and 35 deletions
|
@ -178,12 +178,7 @@ bool APU::NeedToRun(uint32_t currentCycle)
|
|||
}
|
||||
|
||||
uint32_t cyclesToRun = currentCycle - _previousCycle;
|
||||
if(_frameCounter->IrqPending(cyclesToRun)) {
|
||||
return true;
|
||||
} else if(_deltaModulationChannel->IrqPending(cyclesToRun)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return _frameCounter->NeedToRun(cyclesToRun) || _deltaModulationChannel->IrqPending(cyclesToRun);
|
||||
}
|
||||
|
||||
void APU::Exec()
|
||||
|
|
|
@ -23,7 +23,6 @@ private:
|
|||
shared_ptr<Console> _console;
|
||||
int32_t _stepCycles[2][6];
|
||||
NesModel _nesModel;
|
||||
int32_t _nextIrqCycle;
|
||||
int32_t _previousCycle;
|
||||
uint32_t _currentStep;
|
||||
uint32_t _stepMode; //0: 4-step mode, 1: 5-step mode
|
||||
|
@ -43,8 +42,6 @@ public:
|
|||
{
|
||||
_nesModel = NesModel::Auto;
|
||||
|
||||
_nextIrqCycle = 29828;
|
||||
|
||||
_previousCycle = 0;
|
||||
|
||||
//"After reset: APU mode in $4017 was unchanged", so we need to keep whatever value _stepMode has for soft resets
|
||||
|
@ -67,7 +64,8 @@ public:
|
|||
|
||||
void StreamState(bool saving) override
|
||||
{
|
||||
Stream(_nextIrqCycle, _previousCycle, _currentStep, _stepMode, _inhibitIRQ, _nesModel, _blockFrameCounterTick, _writeDelayCounter, _newValue);
|
||||
int32_t unusednextIrqCycle;
|
||||
Stream(unusednextIrqCycle, _previousCycle, _currentStep, _stepMode, _inhibitIRQ, _nesModel, _blockFrameCounterTick, _writeDelayCounter, _newValue);
|
||||
|
||||
if(!saving) {
|
||||
SetNesModel(_nesModel);
|
||||
|
@ -103,7 +101,6 @@ public:
|
|||
if(!_inhibitIRQ && _stepMode == 0 && _currentStep >= 3) {
|
||||
//Set irq on the last 3 cycles for 4-step mode
|
||||
_console->GetCpu()->SetIrqSource(IRQSource::FrameCounter);
|
||||
_nextIrqCycle++;
|
||||
}
|
||||
|
||||
FrameType type = _frameType[_stepMode][_currentStep];
|
||||
|
@ -127,9 +124,6 @@ public:
|
|||
if(_currentStep == 6) {
|
||||
_currentStep = 0;
|
||||
_previousCycle = 0;
|
||||
if(_stepMode == 0 && !_inhibitIRQ) {
|
||||
_nextIrqCycle = 29828;
|
||||
}
|
||||
} else {
|
||||
_previousCycle += cyclesRan;
|
||||
}
|
||||
|
@ -145,12 +139,6 @@ public:
|
|||
//Apply new value after the appropriate number of cycles has elapsed
|
||||
_stepMode = ((_newValue & 0x80) == 0x80) ? 1 : 0;
|
||||
|
||||
if(!_inhibitIRQ && _stepMode == 0) {
|
||||
_nextIrqCycle = 29828;
|
||||
} else {
|
||||
_nextIrqCycle = -1;
|
||||
}
|
||||
|
||||
_writeDelayCounter = -1;
|
||||
_currentStep = 0;
|
||||
_previousCycle = 0;
|
||||
|
@ -171,22 +159,13 @@ public:
|
|||
return cyclesRan;
|
||||
}
|
||||
|
||||
bool IrqPending(uint32_t cyclesToRun)
|
||||
bool NeedToRun(uint32_t cyclesToRun)
|
||||
{
|
||||
if(_newValue >= 0 || _blockFrameCounterTick > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(_previousCycle + (int32_t)cyclesToRun >= _stepCycles[_stepMode][_currentStep]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(_nextIrqCycle != -1) {
|
||||
if(_previousCycle + cyclesToRun >= (uint32_t)_nextIrqCycle) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
//Run APU when:
|
||||
// -A new value is pending
|
||||
// -The "blockFrameCounterTick" process is running
|
||||
// -We're at the before-last or last tick of the current step
|
||||
return _newValue >= 0 || _blockFrameCounterTick > 0 || (_previousCycle + (int32_t)cyclesToRun >= _stepCycles[_stepMode][_currentStep] - 1);
|
||||
}
|
||||
|
||||
void GetMemoryRanges(MemoryRanges &ranges) override
|
||||
|
|
Loading…
Add table
Reference in a new issue