Thursday, November 2, 2017

Just posting a link to a simple music player I wrote for the Apple II Mockingboard a few years ago.
It's written for the 6502 AS65 assembler that comes with the CC65 C compiler.
The Mockingboard has two 6522 VIA chips, and two General Instruments AY sound chips. The VIAs are used to interface the sound chips, and provide additional features such as programmable interrupts.

The player uses a repeating timer interrupt from the VIA chip to play music with minimal impact on the main program that uses it.  It's a port of a music player I wrote for the Oric a few years earlier. The Oric has similar hardware out of the box, but only one VIA and one AY chip.  That version used a one shot timer though due to me not having VIA docs at the time.

The interrupt handler is pretty low impact.  It decrements the timer and exits quickly if no sound chip register needs to be set.  It just dumps raw data to the sound chip when required.  The data format is documented in the source code, and the code is pretty well commented.
It's not very practical for large pieces of music due to the lack of repeats and resulting size of the data, but for simple background music that repeats endlessly, or one shot sound effects it works really well.  The code still needs some work in order to play sound samples and music at the same time, but that's just a matter of adding additional counters for each sound.
The code includes sample data that plays chords, and background music for several screens from Donkey Kong.  The emulator disk image should run a demo that lets you select which song to play.

To build the code you will need the AS65 assembler.  I used a simple DOS batch file to build it instead of a make file.  If you use that, it requires a2tools to automatically transfer the file to a disk image.  a2tools can be found on Asimov, but it's only a 32 bit exe.  Let me know if you need a 64 bit version and I'll post my custom build.  Or you can delete that line from the batch file, and use Cyderpress to transfer it to a disk image.

FWIW, this is a good though simple example of how you can drive a piece of hardware in "real time".  You could output and/or sample data at specific intervals.  Just adjust the timer for the rate you need and remember to calculate the delay from the trigger of the interrupt until you actually read or write data so you don't drop any data or set a piece of hardware too late.

Here's the link. There is a newer version of the source code in my project directory, but this is a version I shared previously so it should be working.  If I get a chance to test the newer code and build a new archive I'll post that.
https://www.dropbox.com/s/xibf8xu9zh3n5bu/DonkeyKongApple.zip?dl=0