Music in Interrupts Part 2
Well then, most of you already know how to play Soundtracker music pieces in interrupt mode 2; the article in one of the previous issues and the setup program should have done their job, because it really isn't hard. But now we come to something more complicated: let's assume you have written a program, a strategy game that uses almost the entire 48K memory, leaving about 400 bytes free, but you want to use a music track that is 8 KB in size!
If you happen to have a 128K Speccy handy, that is really no problem at all now—we simply take a free bank. Wait! Do I hear you shouting that when the bank is switched, the entire program in the other bank becomes invisible to the computer? In principle and practice, that is indeed true, and for this reason I came up with a way to make it possible anyway.
If you think about it, it is actually quite simple to implement, even for inexperienced wannabe coders like me, because the interrupt routine as it was previously used can still be used; only a small additional routine switches the bank each time the music is supposed to be played, plays a part of the song, and then switches the bank right back immediately. The rest of the program doesn't even notice the whole thing, because the switching itself takes up very little processor time. The playback routine is the actual time-consuming part, but if you have one of the modern Soundtracker versions from the Near East, e.g. Soundtracker Pro (ha, unfortunately only for Beta Disk users), it already comes with a faster playback routine built in, just like the ST-Compiler itself. Unfortunately, despite having the same screen layout, this Soundtracker version is not entirely compatible with our ST. ProTracker, however, is just as suitable as anything else!
Here is the listing along with a description:
(As the bank number, I use the number that serves for switching, meaning not bank no., but bank no.+16, which is much simpler.)
First, before the interrupt handler jumps to the routine, the following addresses should be poked:
- 23388: Number of the current bank to switch back to once the music has been played (usually 16)
- 23549: Number of the bank containing the music track (banks 16, 17, 19, 20, 22, and partially 23 can be used, but only 16, 20, and 22 are so-called fast banks that are not slowed down by the second ULA; on the Pentagon it doesn't matter anyway which banks are chosen, as all of them are fast.)
These addresses are not mandatory, just non-binding suggestions. They can be any two addresses between 16384 and 49151, but I know what I'm doing and chose the addresses with care. The first address is the one that gets poked with the current bank number in 128K Basic anyway. The other address also lies in the normal printer buffer, but 1 below the lowest address normally required by PK Lite for the decompression routine. Just in case someone gets the idea of compressing program parts to make even better use of memory space.
Assuming that the music is in bank 17 and starts at 49152 (start of bank), and we are in bank 16, we load the music: (in USR mode)
OUT 32765,17: LOAD *"MUSIK" CODE: RANDOMIZE USR 49152 ('Music initialisation): OUT 32765,16: POKE 23388,16: POKE 23549,17
The interrupt maker should have been programmed long before in such a way that it doesn't collide with the bank switching or produce ULA snow, best from 32768 onwards. The addresses of the current and music bank can be changed freely since this only works in USR 0 mode anyway; the 128K mode bank switching constantly works against interrupt mode 2 and triggers a system crash. If you want to prevent that, you really have to program everything else in assembler too.
Bank Switcher:
ORG 33050 (this address is only a suggestion!)
33,253,91 LD HL,23549 ; Load bank no. of music into HL
1,253,127 LD BC,32765 ; Bank switching
86 LD D,(HL)
237,81 OUT (C),D
205,6,192 CALL 49158 ; Call music (49152+6)
33,92,91 LD HL,23388 ; Load old bank no. into HL
1,253,127 LD BC,32765 ; Bank switching
86 LD D,(HL)
237,81 OUT (C),D
201 RET ; Return from routine
Actually, the instruction OUT (C),D should read differently: OUT (BC),D, but such an instruction does not exist; the existing instruction used here does exactly what it is supposed to do, though: value D is not written to address C, but to BC!
Simple, isn't it? Naturally, this is not the optimum, but rather the most comprehensible form, and one should also take care when switching to other banks, but I think this short article has shown that even as an MC newcomer you can definitely program interesting things. Besides, you now know how to switch banks in assembler.
A demo of the whole thing including all routines (PD) can be found in the "SONSTIGES" section under the name "MUSIC-I". So much for this topic, have fun!
Since all of this is used in USR 0 mode, +3 users cannot use their disk drives (but certainly +D or MB02), but the +3 is not the optimum anyway when it comes to construction and sound output.
L. C. D./Tiger's Claw
I am waiting for your pr
Share your thoughts about the article