Revenir au plan du site
Afficher un caractère en programmation système et hardware
Si vous n'avez pas encore commencé à lire la présentation de l'assembleur Z80 ou que vous ne connaissez pas l'assembleur, il n'est pas nécessaire de le connaitre pour lire cet article.
Le but de cette présentation est uniquement de montrer comment des programmes fonctionnent, quelles sont les avantages et inconvénients de tel ou tel type de programmation.
Voici l'affichage du mot CPC suivi d'un retour chariot en programmation système. On voit que le programme est très simple et qu'une fonction est dédiée à l'affichage des caractères. ce programme va fonctionner dans toutes les résolutions de sortie (basse, moyenne, haute) et avec toutes les encres possibles. Les routines sont très flexibles mais ça se paie au prix fort.
ld A,'C' : call #BB5A ; le vecteur #BB5A permet d'afficher le caractère
ld A,'P' : call #BB5A ; dont la valeur ASCII est dans le registre A
ld A,'C' : call #BB5A
ld A,10 : call #BB5A
ld A,13 : call #BB5A
ret
|
Pour la forme, nous allons créer une fonction qui n'existe pas dans le système, afin d'afficher une chaine de caractères et s'arrêter au caractère zéro.
ld hl,message
affiche_chaine
ld a,(hl) : inc hl ; récupérer la valeur dans le tableau et incrémenter le pointeur
or a : ret z ; est-ce que la valeur est zéro? Si oui on sort
call #BB5A ; afficher le caractère
jr affiche_chaine
message defb 'CPC',10,13,0
|
Que se passe-t'il si nous devons tout faire nous même? Hé bien pour commencer, il va nous falloir une fonte de caractères! Le système utilise celle stockée
dans la ROM qui est une fonte prévue pour la haute résolution, le mode 2. À partir de cette fonte, le système est capable de la reconstruire pour les
autres résolutions, tout en ajoutant un système complexe afin de gérer chaque encre.
Nous concernant, l'exemple suivant s'appliquera au mode 1. Nous pouvons récupérer la routine affiche_chaine mais il faudra effectivement afficher le
caractère à un moment ou un autre!
ld hl,message
affiche_chaine
ld a,(hl) : inc hl ; récupérer la valeur dans le tableau et incrémenter le pointeur
or a : ret z ; est-ce que la valeur est zéro? Si oui on sort
push hl : call affiche_caractere : pop hl ; on a besoin de conserver notre pointeur HL
jr affiche_chaine
message defb 'CPC',0
affiche_caractere
ld h,0 : ld l,a : add hl,hl : add hl,hl : add hl,hl : add hl,hl ; nos caractères font 16 octets
ld bc,fonte : add hl,bc ; HL=adresse des données du caractère dans le tableau fonte
ld de,(position_char) ; on récupère la position du curseur
; et on affiche
ld xl,8 ; sur 8 lignes, nous pouvons utiliser IX ^_^
ld bc,#800-1 ; pour passer à la ligne suivante et revenir sur l'octet d'avant
affiche_ligne_caractere
ld a,(hl) : inc hl : ld (de),a : inc de ; lecture du premier octet et écriture à l'écran
ld a,(hl) : inc hl : ld (de),a ; lecture du deuxième, écriture à l'écran
ex hl,de : add hl,bc : ex hl,de ; on ajoute BC à DE (on permute deux fois HL et DE pour faire l'addition)
; le retour à la ligne est fait, on peut continuer
dec xl : jr nz,affiche_ligne_caractere
; terminé, il faut avancer notre curseur
ld hl,(position_char) : inc hl : inc hl : ld (position_char),hl
ret
position_char defw #C000
fonte ; données de la fonte
|
Notre routine d'affichage est très simple, le code n'est pas énorme (il serait un peu plus long avec des optimisations...) Elle ne gère pas le retour chariot, c'était pour donner une idée de la complexité qu'il y a
à se passer du système. Maintenant, nous allons réaliser une mesure du temps nécessaire pour exécuter nos deux programmes. Dans un souci d'équité, la mesure du programme système ne concerne que les trois premiers
caractères, je n'ai pas mis le retour chariot.
Temps d'éxécution du programme pur système : +9000 nops
Temps d'éxécution du programme pur hardware : 800 nops
On est quand même sur un facteur 10 en vitesse...