This function, written in assembly, is intended to be used in games or demos. It provides a single channel sound track sync'ed with vertical retrace that can be generated from a RTTL (nokia ringtone language) string.
The function uses a 3 byte format composed by the duration of each note (1 byte) as well as data related to its frequency (2 byte).
duration (tempo) : [ 1 byte ] 1..255 "frequency" : [---lsb--][0000-msb] 0..4095
This is a non-blocking function that should be called at each VDP vertical retrace interrupt. Therefore the duration corrensponds to multiples of 1/60Hz or 1/50Hz depending upon the country where the machine were sold.
The "frequency" is indeed a division factor applied to PSG master clock frequency in order to generate the desiered note tune.
A note with ZERO duration serves as a command
Duration : [ 0 ] It's a command [ccccrrrr][dddddddd] cccc command 0..15 rrrr argument 0..15 dddddddd data 0..255
So far 3 commands have been defined.
cccc = 0, : Replay the song
rrrr, dddddddd : Don't care.
cccc = 1, : Write a PSG register
rrrr = PSG register [0..15]
dddddddd = data [0..255] to be written.
cccc = 2, : Write a PSG register and continue interpreting
rrrr = PSG register [0..15]
dddddddd = data [0..255] to be written
The main difference from commands 1 and 2 is that the latter allows a sequence of writes on the PSG for the same time slot.
The songs can be generated from "Ringtones" in RTTL (nokia) format by running a python script that will print a sequence of byte definitions to be included in the program.
Hence the follwoing ringtone:
"Super Mario - Main Theme:d=4,o=5,b=125:a,8f.,16c,16d,16f,16p..... "
becomes:
"; start song: Super Mario - Main Theme db 28,127,0 ; db 21,160,0 ; db 7,213,0 ; db 7,190,0 ; db 7,160,0 ; db 7,0,0 ; pause ... ... ..."
The program provides an skeleton with a Init function and a main loop that syncs to the vertical retrace by halting the Z80
Great hack of an old platform. Can you post a video?