SSI263 phoneme playback bug: (fixes #1104)

Fix for rare race-condition, where a phoneme could complete immediately before SSI263's interrupt is enabled:
- resulting in A2 code failing to detect SSI263 or speech phrase never completing.
Only ever possible when debugger-stepping or in full-speed mode.
This commit is contained in:
tomcw 2022-05-29 10:25:01 +01:00
parent 89cbb0c65c
commit 8f07479dad
2 changed files with 5 additions and 9 deletions

View File

@ -11,7 +11,7 @@ Tom Charlesworth
1.30.10.0 - 27 May 2022
-----------------------
. [Change #51097] Extend Uthernet II to support DNS offloading. [audetto]
. [Change #1097] Extend Uthernet II to support DNS offloading. [audetto]
- Details: https://github.com/a2retrosystems/uthernet2/wiki/Virtual-W5100-with-DNS
- No need for ethernet, so now works with host PC's WiFi.
- Supported by @oliverschmidt's A2Stream v1.2.

View File

@ -361,6 +361,9 @@ void SSI263::Play(unsigned int nPhoneme)
m_currSampleSum = 0;
m_currNumSamples = 0;
m_currSampleMod4 = 0;
// Set m_lastUpdateCycle, otherwise UpdateAccurateLength() can immediately complete phoneme! (GH#1104)
m_lastUpdateCycle = MB_GetLastCumulativeCycles();
}
void SSI263::Stop(void)
@ -393,14 +396,9 @@ void SSI263::Update(void)
#endif
if (m_phonemeAccurateLengthRemaining)
{
m_phonemeCompleteByFullSpeed = true; // Let UpdateAccurateLength() call UpdateIRQ()
m_lastUpdateCycle = MB_GetLastCumulativeCycles(); // Set m_lastUpdateCycle, otherwise UpdateAccurateLength() just early-returns!
}
else
{
UpdateIRQ();
}
}
m_updateWasFullSpeed = true;
@ -493,9 +491,6 @@ void SSI263::Update(void)
const double kMinimumUpdateInterval = 500.0; // Arbitary (500 cycles = 21 samples)
const double kMaximumUpdateInterval = (double)(0xFFFF + 2); // Max 6522 timer interval (1372 samples)
if (m_lastUpdateCycle == 0)
m_lastUpdateCycle = MB_GetLastCumulativeCycles(); // Initial call to SSI263_Update() after reset/power-cycle
_ASSERT(MB_GetLastCumulativeCycles() >= m_lastUpdateCycle);
updateInterval = (double)(MB_GetLastCumulativeCycles() - m_lastUpdateCycle);
if (updateInterval < kMinimumUpdateInterval)
@ -657,6 +652,7 @@ void SSI263::UpdateAccurateLength(void)
if (!m_phonemeAccurateLengthRemaining)
return;
_ASSERT(m_lastUpdateCycle); // Can't be 0, since set in Play()
if (m_lastUpdateCycle == 0)
return;