Wednesday, 18 June 2014

Sound advice

I've ported the sound code to 6809 and after deafening silence last night, managed to elicit sound from the Coco speaker today. Since I'm porting the Apple II's 1-bit sound, I actually have the choice of using the Coco's 1-bit sound output, or the 6-bit DAC. For now, I support either (at build time).

As it stands without any debugging, the sound of the player falling already sounds more-or-less correct. Since the PWM is done in a tight loop, it's all critically dependent on the CPU speed and cycle counts, and without tweaking the values (or the routine) it's invariably a different pitch - slightly higher on the Coco. When it's all debugged, I'll evaluate my options for fine tuning this and see where it goes. Other - more complex - sounds wreak havoc with the game speed atm, but I haven't even started debugging yet.

The sound routines consist of playing back a series of notes (frequencies) each with an associated duration. The durations are specified in absolute time, rather than multiples of the frequency, making 'composing' and game speed tweaking a little easier. And here-in lies a bug that had me scratching my head for a while until I worked out what was going on...

The duration is actually a multiple of 256 iterations of the sound bit-bash loop. The routine to play the sound uses the 6502 Y register to count these 256 iterations before decrementing the duration. The issue is, the Y register is not initialised in the routine and starts with what is effectively a random value. This means that the first count of the duration is - on average - shorter and results in a wrong sum duration for the note. Obviously the relative error is dependent on the note's duration.

Anyway, I decided to retain the bug in the 6809 port, although the randomness of the error will differ given the differences in implementation (Y register vs direct-page register) but you likely will never hear it.

Hopefully tonight I'll get a chance to debug the rest of the sound. The main difference between the falling sound and other sounds is that the former plays a single note at a time, whereas the latter queues a series of notes to be played in a sound buffer. Subsequently the latter implements a different algorithm to adjust the game speed for the sound and I would suspect that this is the source of the bug since the game 'stutters' when a sound (other than falling) is played.

UPDATE: The sound has been debugged, except for a start-up issue where the queued sound has an extraneous note on the end. It seems to disappear permanently as soon as a note (as opposed to a multi-note sound) is played. I suspect the sound queue isn't initialised properly, but it's too late to track it down. Tomorrow...

That aside, it's sounding pretty good. The Apple II Lode Runner sound was never going to win any awards - being little more than beeps and trills - so I'm happy enough with the port even without adjusting the pitch. So I guess the next beta will be the full release just without 150 levels or high score load/save. These have been left to last because they present a challenge, and also will have completely different solutions for floppy disk and (if it happens) cartridge releases.

It would then take me a day to do a Championship Lode Runner release.


  1. How many cycles does it spend in the sound output? Or what percentage of time? Gives one an idea of how much CPU time to reserve for sound if it requires bit-banging.

  2. To be honest, I haven't taken a lot of notice of the number of cycles - mainly because I haven't had to. Because the sounds are so infrequent within the game, the sound routines actually tweak the ballast delay whenever they're played. So without sound it was running at a consistent speed, and porting the sound routines added the tweak so that it remained at a constant speed without my intervention. Quite fortuitous really.

    The main loop includes (at least) one call to the sound update routine, which plays a single note from the queue. The notes are typically a handful of iterations of 256 relatively tight loops with a few instructions within it. On the Coco there's a little more to do to actually tickle the sound output, but the increased clock speed more than compensates.