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 ###