Copy Link
Add to Bookmark
Report

Tutorial Assembleur - Chapitre 07a

eZine's profile picture
Published in 
Tutorial Assembleur
 · 11 Oct 2020

  

TUTORIAL ASSEMBLEUR - chapitre 7
--------------------------------

Programmation graphique
-----------------------

Introduction
------------

Nous allons aborder un vaste sujet. En effet, il existe une infinité de possibilités
pour créer des effets avec un ordinateur. J'essayerais d'être simple et d'aller progressivement
pour éviter les confusions. Tout d'abord, nous verrons la mémoire vidéo, les différents
modes vidéos du BIOS. Nous ne verrons pas spécialement les autres modes
(svga, mode-X, fakemode, truecolor..), il existe assez de docs sur ces modes et je m'en tiens
à un cours d'introduction.

La mémoire vidéo
----------------

Il existe un emplacement en mémoire qui s'appelle la mémoire video (VRAM = video-ram).
Ce bloc de 64ko (en mode réel) commence à partir de l'adresse 0a000h:0000.
Pour pouvoir utiliser cette emplacement, il faut initialiser depuis un mode texte
(ou un autre mode graphique), le mode video désiré.

Nous utiliserons tout d'abord pour sa simplicité, le mode 013h de l'interruption 010h. Ce mode
possède une résolution de 320x200. Nous aurons donc 320 pixels en largeur et 200 en hauteur.
Le nombre de couleurs est de 256, ce qui permet déjà pas mal de chose.

Dans ce mode, il suffit d'écrire la couleur du pixel (un byte) dans la mémoire.
La position du pixel dans la mémoire n'est pas calculée selon les coordonnées X,Y
mais linéairement. Normalement, dans un language comme le BASIC, on utilise l'instruction
PSET (X,Y),couleur. En asm, on ne va pas utiliser 2 valeurs pour adresser directement
dans la mémoire mais un seul offset.

Il faut donc convertir ces coordonnées X,Y en adresse linéaire et exploitable.
Nous utilisons la formule :

[(Y*320)+X]=offset_du_pixel.

Pour mieux comprendre ce qui se passe, voici un schéma de la VRAM :

0 319 (dernier pixel de la ligne)
ligne 0 : **********************************
ligne 1 : **********************************
320 640


Les pixels sont disposés les un après les autres. Un pixel à la position (12,79) aura
comme offset :

(79*320)+12 = 25292

Nous voulons un pixel de couleur 14 (couleur jaune pour la palette standard du DOS),
nous écrirons à après avoir initialisé le mode vidéo et les registres, le byte de valeur 14
à l'adresse 0a000h:025292d.

Un petit exemple directement compilable dans A86:

MOV AX,013h ; nous utilisons le mode 013h => 320x200x256c
INT 10h ; l'interruption 10h utilisée pour tout ce qui concerne la vidéo
MOV AX,0A000h ; on place 0A000h dans AX que l'on va
MOV ES,AX ; transférer dans ES
MOV AL,14 ; pixel index 14 => jaune
MOV ES:[25292],AL ; on ne peut pas écrire directement MOV ES:[25292],14
RET ; même chose que MOV AX,04ch - INT 21h
; mais en plus court => fin programme

Vous aurez un beau pixel jaune sur l'écran =8)

Cependant, il reste un petit problème, nous sommes restés dans le mode 013h en revenant au DOS
et nous n'avons plus de mode texte. La solution consiste à placer avant le RET, les instructions
suivantes :

MOV AX,03h
INT 10h

Nous mettons d'abord 03h pour signaler que nous voulons le mode texte 03h (80x25) et INT 10h
pour initialiser le mode. Vous n'aurez plus le temps de voir votre pixel. Il faut ajouter
avant le retour en mode texte, ces instructions :

XOR AX,AX ; toujours utiliser XOR pour mettre des registres à 0
INT 16h ; interruption du clavier

Vous aurez ainsi le temps de voir votre pixel et tant que vous ne touchez pas votre clavier,
vous pourrez l'admirer, l'interruption 16h attend que vous appuyez sur une touche pour
continuer et passer aux instructions qui suivent. Nous avons donc au final, le
petit programme suivant :

MOV AX,013h ; nous utilisons le mode 013h => 320x200x256c
INT 10h ; l'interruption 10h utilisée pour tout ce qui concerne la vidéo
MOV AX,0A000h ; on place 0A000h dans AX que l'on va
MOV ES,AX ; transférer dans ES
MOV AL,14 ; pixel index 14 => jaune
MOV ES:[25292],AL ; on ne peut pas écrire directement MOV ES:[25292],14
XOR AX,AX ; comme MOV AX,0 mais plus court
INT 16h ; interruption du clavier - attente de l'appui d'une touche
MOV AX,03h ; mode texte
INT 10h ; on l'appelle
RET ; retour au DOS

Effacer l'écran
---------------

Maintenant que nous avons quelques notions et que nous savons utiliser les boucles
(si vous ne savez pas, retournez aux autres chapitres, c'est indispensable), nous allons
effacer l'écran avec la couleur 0 qui est le noir tant que vous ne touchez pas à la palette.
En ce qui concerne celle-ci, nous verrons dans une prochaine leçon, comment la modifier.

Nous avons à effacer exactement 64000 bytes. Nous n'allons pas les effacer un à un mais
directement deux par deux (16 bits) ou quatre par quatre en 32 bits. Il suffit de créer
une boucle qui les effacera et regardera si nous sommes à la fin de l'écran.
Pour gagner la vitesse, nous utiliserons des words et des dwords au lieu des bytes.

Voici un exemple :

MOV AX,013h ; nous utilisons le mode 013h => 320x200x256c
INT 10h ; l'interruption 10h utilisée pour tout ce qui concerne la vidéo
MOV AX,0A000h ; on place 0A000h dans AX que l'on va
MOV ES,AX ; transférer dans ES
XOR DI,DI ; premier pixel de l'écran
MOV AX,0 ; on met AX à 0, AL et AH = 0 = noir

Debut:
MOV ES:[DI],AX ; on place directement le word à l'emplacement de DI
ADD DI,2 ; on travaille avec des Words donc on augmente de deux et plus de un
CMP DI,64000 ; on regarde si on dépasse
JNAE Debut ; (saute si pas supérieur), dès que nous avons DI>=64000, stop
MOV AX,03h ; mode texte
INT 10h ; on l'appelle
RET ; retour au DOS

Nous avons vu dans le précedent chapitre, que l'utilisation de STOSB permettait
de remplacer des MOV, nous allons diminuer la taille du programme:

MOV ax,013h
INT 010h ; ca reste la meme chose
PUSH 0a000h
POP es ; permet de diminuer la taille d'un byte, on utilise la pile
XOR di,di
XOR ax,ax ; met di à 0 et ax=couleur à 0 aussi

MOV cx,32000 ; nous allons effacer 32000 words = 64000 bytes
REP STOSB ; MOV ES:[DI],ax ¦ ADD DI,2 ¦ et ceci, 32000 fois.
MOV al,03h ; pas besoin d'initialiser AX à 03, AH est déjà à 0
INT 010h ; on initialise que AL et on appelle l'interruption
RET

C'est de cette manière que l'on procède dès que l'on optimise du code pour la taille
(intros 4k..). Faites attention aux bugs lors des optimisations.

### Chapitre 7 - dake / c a l o d o x ###
### http://www.space.ch/scene/calodox ###

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT