Écrire dans la mémoire vidéo VGA
Dans cet article on regarde comment on peut écrire directement dans la mémoire vidéo du mode VGA, sans passer par le BIOS.
Un point sur la situation
Prenons deux secondes pour regarder ce qu’on a fait jusqu’ici :
- charger des secteurs du disque dur vers la mémoire
- écrire des chaînes de caractères à l’écran
Tout cela, on l’a réalisé à l’aide du BIOS. Mais lorsqu’on passera dans un futur proche en 32 bits (mode protégé) nous n’aurons plus accès au BIOS. On va donc devoir trouver d’autres moyens pour continuer à réaliser ces actions. Une chose à la fois, aujourd’hui on regarde le fonctionnement de base de la mémoire vidéo du VGA.
Mode texte couleur
Quand le PC démarre, il est en mode texte, 80 colonnes sur 25 lignes, en couleur. En couleur seulement si le moniteur est lui-même couleur, mais on va supposer que c’est le cas et oublier les moniteurs monochromes. La mémoire vidéo texte couleur est mappée à l’adresse 0xb8000. Chaque lettre/case/cellule est codée sur deux octets : un octet pour le code ASCII et un second pour la couleur.
| Adresse | Fonction |
|---|---|
| 0xb8000 | code ASCII rangée supérieure, première colonne (coin en haut à gauche) |
| 0xb8001 | couleur rangée supérieure, première colonne |
| 0xb8002 | code ASCII rangée supérieure, deuxième colonne |
| 0xb8003 | couleur rangée supérieure, deuxième colonne |
Pour l’octet de couleur, voici comment il est codé :
- les bits 0 à 3 définissent la couleur de premier plan (16 possibles)
- les bits 4 à 6 définissent la couleur d’arrière-plan (8 possibles)
Et le bit 7 ? On ne va pas l’utiliser car il dépend du matériel. Mais sur Qemu il permettra d’accéder à 16 couleurs pour l’arrière-plan.
La liste des couleurs :
- 0 noir
- 1 bleu
- 2 vert
- 3 cyan
- 4 rouge
- 5 rose
- 6 marron
- 7 gris clair
- 8 gris foncé
- 9 bleu clair
- 10 vert clair
- 11 cyan clair
- 12 rouge clair
- 13 rose clair
- 14 jaune
- 15 blanc
Du code
On modifie message.nasm :
org 0x9000
bits 16
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
mov ebx, 0xb8000 ; (1)
mov byte [ebx], 'B'
inc ebx ; (2)
mov byte [ebx], 0x34
cli ; (3)
hlt
times 512-($-$$) db 0
(1) mov ebx, 0xb8000
mov byte [ebx], 'B'
On charge EBX avec l’adresse de début de la mémoire vidéo, 0xb8000. Puis on met le code ASCII de la lettre B à cette adresse. Notez au passage qu’on peut très bien utiliser comme ici un registre 32 bits (EBX) alors qu’on est en mode 16 bits.
(2) inc ebx
mov byte [ebx], 0x34
On passe à l’adresse suivante, 0xb8001, pour y mettre la couleur. 0x34 nous donne du rouge sur fond cyan.
(3) cli
hlt
Rien à voir avec le VGA et la mémoire vidéo.
J’ai remplacé l’ancien jmp $ par cli et hlt. Je trouve ça plus propre.
L’instruction hlt met le processeur en pause jusqu’à la prochaine interruption.
C’est pourquoi on désactive d’abord les interruptions avec cli.
Jeu de caractères
Normalement, le PC devrait avoir le jeu de caractères dit code page 437. Un ASCII étendu avec des accents et quelques caractères semi-graphiques. On peut tester :
org 0x9000
bits 16
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
mov ebx, 0xb8000
mov byte [ebx], 3 ; un coeur
inc ebx
mov byte [ebx], 0x0f ; blanc sur fond noir
inc ebx
mov byte [ebx], 66 ; la lettre B
inc ebx
mov byte [ebx], 0xe4 ; rouge sur fond jaune
inc ebx
mov byte [ebx], 130 ; la lettre é
inc ebx
mov byte [ebx], 0x0f ; blanc sur fond noir
cli
hlt
times 512-($-$$) db 0Résultat dans Qemu : 
Mes trois ordinateurs de test affichent bien les caractères. Mais la lettre B est en rouge clignotant sur fond marron ; c’est le problème avec le bit 7 de la couleur.
Conclusion
On est prêt à affronter le mode 32 bits en ce qui concerne l’affichage. Même si pour être honnête, on est encore loin de gérer tout le bazar nécessaire :
- afficher une chaîne
- gérer le curseur
- gérer le scrolling
Malgré tout, l’affichage d’un unique caractère à un endroit précis sans passer par le BIOS était le premier pas indispensable. Et on l’a fait.
Glossaire
ASCII — American Standard Code for Information Interchange
Jeu de codage des caractères sur 7 bits (codes 0 à 127), défini en 1963.
VGA — Video Graphic Array
Standard d’affichage qui date de 1987.
Références
Cet article fait partie d’une série :
Commentaires
Pas encore trouvé de solution simple et non-invasive pour avoir des commentaires sur le blog. En attendant vous pouvez laisser votre commentaire et/ou engager une discussion sur mastodon@lkdjiin ou twitter@lkdjiin