π
<-
Chat plein-écran
[^]

[FR] Langage assembleur sur ez80 - Tutoriel

Assembleur, Axe, ICE, BBC Basic...

[FR] Langage assembleur sur ez80 - Tutoriel

Unread postby TheMachine02 » 26 Feb 2017, 18:23

Guide du langage assembleur pour calculatrices à processeur ez80
Ti-83 Premium CE & TI84+CE
Version
: 0.0


* * *



I / Préparation


1 - L'édition d'un programme


Il existe à l'heure actuelle de nombreuses plateformes pour l'édition. Vous pouvez utiliser n'importe quel éditeur de texte, du Bloc-notes, à WordPad en passant bien sûr par Notepad++. Notepad++ a l'avantage de pouvoir définir un
highlight
automatique des commandes ASM.
Créez un document texte et changez son extension en .z80, .ez80 ou .asm, l'extension n'ayant que peu d'importance. (Il faut seulement que ce fichier soit reconnu et ouvert par votre OS avec le bon programme que vous utilisez). Par la suite, j'utiliserai l'extension .ez80.

2 - L'assemblage


Pour créer le programme que vous pourrez par la suite envoyer sur la calculatrice, il faut effectuer une étape consistant à transformer ce que vous avez écrit en code compréhensible par le processeur de la calculatrice. Il s'agit de l'
assemblage
. Rassurez vous, cette étape n'est pas à faire à la main, mais un programme appelé assembleur va faire ça pour nous.

Le programme s'appelle SPASM, et est téléchargeable gratuitement ici.

Cependant, nous avons aussi besoin d'autres éléments. La plupart des programmes assembleurs reposent sur des fonctions toutes faites présentes dans l'OS de votre calculatrice, ou encore sur des nombres constants qui ont une signification particulière. Comme nous n'allons pas apprendre tout ces nombres par cœur, nous pouvons demander au compilateur de créer des noms de fonctions bien plus compréhensibles par un être humain. Le fichier qui permet d'effectuer ceci s'appelle un fichier
include
.
Vous pouvez trouver le fichier include correspondant à votre calculatrice ici.

À noter :

Ce fichier n'est pas fourni par TI. Les valeurs qui y sont présentes ont été trouvées par des utilisateurs chevronnés. Ceci n'exclut donc pas des erreurs (même si jusque là, aucune n'a été découverte), et surtout il n'est pas complet. Veillez à le mettre à jour de temps en temps.


Il n'est pas nécessaire pour l'instant de tenter de comprendre ce fichier, je vous assure que par la suite il vous semblera simple :)


Créez un nouveau fichier dans votre répertoire dédié à la programmation assembleur et appelez le
ti83pce.inc. Copiez-collez le contenu du lien ci-dessus et enregistrez : votre fichier est près à l'emploi.
Une fois ceci fait, nous allons voir comment compiler le programme avec SPASM.
Sous windows, il faut créer un fichier de commande .bat
dans le même répertoire que votre fichier .ez80, votre .inc et spasm64.exe
:
  • Créez un fichier texte
  • Copiez les deux lignes suivantes : spasm64 -E exemple.ez80 TEST.8xp et pause
  • Fichier, Enregistrer sous...
  • Renommez le fichier en "build.bat"
  • Et enregistrez le tout.
Votre fichier .bat est prêt à être utilisé !

Les deux lignes signifient d'exécuter le programme spasm64 sur le fichier "exemple.ez80" (nom que vous pouvez changer), et de créer le programme résultant "TEST.8xp". L'option -E permet de compiler pour le processeur ez80 de la TI-83PCE. Une pause est mise à la fin pour que vous puissiez voir les erreurs (présentes ou non) lors de la compilation.

3 - Transfert et émulation


Une fois un .8xp obtenu vous pouvez soit l'envoyer sur votre calculatrice (en suivant ce tuto ou utiliser un émulateur.

Il est conseillé d'utiliser l'émulateur en premier lieu car il est très facile de faire un erreur en assembleur, ce qui peut conduire à un RAM clear. Sur l'émulateur vou pourrez en plus débugger vos programmes directement avec des fonctions telles que l'éxecution ligne par ligne, avec un visualisation de la mémoire en temps réel


Voyons donc comment utiliser l'émulateur.


Tout d'abord, allez le télécharger ici : http://jacobly.com/CEmu/master/latest/ Ce lien est régulierement mis à jour, donc n'hésitez pas à aller le retélécharger de temps en temps.
Au premier lancement, il demande une ROM. Vous pouvez obtenir une ROM à partir de votre calculatrice en suivant la procédure suivante :

  • Selectionnez "Create a ROM image from a real calculator" puis "continue"
  • Puis "Save Programme" donnez le nom que vous voulez .
  • "Enregistrer" vous pouvez mettre le nom que vous voulez .
  • Envoyez le programme sur la calculatrice
  • Exécutez le programme "DUMP" avec "Asm(" trouvable dans le catalogue.
  • Maintenant en réactulisant "Ti Connect" il faut récupérer les "AppVar" de "ROMData0" à la "ROMDataK" et les copier sur l'ordinateur (je vous conseille de les copier dans un sous dossier), vous devez en obtenir 12. Vous pouvez les supprimer de votre calculatrice.
  • De retour sur CEmu Setup, choisisez "Selects Segments ..." et là vous selectionnez toutes les "ROMData" qui ont été copié de la calculatrice.
  • "Browse..." vous mettez un nom et vous l'enregistrez .

Votre ROM a maintenant été crée. La suite du setup est plutôt simple, vous pouvez regarder toute les options disponibles de l'émulateur. Ce que nous allons utiliser majoritairement avec est l'onglet "debbuger" et "memory"

Une ROM est strictement personnelle et le partage de la ROM sur internet est illégal, alors ne la mettez pas en ligne !


4 - Hello World

Bon maintenant vous allez compiler et exécuter votre premier programme, le classique hello world :)

Code: Select all
   #include "ti83pce.inc"
   
   .assume ADL=1
   .db tExtTok,tAsm84CeCmp
   .org userMem
   
   call _ClrScrnFull
   ld hl, $04 \ ld (curRow),hl
   ld hl, $06 \ ld (curCol),hl
   ld hl,Text
   call _PutS
   call _GetKey
   call _ClrScrnFull
   
   ret
text:
   .db "Hello world !",0


Expliquons donc le code pas à pas :)

La première ligne #include "ti83pce.inc permet d'inclure dans la compilation votre fichier .inc précédemment copié. Si vous vous en souvenez, il permet de faire le lien entre des listes de nombres et un texte particulier. Comme nous allons le voir par la suite, il est particulièrement utile pour ce programme.
.assume ADL=1 est une instruction destinée au compilateur pour signifier que le CPU est bien en mode ADL (adresse Long), soit en mode 24 bits, dans lequel nous allons travailler.
.db tExtTok,tAsm84CeCmp permet de signifier à l'OS qu'il ne sagit pas d'un programme TI-Basic mais bien d'un programme assembleur, nécessitant Asm( pour être exécuté.
.org userMem indique au compilateur quelle est l'adresse initiale dans la mémoire du programme. L'OS copie le programme en userMem lorsqu'il est exécuté, donc tout les programmes assembleurs commencent ici.

Ces quatre premières lignes sont appelés
header
du programme. Elles sont essentielles au fonctionnement de ce dernier et doivent toujours être présentes


Code: Select all
   call _ClrScrnFull
   ld hl, $04 \ ld (curRow),hl
   ld hl, $06 \ ld (curCol),hl
   ld hl,Text
   call _PutS
   call _GetKey
   call _ClrScrnFull


Ceci est le corps de votre programme. Sans rentrer dans les détails, il appelle différente fonction système de la calculatrice afin d'afficher le fameux Hello World. Nous pouvons ici voir la puissance du fichier include : au lieu de devoir mettre
l'adresse
, c'est à dire la valeur litérale, des différents appels à l'OS, nous pouvons simplement mettre un nom bien plus facile à retenir.

ret Permet de retourner à l'OS et fini le programme

Code: Select all
text:
   .db "Hello world !",0

Ceci est encore une instruction au compilateur. Il permet d'inclure dans le programme des octets de donnés, ici sous forme de chaîne de caractère, qui sera par la suite utilisable par le programme à l'aide du
label
"text:". Nous vous expliquerons tout ceci plus en détail dans le chapitre sur la mémoire.

Il ne vous reste plus qu'à
compiler
votre programme à l'aide du fichier .bat et envoyer le programme sur l'émulateur ou votre calculatrice.
Vous obtenez le résultat suivant :
Image

Vérifiez que le compilateur ne revoie pas d'erreurs. Si c'est le cas vérifiez que le .inc est bien dans le bon répertoire, de même que spasm64, et votre fichier exemple.ez80. Un programme qui a renvoyé des erreurs à la compilation ne fonctionnera sans doute pas


Vous connaissez donc maintenant la structure générale d'un (petit) programme assembleur. Apprenons donc maintenant à le remplir !

* * *


II / Le zilog ez80


1 - Les registres


Les registres sont de petites zones de mémoire présentes directement dans la puce du processeur. Le processeur effectue toute ses opérations à l'aide de ces registres qui ne peuvent qu'enregistrer une
valeur
, dont la fonction et la taille dépend du registre.

Nous pouvons distinguer plusieurs classes de registres :

  • Les registres de travail. C'est ceux que vous utiliserez le plus souvent.
  • Les regitres d'index. Très puissant ils permettent de récupérer des données en mémoire très facilement.
  • Les registres de contrôle. Le processeur utilise ces registres pour diverses opérations, ils sont parfois réduit à l'état d'un simple bit.

Les registres sont en général des zones de mémoire de 8bits. Cependant, le ez80 permet de combiner ces zones pour former des zones de 24 bits. Il est cependant à noter que la combinaison est fixe, et que les 8bits les plus supérieur (ou msb) du registre ne peuvent pas être accédés. Ceci est un ancien artefact du jeu de donnée du z80 (le prédécesseur du ez80), qui travaillait sur des registres 8 bits & combinés en 16 bits. Il est aussi à noter que certains registres peuvent effectuer des actions particulières que d'autres ne peuvent pas.

Registres CPU de travail


Registres individuels 8 bits
Registre
Utilisation
A
Accumulateur
, il est le registre opérande et résultat des opérations mathématiques sur 8 bits
F
flags
. Ce registre ne peut pas être directement lu/écrit. Il sert à enregistrer des feedbacks des instructions
L
utilisateur défini
H
utilisateur défini
L
utilisateur défini
D
utilisateur défini
E
utilisateur défini
B
utilisateur défini
C
utilisateur défini


Registres combinés 24 bits

Il est à noter que ces registres proviennent de la combinaison des registres 8 bits. Une modification des registres 8 bits entrainera une
modification
des registres 24 bits. Ainsi, pour le registre
HL
l'octet de poids faible correspond au registre 8 bits
L
tandis que l'octet de poids moyen correspond au registre
H
. Il en est de même pour les autres registres. L'octet de poids fort n'a pas d'existence propre en tant que registre 8 bits, mais possède le nom de
HLU
,
DLU
ou
BLU
.
Registre
Utilisation
HL
Accumulateur 24 bits
, il est le registre opérande et résultat des opérations mathématiques sur 24 bits. Il peut aussi servir à indexer des données en mémoire
DE
Destination
, mais surtout utilisateur défini. Il est utilisé par certaines instructions comme le registre de destination de copie. Il peut aussi servir à indexer des données, mais avec moins de possibilitées que
HL
BC
Byte Counter
, mais surtout utilisateur défini. Il est utilisé par certaines instructions comme un compteur.Il peut aussi servir à indexer des données, mais avec moins de possibilitées que
HL


Registres CPU de contrôle


Registre
Utilisation
SPL
StackPointerLong
, est un pointeur vers le sommet du stack. Il peut dans certains cas être utilisé comme un registre 24 bits de travail
PC
ProgramCounter
, est un pointeur vers l'instruction actuellement executée. Certaines instructions peuvent le modifier
I
Interrupt
, est un registre utilisé dans le cadre des interruptions. C'est un registre 16 bits
MBASE
MemoryBASE
, est un registre utilisé dans le cadre d'exécution de code en mode z80, nous en parlerons à la toute fin de ce tutoriel
R
Refresh
, est un compteur du nombre d'instructions fetchées par le processeur, très rarement utilisé.
ADL
ADL
est un bit indiquant que le mode dans lequel le processeur travaille (z80/ez80)
MADL
MADL
est un bit indiquant que le processeur travaille dans un mode mixé z80&ez80
IEF1
IEF1
est un bit indiquant que les interruptions de niveau 1 sont actives
IEF2
IEF2
est un bit indiquant que les interruptions de niveau 2 sont actives


2 - Les instructions


3 - La mémoire


La mémoire sur ez80 est un espace linéaire de 24-bits. Bien entendu, toute cette mémoire n'est pas que de la RAM. Plus spécifiquement, sur 83PCE, le processeur est interfacé avec une puce RAM de 256Ko, ainsi que 153Ko de VRAM.
Le processeur accède au contenu de la mémoire à l'aide d'une
adresse
. Une adresse est juste un nombre indiquant la 'case' dans laquelle la valeur sur laquelle nous voulons travailler se trouve. La RAM se situe à l'adresse $D00000, tandis que la VRAM se situe à l'adresse $D40000. L'adresse est dénomée
pointeur
.

il est usuel de décrire les adresses avec leur valeur héxadécimal. C'est plus concis et nous avons une notion plus simple de la taille des zones mémoires (100 en héxadécimal correspond à 256). Le préfixe $ permet de bien signifier au compilateur que cette valeur est héxadécimale.


Le ez80 dispose de plusieur moyen de travailler sur la mémoire. Nous pouvons distinguer :
  • un mode d'adressage
    direct
  • un mode d'adressage
    indirect
Dans tout les cas, le processeur peut ainsi copier le contenu d'une case mémoire dans un registre à l'aide de l'instruction
ld
, ou 'LOAD'.

Mode d'adressage direct


Dans ce mode, nous allons donner au processeur directement la valeur du pointeur sur lequel nous travaillons. Le pointeur est fixé en dur dans le code du programme et ne peut pas être changé (sauf utilisation avancée).
Pour ce faire, il faut utiliser la syntaxe suivante de l'instruction load: ld reg,(adresse) pour charger une valeur dans un registre ou ld (adresse),reg pour enregistrer le contenu d'un registre en mémoire. Mettre l'adresse entre parenthèses permet de signifier que nous voulons charger la valeur
pointée
par l'adresse et non pas la valeur absolue de l'adresse dans le registre.

Il faut noter que tout les regitres ne peuvent pas être utilisés par cette instruction. En registre 8 bits, seul
A
peut être utilisé. En registre 24 bits,
HL
,
DE
,
BC
,
SP
et les regitres index
IX
,
IY
peuvent être utilisés


Mode d'adressage indirect


Cette fois ci, au lieu de donner l'adresse au processeur, nous allons lui indiquer quel registre contient la valeur du pointeur sur la mémoire. Le processeur va lire cette valeur, chercher l'octet à cette adresse et la charger dans un registre ou copier le registre en mémoire.
Ici, c'est la syntaxe suivante de
ld
qui est utilisée : ld reg,(reg) et ld (reg),reg. Nous pouvons constater l'utilisation encore présente des parenthèses.

Il faut noter que tous les registres ne peuvent pas servir de destination et de pointeur. En général, le registre
HL
peut tout le temps servir d'adresse et de destination.
DE
et
BC
eux, ne peuvent servir d'adresse que avec
A
comme destination. Il convient de regarder dans la liste des instructions si la combinaison voulue existe


Instructions de copie de bloc


Ces instructions sont très utiles si nous voulons copier des données séquentielles d'un destiantion vers une adresse cible. Elles peuvent copier en incrémentant les adresses à chaque fois, ou alors copier les données de manière inversée – en décrémentant les adresses.
Ces instructions sont des outils très puissants, car ils permettent de faire très rapidement un grand nombre d'action, et ce de manière quasi-automatisée.

La première est ldir. Elle copie l'octet présent à l'adresse contenue dans
HL
vers l'adresse contenue dans
DE
puis incrémente
HL
et
DE
. Elle décrémente ensuite
BC
et répète si le résultat de la décrémentation n'est pas zéro.
Ainsi, si le nombre d'octet à copier doit être placé dans
BC
pour que cette copie soit efficace.

Il est important de considérer l'ordre du test et de la décrémentation de
BC
. Le test
BC
=0 est effectué
après
la décrémentation. Si la valeur de
BC
était zéro au début de l'instruction, celle-ci va copier 16777216 octets et va sans doute provoquer un RAM clear.
BC
correspond ainsi vraiment au nombre d'octet à copier.


L'autre instruction est lddr. Elle agit de la même manière que la précédente mais
HL
et
DE
sont décrémentés au lieu d'être incrémentés.

Gestion de la mémoire


La méthode précédente a le fort fâcheux désavantage de devoir mettre à chaque fois l'adresse. Celle ci est parfois très compliquée et le programme peut travailler sur plusieurs octets de mémoire (voire même quelques milliers ou plus...). Heureusement, le compilateur permet de définir un nom pour chacune de ces zones. Plusieurs commandes peuvent réaliser ceci :

Code: Select all
nom   .equ  adresse
#define nom adresse
nom:


Les deux premières sont notamment celles utilisées par
l'include
, si vous vous en souvenez. Cependant la troisième est particulière : il n'y pas d'adresse incluse dans la syntaxe :o C'est parce que l'adresse définie par cette syntaxe est
implicite
. L'adresse correspond à l'adresse que possède cette ligne dans votre programme.

Ceci permet de faire un lien parfait avec les commandes suivantes, de création de zone libre de mémoire dans le programme :

Code: Select all
.db valeur
.dl valeur
.fill size [,valeur]


.db place un octet dans le déroulement du programme ayant pour valeur celle spécifiée, tandis que .dl en place trois.

Vous pouvez tenter dès à présent l'expérience suivante : placez .db $C9 au début de votre programme de test. Vous constatez que le processeur l'interprète comme l'instruction 'RET'. Ceci est pour vous montrer que les instruction et les valeurs en mémoire forment un seul grand ensemble compris par le processeur selon l'utilisation que fait le programmeur de la mémoire


La dernière commande .fill permet de placer
size
octet dans le programme à l'adresse correspondante dans le déroulement du programme. Si la valeur est spécifiée alors celle-ci est répétée, sinon, un 0 est placé.

En conclusion, pour travailler sur des octets en mémoire, nous utilisons l'instruction
ld
. Celle ci supporte plusieur mode d'adressage, qui ont leur utilisation dans des contextes différents.
.db
et
.dl
permettent de placer des octets dans le programme avec une valeur définie


1 - Les flags

Les flags sont stockés dans le registre f, comme vu précédement. Chaque flag est représenté par un bit (0/1) et permettent de signifier certains événements provoqués par les instructions.
Flag – bit - nom
Fonction
S
– bit 7 - sign
Si la dernière instruction mathématique a rendu un résultat négatif alors, ce flag est
SET
. Sinon, il est
RESET
Z
– bit 6 - zero
Si le dernier calcul a causé un registre égal à zéro, alors il est
SET
. Sinon, il est
RESET
H
– bit 4 - half-carry
P/V
– bit 2 – parity/overflow
Ce flag vérifie deux conditions. Si le registre change de signe à travers une opération alors il est
SET
. Sinon, il est
SET
quand le registre possède une valeur PAIRE ou
RESET
quand la valeur est IMPAIRE
N
– bit 1 – add/sub
Si la précédente opération était une soustraction alors, il est
SET
. Si c'était une addition alors il est
RESET
C
– bit 0 - carry
Si le résultat de la précédente opération est trop large pour tenir dans le registre de destination, alors ce flag est
SET
. Sinon il est
RESET
.


Il est très important de noter que toutes les instructions n'affectent pas les flags de la même façon, et ceci peut-être très important dans l'exécution du programme. Il convient de vérifier dans la documentation si les flags voulus sont bien affectés par l'instruction utilisée.


Deux instructions spécifiques permettent de travailler sur le
carry
uniquement, fonction qui peuvent se révéler utiles pour créer des codes d'erreurs par exemple :

scf met le carry flag à 1
ccf inverse le carry flag

D'autres instructions peuvent être utilisées pour travailler sur les flags :

or a,a
RESET
le carry, tout les autres flags sont modifiés en fonctions de A
xor a,a
RESET
le carry,
SET
le flag z, met le registre A à zéro.

1 - Mathématique de base


Voyons maintenant comment effectuer des opérations sur les registres.

Le ez80 est un processeur
24-bits
. Son
ALU
(ArithmeticLogicUnit) ne gère que des nombres 8 bits ou des nombres 24 bits. Il faut prendre en compte que l'ALU de la famille des ez80 est assez limitée par rapport à une unité d'un processeur moderne (x86 ou ARM).
Ainsi, celle ci gère l'addition, la soustraction et la multiplication, ainsi que des opérations logiques sur 8 bits.

L'addition


Cette opération peut être effectuée sur 8 bits ou 24 bits. Dans les deux cas, le ez80 additionne
l'accumulateur
et un registre opérande et stocke le résultat dans l'accumulateur.
En 8 bits, l'accumulateur est le registre
A
. En 24 bits, ce sont les registres
HL
,
IX
, et
IY
.
La syntaxe est la suivante : add accumulateur, opérande

Il est à noter qu'en mode 8 bits, l'opérande est un registre 8 bits, en 24 bits un registre 24 bits. Vous ne pouvez pas additionner des registres de taille différente. De plus, vous pouvez additioner l'accumulateur à lui même (ce qui représente un multiplication par deux de l'accumulateur)


Il existe aussi l'instruction adc accumulateur, opérande qui ajoute l'opérande et la valeur du
flag
carry (cf au chapitre suivant) à l'accumulateur.

L'addition normale
add
sur 24 bits ne modifie pas tous les flags selon leur définition. Les flags
Z
,
P/V
et
S
ne sont pas modifiés


Soustraction


De la même manière, le ez80 soustrait un registre opérande à l'accumulateur et stocke le résultat dans l'accumulateur. La syntaxe est la suivante : sub accumulateur, opérande. Cependant cette instruction n'existe que pour l'accumulateur 8 bits.

Pour les registres 24 bits, seul l'instruction sbc accumulateur, opérande existe, et l'accumulateur n'est que le registre
HL
. Ici, cette instruction soustrait l'opérande et la valeur du carry (comme pour
adc
). Pour obtenir une soustraction pure (sans l'action du carry), il faut d'abord mettre le carry à zéro :
Code: Select all
or a,a
sbc hl, reg

Ici, l'instruction logique
or
que nous verrons par la suite sert pour mettre la valeur du carry à zéro.
Les flags sont modifiés selon leur définition après
sbc
et
sub


Multiplication


Le ez80 a introduit par rapport au z80 une instruction de multiplication. La syntaxe est la suivante : mlt reg.
reg
est un registre 24 bits.
Cette instruction multiplie le registre bas 8 bits avec le registre haut 8 bits. Prenons un exemple pour éclaircir.
Code: Select all
ld h, 8
ld l, 3
mlt hl

Le résultat obtenu est
HL
=
H
*
L
, soit 24

Attention, le résultat de cette multiplication n'est pas signé, c'est à dire qu'il ne prend pas en compte le complément à deux. Vous devrez vous même rajouter du code pour multiplier deux nombres signés. De plus, le registre
U
(le plus haut nous vous rappelons), est mis à zéro lors de l'opération


La multiplication accepte les registres
HL
,
DE
,
BC
, et
SP
. De plus, elle n'altère pas les flags.

1 - Les routines


1 - Le stack


Le stack, pile en français, permet de stocker des données temporairement à partir notamment des registres. Elle est organisée sous la forme
LIFO
,Last in, first out, équivalent au dernier entré, premier sorti.
La pile utilise le registre de la pile soit SP, SPL en mode d'adressage ADL comme pointeur de la pile . Il permet de stocker l'adresse où se trouve la dernière valeur de la pile . En mode SPL, ce registre contient des adresses de 3 octets. Toute modification de ce registre induit un déplacement de la postion du stack

Si le registre
SP
est utilisé comme un registre de travail, alors le stack n'est plus utilisable et toute instruction travaillant sur le stack corrompera la mémoire


Deux instructions sont essentielles pour travailler sur la pile : push et pop
Pour pouvoir placer des données dans la pile on utilise l'instruction
push
et
pop
pour récupérer la dernière valeur placée. Lors de l'utilisation de ces instructions, le registre
SPL
est affecté.
Il est décrémenté de 3 lors de l'instruction
push
et incréménté de 3 lors de l'instruction
pop
.

Le stack grandit avec des adresses décroissante, ce qui justifie la décrémentation de l'adresse lorsqu'une nouvelle valeur est placé sur le stack


Lors d'un travail sur le stack, il faut faire attention de bien avoir la même valeur de
SP
en entrée et en sortie d'une fonction ou d'un programme. Sinon, cela peut conduire à un crash.

1 - Les OS call

1 - Les ports


Les ports sont très importants en assembleur : ils permettent entre autre, de gérer la pression des touches sur le clavier, configurer l'écran, communiquer par USB avec une autre calculatrice... c'est une notion incontournable de l'assembleur ! Ces derniers servent donc à faire le lien entre les composants de la calculatrice et le programmeur. Concrètement, on va, par exemple, pouvoir dire à l'horloge de la calculatrice de changer l'heure, à l'écran de s'éteindre, au port USB d'envoyer quelque chose... tout cela grâce aux ports !
Cependant, un élément va compliquer leur utilisation sur les calculatrice eZ80. En effet, les ports des calculatrices eZ80 sont dits "memory-mapped". Pour faire court, sur les calculatrices Z80 (Ti-83+/Ti-84+...), les ports étaient accessibles directement et normalement grâce aux instructions IN a,(port) pour récupérer la valeur d'un port, et OUT (port),a pour la modifier. Néanmoins, sur Ti-83 Premium CE l'utilisation des instructions IN et OUT est prohibée et tenter des les utiliser ne causera soit rien, soit un RAM CLEARED. Ces restrictions sont supposées protéger et donner un sens au mode examen qui aurait pu être facilement reproduit et contourné dans le cas où un programme avait pu utiliser le port de la LED du mode examen afin d'en imiter le fonctionnement.
Heureusement, il existe quand même une solution pour accéder aux ports que nous permet d'utiliser Texas Instrument. En effet, certains ports sont
"mappés en mémoire"
c'est-à-dire qu'ils vont pouvoir être modifiés seulement en modifiant une adresse mémoire. C'est le cas notamment pour le clavier, l'écran, les timers, l'USB... mais bien entendu pas la LED du mode examen !

Les ports sont mappés à partir de l'adresse mémoire $E00000. Par exemple, le port du clavier est mappé en mémoire à partir de l'adresse $F50000. Afin de connaître tous les ports qui peuvent être utilisés, je vous conseille de suivre ce lien vers le wikiti. Vous y trouverez tous les ports qui ont été découverts jusqu'à maintenant. Pour savoir si un port est "memory-mapped", il suffit de voir si le champ "Memory-mapped address:" existe en haut de la page décrivant le port, dans la section "Synopsis".

Afin de mieux comprendre comment cela fonctionne, nous allons aborder un exemple simple, récupérer les minutes de l'heure actuelle :
Code: Select all
ld hl,($F30004) ; On récupère les minutes.
call _dispHL ; On affiche HL qui contient le nombre de secondes

Expliquons un petit peu. Nous voyons à cette adresse que le port "Real-Time Clock" est le port numéro $8000 et est mappé à l'adresse $F30000 en mémoire. De plus, les minutes sont stockées du port $8004 à $8007
(toutefois les minutes n'allant que de 0 à 59, seulement un octet sera utilisé sur les quatre dédiés aux minutes)
. L'adresse à récupérer est donc $F30004. Ensuite, on affiche les minutes avec la fonction système _dispHL qui, comme son nom le laisse présager, affiche la valeur du registre HL à l'écran.

Nous allons, en dernier lieu et partiellement, voir l'utilisation des ports les plus importants, c'est-à-dire le port du clavier et de l'écran.

Utilisation du clavier

Le clavier a une utilisation spéciale et un peu plus complexe malgré sa fréquente utilisation dans les programmes. Il nécessite quelques connaissances.
Le port du clavier a pour numéro $A000 et est mappé à l'adresse $F50000. Avant de détecter la pression des touches, nous avons besoin d'initialiser le clavier. Pour cela nous allons devoir d'abord choisir un mode pour la clavier. Il en existe quatre mais seulement trois peuvent éventuellement nous intéresser :
  • Le mode "repos" :
    le clavier ne fait rien et ne scanne rien
  • Le mode "unique scan" :
    le clavier est scanné une fois, puis il revient au mode "repos"
  • Le mode "scan continu" :
    le clavier est scanné encore et encore indéfiniment...
Le mode qui va être utilisé le plus souvent est le deuxième mode, l'unique scan. Le code minimal pour lire le clavier est par conséquent :
Code: Select all
   di ; On désactive les interruptions (obligatoire)
   ld hl,$F50000
   ld (hl),2 ; On met le clavier en mode "un seul scan"
   xor a,a
scan_wait:
   cp a,(hl) ; On attend que le clavier soit retourné en mode repos ce qui voudra dire que la détection des touches est terminée
   jr nz,scan_wait

   ; Quand la détection est terminée, on peut commencer à lire les ports
   ld a,($F50012)
   cp a,32 ; si la touche 2NDE a été pressée...
   call z,routine
   ei ; On peut réactiver les interruptions

Ici, nous avons pris l'exemple de la touche 2NDE dont l'état (enfoncée ou non) se situe à l'adresse $F50012 sur le bit 5. Pour connaître la correspondance des touches, je vous conseille de jeter un œil au tableau sur cette page. Comme on peut le voir on fait une pause (scan_wait) avant de lire le clavier, sans elle la lecture serait erronée donc ne l'oubliez pas !

Utilisation de l'écran

Le port de l'écran nécessite un chapitre entier mais nous allons aborder brièvement les bases de son utilisation. L'écran est par défaut en 16bits, c'est à dire qu'il y a 2^16=65536 couleurs disponibles par pixel. Chaque pixel possède une nuance de rouge, de vert et de bleu, les trois couleurs primaires en informatique. Par défaut
(et je dis par défaut car il est possible de mettre l'écran en mode 8bits)
chaque pixels possède donc 16 bits. Les cinq premiers bits codent pour le rouge, les six suivants pour le vert, et enfin les cinq derniers pour le bleu. On remarque que nous avons :
%
00110
011100
10110


Maintenant, l'objectif est de savoir comment modifier la valeur d'un pixel à l'écran. Notre Ti-83 Premium CE possède une vRam autrement dit une Vidéo RAM qui est un espace mémoire destiné à faire l'intermédiaire entre la mémoire et l'écran. Grosso modo, il suffit tout simplement de modifier la vRam pour que les pixels changent instantanément de couleur sur l'écran.
Nous savons que l'écran fait 320*240 pixels, avec 16 bits par pixel (=2 octets). La vRam fait donc logiquement 320*240*2, soit 153,6Ko, ce qui est énorme quand on sait que la RAM disponible à l'utilisateur fait autant !
La vRam est située à partir de l'adresse $D40000 sur 153600 octets. Prenons un exemple tout simple, on veut changer le 187ème pixel pour qu'il affiche du rose :
Code: Select all
ld hl,%1111100000010000
ld (vRam+(186*2)),hl

À noter que comme le registre HL fait 24 bits, les 16 bits du pixel 187 seront bien modifiés, toutefois la moitié du pixel suivant (8 bits), le 188, sera mise à 0.
Il est alors possible de modifier une grand partie de l'écran grâce à un LDIR, et avec un peu de réflexion, d'afficher des sprites et des images à l'écran.

En rappel, n'oubliez pas d'aller voir le wikiti pour connaître tous les ports et leur adresse !
Voir la liste des ports connus à ce jour.

1 - Mathématique avancé

1 - Les timers


* * *


En construction


Merci à Dark_Coco pour le début du tutoriel, merci à Wistaro pour la mise en page :) .
Last edited by TheMachine02 on 26 Feb 2017, 20:33, edited 8 times in total.
User avatar
TheMachine02Donat.
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 81.8%
 
Posts: 285
Images: 0
Joined: 16 Jan 2013, 18:27
Gender: Not specified
Calculator(s):
Class: Médecine

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby Epharius » 26 Feb 2017, 19:29

Ah ouais, right, fallait faire ce tutoriel :p
Bon par contre le problème c'est que si je veux apporter des modifs je ne peux pas, donc à part si vous voulez vous la jouer perso ce serait cool de mettre à un endroit où tout le monde (du moins ceux qui en sont autorisés) peuvent modifier (genre wiki).

Genre :
xor a,a RESET le carry, RESET le flag z, met le registre A à zéro.

J'aurais bien voulu modifier en
xor a,a RESET le carry, SET le flag z, met le registre A à zéro.
:p
Le projet Geometry Dash est terminé ! N'hésitez pas à aller jeter un coup d’œil au topic du projet ! Vous pouvez le télécharger ici.

Unis par la flèche sacrée de cupidon :favorite:
Image
User avatar
EphariusPremium
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 81.7%
 
Posts: 991
Images: 4
Joined: 08 Dec 2014, 17:38
Gender: Male
Calculator(s):
Class: ENSIMAG

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby TheMachine02 » 26 Feb 2017, 19:40

Bah on pourra le mettre sur le wiki après, tu me dis les modifications & je change hein ça pose pas trop de problème :p De même tu m'envoies les parties et j'inclus tout ça :)
User avatar
TheMachine02Donat.
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 81.8%
 
Posts: 285
Images: 0
Joined: 16 Jan 2013, 18:27
Gender: Not specified
Calculator(s):
Class: Médecine

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby Epharius » 26 Feb 2017, 20:20

ok, faudra que tu penses à corriger les fautes d'orthographe du coup ;)
Je ferai une partie plus tard quand j'aurai le courage.
Le projet Geometry Dash est terminé ! N'hésitez pas à aller jeter un coup d’œil au topic du projet ! Vous pouvez le télécharger ici.

Unis par la flèche sacrée de cupidon :favorite:
Image
User avatar
EphariusPremium
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 81.7%
 
Posts: 991
Images: 4
Joined: 08 Dec 2014, 17:38
Gender: Male
Calculator(s):
Class: ENSIMAG

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby Wistaro » 26 Feb 2017, 20:54

Merci beaucoup pour ce tutoriel de qualité !

Ça manquait en français :)
Nouveau sur le site,
Anonymous
? Avant de poster sur le chat et sur le forum, n'oublie pas de . En cas de problème, tu peux m'envoyer un message, je réponds rapidement.

Liens utiles:

Image
Découvre mes programmes et mon site!
User avatar
WistaroModo.G
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 62.6%
 
Posts: 2933
Images: 37
Joined: 25 Feb 2013, 16:21
Location: Toulouse
Gender: Male
Calculator(s):
Class: Etudiant ingénieur (dernière année)
YouTube: Wistaro
Twitter: Wistaro
GitHub: Wistaro

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby Adriweb » 26 Feb 2017, 21:28

Hm, c'est (très) bien, mais tu risques d'atteindre les limites de caractères pour le post.
Il faudrait voir si tu peux faire 2-3 réponses bidon à ce topic, et je changerais le timestamp pour qu'ils apparaissent juste après le post initial.

Et sinon, des sources d'info en anglais:
- http://media.taricorp.net/83pa28d/welcome.html (z80)
- https://ce-programming.github.io/documentation/
- https://ez80.readthedocs.io/en/latest/
- ...
User avatar
AdriwebAdmin.
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 52.9%
 
Posts: 12810
Images: 1083
Joined: 01 Jun 2007, 00:00
Location: France
Gender: Male
Calculator(s):
Class: (ingénieur)
Twitter: adriweb
GitHub: adriweb

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby grosged » 28 Feb 2017, 10:55

:~o !! C'est chouette comme tuto !! 8-)
Et en plus, mentionner les "routines-système" à travers l'exemple "Hello world" , c'est bien vu ;)
( j'dois être maso : j'en utilise jamais :p )

ça me fait penser que j'avais fébrilement commencé un tuto sur le processeur ARM (dont je ne connais pas encore toutes les subtilités, d'ailleurs...)
Last edited by grosged on 28 Feb 2017, 14:08, edited 1 time in total.
User avatar
grosgedVIP++
Niveau 13: CU (Calculateur Universel)
Niveau 13: CU (Calculateur Universel)
Level up: 67.1%
 
Posts: 692
Images: 21
Joined: 14 Sep 2011, 12:29
Gender: Male

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby GalacticPirate » 28 Feb 2017, 12:45

J'ai corrigé quelques fautes d'orthographe et amélioré la syntaxe au début du tuto. Bon travail !
Mon profil TI-Planet
Mon Internetometer
Devenez premium !
ImageImageImage
Modérateur de TI-Planet.org depuis décembre 2015, et membre actif de la communauté depuis Mai 2015, je suis toujours disponible pour aider (ou pas :troll: )Cliquez ci-dessus pour me donner un Internet ! Ça ne sert absolument à rien mais c'est marrant :pCliquez ci-dessus pour faire un don à TI-Planet.org via PayPal et devenir Donateur ou Premium (à partir de 3€) ! Vous aurez accès à des générations illimitées et prioritaires avec Mviewer GX Creator, ainsi qu'au forum secret ! :bj: En plus, vous pourrez être orange sur le chat :troll:

Image
User avatar
GalacticPirateModo
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 90%
 
Posts: 1151
Images: 2
Joined: 23 May 2015, 10:36
Location: Bourg-La-Reine, 92, France
Gender: Male
Calculator(s):
Class: L1
YouTube: Zack Voyager
Twitter: @STVthebest
Facebook: Zack Voy

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby sautax » 28 Feb 2017, 18:13

Merci beaucoup ! j'attendais un tutoriel en français depuis longtemps parce que je comprenais pas des choses sur les tutos anglais ....
:bj:
Mes projets :

-Environnement numworks sur PC
-TILIB
-AGAME
User avatar
sautaxProg.
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Level up: 16.7%
 
Posts: 65
Joined: 21 Sep 2016, 14:31
Location: Quelque part dans le sud
Gender: Male
Calculator(s):
Class: Terminale S-SI
YouTube: sautax

Re: [FR] Langage assembleur sur ez80 - Tutoriel

Unread postby Dark coco » 28 Feb 2017, 22:38

Je propose de m'attaquer au "stack" :) . Si quelqu'un est déjà dessus, merci de me le signaler . ;)
(21:48:26) Hamza.S: Dark_coco : tu a écris 2 phrases sans faute
(19:15:10) Hayleia: ah ça je confirme que t'as appris à écrire à l'école de baptiste_leprovost :troll:
User avatar
Dark cocoAnimat.
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 65.8%
 
Posts: 95
Joined: 15 Jan 2017, 14:39
Gender: Male
Calculator(s):
Class: dut gte

Next

Return to Langages alternatifs

Who is online

Users browsing this forum: No registered users and 4 guests

-
Search
-
Featured topics
Omega, le fork étendant les capacités de ta NumWorks, même en mode examen !
Comparaisons des meilleurs prix pour acheter sa calculatrice !
12
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...

Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety 
-
Stats.
472 utilisateurs:
>462 invités
>4 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)