I like to move it (move it) !

Yes, but using a joystick !

Bien ! Commençons par le plus simple : le déplacement vertical. En tirant le levier vers le bas, nous allons lever le nez de notre avion virtuel, donc faire descendre l’horizon, et inversement vers le haut.

Le registre SWCHA est composé de 8 bits représentant les 4 directions du joystick 1 et 2. Des bits 7 à 0, droite-gauche-bas-haut joystick 1, puis la même chose pour le joystick 2. Au « repos », les bits sont à 1 (tut tut, pas de mauvais esprit s’il vous plait 😉 ) et passent à 0 lorsqu’une direction est donnée.

De façon assez étonnante, les ports joysticks peuvent être utilisés comme entrée ou comme sortie. Afin que SWCHA représente une entrée d’information provenant des joysticks, il faut préalablement avoir mis à 0 les bits correspondants du registre SWACNT.

La position de l’horizon devenant variable, nous allons utiliser notre première case mémoire. La vaste ram à notre disposition (oui, 128 octets !) couvre les adresses $80 à $FF. Utilisons une constante pour plus de clarté :

YPosition = $80

Initialisons SWACNT ainsi que la position de départ de l’horizon :

   lda #%00000000
   sta SWACNT
   lda #95
   sta YPosition

Et dans l’espace « logique du programme », le test des joysticks afin de déplacer l’horizon en conséquence :

   ; test du joystick 1
;TestHaut   
   lda #%00010000    ; haut
   bit SWCHA
   bne TestBas
   
   lda YPosition
   cmp #5  ; on laisse au moins 5 lignes de ciel
   beq TestBas
   dec YPosition  ; l'horizon monte

TestBas
   lda #%00100000    ; bas
   bit SWCHA 
   bne FinTest
   
   lda YPosition
   cmp #192-5-5 ; 5 de prairie minimale, et 5 de montagne
   beq FinTest
   inc YPosition  ; l'horizon descend

FinTest    

(N’oublions pas les 5 lignes de montagne, sinon on s’expose à de jolis clignotements !)

Enfin, la logique d’affichage doit maintenant tenir compte de notre position variable :

   LDY #1
   
Ciel              ; lignes de ciel
   STA WSYNC   
   lda #$82
   sta COLUBK
   lda #0
   sta PF0
   sta PF1
   sta PF2
   iny
   cpy YPosition
   bne Ciel

   ldx #0
Montagne             ; 5 lignes de montagne
   sta WSYNC
   lda ColHoriz,x
   sta COLUBK
   LDA Horiz0,x
   sta PF0
   LDA Horiz1,x
   sta PF1
   LDA Horiz2,x   
   sta PF2 
   inx
   iny
   cpx #5
   BNE Montagne
    
   ; lignes de prairie        
Prairie     
   sta WSYNC
   lda #$c0
   sta COLUBK
   lda #0
   sta PF0
   sta PF1
   sta PF2
   iny
   cpy #192
   BNE Prairie
   ; ---------- Kernel terminé --------------------------------

Passons maintenant au mouvement horizontal. La direction gauche fera défiler les montagnes vers la droite, et inversement, de façon circulaire.
Pour ce faire, le « dessin » des montagnes doit être copié en ram car nous allons lui appliquer des opérations de décalage de bits selon la direction.

Déclaration des variables :

PF0_Data = $81  ; et $82 $83 $84 $85
PF1_Data = $86  ; et $87 $88 $89 $8A
PF2_Data = $8B  ; et $8C $8D $8E $8F

Et copie des données en ram dans les initialisations au démarrage :

   ldx #0
CopyData   
   lda Horiz0,x
   sta PF0_Data,x
   lda Horiz1,x
   sta PF1_Data,x
   lda Horiz2,x
   sta PF2_Data,x
   inx
   cpx #5
   bne CopyData

Reste à adapter notre logique d’affichage de façon à utiliser les données en ram, au lieu de celles en dur. Cela se fait simplement en remplaçant les références à Horiz0, Horiz1 et Horiz2 par PF0_Data, PF1_Data et PF2_Data.

La complexité du déplacement du playfield vers la gauche ou la droite réside, d’une part dans le fait que PF0 et PF2 sont inversés, d’autre part dans le fait que seuls les bits 7 à 4 du PF0 sont utilisés.

Voyons tout d’abord le déplacement des montagnes vers la gauche.
Puisque PF2 est inversé, il faut le décaler vers la droite par l’instruction LSR. Celle-ci insère un zéro à gauche (en bit 7), et le bit 0 qui tombe est récupéré dans le flag Carry (C). Ensuite, nous décalons PF1 vers la gauche avec l’instruction ROL. Celle-ci insère à droite (bit 0) le carry et récupère le bit 7 qui tombe dans carry. Enfin, PF0 inversé, vous avez compris, nous le décalons vers la droite (ROR), avec carry inséré à gauche (bit 7). Sauf que ! Vu que seuls les bits 7 à 4 sont utiles, en se décalant, le bit 0 qui tombe ne nous intéresse pas, nous devons tester la valeur du bit 3 afin d’éventuellement positionner le bit 7 de PF2.

   ; Déplacer les montagnes vers la gauche
   ldx #0
ScrollLeft
   lsr PF2_Data,x ; PF2 "inversé" -> décale à droite, insertion d'un zéro
                  ;                qui sera éventuellement modifié + bas
                  ; Le bit qui tombe va en Carry (C)
   rol PF1_Data,x ; décale à gauche, en insérant C 
   ror PF0_Data,x ; PF0 "inversé" -> décale à droite, insertion de C
   lda PF0_Data,x ; Seuls les 4 bits de gauche servent au playfield,
   and #%00001000 ; nous testons la valeur du bit 3
   beq SuiteLeft  ; si A = 0, c'est que le bit 3 était à 0 -> rien à faire
                  ; sinon le bit 7 du PF2 est mis à 1
   lda PF2_Data,x
   ora #%10000000   
   sta PF2_Data,x
SuiteLeft   
   inx
   cpx #5
   bne ScrollLeft

Principe similaire pour le déplacement des montagnes vers la droite. La particularité concerne le bit 7 de PF2 qui tombe dans carry après décalage (ROL), et qui doit positionner le bit 4 de PF0.

   ; Déplacer les montagnes vers la droite
   ldx #0
ScrollRight
   lda PF0_Data,x ; Seuls les 4 bits de gauche servent au playfield,
   and #%11110000 ; on annule les bits inutilisés avant le décalage
   asl            ; PF0 inversé -> décalage gauche
                  ; Le bit qui tombe va en Carry (C)
   sta PF0_Data,x 
   ror PF1_Data,x ; décale à droite, en insérant C 
   rol PF2_Data,x ; PF2 "inversé" -> décale à gauche, en insérant C 
   bcc SuiteRight ; Si C <> 0
   lda PF0_Data,x ; on l'insère dans le bit 4 de PF0
   ora #%00010000   
   sta PF0_Data,x
SuiteRight   
   inx
   cpx #5
   bne ScrollRight

Cet exercice nous a fait mettre en pratique

  • SWCHA
  • SWACNT

Vous pouvez télécharger ce fichier source prêt à compiler ici : http://dl.dropbox.com/u/56947388/Cambouis/test_joy.asm
(click-droit/enregistrer la cible sous)

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :