Fixed length counter reload behavior (fixes test "len_reload_timing")

This commit is contained in:
Souryo 2016-01-02 17:35:30 -05:00
parent 61ac52d82e
commit eec6bc8f77
2 changed files with 23 additions and 2 deletions

View File

@ -135,6 +135,13 @@ void APU::Run()
while(_previousCycle < _currentCycle) {
_previousCycle += _frameCounter->Run(cyclesToRun);
//Reload counters set by writes to 4003/4008/400B/400F after running the frame counter to allow the length counter to be clocked first
//This fixes the test "len_reload_timing" (tests 4 & 5)
_squareChannel[0]->ReloadCounter();
_squareChannel[1]->ReloadCounter();
_noiseChannel->ReloadCounter();
_triangleChannel->ReloadCounter();
_squareChannel[0]->Run(_previousCycle);
_squareChannel[1]->Run(_previousCycle);
_noiseChannel->Run(_previousCycle);

View File

@ -13,6 +13,8 @@ private:
protected:
bool _lengthCounterHalt;
uint8_t _lengthCounter;
uint8_t _lengthCounterReloadValue;
uint8_t _lengthCounterPreviousValue;
void InitializeLengthCounter(bool haltFlag)
{
@ -23,7 +25,9 @@ protected:
void LoadLengthCounter(uint8_t value)
{
if(_enabled) {
_lengthCounter = _lcLookupTable[value];
_lengthCounterReloadValue = _lcLookupTable[value];
_lengthCounterPreviousValue = _lengthCounter;
SetRunFlag();
}
}
@ -86,6 +90,16 @@ public:
BaseApuChannel::Run(targetCycle);
}
void ReloadCounter()
{
if(_lengthCounterReloadValue) {
if(_lengthCounter == _lengthCounterPreviousValue) {
_lengthCounter = _lengthCounterReloadValue;
}
_lengthCounterReloadValue = 0;
}
}
void TickLengthCounter()
{
if(_lengthCounter > 0 && !_lengthCounterHalt) {