Revenir au plan du site
Les rudiments d'assembleur à connaitre avant de démarrer
Stocker ses compteurs ou ses données dans le code
La méthode classique ou académique veut qu'on utilise une variable, située en général à la fin du programme.
ld hl,(pointeurEcran) : inc hl : ld (pointeurEcran),hl
...
pointeurEcran defw #C000
|
Il est possible d'utiliser le code lui même pour stocker la valeur. On ira chercher la donnée dans l'opcode. Concernant les instructions
LD registre,valeur, la valeur est toujours
située à la fin de l'opcode, qu'elle soit 8 bits ou 16 bits. On peut donc définir un pointeur dessus.
ld hl,#C000 : pointeurEcran=$-2 : inc hl : ld (pointeurEcran),hl
|
Cette technique est régulièrement utilisée pour des compteurs de boucle car le comptage se fait 'sur place' et ça évite de chercher où est stockée la variable. En général il y a une initialisation
avant la boucle et ensuite, roule ma poule!
ld a,30 : ld (compteurFin),a
MaBoucle
...
ld a,#12 : compteurFin=$-1 : dec a : ld (compteurFin),a : jr nz,MaBoucle
|
Bien entendu, vous ne faites ceci que quand vous avez utilisé tous les registres à disposition...
Couper le système temporairement
Le souci du système, c'est qu'il passe son temps à toucher à plein de choses sans qu'on lui demande. Par exemple, bien que les couleurs ne changent pas, il passe son temps à les remettre! Ce n'est pas gênant
pour l'intégralité des programmes présents ici, vu que l'idée est de s'en passer pour toujours, mais si on veut réaliser une petite intro qui lance un programme qui a besoin du système, une désactivation
temporaire peut être utile.
di ; couper les interruptions au cas où
ld hl,(#38) ; prendre les 2 octets à l'adresse du saut d'interruption
ld (restaurationSysteme),hl ; les mettre dans le code de restauration
ld hl,#C9FB : ld (#38),hl ; les opcodes EI:RET inversés (accès 16 bits)
ei
...le programme...
ld hl,#1234 : restaurationSysteme=$-2
ld (#38),hl
ret
|
Note : Je vous rappelle que le système a besoin d'avoir en permanence les registres AF',BC',DE',HL',IX' et IY'. Si vous voulez vous en servir entre temps, il faudra les sauvegarder et les restituer aussi!
Programme permettant de réutiliser le système ensuite et d'utiliser tous les registres
di ; couper les interruptions au cas où
ld hl,(#38) ; prendre les 2 octets à l'adresse du saut d'interruption
ld (restaurationSysteme),hl ; les mettre dans le code de restauration
ld hl,#C9FB : ld (#38),hl ; les opcodes EI:RET inversés (accès 16 bits)
exa : push af
exx : push bc,de,hl,ix,iy
ld (restaurePile),sp
ei
...le programme qui peut utiliser tous les registres et changer la pile...
di
ld sp,#1234 : restaurePile=$-2
pop iy,ix,hl,de,bc,af : exx : exa
ld hl,#1234 : restaurationSysteme=$-2
ld (#38),hl
ret
|
Note : N'oubliez pas que vouloir revenir au système vous oblige à préserver les zones mémoires utilisées par le système (voir chapitre
[organisation mémoire]).
Dérouler ses boucles
Même si je l'utilise le moins possible dans la plupart des articles, il m'arrive de doubler certaines boucles, c'est plus rapide et ça permet de faire des zig-zags à l'écran, donc de simplifier l'algorithme.
ld a,50
boucleLente
ld (hl),a : inc hl
dec a : jr nz,boucleLente
; temps d'exécution = 2+49x8+7 = 401 nops, je vous passe les détails
ld a,25
boucleRapide
ld (hl),a : inc hl
ld (hl),a : inc hl
dec a : jr nz,boucleRapide
; temps d'exécution = 2+24x12+11 = 301 nops
|
Aligner ses données
L'intérêt majeur d'avoir des tableaux de 256 valeurs ET dont l'adresse de départ se situe sur un multiple de 256 est de pouvoir optimiser la lecture et d'intégrer le rebouclage sans gérer de compteur.
En effet, si on augmente uniquement le poids faible de l'adresse, l'index va repasser tout seul de 255 à zéro. C'est pour cette raison qu'on aligne le début du tableau sur un multiple de 256.
PrendsUneValeur
ld hl,monTableau : valeurCourante=$-2
ld a,(hl) ; lire la valeur
inc l ; incrémenter uniquement le poids faible, H ne change pas
ld (valeurCourante),hl ; enregistrer le pointeur pour un nouvel appel
ret
align 256
monTableau
; blablabla
|
Avec un tableau de mettons, 320 valeurs, il faudrait comparer l'adresse courante avec l'adresse de fin, ou intégrer un compteur allant de 320 à 0, ou encore attendre une valeur de fin (zéro, 255, mais pas utilisée dans les vraies valeurs ce qui n'est pas toujours possible)