Initiation à lassembleur 6809
Exemples de programmes
Chronomètre
Pour finir, un programme un peu plus difficile, mais qui illustrera lutilisation du vecteur IRQ.
Une interruption est une routine déclenchée à intervalles réguliers par
le système. Lexécution du programme principal est alors « interrompu » et le système
décide deffectuer lexécution du programme dinterruption. Lorsque celui-ci a été entièrement
exécuté, lexécution du programme principal reprend dans létat et à lendroit où le
système la laissé. Le clignotement du curseur à lécran, par exemple, est gèré par
un système dinterruption.
Linterruption IRQ que nous allons utiliser se déclenche tous les dixièmes de secondes.
Notre chronomètre sera donc précis au dixième de seconde.
Il faudra veiller à restaurer le pointeur dinterruption IRQ standard en sortie de programme.
Seule la mise à jour du compteur sera dans le programme dinterruption. Laffichage
se fera dans le programme principal, son temps dexécution étant trop long pour être en interruption.
Le compteur doit être récupéré en une seule instruction si lon veut que sa valeur soit exacte,
linterruption étant toujours active lors de la récupération de ce compteur et ayant la particularité
de pouvoir se déclencher entre lexécution de deux instructions mais pas PENDANT lexécution
dune instruction. Cest la raison pour laquelle on utilisera un « PULU D,X » pour
récupérer lheure, les minutes , les secondes et les dixièmes en une seule fois et sans erreur
de lecture.
Les interruptions devront être activées après que leur vecteur sera défini et désactivées
avant quil soit rétabli.
On notera lutilisation de linstruction DAA, très pratique pour assurer un
compteur en décimal. A laide de cette instruction, le registre A est ramené à un compteur en décimal :
lunité (le quartet de poids faible de A) varie de 0 à 9, la dizaine (le quartet de poids fort
de A) varie de 0 à 9 et la centaine éventuelle est expulsée dans le flag C de CC. Tout cela en vue de
réduire le programme dinterruption et daccélérer laffichage des compteurs.
Le chronomètre sera centré sur lécran, affiché en blanc sur noir avec les caractères
standard en double taille.
Lappui dune touche quelconque stoppera le chronomètre ou le relancera après
remise à 0. Lappui de la barre espace permettra de sortir du programme. Les étiquettes sont en
première colonne, le programme TO en 2ème colonne, le programme MO en 3ème colonne et les commentaires
en 4ème colonne :
DEBUT | LDU #MSIN | LDU #MSIN | Pointe sur le message dinitialisation
| BSR AFFM | BSR AFFM | Initialise lécran
* Initialisation de linterruption
| LDU #COMPT | LDU #COMPT | Pointeur sur le compteur
| CLR ,U | CLR ,U | |
| CLR 1,U | CLR 1,U | | Efface le compteur
| CLR 2,U | CLR 2,U | | du chronomètre
| CLR 3,U | CLR 3,U | |
| | LDA $2063 | Lit le flag dinterruption
| LDX $6027 | LDX $2061 | Lit le pointeur dinterruption
| PSHS X | PSHS A,X | Protège les paramètres dinterruption
| | CLR $2063 | Désactive linterruption
| LDX #CHRON | LDX #CHRON | | Place le pointeur dinterruption IRQ
| STX $6027 | STX $2061 | | personnel
| LDA $6019 | | |
| ORA #$20 | | | Active linterruption
| STA $6019 | COM $2063 | |
* Attend la frappe dune touche
B0 | SET * | SET * |
| BSR AFFIC | BSR AFFIC | Affiche le chronomètre
| JSR $E806 | CALL $0A | Attend la frappe dune touche
| TSTB | TSTB | | Si pas de touche appuyée,
| BEQ B0 | BEQ B0 | | boucle sur laffichage du chronomètre
* Stoppe le chronomètre
| LDA $6019 | CLR $2063 | |
| ANDA #$FF-$20 | | | Désactive linterruption
| STA $6019 | | |
| PULS X | PULS A,X | Récupère les paramètres dinterruptions
| STX $6027 | STX $2061 | Restaure le pointeur dinterruption IRQ
| | STA $2063 | Restaure le flag dinterruption
| PSHS B | PSHS B | Protège le code de touche appuyée
| BSR AFFIC | BSR AFFIC | Affiche le chronomètre
| PULS B | PULS B | Restaure le code de touche appuyée
* Sortie si demandée
| CMPB #$20 | CMPB #$20 | | Si code de touche appuyée est la
| BEQ FIN | BEQ FIN | | barre espace, sort du programme
* Remise à 0 du chronomètre
B0 | SET * | SET * |
| JSR $E806 | CALL $0A | Attend lappui dune touche
| TSTB | TSTB | | Si pas de touche appuyée,
| BEQ B0 | BEQ B0 | | attend lappui dune touche
| CMPB #$20 | CMPB #$20 | | Si pas barre espace, réinitialise le
| BNE DEBUT | BNE DEBUT | | compteur et relance le chronomètre
* Sortie du programme
FIN | SWI | STOP | Arrêt du programme
* Affichage du chronomètre
AFFIC | LDU #COMPT | LDU #COMPT | Pointeur sur le compteur
| PULU D,X | PULU D,X | Récupère les 4 compteurs
| PSHS D,X | PSHS D,X | Empile les 4 compteurs
| LDU #TEMPS | LDU #TEMPS | Pointe sur le message de chronomètre
| LDY #4 | LDY #4 | Affichage de 4 compteurs
B0 | SET * | SET * |
| LDB ,S | LDB ,S | Lit un compteur
| LDA #$10 | LDA #$10 | | Passe le quartet fort
| MUL | MUL | | en quartet faible dans A
| LDB ,S+ | LDB ,S+ | Relit le compteur pour quartet
faible
| ANDB #$F | ANDB #$F | | Ajuste lunité et la dizaine
| ADDD #$3030 | ADDD #$3030 | | en décimal
| STD ,U++ | STD ,U++ | Ecrit le nombre en décimal
| LEAU 1,U | LEAU 1,U | Passe le caractère « : »
| LEAY -1,Y | LEAY -1,Y | | Pour les
| BNE B0 | BNE B0 | | 4 compteurs
| LDU #POSIT | LDU #POSIT | Pointe sur le message de chronomètre
| BRA AFFM | BRA AFFM | Affiche le message de chronomètre
* Affichage dun message
B0 | SET * | SET * |
| JSR $E803 | CALL $02 | Envoie le caractère à PUTC$
AFFM | LDB ,U+ | LDB ,U+ | Lit un caractère
| BNE B0 | BNE B0 | Si pas caractère $00, caractère suivant
| RTS | RTS | Retour au programme principal
* Programme d'interruption
CHRON | LDU #COMPT+3 | LDU #COMPT+3 | Pointeur sur le compteur
* Traite les 10èmes de secondes
| LDA ,U | LDA ,U | Lit le compteur pour les centièmes
| ADDA #$10 | ADDA #$10 | Ajoute dix centièmes de seconde
| DAA | DAA | Ajuste en décimal
| BCC CHRN0 | BCC CHRN0 | Si en deçà de $100, sort du programme
| CLR ,U | CLR ,U | Met le compteur à 0
* Traite les secondes et les minutes
| LDB #2 | LDB #2 | Même chose pour les secondes et minutes
B0 | SET * | SET * |
| LDA ,-U | LDA ,-U | Lit un compteur
| INCA | INCA | Ajoute une unité
| DAA | DAA | Ajuste en décimal
| CMPA #$60 | CMPA #$60 | | Si en deçà de $60,
| BLO CHRN0 | BLO CHRN0 | | sort du programme
| CLR ,U | CLR ,U | Met le compteur à 0
| DECB | DECB | | Passe au compteur
| BNE B0 | BNE B0 | | suivant
* Traite les heures
| LDA ,-U | LDA ,-U | Lit le compteur des heures
| INCA | INCA | Ajoute une unité
| DAA | DAA | Ajuste en décimal
| CMPA #$24 | CMPA #$24 | | Si compteur en deçà de
| BLO CHRN0 | BLO CHRN0 | | $24, sort du programme
| CLRA | CLRA | Met le compteur à 0
CHRN0 | STA ,U | STA ,U | Ajourne le compteur
| JMP $E830 | RTI | Sort du programme dinterruption
COMPT | RMB 4 | RMB 4 | Buffer pour le compteur
* Message dinitialisation de lécran
MSIN | FCB $1F,$20,$20 | FCB $1F,$20,$20 | | Ouverture maximum
| FCB $1F,$12,$14 | FCB $1F,$12,$14 | | de la fenêtre
| FCB $1B,$47 | FCB $1B,$47 | Couleur de forme 7 (blanc)
| FCB $1B,$50 | FCB $1B,$50 | Couleur de fond 0 (noir)
| FCB $1B,$60 | FCB $1B,$60 | Couleur de tour 0 (noir)
| FCB $0C | FCB $0C | Efface lécran
| FCB $1F,$21,$21 | FCB $1F,$21,$21 | | Laisse seulement les lignes
| FCB $1F,$11,$12 | FCB $1F,$11,$12 | | 11 et 12 libres
| FCB $1B,$20,$54 | FCB $1B,$20,$54 | Couleur de fond 4 (bleu)
| FCB $1F,$20,$20 | FCB $1F,$20,$20 | | Réouverture maximum
| FCB $1F,$12,$14 | FCB $1F,$12,$14 | | de la fenêtre
POSIT | FCB $1F,$4C,$49 | FCB $1F,$4C,$49 | Curseur en ligne 12/colonne 9
| FCB $1B,$4F | FCB $1B,$73 | Caractères en double taille
TEMPS | FCC "00:00:00:00" | FCC "00:00:00:00" | Message du chronomètre
| FCB $1B,$4C | FCB $1B,$70 | Caractères en simple taille
| FCB 0 | FCB 0 | - Fin de message -
| END | END | Fin du programme à assembler |