CODING ★ AS SCIER TOI... ★

Assembleur ACPC n°26
Pour suivre les contes extraordinaires des octets de la planète Z-80, sur laquelle les guerriers de la galaxie Maquettus ont vérole le listing du mois dernier. La guerre est déclarée, mais restant les bons dans ces histoires, on vous le redonne dans son intégralité sans censure.

Il nous reste à voir ensemble les quelques derniers petits sous-programmes de notre jeu, pour boucler la boucle du serpent. Je suppose qu'impatient comme vous l'êtes vous avez déjà saisi notre programme du mois d'avril et que vous y avez joué au moins pendant un quart d'heure. Pas trop mal comme support à une initiation, non ? Nous allons voir de très près les sous-programmes : TEST qui vérifie l'existence d'une collision, MODIF qui change la direction du serpent en fonction des touches enfoncées par le joueur, VITE qui accélère le jeu pour le rendre injouable et enfin SCORE qui porte bien son nom.

UN PETIT COUP A GAUCHE

Un petit coup à droite. Dans le sous-programme MODIF, on calcule le nouvel emplacement de la tète du serpent Avant de me lancer dans de longs discours, je dois vous signaler un léger détail à propos du mode de chargement d'un double registre par une case mémoire.

Il n'y a aucune confusion quand on dit LD A,(POPO). Dans l'ACCU, on trouve après cette instruction la valeur de la case mémoire POPO. Par contre, LD HL,(POPO) est un peu différent. Après cette instruction, H sera égal à la valeur de la case mémoire POPO+1 et L sera égal à la valeur de la case mémoire POPO. H suffit de le savoir et de se le rappeler. De même, LD (POPO),HL aura comme effet de charger dans la case mémoire POPO la valeur de L et dans POPO+1 la valeur de H. Tout ça pour vous dire que, dans notre programme, la valeur de la position en Y est dans la case (XY) et la valeur correspondant à la position en X est stockée dans la case (XY+1). Dans nos opérations également, H sera chargé avec la position en X, quant à L, il pointe sur Y comprendo ?

Revenons à MODIF. On charge les coordonnées de la tête dans HL (donc H=X et L=Y), on charge dans l'ACCU la valeur de la touche enfoncée lors de l'appel de la sous-routine du clavier. Il ne reste plus qu'à comparer bêtement cette valeur et de modifier les coordonnées en conséquence. Le code ASCII 240 représente la flèche vers le haut CP 240 revient à dire : "compare l'accumulateur avec la valeur 240." S'il y a égalité, le Flag Z est mis à 1 et on peut brancher une adresse avec un saut conditionnel du type JR Z,ADRESSE (pour s'en souvenir, penser saute si 0, ou RET si 0, etc.). L'inverse est bien sûr vrai : JR NZADRESSE (saute si non 0 ou si tout bêtement la comparaison rend une valeur non nulle ou encore si le Flag Z n'est pas mis). Ne vous découragez surtout pas, on verra tout cela plus tard et croyez-moi, c'est d'une facilité enfantine (quand on l'a compris).

Je disais donc, si le mec appuie sur la touche flèche haut, on décrémente la valeur L (qui est, je le rappelle, la position en Y). Pour la valeur 241, on incrémente L, pour 242 on décrémente H (la position en X), quant à la valeur 243, on incrémente H. Une fois la modification effectuée, on stocke dans XY la nouvelle position de la tête de notre serpent. Vous remarquez qu'après chaque comparaison, il est inutile de lire la suite et on se branche directement à l'adresse MODI4.

AIE, AIE, AIE, PAS LA TETE

Nous avons le nouvel emplacement de notre tête. H suffit de savoir maintenant si cette tête touche un mur ou se mord le corps. Pour cela on utilise le sous-programme TEST. On charge les coordonnées dans HL. Le BB75 place le curseur à cet emplacement. L'appel du père BB60 lit le caractère sur l'écran et le place dans l'ACCU (c'est l'équivalent Basic de l'instruction TEST). Dans notre programme, il ne peut y avoir de lézard, mais imaginez cet appel avec un écran rempli n'importe comment (un dessin par exemple), le système ne reconnaîtrait pas de caractère et renverrait dans l'ACCU la valeur zéro, et la CARRY serait mise (d'où la possibilité de branchement du genre JR,NC ADRESSE ou RET C). On compare le caractère lu à l'écran avec 32, qui est le code ASCII d'un espace. S'il s'agit d'un espace, on sort du sous-programme par l'instruction RET Z. Dans le cas contraire, on a affaire à un autre caractère qui peut être une brique du mur ou le corps du serpent Dans les deux cas, le joueur a perdu et il faut revenir au Basic. Je dois vous donner quelques renseignements sur la pile et les instructions CALL et RET.

La pile est tout simplement une adresse mémoire dans laquelle des valeurs sont stockées par le microprocesseur. Lors de l'appel d'un CALL, l'adresse est stockée sur la pile et le programme exécute un saut (JP) à l'adresse indiquée après le CALL. Le programme exécute ce qu'il rencontre et à la vue d'un RET, refit la pile et ressaute à la même adresse incrémentée de trois.

1 POPO CALL DEDE
2 TOTO-
3
4
5
6 DEDE -
7
8
9 RET

Pour mieux comprendre, en ligne 1, il y a, disons, n'importe quoi sur la pile.

Le programme dit : tiens, un CALL ! Je place l'adresse de son appel sur la pile (donc il y a sur la pile POPO) et je vais faire un tour du côté de DEDE. On fait sa petite promenade en passant par les lignes 6, 7 et 8 et, d'un coup, le programme se dit ô quelle joie de rencontrer un RET, je m'empresse de lire la pile. "Allô, allô, ici la terre, vous me recevez ?" Je lis sur la pile POPO. Trois octets plus loin, c'est TOTO, j'y cours. Et le voilà en ligne 2 et je suis son parcours. Dans notre exemple, il y avait un appel par un CALL, mais vous pouvez faire plusieurs appels, ils seront tous stockes à la queue leu leu sur la pile. On peut, à l'aide de la pile, sauvegarder des doubles registres comme HL, BC, DE ou AF et les autres IX et IY par l'instruction PUSH. Leur valeur sera bêtement mise sur la pile. De même, on peut les relire par l'instruction POP qui lit le contenu du haut de ia pile. Imaginez, HL-12345, DE=555 suivi de PUSH HL et POP DE. A votre avis, DE sera égal à quoi ? Tout simplement à 12345, tout comme HL.

Cela étant, si le caractère lu à l'écran n'est pas un espace, on retire la valeur stockée en haut de la pile par un registre quelconque (en l'occurrence IY), ce qui a pour effet d'annuler l'appel du CALL TEST placé dans la boucle principale du jeu. A la vue du RET, la valeur suivante de la pile sera lue, et devinez quoi, c'est l'adresse du retour au Basic sauvée après le CALL 40000, fait à partir de ce même Basic pour entrer en jeu (astucieux, non ?).

PLUS VITE, PLUS VITE

Le sous-programme VITE doit accélérer le jeu. Souvenez-vous, dans la partie consacrée au clavier, on testait 256 fois le clavier, ce qui prenait un certain temps. Pour cela, on plaçait dans le registre B la valeur 0. Ici, on lit cette valeur qui est stockée à l'adresse INKEY+1, on la diminue de 1 et, si elle est différente de 0, on la remplace. Le RET Z s'occupe de ne pas remplacer un 0 ce qui ralentirait le programme après l'avoir accéléré 256 fois (mais, par expérience, j'ai remarqué qu'il était impossible de résister longtemps à l'accélération du jeu). Pour lire le score du joueur, on aurait pu le faire en lisant la case mémoire (INKEY+1), mais pour la forme, j'ai écrit un petit compteur, histoire de vous montrer son fonctionnement Voilà, on dit au revoir à notre petit serpent et, pour finir, je vous touche deux mots sur les débordements qui, d'après votre courrier, ne paraissent pas si évidents à comprendre, imaginez des valeurs décimales (1, 23, 56, etc.), 8+1 égale 9. 9+1 égale 10, 78+1 égale 79, et 99+1 égale 100. Si on prenait comme convention que récriture de ces nombres ne pouvait se faire qu'avec deux chiffres, pour les 9, 10,79 on aurait aucun problèmes, mais pour 100, on serait obligé de tronquer le 1 et on trouverait la valeur 00 ou, pour 98+7 égale 105, on trouverait 05. C'est exactement ce qui se passe avec les registres. On ne peut écrire dans un registre simple que 8 bits et dans les doubles, 16. La valeur maximale que peut prendre un registre simple est 255 (pour un double comptez &FFFF ou 65535). Au-delà de ces valeurs, on refait le tour en commençant à 0. C'est ce que l'on appelle un débordement. Par contre, si une opération quelconque était la cause d'un débordement, le Flag C (CARRY) serait mis à 1 pour le signaler au programmeur qui peut à ce moment décider de faire ce que bon lui semble. Pour illustrer les pourquoi du comment des débordements, je vous donne la méthode pour additionner l'ACCU à un double registre. Ça peut toujours servir.

ADD A,L
LD L,A
LD A,H
ADC A,0
LD H,A

On additionne à l'ACCU le contenu de L, puis on replace dans L cette valeur. Si on était sûr que le résultat de cette addition ne dépasserait pas 255, on pourrait arrêter le tout, mais dans le cas d'un débordement, le résultat serait faussé. Pour cela, on additionne la CARRY au registre H (donc éventuellement H=H+1), car l'instruction ADC additionne les deux paramètres et la CARRY

Sur ce, je vais me faire, une partie d'lndy et, le mois prochain, je .vous prépare une suite de petites routines permettant des calculs de type mathématique, comme des multiplications et autres petits prog. toujours utiles à connaître.

Zéde, qui remercie le serpent , A100% n°26

Page précédente : Assembleur ACPC n°25
★ AMSTRAD CPC ★ DOWNLOAD ★

Other platform tool:
» asm26DATE: 2012-08-27
DL: 122
TYPE: image
SiZE: 174Ko
NOTE: w367*h1893

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Assembleur ACPC n°23 - Il cours, il cours l'assembleur
» Coding » Bidouilles ACPC n°44 - Les vecteurs system (2/6)
» Coding » Assembleur ACPC n°34
» Coding » Assembleur ACPC n°10 - Initiation : Les decalages
» Coding » Assembleur ACPC n°21 - CRTC + astuces
» Coding » Assembleur ACPC n°16: Organisation des pixels à l'écran
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 569 millisecondes et consultée 1707 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.