Jouer un soundtrack avec Arkos Tracker

Dans notre série ‘et si on faisait un jeu musical’, nous allons commencer par apprendre a jouer de la musique sur CPC. Ou plus précisément jouer un soundtrack, en l’occurence créé avec Arkos Tracker. Je ne fais que reprendre les explications livrées avec ce tracker, toujours en utilisant RASM comme assembleur. Le but c’est qu’a la fin de ce billet, nous ayons un squelette d’application pour aborder la suite.

Export binaire d’un fichier aks

La première chose a faire, c’est d’exporter un fichier Arkos Tracker en fichier binaire, qui sera lisible par le player fourni avec arkos tracker. Ici c’est Arkos Tracker 1 qui est utilisé pour l’export.

Pour cela, on a besoin de connaitre l’adresse ou l’on souhaite charger la musique dans la mémoire de l’Amstrad. Soyons généreux, attribuons le bloc #4000-#7FFF. Le player sera logé en #8000, notre programme en #a000.

  • Adresse du player 0x8000
  • Adresse de la track 0x4000
  • Adresse du programme 0xA000 (point d'entrée)

Dans Arkos Tracker, apres avoir ouvert le fichier que l’on souhaite exporter, dans le menu export, choisir ‘exporter en binaire’, et indiquer 4000 comme addresse.

Application minimale

Le « squelette » de notre application est  le suivant:

MUSIC_ADDRESS       EQU #4000
PLAYER_ADDRESS      EQU #8000
PROGRAM_ADDRESS     EQU #A000

include "toolbox.asm"

ORG PROGRAM_ADDRESS

    DISABLE_INT (INTER+1)   ; Desactive vecteur IT
    PUSH_MIRROR_REGS        ; Sauve les registres miroirs

MAIN:
    LD DE,MUSIC_ADDRESS     ; Initialise musique
    CALL PLAYER_ADDRESS
MAINLOOP:
    WAITSYNC                ; Attentre trame vidéo 
    DI          
    GETKBSTATE KBSTATE      ; Recupere etat clavier
    EI  
    CALL PLAYER_ADDRESS + 3 ; Joue le soundtrack    
ENDLOOP:    
    LD  A,(KBSTATE+5)       ; Touche ESPACE?
    BIT 7,A
    JP  NZ,MAINLOOP         ; Nouvelle boucle

EXIT:
    POP_MIRROR_REGS         ; Rétablit les registres miroirs
INTER:  
    LD  HL,0                ; Retablit les ITs d'origine 
    LD  (#38),HL    
    CALL BIOS_RESET_AUDIO   ; Silence
    RET                     ; Retour au basic

KBSTATE: ds 10              ; Etat du clavier

ORG PLAYER_ADDRESS
    READ "arkos/arkostrackerplayer_cpc_msx.asm"
    ;READ "arkos/arkostrackerplayer_cpcstable_msx.asm"

ORG MUSIC_ADDRESS
    INCBIN "SONG8000.BIN"

Il manque la définition de quelques macros (Attente synchro écran, récupération état du clavier…), nous allons mettre tout cela dans un fichier à part, toolbox.asm. D’abord quelques définitions, les registres du PPI en particulier:

; Registres PPI8255
PPI_PortA_H EQU #F4 ; RW
PPI_PortB_H EQU #F5 ; RO
PPI_PortC_H EQU #F6 ; WO
PPI_CTRL_H  EQU #F7 ; Registre de controle. WO

PPI_PortA   EQU #F400
PPI_PortB   EQU #F500
PPI_PortC   EQU #F600
PPI_CTRL    EQU #F700

;Routines de la ROM 
BIOS_RESET_AUDIO    EQU #BCA7

Ensuite une macro pour désactiver proprement les interruptions:

;Désactive les interruptions, et prépare leur restauration
MACRO DISABLE_INT store
    DI 
    LD      HL,(#38) 
    LD      ({store}),HL 
    LD      HL,#c9fb    ; EI + RET
    LD      (#38),HL 
    EI 
MEND

Il est toujours de bon ton de restaurer les registres miroirs en quittant notre application:

; Sauvegarde des registres  AF',BC,DE' et HL'
MACRO PUSH_MIRROR_REGS
    DI
    EXX
    PUSH HL
    PUSH BC
    PUSH DE
    EXX
    EX AF,AF'
    PUSH AF
    EX AF,AF'
    EI
MEND

; Restauration des registres  AF',BC,DE' et HL'
MACRO POP_MIRROR_REGS
    DI
    EX AF,AF'
    POP AF
    EX AF,AF'   
    EXX
    POP DE
    POP BC
    POP HL
    EXX
    EI
MEND

L’attente de synchro écran se fait par la lecture d’un bit du PPI:

; Attente synchro ecran
MACRO WAITSYNC 
    LD      b,PPI_PortB_H
@SYNC:
    IN      a,(C) 
    RRA 
    JP      nc,@SYNC 
MEND

Enfin, le plus complexe, la lecture de l’état du clavier, ici on récupére l’état complet. Cela nous sert pour le moment a  quitter l’application, mais a terme, d’autres touches seront utilisables.

;Récupere l'état des touches du clavier et joystick
MACRO GETKBSTATE DEST   
    LD      BC,PPI_PORTA |#0E   ; Selection registre 14 du PSG
    OUT     (C),C 
    LD      BC,PPI_PORTC |#C0  
    OUT     (C),C       
    XOR     A 
    OUT     (C),A   

    LD      BC,PPI_CTRL |#92 
    LD      HL,{DEST}
    OUT     (C),C       
    LD      C,#40
    LD      D,10
@KBGETLINE
    LD      B,PPI_PORTC_H      ; Selectionne ligne de clavier
    OUT     (C),C 
    LD      B,PPI_PORTA_H 
    IN      A,(C) 
    LD      (HL),A
    INC     HL      
    INC     C                  ; Ligne suivante
    DEC     D                  
    JR      NZ, @KBGETLINE  
    
    LD      BC,PPI_CTRL |#82   ;On a fini de manipuler
    OUT     (C),C              ; le PSG
    LD      BC,PPI_PORTC
    OUT     (C),C       
MEND

Il reste maintenant à compiler le tout, charger le binaire en mémoire, et exécuter avec CALL &A000. La musique devrait se jouer, et l’application quitter en pressant la barre espace.

Références

Formats Audio pour CPC: https://cpcrulez.fr/coding_amslive15-YM.htm

Arkos Tracker: http://www.julien-nevo.com/arkostracker/