Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Mockingboard: music not working when using Timer1 from both 6522's #685
To be precise (I had personally asked Tom to remain vague while waiting for the official release - Thanls Tom), this issue concerns CHIP, the last Musidisk from French Touch.
Here is part of the email that I sent him with more details:
This release uses 2 interrupts (Timer 1 from both 6522).
And here comes the issue with AppleWin: I had no sound at all... The play routine is well executed, the AY registers are set but nothing happens!
I need only disable the second interrupt to restore sound (the sound being played during the first INT)...
To set interrupts, I use:
If I disable INT by commenting on both lines (2), sound is not restored...
I obviously tested on a real Apple II (now I can!) and sound is played correctly, using both interrupts. And display is the one expected.
Edit: Full source code available here: http://fr3nch.t0uch.free.fr/CHP/CHP.html
The problem starts with: when to update the Mockingboard sound ring-buffer?
The emulator has a ~0.4 second ring-buffer for Mockingboard sound. Periodically the emulator will update this sound buffer. The period I chose for AppleWin to update at is the TIMER1 interval (eg. typically 60Hz). It's best to do this after the AY8910 registers have been updated (ie. not mid-way through updating them), so AppleWin was doing it when the TIMER1 interrupt occurred.
AppleWin saved the number of the 6522 of the last TIMER1 (eg. AppleWin has 4x TIMER1's: 2 6522's per Mockingboard x 2 supported Mockingboards). Then when a TIMER1 underflow interrupt occurred, it checked that the 6522 number matched the last TIMER1 to be setup.
So here's what was happening:
Basically the 6522 TIMER1 underflowing never matched the expected lastTIMER1... so silence!
The fix involves counting cycles between Mockingboard updates to determine the update interval. Currently I special-case this for when there are multiple TIMER1's active. I think I can evolve this into a generic solution, but need more time to test this idea. So for now, I'll just go with the special-case.
OK, so I didn't give the whole story... 2 other cases:
Which method does FAKE OFF use?
Just a very simple loop that launches the "play" routine as quickly as possible (as it is to generate "samples").
Yes. The back-end emulation for AY8910 is from a Spectrum 128 emulator ("fuse"). For the current (eg) 60Hz frame, every AY8910 access is recorded with a timestamp. Then when AppleWin updates the sound-buffer, these AY8910 accesses are converted into signed 16-bit audio samples, which are then written to the sound-buffer.
So even though AppleWin only updates the sound-buffer (eg) at 60Hz, all the AY8910 accesses are correctly "played back" at the correct time. This is why AppleWin is able to play samples using the AY8910.