Fixed cycle counting overflow that was causing DSB2 to halt execution.

This commit is contained in:
SpinDizzy 2021-03-07 10:12:37 +00:00
parent 6cf9974102
commit de470aaf52
2 changed files with 60 additions and 64 deletions

View file

@ -31,8 +31,6 @@
* --------- * ---------
* - Should MPEG_SetLoop() check for loopEnd==0? This causes crashes. Usually * - Should MPEG_SetLoop() check for loopEnd==0? This causes crashes. Usually
* only occurs when loopStart is also 0, and that can only be checked here. * only occurs when loopStart is also 0, and that can only be checked here.
* - Volume fade out in Daytona 2 is much too slow. Probably caused by 68K
* timing or interrupts.
* - Check actual MPEG sample rate. So far, all games seem to use 32 KHz, which * - Check actual MPEG sample rate. So far, all games seem to use 32 KHz, which
* may be a hardware requirement, but if other sampling rates are allowable, * may be a hardware requirement, but if other sampling rates are allowable,
* the code here will fail (it is hard coded for 32 KHz). * the code here will fail (it is hard coded for 32 KHz).
@ -1017,27 +1015,28 @@ void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
M68KSetIRQ(1); // indicate pending command M68KSetIRQ(1); // indicate pending command
//printf("68K INT fired\n"); //printf("68K INT fired\n");
m_totalCyclesElapsed += M68KRun(500); m_cyclesElapsedThisFrame += M68KRun(500);
} }
// gm_matthew made the interesting discovery that IRQ2 may in fact be a timer interrupt // Matthew Daniels made the interesting discovery that IRQ2 may in fact be a timer interrupt
// rather than a per-frame interrupt.For Daytona 2 and Sega Rally 2, assuming a value // rather than a per-frame interrupt.For Daytona 2 and Sega Rally 2, assuming a value
// of 1KHz fixes music fade outs and some timing issues. It is very likely this is a // of 1KHz fixes music fade outs and some timing issues. It is very likely this is a
// configurable timer and we should be on the look-out for games which appear to use // configurable timer and we should be on the look-out for games which appear to use
// different values. It is equally likely that all games share a similar code base and // different values. It is equally likely that all games share a similar code base and
// use 1KHz as the timer rate. // use 1KHz as the timer rate.
while (m_totalCyclesElapsed < m_nextFrameEndCycles) while (m_cyclesElapsedThisFrame < k_framePeriod)
{ {
if (m_totalCyclesElapsed >= m_nextTimerInterruptCycles) if (m_cyclesElapsedThisFrame >= m_nextTimerInterruptCycles)
{ {
// Fire timer interrupt and schedule next one // Fire timer interrupt and schedule next one
M68KSetIRQ(2); M68KSetIRQ(2);
m_nextTimerInterruptCycles = (m_totalCyclesElapsed + k_timerPeriod) - (m_totalCyclesElapsed + k_timerPeriod) % k_timerPeriod; m_nextTimerInterruptCycles += k_timerPeriod;
} }
int cyclesToRun = (std::min)(m_nextTimerInterruptCycles, m_nextFrameEndCycles) - m_totalCyclesElapsed; int cyclesToRun = (std::min)(m_nextTimerInterruptCycles, k_framePeriod) - m_cyclesElapsedThisFrame;
m_totalCyclesElapsed += M68KRun(cyclesToRun); m_cyclesElapsedThisFrame += M68KRun(cyclesToRun);
} }
m_nextFrameEndCycles = (m_totalCyclesElapsed + k_framePeriod) - (m_totalCyclesElapsed + k_framePeriod) % k_framePeriod; m_cyclesElapsedThisFrame -= k_framePeriod;
m_nextTimerInterruptCycles -= k_framePeriod;
M68KGetContext(&M68K); M68KGetContext(&M68K);
@ -1097,8 +1096,7 @@ void CDSB2::Reset(void)
//printf("DSB2 PC=%06X\n", M68KGetPC()); //printf("DSB2 PC=%06X\n", M68KGetPC());
M68KGetContext(&M68K); M68KGetContext(&M68K);
m_totalCyclesElapsed = 0; m_cyclesElapsedThisFrame = 0;
m_nextFrameEndCycles = k_framePeriod;
m_nextTimerInterruptCycles = k_timerPeriod; m_nextTimerInterruptCycles = k_timerPeriod;
DebugLog("DSB2 Reset\n"); DebugLog("DSB2 Reset\n");
@ -1185,8 +1183,7 @@ void CDSB2::LoadState(CBlockFile *StateFile)
// Technically these should be saved/restored rather than being reset but that would mean // Technically these should be saved/restored rather than being reset but that would mean
// the save state format has to be modified and the difference would be imperceptible anyway // the save state format has to be modified and the difference would be imperceptible anyway
m_totalCyclesElapsed = 0; m_cyclesElapsedThisFrame = 0;
m_nextFrameEndCycles = k_framePeriod;
m_nextTimerInterruptCycles = k_timerPeriod; m_nextTimerInterruptCycles = k_timerPeriod;
// Restart MPEG audio at the appropriate position // Restart MPEG audio at the appropriate position

View file

@ -320,8 +320,7 @@ private:
M68KCtx M68K; M68KCtx M68K;
static const int k_framePeriod = 4000000/60; static const int k_framePeriod = 4000000/60;
static const int k_timerPeriod = 4000000/1000; // 1KHz timer static const int k_timerPeriod = 4000000/1000; // 1KHz timer
int m_totalCyclesElapsed; int m_cyclesElapsedThisFrame;
int m_nextFrameEndCycles;
int m_nextTimerInterruptCycles; int m_nextTimerInterruptCycles;
}; };