; Programme pour illustrer le fonctionnement du mode write 3 du VGA. ; Affiche des caractères 8x8 à des emplacements aléatoires sans affecter ; le fond, en utilisant la police 8x8 en ROM du VGA. Conçu pour l'utilisation ; des modes 0Dh, 0Eh, 0Fh, 10h, et 12h. ; S'exécute uniquement sur les VGA ( Modèles 50 & supérieurs et IBM Display Adapter ; et 100% compatibles). ; Assemblé avec TASM 4.0, lié avec TLINK 6.10 ; Testé par Mischel 11/21/94 ; stack segment para stack 'STACK' db 512 dup(?) stack ends ; VGA_VIDEO_SEGMENT equ 0a000h ;segment de la mémoire vidéo de VGA SCREEN_WIDTH_IN_BYTES equ 044ah ;offset de la variable BIOS FONT_CHARACTER_SIZE equ 8 ;nombre d'octets dans chaque caractère ;de police ; ; registre VGA équivaut à. ; SC_INDEX equ 3c4h ;registre index SC SC_MAP_MASK equ 2 ;index du registre map mask SC GC_INDEX equ 3ceh ;registre index GC GC_SET_RESET equ 0 ;index registre set/reset GC GC_ENABLE_SET_RESET equ 1 ;index registre enable set/reset GC GC_ROTATE equ 3 ;index registre de rotation ;des données/fonction logique GC_MODE equ 5 ;registre mode de GC GC_BIT_MASK equ 8 ;index registre du masque de bit de ;GC dseg segment para common 'DATA' TEST_TEXT_ROW equ 69 ;rangée à afficher du texte test TEST_TEXT_COL equ 17 ;colonne à afficher du texte test TEST_TEXT_WIDTH equ 8 ;largeur d'un caractère en pixels TestString label byte db 'Hello, world!',0 ;chaîne test à afficher. FontPointer dd ? ;offset de la police dseg ends ; cseg segment para public 'CODE' assume cs:cseg, ds:dseg start proc near mov ax,dseg mov ds,ax ; ; Sélectionne le mode graphique 640x480. ; mov ax,012h int 10h ; ; Paramètre l'écran tout en bleu, en utilisant la lisibilité des registres VGA ; pour préserver les bits réservés. ; mov dx,GC_INDEX mov al,GC_SET_RESET out dx,al inc dx in al,dx and al,0f0h or al,1 ;seul le plan est initialisé, ;les autres sont réinitialisés out dx,al dec dx mov al,GC_ENABLE_SET_RESET out dx,al inc dx in al,dx and al,0f0h or al,0fh ;active set/reset pour tous les ;plans out dx,al mov dx,VGA_VIDEO_SEGMENT mov es,dx ;pointe sur la mémoire vidéo mov di,0 mov cx,8000h ;remplit tous les 32k mots mov ax,0ffffh ;à cause de set/reset, la valeur ;écrite actuellement n'a pas ;d'importance rep stosw ;remplit en bleu ; ; Paramètre le pilote pour utiliser la police 8x8. ; mov ah,11h ;fonction génératrice de ;caractère du BIOS VGA, mov al,30h ;retourne les informations mov bh,3 ;récupère le pointeur de police ;8x8 int 10h call SelectFont ; ; Affiche la chaîne test, en faisant défiler les couleurs. ; mov si,offset TestString mov bx,TEST_TEXT_ROW mov cx,TEST_TEXT_COL mov ah,0 ;commence par la couleur 0 StringOutLoop: lodsb and al,al jz StringOutDone push ax ;préserve la couleur call DrawChar pop ax ;restaure la couleur inc ah ;prochaine couleur and ah,0fh ;plage de couleurs de 0 à 15 add cx,TEST_TEXT_WIDTH jmp StringOutLoop StringOutDone: ; ; Attend une touche clavier, puis paramètre le mode texte & fin. ; mov ah,1 int 21h ;attend une touche clavier mov ax,3 int 10h ;restaure le mode texte ; ; Quitte vers DOS. ; mov ah,4ch int 21h Start endp ; ; Routine pour afficher un caractère texte dans un mode graphique linéaire ; (0Dh, 0Eh, 0Fh, 010h, 012h).Le fond autour des pixels qui forment ; le caractère est préservé. ; La police utilisée doit être pointée par FontPointer. ; ; Input: ; AL = caractère à afficher ; AH = couleur à afficher dans le caractère (0-15) ; BX = rangée du caractère texte à afficher ; CX = colonne du caractère texte à afficher ; ; Force la fonction ALU à "se déplacer". ; Force le mode write 3. ; DrawChar proc near push ax push bx push cx push dx push si push di push bp push ds push ax ;preserve le caractère à afficher ;dans AL ; ; Configure set/reset pour produire la couleur du caractère, en utilisant la ; lisibilité du registre VGA pour préserver le paramétrage des bits réservés 7-4. ; mov dx,GC_INDEX mov al,GC_SET_RESET out dx,al inc dx in al,dx and al,0f0h and ah,0fh or al,ah out dx,al ; ; Sélectionne le mode write 3, en utilisant la lisibilité du registre VGA ; pour laisser tels quels les bits autres que ceux du mode write. ; mov dx,GC_INDEX mov al,GC_MODE out dx,al inc dx in al,dx or al,3 out dx,al ; ; Positionne DS:SI pour pointer sur la police et ES pour pointer sur la mémoire ; vidéo. ; lds si,[FontPointer] ;pointe sur la police mov dx,VGA_VIDEO_SEGMENT mov es,dx ;pointe sur la mémoire vidéo ; ; Calcule l'adresse d'écran du début de l'octet du caractère. ; pop ax ;récupère le caractère à ;afficher dans AL push ds ;pointe sur le segment des ;données BIOS sub dx,dx mov ds,dx xchg ax,bx mov di,ds:[SCREEN_WIDTH_IN_BYTES] ;reprend la ;largeur d'écran ;BIOS pop ds mul di ;calcule l'offset du début de ;la rangée push di ;met de coté la largeur d'écran mov di,cx ;met de coté la colonne and cl,0111b ;garde seulement l'adresse de ; la colonne dans l'octet shr di,1 shr di,1 shr di,1 ;divise la colonne par 8 pour ;faire une adresse 8 bits add di,ax ;et pointe sur l'octet ; ; Calcule l'adresse de la police du caractère. ; sub bh,bh shl bx,1 ;nécessite 8 octets par ;caractère utilise shl bx,1 ;un mulitplicateur sinon shl bx,1 ;offset dans la police du ;caractère add si,bx ;offset dans le segment du ;caractère ; ; Configure la rotation GC. Dans le mode write 3, il s'agit de la rotation ; de la donnée du processeur avant d'avoir effectué un AND avec le registre Bit ; Mask pour former le masque de bits. Force la fonction ALU à "se déplacer". Utilise ; la lisibilité du registre VGA pour laisser tels quels les bits réservés. ; mov dx,GC_INDEX mov al,GC_ROTATE out dx,al inc dx in al,dx and al,0e0h or al,cl out dx,al ; ; Configure BH comme masque de bits de la moitié gauche, BL comme rotation de la ; moitié droite. ; mov bx,0ffffh shr bh,cl neg cl add cl,8 shl bl,cl ; ; Affiche le caractère, la moitié gauche, puis la moitié droite dans ; l'octet suivant, en utilisant la rotation de donnée pour positionner le ; caractère dans la plage d'octet puis en utilisant le mode write 3 pour combiner ; la donnée du caractère au masque de bits et activer la valeur set/reset ; (la couleur du caractère) seulement dans la partie correcte (là où les bits de ; la police du caractère sont à 1)du caractère pour chaque octet. ; Si les bits de la police du caractère sont à 0, la couleur ; de fond est préservée. ; Ne vérifie pas si le caractère est aligné sur un octet, ni si une ; rotation ou une seule écriture sont requises. ; mov bp,FONT_CHARACTER_SIZE mov dx,GC_INDEX pop cx ;récupère la largeur d'écran dec cx dec cx ; -2 car cela fait deux octets ; pour chaque caractère CharacterLoop: ; ; Paramètre le masque de bits pour la moitié gauche du caractère. ; mov al,GC_BIT_MASK mov ah,bh out dx,ax ; ; Récupère le prochain octet du caractère & l'écrit dans la mémoire vidéo. ; (moitié gauche du caractère.) ; mov al,[si] ;récupère l'octet du caractère mov ah,es:[di] ;charge les latches stosb ;écrit l'octet du caractère ; ; Paramètre le masque de bits pour la moitié droite du caractère. ; mov al,GC_BIT_MASK mov ah,bl out dx,ax ; ; Re-récupère l'octet du caractère &l'écrit dans la mémoire vidéo. ; (moitié droite du caractère.) ; lodsb ;récupère l'octet du caractère mov ah,es:[di] ;charge les latches stosb ;écrit l'octet du caractère ; ; Pointe sur la prochaine ligne du caractère dans la mémoire vidéo. ; add di,cx ; dec bp jnz CharacterLoop ; pop ds pop bp pop di pop si pop dx pop cx pop bx pop ax ret DrawChar endp ; ; Paramètre le pointeur sur la police à afficher depuis ES:BP. ; SelectFont proc near mov word ptr [FontPointer],bp ;sauve le ;pointeur mov word ptr [FontPointer+2],es ret SelectFont endp ; cseg ends end start