Contexte matériel

Le jeu étudié tourne sur un ordinateur des années 1980 équipé d’un processeur Motorola 6809. L’affichage utilise un écran de 320 × 240 pixels avec 16 couleurs, soit 4 bits par pixel. En mémoire, chaque ligne d’écran occupe 160 octets (320 pixels ÷ 2). Les décors sont composés de tuiles de 28 × 28 pixels. Chaque pixel étant codé sur 4 bits, une rangée de tuile occupe 14 octets (28 pixels ÷ 2). Ainsi, copier une tuile nécessite de transférer 28 lignes de 14 octets chacune vers le tampon vidéo.

Mécanisme de copie de tuiles

Le code original exploite les registres d’indexation du 6809 et le mode d’adressage auto‑incrémenté (,X++ et ,Y++) pour lire et écrire des mots de 16 bits (4 pixels) en une instruction. La boucle interne copie un mot, incrémente les pointeurs, décrémente un compteur et boucle tant que le compteur n’est pas nul. Le pseudo‑code suivant illustre le processus :

LDB #7       ; 7 mots = 28 octets de largeur
@LOOP
    LDU ,X++     ; lire 2 octets (4 pixels)
    STU ,Y++     ; écrire dans le tampon
    DECB         ; décrémenter le compteur
    BNE @LOOP    ; répéter

Après chaque ligne, le pointeur destination Y est avancé de WOFF = SCRW - TILW = 160‑14 = 146 octets pour atteindre le début de la prochaine rangée. Cette logique est encapsulée dans la sous‑routine COPYTILE présentée plus bas.

Optimisation par déroulement de boucle

Le calcul des cycles montre que chaque itération de la boucle interne consomme 21 cycles (8 + 8 + 2 + 3). Copier une rangée complète (7 itérations) coûte alors 157 cycles, ce qui ralentit fortement le rendu d’un jeu à défilement horizontal. La solution classique consiste à dérouler la boucle, c’est‑à‑dire répéter explicitement les instructions de copie au lieu de les itérer. Le code déroulé supprime les instructions de contrôle de boucle (DECB et BNE) et ne conserve que les paires LDU/STU, réduisant le coût par mot à 16 cycles au lieu de 21.

LDU ,X++
STU ,Y++
LDU ,X++
STU ,Y++
LDU ,X++
STU ,Y++
LDU ,X++
STU ,Y++
LDU ,X++
STU ,Y++
LDU ,X++
STU ,Y++
LDU ,X++
STU ,Y++

En multipliant cette séquence pour les 7 mots d’une rangée, le nombre de cycles chute à environ 112 cycles par rangée, soit une amélioration de près de 30 %.

Analyse des performances et limites

Le gain obtenu par le déroulement provient de la réduction du nombre d’instructions de branchement, qui sont coûteuses sur le 6809. Cependant, le code devient plus volumineux : chaque ligne passe de 4 octets d’instructions à 28 octets. Sur des systèmes où la mémoire est critique, ce compromis doit être évalué. De plus, le déroulement ne résout pas le facteur de bande passante mémoire ; le processeur reste limité par la vitesse à laquelle il peut lire et écrire les octets du tampon vidéo. Enfin, l’optimisation repose sur des hypothèses précises (taille de tuile fixe, profondeur de couleur 4 bits) ; tout changement de ces paramètres nécessiterait une ré‑évaluation du calcul de WOFF et du nombre d’itérations.

En résumé, le hack décrit montre comment, même sur du matériel « presque impossible » selon les standards modernes, une analyse fine des cycles d’instructions et le recours au déroulement de boucle permettent de récupérer plusieurs dizaines de millisecondes par image, rendant un side‑scroller jouable sur un 6809.