Basic (CPC) integration

The players can all be called from assembler or C. However, some of us are still developing games on our good old Basic! Here is a little walkthrough on how to do that.

As a prerequisite, please download Rasm.

The example uses the AKG player, but it will work for all the other ones. Contrary to assembler, Basic requires a few securities, else it will crash, so we need to create a small assembler code to “secure” the calls to the players.

A few steps:

  • Export your music (as source), let’s called it MyMusic.asm. Warning, make sure that the option “encode to address”, at the bottom of each export window, is unchecked (we don’t need to add an ORG to the music source as we directly include it to our own).
  • Copy the PlayerAkg.asm player in the same folder. It is located in the sources/playerAkg folder of the AT2 package.
  • In the same folder, we will create our “secure” asm code. Either copy/paste the sources/playerAkg/testers/Basic_CPC.asm program where your music is, or use the code below. Save it as Basic_CPC.asm.
    ;Basic_CPC.asm    
    org #4000

    jp Init   
    jp Play
    jp StopMusic

Init:
    ld hl,Music     ;Initializes the music.
    ld a,0          ;The subsong number (0 is the first one).
    call Player + 0
    ret

Play:
   di
   ex af,af'
   exx
        push af  ;Saves a few registers the system needs.
        push bc
        push ix
        push iy
        call Player + 3   ;Plays the music.
        pop iy
        pop ix
        pop bc
        pop af
    ex af,af'
    exx

    ei
    ret

StopMusic:
    di
    ex af,af'
    exx
        push af
        push bc
        push ix
        push iy
        call Player + 6      ;Stops the music. 
        pop iy
        pop ix
        pop bc
        pop af
    ex af,af'
    exx

    ei        
    ret

Player:
        include "PlayerAkg.asm"         ;The player. Loads the one you want (AKG, AKM, Lightweight, AKY).

Music:  
        include "MyMusic.asm"    ;The music.

Don’t be scared if you don’t understand assembler! Let’s compile this into binary:

rasm Basic_CPC.asm -o playmus

This will create a playmus.bin file, which contains the “secure” calls to the player, the player itself and the music.

Now load this file into Basic. There are many possibilities to do so:

  • If you’re using Winape, you can inject it directly in memory (in the debugger, right click on the memory and load the file in #4000).
  • Use ManageDsk by Demoniak to create a DSK and adds the file in it (as a binary, in #4000).
  • For automated generation, some better tools exist, I let you search for them.

Load the file in Basic (unless you’ve injected it):

memory &3fff
load"playmus.bin",&4000

Now let’s play!

10 call &4000   'initialize the music.
20 call &bd19:call &4003   'plays one frame of the music, at 50hz.
30 if inkey(47)<>0 then 20  'loops as long as space is not pressed.
40 call &4006   'stops the music.

That’s it!

I chose the &4000 address, but you can change it (change the ORG in the source, as well as all the CALLs in the Basic example, and of course the LOAD address). Don’t forget to set the memory command one byte before, so that the Basic program doesn’t overwrite the binary (memory &1234 if you load the music in &1235 for example). The address should be from &1000 to &9000, don’t go too high! Basic will prevent you from doing so anyway.

Finally, it is possible to use interruptions in Basic to play the music while doing something else. If you need such facilities, please let me know and I’ll create another example.