A very important component of any demo is having a kick arse SID chip track backing it. That means, we need to be able to play a track while performing some mastery of the raster bar. It was something I was dreading looking at, but turned out to be a very straight forward thing and only ended up taking about 10 minutes to get working.
First step was to actually get some music to play. Many games and demos store their music (and player) at $1000, which you can dump out and save. But I came across a better solution and one easier to work with. There is a large collection of SID tracks at High Voltage SID Collection . As they put it – “(HVSC) is a freeware hobby project which organises Commodore 64 music (also known as SID music) into an archive for both musicians and fans alike. The work on the collection is done completely in the Team and contributors’ spare time and is proudly one of the largest and most accurate computer music collections known.”
First step was to download the SID collection and also a player. The page has links to various sid chip players and I downloaded the sidplay software.
Each SID file has a 124 byte header, which contains various information about the file. The header spec can be found here. There is also a 2 byte jump value which will be $00, $10 for music stored at $1000. The rest of the data is the music player and music data.
Opening up any of the thousands of SID files, we can view the properties and see this header information. There are three fields which interest us the most – Load range, Init Address and Play Address. All of these can be seen here:
The load range is where we need to store the music data in memory. In this case, it’s $c000 (not $1000 as is normally the case). This is fine as there is a 4Kb block of free memory here for use anyway.
With that knowledge, we’re now ready to write some code and get some music playing. First step is to create a new assembly file. I include the common registers required. I also define 3 constants which mirror the load address, init address and play address that were found in the music header.
Next step is to define our start position in memory – in this case $0801 and I’ve added a little byte series to auto run at start up – saves typing SYS all the time.
Next I want to relocate all the music data to $c000 as per the information shown in the header. Also shown in the header is the music data size – in this case 3165 bytes. A simple loop is used to relocate the data. This is done once at start up.
Now I initialise the screen and border colours to black and also initialise the music player. This is done by setting the x and y registers to 0 and then jumping to the init address. I could have technically loaded x with 0 and used that to store into the border/screen registers also to save some cycles, but I’m not worried about that for such an example 😉
We’re almost done. We want to set up an interrupt that occurs each refresh to update the music player. In this example, I’ll call it on line #40, but you can do this anywhere and it will most likely be dictated by what else you have chewing up raster time in your demo.
The interrupt routine is very simple. After acknowledging the interrupt, we only need to jump to the music play address. I’ve also included a set of commands to set the border colour to white before the jump and then back to black after the jump. I do this only for debugging as I like to see how much raster time the player eats up.
The last part of the file is the music data. Stored as a series of byte commands ripped from the .sid file. This is the data that is relocated. A smart move would be to pack/compress this before release to save space.
That’s it. After compiling and running the code, we have music playing. Notice the section of white border towards the top of the screen. This shows how much raster time the player is taking up each refresh.
I’m in the process of putting together a small command line tool to grab the SID header and data to format them, ready for insertion into an assembly script file.
I really do recommend checking out the High Voltage SID collection. There are some amazing sid tunes there and of course it’s a great library to look through for music in your own creations.
Full source code is available here: Link
[UPDATE – 07/03/2015]
While working on a new production today, I came across an issue with running the music update. The update routine consumed more raster time than other SID tracks I have used, so assume created with a different tool. The init routine would set up the player variables incorrectly. This was tracked down to requiring a lda #000 before jumping to the music init routine. This hasn’t been needed in the past as only the x and y registers required to be initialised. It’s worth noting this issue and probably worth initialising the accumulator anyway as default before jumping to the init code.