Débuter en Asm 83

Tutoriaux par Andy S.

    Cliquez pour revenir au menu du site... ou ici pour retourner au menu du tutorial.

------ Tutorial ASM 1 -------

But: Ce que vous devez savoir
Auteur: Andy_S
Traducteur: [ftp83+]
Date de création : 27/09/97
Dernière mise à jour : 22/12/97
Date de traduction: 26/01/2002
Version: 1.1

 

Il y a plusieurs choses que vous devriez connaître ou faire avant de commencer l'assembleur. Premièrement, vous devriz vous procurer les deux fichiers ti83asm.inc et tokens.inc. Ce sont des fichiers include, vous les utiliserez dans presque tous les programmes assembleur que vous écrirez. Après vous les être procurés, jetez un oeil au début de ti83asm.inc histoire de vous faire une idée générale de quelques romcalls. Les romcalls sont des raccourcis vers des routines préprogrammées en ROM, que vous pouvez utiliser. Un autre fichier que vous devriez regarder est la Référence Hardware du Z80 (appellé z89href.txt). Ce fichier vous fait une introduction sur l'utilisation des registres (qui sont des sortes de variables indélébiles) et aux instructions (qui sont les commandes que vous programmez). Il est probable que vous ne compreniez pas de quoi il s'agit pour le moment, mais cela vous aidera plus tard, quand vous apprendrez les différents registres et commandes. Deuxièmement, vous devriez connaître la manière de commencer un programme en assembleur. Tous les programmes de ce type commencent par

 

.NOLIST

#define equ .equ

#define EQU .equ

#define end .end

#include "ti83asm.inc"

#include "tokens.inc"

.LIST

.org 9327h

 

Les defines permettent aux fichiers include de fonctionner, et les fichiers include vous permettent d'utiliser les routines préprogrammées de votre calculatrice. Le .org 9327h indique au programme où commencer son exécution. Tous les programmes pour TI 83 commenceront à cet endroit. À la fin, il faut indiquer

 

.end

 

et si vous obtenez une erreur, essayez de mettre

 

.end

end

 

parce que le compilateur a besoin de savoir où finit le code. La prochaine chose dont vous aurez besoin est un compilateur. Pour PC, vous pouvez télécharger un programme nommé TASM, qui compilera vos programmes. Après avoir compilé un programme, vous devez le mettre au format TI-83, et il existe un chouette programme appellé 83lnk qui fera ça pour vous. (Si vous utilisez un Mac, le compilateur est CAZ, mais j'ai entendu dire qu'il ne fonctionnait pas.)

 

Pour compiler un programme avec TASM, commencez par télécharger le fichier zip et dézippez-le dans un répertoire unique. Ensuite vous voudrez probablement faire un fichier batch pour tout faire marcher. Pour cela, ouvrez une Commande MS-DOS, et allez dans le répertoire dans lequel vous avez rangé TASM. Après ça, tapez "edit asm.bat" (sans guillemets). Vous devriez obtenir un éditeur simple. Rentrez ce fichier:

 

tasm -i -80 %1.asm

 

ensuite enregistrez et fermez le fichier. Pour compiler quelque chose après ça, tout ce que vous avez à faire est de taper (encore une fois sans les guillemets) "asm nom_prog". Assurez-vous que votre fichier a une extension en .asm, mais ne la tapez pas en tant que partie de la commande. Après avoir exécuté ceci, il vous dira s'il y a eu une quelconque erreur de compilation. Si ce n'est pas le cas, exécutez 83lnk en tapant:

 

83lnk xxxxxx.obj xxxxxx.83p XXXXXX

 

où xxxxxx est votre nom de fichier (sans .asm) et XXXXXX est le nom que vous voulez qu'il ait dans la calculatrice (il DOIT être en majuscule, ne l'oubliez pas!). Ensuite envoyez le fichier 83p à votre calculatrice et essayez-le.

Apprenez à utiliser le compilateur en le testant avec un code source complet. Si ça fonctionne, vous êtes prêts à commencer la programmation en assembleur.

 

------ Tutorial ASM 2 -------

But : Tout savoir sur les registres
Auteur: Andy_S
Traducteur: [ftp83+]
Date de création: 23/12/97
Date de traduction: 24/04/02
Version: 1.0

 

Les registres sont utilisés pour stocker des valeurs. Ce sont comme des variables permanentes, parce que vous ne pouvez pas vous en débarrasser, mais en fait ils sont plus que ça. Il y a 8 registres principaux, a, b, c, d, e, f, h, et l. Malheureusement vous ne pouvez pas toujours choisir la lettre que vous aimez le mieux à ce moment et utiliser ce registre (mais parfois vous pouvez!). Des instructions z80 on besoin d'une entrée de certains, et retournent des valeurs dans certains autres.

Le registre "a" est le plus important. Il est aussi appelé l'accumulateur. Lorsque vous utilisez la commande cp (qui fait une comparaison), il vérifie si votre valeur correspond à celle dans l'accumulateur.

 

Les registres b, c, d, e, h, et l sont des registres 8 bits. Cela signifie que chacun peut contenir un octet d'information (qui peut être n'importe quel nombre de 0 à 255). Cependant si vous avez besoin de plus que ça, certains peuvent être combinés pour former des registres 16 bits (de 0 à 65536). Ceux que vous pouvez combiner sont b et c, c et e, et h et l. Lorsque vous els combinez vous obtenez les nouveaux registres nommés bc, de, et hl. Ils peuvent maintenant être lus en tant que valeur unique, ou la valeur de chacun séparément. En d'autres mots, si vous mettez 2 dans b, et 3 dans c, alors bc vaut 515. Pour expliquer pourquoi, vous devez comprendre un minimum à propos du binaire.

 

Le binaire est une manière de noter les nombres en utilisant seulement des 0 et des 1. Pour lire un nombre binaire, vous devez le regarder comme suit:

 

Le nombre que vous essayez de lire: 00100110

 

Imaginez ça dans votre tête: 76543210

 

Maintenant tout ce que vous avez à faire est d'aller (normalement à partir de la droite) et regarder s'il y a un 1 ou un 0 à chaque emplacement. S'il y a un un, élevez 2 à la puissance du nombre que vous imaginez situé en-dessous. Ensuite additionnez toutes ces réponses. Le nombre ci-dessus serait par exemple:

 

2^1 + 2^2 + 2^5 = 2 + 4 + 32 = 38

 

il s'agit donc du nombre 38. Maintenant retournons aux exemples de 2 et 3... Le nombre 2 en binaire est 00000010 et le nombre 3 est 00000011., donc si vous juxtaposez les deux, vous obtenez

 

0000001000000011

 

que vous lisez de la même manière que précédemment, mais allez de 7 à 8 à 9, et ainsi de suite lorsque vous imaginez vos nombres. Si vous faites comme ceci, vous obtenez 515. Mais en les considérant individuellement, ils restent 2 et 3. Les registres 16 bits sont assez adaptés pour retenir les adresses mémoires.

Au lieu de vous montrer une tonne d'exemples que vous ne comprendriez pas encore, à partir de maintenant, je mettrais une remarque si une commande utilise un registre spécifique.

 

------ Tutorial ASM 3 -------

But: afficher du texte sur le homescreen
Auteur: Andy_S
Traducteur: [ftp83+]
Date de création : 26/09/97
Dernière mise à jour : 22/12/97
Date de traduction: 24/04/02

Version: 1.1

 

Ok, alors pour faire afficher du texte à l'écran par un programme... Pour commencer, mettez tous les #includes et #defines que vous devriez connaître avant de lire ceci, et bien sûr

 

.org 9327h

 

Ensuite, vous voudrez probablement vider l'écran de son contenu, pour cela il faut mettre

 

call _clrlcdfull

 

en tant que première ligne de votre programme, à moins que vous *ne vouliez pas* vider l'écran, auquel cas ignorez cette instruction. Remarquez que la ligne avec .org est alignée à gauche, et pas le "call" . Dans le principe, toute ligne commençant par "." ne devrait pas comprendre d'espace devant ce point, et toutes les autres lignes à l'exception des labels (on va les voir dans une minute) devraient avoir un peu d'espace devant elles (une tabulation fonctionne bien).

 

Positionner le texte est la prochaine chose importante à faire. Il s'agit de spécifier où sur l'écran le texte devra aller. Vous avez le choix entre 8 lignes et 16 colonnes. Pour vous embrouiller un peu, les nombres vont de 0 à 7 pour les lignes, et de 0 à 15 pour les colonnes, au lieu de 1 à 8 et de 1 à 16, car la ligne 0 est en fait la véritable ligne 1, et ainsi de suite pour le reste. La calculatrice enregistre la position du curseur dans 21 octets nommés CURROW et CURCOL. Le numéro de ligne va en premier, le numéro de colonne en second. Cependant et heureusement, il sont juxtaposés dans la mémoire, ce qui signifie que vous n'avez qu'à entrer un seul nombre!

 

Par exemple, mettons que vous voulez afficher du texte commençant à la ligne 3 et à la colonne 4. Pour ce faire mettez un 2 (souvenez-vous que vous devez soustraire 1) dans CURROW et un 3 dans CURCOL. Pour faire ceci, vous avez besoin d'utiliser le registre hl. Alors

 

ld hl,0203h

ld (CURROW),hl

 

est la partie suivante de notre programme. Cela indique à la calculatrice de charger la valeur 0203h (le h signifie hexadécimal) dans hl. Ensuite il charge hl dans CURROW. Comme hl peut stocker 2 octets, il met le premier dans CURROW et le second dans l'octet suivant, qui se trouve être CURCOL.

 

Ensuite vous devez spécifier ce que vous voulez afficher. Pour cela, il faut charger l'adresse de votre chaîne de caractères, nous considèrerons pour le moment que cette chaîne est "Str". Remarquez que cette chaîne est seulement *nommée* Str, mais n'est pas elle-même "Str". (Str est en fait un label; nous découvrirons bientôt ce que c'est qu'un label.) Pour charger l'adresse de la chaîne dans hl, vous mettez

 

ld hl,Str

 

comme ligne suivante. Assez facile ? Après ça tout ce que vous avez à faire est de l'afficher. Histoire de vous faciliter la tâche. seulement un "call" est nécessaire pour faire ça.

 

call _puts

 

Pour terminer le programme, vous avez besoin d'une ligne

 

ret

 

indiquant à la calculatrice de retourner en mode normal. La seule chose restante après cela est la chaîne elle-même. Pour mettre celle-ci en place, vous avez besoin d'une ligne comme ceci

 

Str: .db "assembly",0

 

dans votre code. La partie "Str" est un label qui indique que cette chaîne de caractères sera appelée "Str". (Donc voilà ce que c'est qu'un label! N'oubliez pas qu'il n'y a pas d'espace devant.) Le .db signale à la calculatrice que vous allez avoir besoin de place pour une chaîne de caractères. La chaîne est "assembly", mais peut être remplacée par ce que vous voulez. Le ",0" à la fin indique à _puts où arrêter l'affichage. Enfin, souvenez-vous que vous avez besoin de

 

.end

 

en bas du code pour que l'assembleur sache où s'arrêter. Ensuite compilez votre code. C'est fini !

En considérant que vous avez suivi tout ça, votre source complète devrait être :

 

.NOLIST

#define equ .equ

#define EQU .equ

#define end .end

#include "ti83asm.inc"

#include "tokens.inc"

.LIST

.org 9327h

 

call _clrlcdfull ; si vous vouliez un écran vierge

ld hl,0203h

ld (CURROW),hl

ld hl,Str

call _puts

ret

Str: .db "assembly",0

.end

 

------ Tutorial ASM 4 -------

But: comprendre les commandes cp, call, and jp
Auteur: Andy_S
Traducteur: [ftp83+]
Date de création: 26/09/97
Dernière mise à jour: 22/12/97
Date de traduction: 28/04/02
Version: 1.0

 

Peut-être que certains d'entre vous se posent des questions à propos des commandes call et jp, et particulièrement les lettres qui les suivent parfois. Habituellement, ces lettres sont z ou nz. Pour simplifier, z signifie zéro, et n non. Ce que cela signifie est une autre histoire.

 

Si vous avez programmé dans n'importe quel autre langage, vous connaissez probablement les boucles If-Then. Ce qu'une telle boucle indique habituellement est que si une variable est égale (ou différente) d'une certaine valeur, alors "faire quelque chose". Ça a l'air complexe comme ça, mais un exemple simplifiera les choses.

 

if (x = 3) then goto Start

 

Cette ligne (qui n'est pas de l'assembleur, ne la mettez pas dans votre code !) indique: si x est égal à 3, aller à Start.
Si x n'est *pas* égal à 3, alors le programme n'ira pas à Start. L'équivalent assembleur de cette ligne est:

 

ld a,(x)

cp 3

jp z,start

 

qui peut paraître étrange car une seule ligne s'est transformée en trois. Cependant une fois expliqué tout deviendra clair. Tout d'abord, x est chargé dans a (aussi connu comme l'accumulateur). La ligne cp 3 signifie "comparer 3 avec a" (remarquez que cette commande compare toujours avec la valeur présente dans a!), donc elle vérifie si x = 3. Le jp z,start signifie "Si égal à zéro, aller à start". Que vient faire le zéro là-dedans ? Eh bien les comparaisons sont faites par soustraction. Donc, par exemple, mettons que x *est* égal à 3. L'instruction cp fera ensuite (sans changer les valeurs) 3 moins 3. Cela vaut évidemment 0. Si x avait été égal à 4, l'opération effectuée aurait été 4 moins 3, qui n'est pas égal à 0. Donc, pour vérifier que x n'est pas égal à 3, vous pouvez faire

 

ld a,(x)

cp 3

jp nz,start

 

qui signifie "aller à start si non égal à zéro". En d'autres mots, utilisez z si vous voulez "égal à" et nz si vous voulez "non égal à". Les calls marchent de la même manière, donc si vous préférez faire un call plutôt qu'un jump, vous auriez utilisé un "call z", ou un "call nz". Bien sûr, pour faire un call, vous avez besoin d'en savoir plus sur l'usage des labels, et pour charger la valeur d'une variable telle que x, vous devez savoir comment créer des variables. Mais nous verrons cela dans une autre leçon.

 

------ Tutorial ASM 5 -------

 

Sujet: Les entrées getkey
Auteur: Andy_S
Traducteur: [ftp83+]
Date de création: 29/09/97
Dernière mise à jour: 22/12/97
Date de traduction: 12/07/02
Version: 1.1

 

Pratiquement tous les programmes ont besoin d'intervention de l'utilisateur, donc il est nécessaire de savoir comment effectuer ces interventions au moyen du clavier. Il y a trois manière de détecter l'appui sur une touche.

La première méthode utilise le romcall _getkey. Cette méthode attends que l'on appuie sur une touche, et retourne une valeur dans l'accumulateur (qui est a). La valeur retournée est une va l eur hexadécimale.; pour trouver cette valeur, consultez le tableau (CODES DES TOUCHES) de la page de TI (http://www.ti.com/calc/docs/83asmkey.htm) des valeurs retournées lors de l'appui sur la touche. Utilisez _getkey de cette manière :

 

call _getkey

cp 05h

jr z,label

 

où label représente l'endroit où vous voulez que le programme aille si la touche repérée 05h est pressée (le code 05h correspond à la touche Enter), et bien entendu il faudrait en programmer d'autres dans le cas où l'appui aurait été fait sur une touche différente. En utilisant cette routine, la calculatrice attends que l'on appuie sur une touche, donc ce n'est pas pratique si vous avez besoin de répéter une action pendant que la machine attends que l'on appuie sur une touche. Cette méthode serait plutôt utilisée pour faire une pause, quand l'appui sur une touche n'est pas très important.

 

La seconde méthode utilise le romcall _getk. Cette routine n'attends pas que l'on appuie sur une touche, et retourne la valeur dans op2 (op1 et op2 sont des emplacements spéciaux de la mémoire que plusieurs romcalls utilisent comme lieu de stockage pour retourner une valeur) plutôt que dans l'accumulateur. Habituellement, cette routine est utilisée comme ceci

 

keyloop:

call _getk

call _op2toop1

call _convop1

or a

jr z,keyloop

ret

 

La ligne _op2toop1 déplace la valeur obtenue en op1, et la ligne _convop1 place cette valeur dans l'accumulateur, ensuite vous pouvez faire un cp, juste comme avant. La ligne "or a" est une autre manière de dire "cp 0", mais en utilisant moins de mémoire (Il faut vérifier par rapport à zéro car _getk retourne la valeur 0 si aucune touche n'a été pressée). La ligne suivante, jusqu'à la dernière, répète la boucle si on n'appuie sur aucune touche. Les valeurs retournées par _getk sont les mêmes que par la commande getkey en TI BASIC. Lisez le guide de l'utilisateur si vous ne savez pas comment trouver ces valeurs.

 

La boucle présentée ici n'est pas vraiment mieux que _getkey, car elle attends aussi que l'on appuie sur une touche. Cependant, si vous enlevez ces lignes

 

or a

 

jr z,keyloop

la routine recherchera l'appui sur une touche, et retournera la valeur dans l'accumulateur, éventuellement 0 si aucune touche n'a été pressée, sans répéter la boucle. Vous pouvez ensuite continuer avec le reste de votre boucle, et rappeler la routine encore une fois après l'avoir exécutée. Cette manière de procéder vous permettra de continuer à rechercher les appuis sur les touches tout en laissant le reste du programme s'exécuter.

 

La troisième méthode, connue  sous le nom d'entrée directe, est plus compliquée et nous en discuterons dans un prochain tutorial.

 

------ Tutorial ASM 6 -------

But: afficher du texte sur l'écran des graphiques et le home screen
Auteur: Andy_S
Traducteur: [ftp83+]
Date de création: 30/09/97
Dernière mise à jour: 23/12/97
Date de traduction: 13/07/02
Version: 1.1

 

Ok, vous avez compris comment afficher une chaîne de caractères sur le home screen (lisez le tutorial ASM 1 si vous ne l'avez pas fait). Maintenant vous allez apprendre comment afficher du texte sur l'écran utilisé par les graphiques en utilisant des plus petits caractères. La différence est qu'au lieu d'utiliser CURROW et CURCOL, vous utilisez PENCOL et PENROW. Mais il est important de signaler un détail qui peut s'avérer déroutant: cette fois la colonne va en premier, et la rangée en second. Encore une fois, vous ne devez qu'utiliser la première (NDT: Again, you only have to use the first one. dans le texte original). Par exemple, mettez.

 

ld hl,0929h

ld (PENCOL),hl

 

Pour afficher le texte 10 pixels à droite, et 30 pixels vers le bas (rappelez-vous que le premier nombre est 0). Chaque ligne et chaque colonne a une largeur d'un pixel. Ensuite vient le romcall pour afficher le texte proprement dit. Ce call est

 

call _vputs

 

Rappelez-vous, il faut d'abord qu'une chaîne de caractères dans hl pour utilisation par _vputs. Il y a aussi d'autres méthodes pour afficher du texte. Par exemple, si vous voulez afficher juste un caractère, au lieu d'utiliser _vputs, vous pouvez utiliser _vputmap. La manière de l'utiliser est de charger le caractère souhaité dans l'accumulateur (par exemple, 65 correspond à la lettre "d") et ensuite écrire le call _vputmap. Comme ceci

 

ld a,65 call _vputmap

 

Ce code affichera "d" à (PENCOL, PENROW). La même méthode est utilisable pour afficher du texte sur le home screen en utilisant le romcall _putc. Ce texte sera affiché à (CURROW, CURCOL). Si vous voulez simplement un espace blanc sur l'écran graphique, vous pouvez utiliser le romcall _vputblank, qui déplacera le curseur de deux pixels vers la droite.

 

Une autre manière d'afficher du texte, au lieu d'avoir une chaîne de caractères terminée par ",0", est d'utiliser un romcall pour les deux types de texte pour qu'ils aient une longueur fixe. La manière de fixer cette longueur sur le home screen est d'utiliser _putps. La longueur est déterminée par le premier octet, comme

 

ld hl,str

call _putps

ret

str: .db 10, "abcdefghij"

 

Si le texte doit être affiché sur l'écran des graphiques, ce n'est pas le premier octet de la chaîne de caractères, mais la valeur dans le registre b, et le romcall à utiliser est _vputsn.

 

ld hl,str

ld b,10

call _vputsn

ret

str: .db "abcdefghij"

 

Bien sûr vous devez toujours indiquer au programme où afficher le texte. Ceci conclut les principales manières d'afficher du texte.

Haut de la page