10-8 Gestion du chronomètre
10-8-1 Incrément du
compteur
Comme je l’ai dit plus haut, le chronomètre et les scores sont gérés en BCD (Binaire Codé Décimal). Ainsi « 59 min 59 sec 99 centièmes » sera codé &59,&59,&99 en héxadécimal. C’est la synchronisation sur la VBL qui fait que le programme reboucle tous les 50èmes de seconde. On profite donc de cette base de temps pour incrémenter notre chronomètre tous les 2 centièmes de seconde. C’est bien suffisant pour donner la vision d’un défilement de chiffres ultra-rapide. Mais ici on se contente d’incrémenter le compteur juste avant la VBL. L’affichage se fait après.
Le Z80 possède une unique instruction pour gérer les nombres BCD : DAA (Decimal Adjustment of the Accumulator), en gros ajustement décimal du registre A. Le problème est que cet ajustement ne peut se faire qu’après une addition ou soustraction sur le registre A (même pas un incrément ou décrément). Pour les centièmes, on ajoute donc 2 (Deux 100èmes = un 50ème) et pour les secondes et minutes, on ajoute 1. l’ajustement décimal de &98 + 2 = &9A entraine la mise à 0 de A et la mise à 1 de la retenue C. C’est comme ça que l’on sait si l’on doit incrémenter les secondes après ça. Ensuite, on se base sur une comparaison avec 60 pour savoir si on passe aux minutes. Dans le cas où le joueur se serait endormi sur son clavier et aurait laissé passer 1 heure, la partie s’arrête automatiquement. Quand tous les chiffres nécessaires ont été incrémentés, on saute à VBL pour l’attente de synchro verticale.
Enfin, on n’incrémente le compteur que si la variable CHRONO est différente de 0. Celle-ci est remise à 0 à l’initialisation de la course, et mise à 1 quand une touche reconnue est appuyée.
COURSE2 LD A,(CHRONO)
; A = flag du chronomètre
OR A
; chrono actif?
JP Z,VBL
; Non => VBL
LD HL,TEMPS+2
; HL pointe le chrono pour indexage rapide
LD A,(HL)
; Analyse des centièmes
ADD 2
; + 1/50ème = + 2/100èmes
DAA ;
Ajustement BCD (&98 + 2 = &00 + Carry à 1)
LD (HL),A
; sauvegarde des centièmes
JR NC,VBL ; Pas
de retenue? => VBL
DEC HL
LD A,(HL) ;
Analyse des secondes
ADD 1
; + 1 seconde (INC ne marche pas avec DAA)
DAA ;
Ajustement BCD
LD (HL),A ;
mémorisation des secondes
CP &60 ; 60 secondes?
JR NZ,VBL ; Non
=> VBL
XOR A
LD (HL),A ; Remise à 0 des secondes
DEC HL
LD A,(HL) ;
Analyse des minutes
ADD 1
; + 1 minute (INC ne marche pas avec DAA)
DAA ;
Ajustement BCD
LD (HL),A ;
mémorisation des minutes
CP &60 ; 60 minutes?
JP Z,PERDU ; Oui
=> perdu! (faut pas éxagérer non plus)
10-8-2 Affichage du
compteur
Le compteur est affiché après la
voiture et il n’y a pas de condition à cela, il est donc rafraîchit tout le
temps. Le principe est le même que pour l’initialisation des scores dans l’image
d’intro. On isole les unités par masquage ET &0F et les dizaines par 4 décalages
à droite SRL. Les chiffres sont également affichés avec le sous-programme AFFICHE avec pointage écran par HL. La seule chose
qui diffère, c’est que cette fois on n’affiche pas tout. On commence par les
centièmes, mais on ne continue que s’ils sont à 0 (indiquant un passage au chiffre
supérieur), et ainsi de suite. Quand l’affichage est terminé, le programme
saute à la gestion des crashes de voiture.
LD BC,TEMPS+2 ; BC
pointe le chrono pour indexage rapide
LD A,(BC)
AND &0F ; A
= centièmes
LD HL,&C420 ; HL =
ligne 104 + segment 16 (centièmes)
CALL AFFICHE ;
Affichage des centièmes
OR A
; A = 0?
JP NZ,CRASH
; non => CRASH
LD A,(BC)
SRL A
SRL A
SRL A
SRL A
; A = dixièmes de secondes
LD HL,&C41E ; HL =
ligne 104 + segment 14 (dixièmes)
CALL AFFICHE ;
Affichage des dixièmes
OR A
; A = 0?
JP NZ,CRASH
;
non => CRASH
DEC BC
LD A,(BC)
AND &0F ; A
= unités de secondes
LD HL,&C41A ; HL =
ligne 104 + segment 10 (secondes)
CALL AFFICHE ;
Affichage des unités de secondes
OR A
; A = 0?
JP NZ,CRASH
; non => CRASH
LD A,(BC)
SRL A
SRL A
SRL A
SRL A
; A = dizaines de secondes
LD HL,&C418 ; HL = ligne
104 + segment 8 (dizaines de secondes)
CALL AFFICHE ;
Affichage des dizaines
OR A
; A = 0?
JR NZ,CRASH
; non => CRASH
DEC BC
LD A,(BC)
AND &0F ; A = unités de minutes
LD HL,&C414 ; HL =
ligne 104 + segment 4 (minutes)
CALL AFFICHE ;
Affichage des unités de minutes
OR A
; A = 0?
JR NZ,CRASH
; non => CRASH
LD A,(BC)
SRL A
SRL A
SRL A
SRL A
; A = dizaines de minutes
LD HL,&C412 ; HL =
ligne 104 + segment 2 (dizaines de minutes)
CALL AFFICHE ; Affichage des dizaines