The Secret to Monkey Island would intermittently freeze. Easy places to reproduce the freezes were in rooms with a lot of sounds:
- The kitchen in the SCUMM bar with the pot bubbling, keg pouring, and voice speaking.
- The bottom of the boat with water dripping and voice speaking.
- Many of the cut scenes.
I was able to reproduce the problem in a debugger and found the game was stuck in an infinite loop waiting for sound to stop playing.
The logic in the game is:
Code: Select all
if (voice_playing) {
ctv_terminate() // TERMINATE_PROCESS=8 in CT Voice driver
while (voice_playing) {} // <--- This is the loop it was frozen in.
}
ctv_output(); // OUTPUT_VOICE=6 in CT Voice driver
What I found was the game would freeze when starting a new sound before the previous one finished. When this happens the game expects to provide a certain length of sound bytes, but the sound_dsp module in the AO486 core was still counting down bytes from the previous sound.
Because AO486 core never received all the bytes from the first sound, it never triggered the IRQ to clear the `voice_running` flag, and the game freezes, stuck waiting forever for the sound to finish.
For example in the SCUMM bar kitchen the game would play bubble sound effects from the pot:
- Game requests output of a 7,430 byte block
- DSP signals IRQ after 7,430 bytes.
- Game requests output of a 35,786 byte sound block to play.
- With 8,693 bytes (0x21F9) remaining of the active sound, the game requests a bubble sound of 7,430 (0x1D06) bytes.
- Both the game and the AO486 are deadlocked after 7,430 bytes are played following the interruption of the bubble sound. AO486 expects another 1,267 bytes that never come.
I've updated the sound_dsp module in a fork of the AO486 core which updates the DMA length of expected bytes when a new command is received, rather than waiting for an active sound to finish. I believe interrupting the current sound is in line with what the DOS sound driver is expecting.
https://github.com/user7182/ao486_MiST ... e293847a7a
With this change I was able to play The Secret of Monkey Island from start to finish without it freezing.
I plan to make a pull request to the main repository, but I don't have a lot of confidence I didn't introduce any new problems. I published a pre-built core RBF file in the hopes a few more people could test it in other games they know work, or with other games that also froze.
https://github.com/user7182/ao486_MiSTe ... 6_20220102