New idea for the sound fix. If I can get this to work before I send out test units that'll be great. The sound slowdown works well now but it's not cycle-accurate. That would be more robust but the current hardware can't pause the fast 68k's clock. I thought this would make cycle-accurate sound slowdown impossible. I'll add CPU clock gating to the next version but I have a solution that makes cycle-accurate sound slowdown with the current hardware possible
I can't stop the clock, but what I can do is keep track of how many clock cycles have gone by and then add wait states to subsequent bus cycles to maintain an average rate of 7.8336 MHz. Here's the code:
It's sort of like credit-based flow control in networking but you can go into the negative. The 8-bit Credits register holds a signed (two's complement) number of cycle "credits." When the fast 68k executes a cycle of useful work (i.e. not a wait state), the credit counter is decreased by 1. When the credits are negative (i.e. Credits[7] is 1), the sound QoS inserts wait states in the next bus cycle. Every time a 7.8336 MHz clock falling edge occurs, the credits are increased. So this matches the overall rate of the fast CPU to the slow frequency.
The control for the credit counter is pretty simple. It involves the SndSlowEN "sound slowdown triggered," FSBW "fast/frontside bus waiting," and C8MFall "8 MHz clock just fell" signals. SndSlowEN is true during the 30-40 microseconds after a sound access. FSBW is true on the fifth and subsequent clock cycles of a bus access. So it indicates if wait states are being inserted. C8MFall is an indication in the 25 MHz bus domain that the 7.8336 MHz clock just went from 1 to 0.
When SndSlowEN is false, sound slowdown hasn't been triggered so the credit register gets reset to 0, which is nonnegative, so slowdown won't be triggered. Otherwise, when FSBW is false, that means the current clock is not a wait state and so the 68k is running at "full speed." Therefore we use up one credit. When C8MFall is true, the credit counter increments to give back credits on average at the 7.8336 MHz Mac clock rate. And when both or neither happen, the credit counter stays the same since they either cancel out or neither a C8M fall nor an FSB non-wait state occurred.
The credit counter has quite a large range. Half of it is wasted since it'll never go above 1. The reason for the range is so that it can go all the way to -128. When executing a multiply instruction, depending on the numbers being multiplied, the 68k might think for 66 clock cycles between accessing the RAM! So we need to go to at least -74 if we want the timer not to roll over during a long multiply. Divide is even longer on the 68k and can take up to 160 clocks (IIRC). Rolling over won't crash anything but it'll result in the system running full-speed for 256 more clock cycles than it's supposed to. If that happens repeatedly during sound generation then the sound fix won't work. Fortunately dividing is so slow on the 68000 that it's impractical to use during sound generation anyway. So -127 to 128 is a good range for the sound clock credit counter.
Should work if it fits in the CPLD. It's getting a bit tight. I'll try this in the next day or two.