COURS
ASSEMBLEUR 6809 E
Pour ces cours il vous
faudra
=============================
- Le programme: ASS6809.CHG vers 2.0
Programme pour créer vos fichiers
sources et, les assembler.
Ce cours est destiné à expliquer la
programmation du MICROPROCESSEUR 6809 E en ASSEMBLEUR.
Je vous conseille à tous les livres
suivants:
-
MANUEL TECHNIQUE des TO8, TO9, et TO9+ par Jean-Claude MARIACCIA et Olivier
SAVIN (disponibles en quelques exemplaires dans la brocante de PILOUX).
Ce livre présente entre autres toutes les
routine de
l'extramoniteur
et du moniteur de ces machines (comportant
des
fiches présentant le point d'entrée,les registres d'entrée, de retour, ainsi
que des exemples).
- LE MICROPROCESSEUR 6809 SES
PERIPHERIQUES ET LE PROCESSEUR GRAPHIQUE 9365-66, par Claude DARDANNE.
(Modes d'adressage, instructions, codes,interruptions,
...)
bref,
une vraie mine !
.
Je vous souhaite un bon apprentissage,et si
vous avez des questions ou des remarques concernant des fautes qui on pu être
commises, laissez-moi un message dans ma BAL: MACGYVER ( sur
SERVEUR
87 ou PARIS-THOMS).
Bon courage.
.
NB:
Sauf demande expresse de votre part,je ne traiterais pas les instructions du
microprocesseur et les multiples cas possibles qu'elles offrent en combinaison
avec les différentes modes d'adressage.
Pour avoir des précisions sur les
instructions et tout ce qui concerne le 6809 E, consultez le livre "LE
MICROPRO-
CESSEUR
6809 E, ...", cité plus haut.
INTRODUCTION
************
Le langage BASIC ne peut être exécuté en dehors du programme appelé "INTERPRETEUR". C'est-à-dire que chaque instruction du basic est traduite en langage machine et exécutée une par une au fur et à mesure du déroulement du programme.
Le langage ASSEMBLEUR, lui, ne permet pas
d'exécuter le programme directement: Il faut d'abord l'assembler, c'est-à-dire
le
traduire entièrement en langage machine, directement exécutable par le
processeur.
L'assemblage prend du temps, mais
l'exécution du programme une fois assemblé est très rapide.
Les programmes machine, donc ASSEMBLEUR (
c'est le même programme, mais sous
une autre forme), utilisant les instructions du microprocesseur pour réaliser
leurs traitements.
Généralement, pour réaliser une action
comme afficher un caractère, trace run trait, on appelle une routine (sous
programme) implanté dans la mémoire de l'ordinateur. Les données
nécessaires
à l'exécution de ces sous-programmes sont REGISTRES. La routine, lors de son
appel, lit donc les registres contenant les valeurs constituant les paramètres
d'entrée.
A l'issue de la routine, on récupère, s'il y
a lieu, les valeurs dans des registres fixes ou a préciser(Ex:chaînes de
caratères), constituant les paramètres de retour.(Ex:La routine PUTC affiche un
caractère dont le code ASCII a été placé dans l'accu B du 6809.
Conventions d'écriture:
-----------------------
Une
valeur en décimal ne sera précédée d'aucun signe spécial.
LES REGISTRES du 6809 E
=======================
-2 accus 8 bits (A et B) transformables en 1
accu 16 bits, D. Ils sont utilisés pour les instructions arithmétiques et
de
chargement de données 8 bits (ou 16 bits) en mémoire.
-2 registres d'index X et Y, sur 16 bits. Ils
sont généralement utilisés pour contenir des adresses de données en
mémoire.
-2 registres pointeurs de pile U et S.U
est utilisé uniquement par le programmeur, S par le système. La pile est
un emplacement ou le microprocesseur sauvegarde le contenu de ses registres
internes pendant un certain temps. Elle fonctionne comme une pile
d'assiettes,
ou un fichier séquentiel: pour obtenir le contenu d'un registre, il faut
dépiler tous les précédentes.
Mais
rassurez-vous cette tâche est entiérement (ou presque) gérée par le 6809 E dans
des instructions spéciales.
-un compteur programme PC ( Program Counter),
sur 16 bits, pointant toujours sur l'adresse que le microprocesseur doit
exécuter.
-1 registre "codes conditions",
affichant en permanence l'état de ces bits. Il fera l'objet d'un paragraphe
spécial traitant également les instructions de branchement.
-1 registre de "page mémoire" , sur
8 bits, indiquant la page de mémoire active, et configurable par l'utilisateur.
=====================
Le 6809, possÞde 59 instructions " de
base". Cela peut paraître faible, mais combinées aux différents modes
d'adressage (un peu comme différentes façons de faire comprendre une
instruction au microprocesseur), elles offrent 1464
possibilitées.
Structure d'une instruction:
Elle comporte de un à 4 octets.
Généralement, le premier octet indique l'action à effectuer, les suivants
précisent les opérandes ou sur quelques registres cette action agira.
L'adressage inhérent, ou implicite:
C'est le plus simple, car les opérandes
sont généralement incluses dans le code opératoire(donc un octet).
Ex: INCA, incrémentation de 1
de l'accu A.
ABX, addition de l'accu B
au registre X.
TFR A,B transfert le contenu de A dans B.
Dans ce dernier cas, un post-octet (situé
après le code opératoire) précise quelles sont les opérations de
l'instruction.
5 Dans cet exemple, les opérandes sont A et B).
Ce mode de l'adressage inhérent est est
utilisé aussi dans les instructions d'accès aux piles, pour préciser quels
sont
les registres à dépiler/empiler.
L'adressage immédiat:
=====================
Dans ce mode, l'opérande que l'instruction
doit prendre en compte est située après le code opératoire.
Ex: LDA #$DF Chargement
de A avec la valeur hexadécimal DF.( le symbole "$"
précise que la donnée est en hexadécimal. Pour les instructions LDa (a:
accu quelconque),la valeur a charger dans l'accu doit être du même type que cet
accu (8 bits
pour
A,B et 16 bits pour X,Y,U,S,D).
Ce mode d'adressage est utilisé pour
configurer des registres (microprocesseur ou RAM) en vue de l'appel ultérieur
d'une routine de l'ordinateur ou bien d'un sous-programme.
L'appel
de cette routine se fera par: JSR
ADRESSE, ADRESSE étant le début du sous-programme (=point
d'entrée).
JSR (Jump to SubRoutine) est à
l'assembleur ce que GOSUB est au BASIC. Un retour de sous-programme se
fera par un RTS (Return of SubRoutine). RTS est l'équivalent
de RETURN sous BASIC.
L'adressage direct:
===================
Ce mode d'adressage permet de travailler
sur la mémoire. L'opérande d'une instruction en adressage direct ne sera
constituée
que d'un seul octet registre mémoire sur lequel il faut agir.
Explications...:
On notera que l'adresssage direct sera
spécifié par le signe "<" placé devant l'opérande, dans la syntaxe
assembleur.
Ex: Si le registre de page vaut $A1:
l'instruction STA <$45 stockera le contenu de l'accu A en $A145.
et de l'opérande (poids faibles, $45).
Ce mode présente l'avantage d'être exécuté rapidement, mais ne peut être utilisé que lorsqu'on ne travaille pas sur des zones de mémoire trop importantes (256 octets).
Une toute autre façon de concevoir cet
affichage, le tout étant d'arriver au résultat escompté. Nous commencerons par
décider de l'endroit de la mémoire vive de notre programme en langage machine
sera logé; en utilisant la directive ORG.
.
Avec
ORG $8000, on va décider de l'implanter à partir de cette adresse dans
la partie utilisateur non commutable de la RAM (voir page 189 guide du TO8). L'assembleur va alors, automatiquement, se charger de ranger
séquentiellement le code de chacune des instructions ou données de votre
programme à partir de l'adresse $8000.
Notre
programme commence donc ainsi:
*affichage
d'un caractère graphique mode 320X200 16 couleurs
ORG
$8000
PSHS U,Y,X,DP,B,A
*communication
mode TO7/70
STA
$E7DC
Les lignes précédées d'un * sont des commentaires
non pris en compte lors de l'assemblage. On a
commencé par sauvegarder dans la pile système S, le contenu des
registres U,Y,X,DP,B,A ;c'est une sage précaution
à prendre !
Puis
le programme choisit le mode TO7/70 en
mettant la valeur 0 dans le registre &HE7DC.
*mémorisation
adresse 1er octet de l'écran.
LDX
#$4000
*calcul
adresse de l'octet situé ligne L (coordonnée caractère)
*et
colonne C(en coordonnée caractère) donné par formule
*adr=$4000+C+(L*8*($28))
avec 0<=L<=24 et 0<=C<=39
LDB
COORL
*calcul
valeur d'octet pour ligne du dessous
LDA
COORL
LDB
#$08
MUL
LDA
#$28
MUL
LEAX
D,X
Cette
partie du programme mérite quelques
explications. Le guide du TO8 nous informe page 189 que la mémoire vidéo
s'étend de l'adresse &H4000 jusqu'à &H5FFF; cela nous
intéresse.
On
va donc ranger dans le registre X de 16 bits la valeur de l'adresse mémoire du
premier segment d'écran en haut à gauche.
Mais
ce qu'il faut connaître c'est l'adresse mémoire vidéo qui correspond à un
segment quelconque situé colonne Cligne L. La formule de calcul est fournie en
commentaire dans le programme. On peut la vérifier car si
&H4000+1+(0*&H28)=&H4001.
L'écran
contenant 40 segments de 8 points (40=&H28).
Les
instructions du programme ont pour but de calculer la formule arithmétique
explicitée. Pour cela on range dans le registre 8bits B la valeur du numéro de
colonne (désigné par COORC) le logo va
commencer à s'afficher, on additionne cette valeur à celle contenue dans X qui
est une valeur du premier octet et on laisse le résultat dans X. Puis on met
dans le deuxième registre
8
bits A, la valeur (COORL) du numéro de ligne (en coordonnée caractère) va
s'afficher le logo. Il faut multiplier par 8, cette coordonnée caractère de la
ligne pour avoir sa valeur en coordonnée graphique. Donc, on met la valeur 8
dans le registre
B(il
est libre),celle-ci sera notre multiplicateur et on écrit la puissante
instruction MUL qui a pour effet de multiplier le contenu de A par B en rangeant le résultat dans D(D est un
registre 16 bits formé par l'association de A et de B). La il y a une astuce,
car en fait le résultat de 8 multiplié par le numéro
de
la ligne (en coordonnée caractère) étant toujours inférieur à 255 n'occupera
que 8 bits donc la partie droite de l'accumulateur 16 bits D !
Donc on pourra en toute tranquillité charger la
valeur &H28 dans la partie gauche de D, donc A sans altérer le
contenu de B. Et on emploie à nouveau l'instruction MUL pour multiplier
les contenus de A et de B avec rangement du résultat dans D. On obtiendra
finalement le résultat de notre formule (pour calculer l'adresse mémoire d'un
segment)en ajoutant la valeur de l'adresse du premier segment d'écran. C'est le
rôle de l'instruction LEAX D,X, car X pointera maintenant sur
l'adresse du segment débutant colonne C ligne L. La valeur
indiqué par X sera utilisé pour la suite pour y envoyer les données vers la
mémoire vidéo. La suite du programme consiste à afficher
ligne par ligne chacun des segments, en envoyant dans la mémoire vidéo les valeurs de chaque segment
.On commence par sélectionner la mémoire forme ou RAM A(la RAM B étant la
mémoire couleurs).
*commutation
mémoire forme
LDA
$E7C3
ORA #$01
STA
$E7C3
Il
s'agit par ces 3 instructions dedonner la valeur 1 au bit n° de l'octet
d'adresse &HE7C3 pour réaliser cette communication. Le
programme ira chercher les données dans la zone
mémoire que vous devrez préciser et qui sera repérée par des étiquettes. Un peu comme en
BASIC on met des données à l'aide de l'instruction DATA et on repère ces
données grâce aux numéros de lignes.
Les
données utilisées par le programme sont d'une part le numéro de ligne et le
numéro de colonne sera affiché le bord
supérieur gauche du LOGO, et d'autre part les caractéristiques du LOGO soit les
codes des 48 segments qui le composent.
Laissons
là notre programme en sautant quelques lignes et écrivons en fin de listing
l'ensemble de ces données. Comme nous avons décidé de ranger le code du
programme à partir de l'adresse
&H8000, celui-ci sera rangé dans
les adresses &H8000,&H8001,&H8002 etc..
Pour ne pas prendre de risque de chevauchement entre la zone du programme et celle des données prenons l'adresse &H8100 pour ranger la première donnée.
*rangement
des données
ORG
&8100
COORC
FCB &H15
LOGO
FCB $FF,$FF,$80,$80,$00,$80
FCB $80,$00,$80,$BC,$7E,$80
FCB
$A4,$02,$80,$A4,$06,$80
FCB $A4,$0C,$80,$BC,$18,$80
FCB $A4,$C0,$80,$BD,$80,$80
FCB $A4,$C0,$80,$80,$00,$80
FCB $80,$00,$80,$80,$00,$80
FCB $80,$00,$80,$FF,$FF,$80
END
L'étiquette
COORC pointera sur l'adresse &H8100 qui contient la valeur
décimale (désignée par &) 15 représentant le numéro de colonne, l'étiquette
COORL pointera sur l'adresse &H8101 contenant la valeur 10,
puis LOGO pointera sur l'adresse &H8102 contenant la valeur segment
du logo. FCB est une directive d'assemblage qui permet de réserver un
espace de 8 bits pour y ranger une valeur.
Remontons
dans la suite de notre programme et écrivons les instructions pour transférer
les données.
*récupération
et transfert des données
LDY #LOGO
LDA #&16
LSUIV LDB
,Y+
STB
,X+
LDB
,Y+
LDB
,Y+
STB
,X
On
charge dans le registre 16 bits Y l'adresse pointée par l'étiquette LOGO
(cette adresse vaut &H8102) et on se sert du registre A pour compter
les lignes à afficher( 16 lignes au total). On démarre par l'étiquette LSUIV,
une boucle de transfert de données pour chacune des 16 lignes avec 3 segments
par
ligne. On met dans B le contenu de l'adresse pointé par Y(donc la valeur située
en &H8102 soit $FF) puis on augmente Y de
1
et la prochaine adresse pointée sera &H8103 qui contient la seconde
valeur soit $FF. On range ensuite la valeur contenue dans
B
à l'adresse indiqué par le registre X (celui-ci rappelons le conserve l'adresse
de la mémoire vidéo). On augmente de 1 l'adresse vidéo pour pointer sur le
segment suivant et on
recommence
trois fois la même opération en augmentant à chaque fois de 1 les registres Y
et X pour récupérer la valeur suivante du logo et passer à la case mémoire
vidéo suivante.
Une
fois le troisième segment affiché il n'est plus question de continuer sue la
même ligne mais il faut passer à la ligne du dessous et s'aligner à nouveau sur
la colonne de gauche.
Pour
cela il faut retrouver la bonne adresse vidéo correspondante.
LEAX $26,X
DECA
BNE LSUIV
PULS A,B,DP,X,Y,U
SWI
On
fait pointer alors X sur le 1er segment de la ligne du dessous donc pour
obtenir son adresse à partir de l'adresse du 3ème segment que l'on vient de
traiter on ajoute 40 et on retranche 2 soit ajouter 38 (38 s'écrit 26 en héxa).
On diminue de 1 notre compteur de ligne et s'il n'est pas nul on aura pas fini
de
traiter
les 16 lignes on recommence la boucle en se branchant à l'endroit du programme
désigné par LSUIV (début de
la
boucle ).
Quand
le compteur de ligne est à zéro le programme se termine, on récupère le contenu
des registres par PULS et on termine par l'instruction d'interruption SWI
(non pas RTS car on exécutera ce
programme
à partir de l'assembleur et non pas du Basic).
Rappelons
qu'a la suite de l'instruction SWI le listing du programme n'est pas
terminé puisque nous avons écrit toute
la
partie de stockage des données vue plus haut. La fin logique du programme c'est
la directive END qui est là pour
l'indiquer.
Le
programme ainsi édité s'appelle le programme source.
Il
est recommandé de le sauvegarder sur disquette avant la phase d'assemblage. Il
sera converti en langage machine par la commande A (assemblage).
Un
assemblage en mémoire permet de le tester. Pour cela quitter l'éditeur et
passer en mode moniteur par la touche X.
Une
fois dans l'environnement du moniteur le programme se lance par la commande GO,
celle-ci sera tapée après le prompt >, sous cette forme: G$8000
(cela signifie lancer le programme commençant à l'adresse &H8000)
Le
programme est interrompu dès qu'il rencontre l'instruction SWI.