Recently I was investigating why the Color Computer 3 version of Arkanoid didn’t make any ricochet sounds when the ball bounced off an object in MAME. For an example of the game working properly see this video here: https://youtu.be/1eexgL5b4lo
After talking with the author of the game (Steve Bjork: name drop) he said the sound in question was being played by using the timer interrupt system in the machine. I disassembled the FIRQ handler and quickly found the problem. His playback routine did two things: it wrote a value to the DAC, and determined the proper amount of time to wait before the next DAC update. It did not update the DAC at a constant frequency.
Here is what the ISR did, in the order it did them:
1. Acknowledge the interrupt.
2. Write the new timer delay to the register
3. Enable the interrupt again.
4. Write the value to the DAC.
5. Determine the next timer delay and store it for the next interrupt.
The problem was the first time the ISR was called: It wrote a zero for the amount of delay to the next interrupt, because the delay isn’t properly determined until then end of the ISR. Documentation about the CoCo 3 hardware says this should stop the timer interrupt. And that is what MAME did. But this is not what real hardware does. On real hardware you get an immediate re-aserting of the interrupt when the timer value is set to zero. On the second interrupt the sound system is properly initialized, real timer values were being written, and samples are being sent to the DAC.
In order to find this problem I wrote some test programs. This helped me to fix the above bug, and also discover another bug in MAME. MAME tightly coupled the pulling of the F/IRQ line with setting the F/IRQ flag. On real hardware turning off the interrupt has no effect whether the flags are set.
The archive below is the test code I wrote. Three different routines that set up the timer interrupt. Every time the interrupt is fired the address $400 is incremented.
TEST1 sets up the slow timer with a value of $FFF. TEST2 sets up the fast timer with a value of $FFF. TEST3 sets up the slow timer with a value of $0. All three programs use polling to check if the timers fired (bug #2). TEST3 is the program that test a timer value of zero (bug #1).
Included are video files from my Color Computer 3 with an ’86 GIME. They show what the program display as they are running.