No, I didn’t make any typo by writing the title of this article in upper case. They are just the name of the 2 new commands I’ve added to the BASIC of my LM80C computer, SOUND and VOLUME. Of course, they set a tone to be generated by the PSG and the volume of the audio channel, respectively.
VOLUME has a very simple sintax and just gets 2 params: the first one is the audio channel, the second one is the volume level. The channel can be an integer in the range 0~4: 1, 2, & 3 point to the corresponding channel (1->A, 2->B, 3->C) while 0 stands for “every channel”, meaning that it’s like a global setting. The volume level is an integer in the range 0~15, where 0 is for OFF and 15 is for MAX volume level.
SOUND required more work because I had to manage 3 different user params: the channel, the frequency and the duration. I start explaining them by the latter, because I had to make some changes into the firmware to let it work. I have to say that I made a good choice in the past, when I was finalizing the design of my computer and chose to adopt a Z80 CTC as a timer/counter to generate the clock for the serial interface: by having several timers, I decided to use one of them to increment a simple hundred of seconds counter to have a system to measure the time on my computer. I modified this interrupt service routine by introducing another piece of code that decrements 3 registers, these registers simply keep the remaining duration of the tone to be played. So, if I set a duration of 100, I just want that the tone plays for 100 hundreds of second, which is 1 second. The firmware decrements the duration registers from 100 to 0, and when zero is reached it stops the reprodution by setting the volume level of the corresponding channel to 0.
The frequency param required additional code because the PSG works in the following way: to generate a particular tone it keeps the input frequency clock and divides it by 16 and, then. it divides it again by a 12-bit value set with 2 specific registers. So, if we, like in the LM80C computer, have an input clock of 1.84 MHz and we have a param between 0 and 4,095 (2^12), we can play tones with a frequency between 28 Hz and 115 KHz circa. Obviously, everything over 15/20 KHz won’t be audible. I just did a simple thing: since I wanted to let the user feels that at higher values corresponded higher frequencies, I simply subtracted the input value by 4,096 and stored the results into the PSG registers. In this way the user doesn’t get a frequency whose value is equal to the paramether he/she passed but he/she has, however, the impression that at higher numbers correspond higher tones. This is the same way of working of old computers. My C16 did the same thing: it had a SOUND command that got a value param in the range 0~1023 that, altough it wasn’t the real frequency obtained by the audio chip, it had a correlation between the value inserted and the frequency of the tone played.
The new firmware with the new commands is available as release R2.1 on my Github repository.