Before i could get started it was imperative that i looked at the golden target. The playing of RSIDs and what makes them so special compared to the regular SID music referred to as PSIDs. Most projects around SID playback make assumption on how they could do it that as far as i know: never panned out only ever playing PSID. My hunch is that RSID playback has something to do with the "Complex Interface Adapter" (CIA) chips. These are massive chips in charge of general purpose I/O, but also Timing via a pair of Periodic Interval Timers (PIT1 and PIT2). These are also what control the processor's interrupts (CIA1->IRQ, CIA2->NMI)
To investigate this I used a "C64 Debugger". A Variant of the popular VICE emulator that shows information about the peripheral chips like the SID, CIA and VICs, a live memory map and can be run clock by clock if desired. I then proceeded to load up various SID files including a couple RSIDs and observe how they use the C64 hardware.
By default the C64 is configured with a regular IRQ signal coming from CIA1-PIT1. This IRQ goes of at a frequency of 50hz. Most PSID use this regular IRQ to call the "PlayRoutine" (an address that when jumped to starts the routine for the next step in playback) 50x per second. Some PSIDs deviate and reconfigure the CIA1-PIT1 to instead trigger IRQ more often. The other Timer and CIA2 are left alone.
RSIDs though start to use more elaborate tricks. With the SID chip they start to manipulate the volume register at times to pull off PCM sample playback. Occasionally using the NMI connected CIA2 or even forgoing the timers altogether and just running at full speed. Then I got to play "Hi-Fi Sky" by LMAN which showed the most devious exploit I had seen thus far.
This one did this weird thing where CIA1 was not creating any IRQ, but had its second timer running at an incredibly small interval while the first was standing still at a specific value. The processor kept passing by it. On closer inspection it turned out that the first timer's value matched a JMP opcode. The processor was reading the registers of the first timer which had part of a JMP command. The last byte it read for the target address being the low-byte of Timer2 that was constantly changing. The RSID was using the CIA1 Timers a a time-sensitive JMP Table!!
This is why most players failed and why you had to use a "Cycle Exact" emulator. Even when using a genuine SID chip, most players only assumed the IRQ would get used for a regular signal and any offset in timer value would break the playback if you didn't do it exactly.
So if i want a real chance at playing all the RSIDs. I need to figure out how the substitute the CIAs Timers. Which will be the subject of a future log.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.