; Programme pour illustrer les deux pages disponibles en mode 320x400 ; en 256 couleurs sur VGA. Affiche des barres de couleur en diagonale ; avec toutes les 256 couleurs à la page 0, puis fait de même à la page 1 (mais ; les barres sont inclinées dans l'autre sens), enfin affiche des barres de ; de couleur verticale dans la page 0. ; ; Assemblé avec TASM 4.0, lié avec TLINK 6.10 ; Testé par Jim Mischel 11/21/94 ; VGA_SEGMENT equ 0a000h SC_INDEX equ 3c4h ;registre Index Sequence Controller GC_INDEX equ 3ceh ;registre Index Graphics Controller CRTC_INDEX equ 3d4h ;registre Index CRT Controller MAP_MASK equ 2 ;index du registre Map Mask dans SC MEMORY_MODE equ 4 ;index du registre Memory Mode ;dans SC MAX_SCAN_LINE equ 9 ;index du registre Maximum Scan Line ;dans CRTC START_ADDRESS_HIGH equ 0ch ;index du registre Start Address High ;dans CRTC UNDERLINE equ 14h ;index du registre Underline Location ;dans CRTC MODE_CONTROL equ 17h ;index du registre Mode Control dans ;CRTC GRAPHICS_MODE equ 5 ;index du registre Graphics Mode ;dans GC MISCELLANEOUS equ 6 ;index du registre Miscellaneous ;dans GC SCREEN_WIDTH equ 320 ;nombre de pixels au travers de ;l'écran SCREEN_HEIGHT equ 400 ;nombre de lignes d'affichage à ;l'écran WORD_OUTS_OK equ 1 ;à 0 pour assembler pour les ; ordinateurs qui ne peuvent pas traiter ;les outs de mot dans les registres indexés VGA stack segment para stack 'STACK' db 512 dup (?) stack ends ; ; Macro pour sortir une valeur de mot sur un port. ; OUT_WORD macro if WORD_OUTS_OK out dx,ax else out dx,al inc dx xchg ah,al out dx,al dec dx xchg ah,al endif endm ; ; Macro pour sortit une valeur constante sur un registre indexé VGA. ; CONSTANT_TO_INDEXED_REGISTER macro ADDRESS, INDEX, VALUE mov dx,ADDRESS mov ax,(VALUE shl 8) + INDEX OUT_WORD endm ; Code segment assume cs:Code Start proc near ; ; Paramètre le mode 320x400 en 256-couleurs. ; call Set320By400Mode ; ; Nous sommes en mode 320x400 en 256 couleurs, la page 0 est affichée. ; Remplissons la page 0 de barres de couleur inclinées vers le bas et à droite ; sub di,di ;la page 0 commence à l'adresse 0 mov bl,1 ;les barres de couleur sont inclinées ;vers le bas et à droite call ColorBarsUp ;affiche les barres de couleur ; ; Faisons de même pour la page 1, mais les barres de couleur ; sont inclinées dans l'autre sens. ; mov di,8000h ;la page 1 commencent à l'adresse ;000h mov bl,-1 ;les barres de couleur sont inclinées ;vers le bas ; et vers la gauche call ColorBarsUp ;affiche les barres de couleur ; ; Attend une touche clavier et passe à la page 1 une fois une touche appuyée. ; call GetNextKey CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,8 ;0h ;positionne le registre Start Address High ;à 80h, pour une adresse de départ 8000h ; ; Affiche les barres verticales dans la page 0 alors que la page 1 est affichée. ; ; sub di,di ;la page 0 commence à l'adresse 0 sub bl,bl ;met les barres de couleur à la verticale call ColorBarsUp ;affiche les barres de couleur ; ; Attend une touche clavier et revient à la page 0 une fois une touche appuyée. ; call GetNextKey CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,0 ;0h ;positionne le registre Start Address High ;à 00h, pour une adresse de départ 0000h ; ; Attend une touche clavier et revient en mode texte puis fini après ; une touche clavier. ; call GetNextKey mov ax,0003h int 10h ;mode texte mov ah,4ch int 21h ;nous avons fini ; Start endp ; ; Configure le mode 320x400 en 256 couleurs. ; ; Entrée: aucune ; ; Sortie: aucune ; Set320By400Mode proc near ; ; Premièrement, passe en mode normal 320x200 256 couleurs, qui est un ; mode 320x400 en 256 couleurs dont chaque ligne est doublées; mov ax,0013h ;AH = 0 mode initialisé, AL = 13h ;sélectionne ;le mode graphique 256 couleurs int 10h ;interruption vidéo du BIOS ; ; Change l'adressage CPU de la mémoire vidéo en linéaire (ni pair/impair, ; ni chaîne, ni chain 4), pour nous permettre d'accéder à tous les 256K de ; mémoire vidéo. Une fois fait, la mémoire VGA ressemblera à la mémoire ; en modes 10h et 12h, excepté que chaque octet de la mémoire vidéo ; contrôlera un pixel de 256 couleurs, avec 4 pixels adjacents à toute adresse ; donnée, un pixel par plan. ; mov dx,SC_INDEX mov al,MEMORY_MODE out dx,al inc dx in al,dx and al,not 08h ;désactive la chaîne 4 or al,04h ;désactive pair/impair out dx,al mov dx,GC_INDEX mov al,GRAPHICS_MODE out dx,al inc dx in al,dx and al,not 10h ;désactive pair/impair out dx,al dec dx mov al,MISCELLANEOUS out dx,al inc dx in al,dx and al,not 02h ;désactive la chaîne out dx,al ; ; Efface maintenant l'écran dans son entier, car le mode 13h mode initialisé ; a effacé seulement 64K des 256K de la mémoire vidéo CONSTANT_TO_INDEXED_REGISTER SC_INDEX,MAP_MASK,0fh ;active les écritures de tous les plans, ;nous pouvons donc effacer 4 pixels à la fois mov ax,VGA_SEGMENT mov es,ax sub di,di mov ax,di mov cx,8000h ;nombre de mots dans 64K cld rep stosw ;efface toute la mémoire vidéo ; ; Règle le mode en mode 320x400 256 couleurs en ne parcourant pas chaque ; ligne deux fois. ; mov dx,CRTC_INDEX mov al,MAX_SCAN_LINE out dx,al inc dx in al,dx and al,not 1fh ;paramètre la ligne d'affichage ; maximale = 0 out dx,al dec dx ; ; Change le parcours CRTC du 32 bits en mode octet, permettant à ; CRTC de parcourir plus de 64K de données vidéo. ; mov al,UNDERLINE out dx,al inc dx in al,dx and al,not 40h ;désactive le mot long out dx,al dec dx mov al,MODE_CONTROL out dx,al inc dx in al,dx or al,40h ;active le bit du mode octet, la mémoire ;est donc parcourue de manière linéaire ;comme dans les modes 10h et 12h out dx,al ret Set320By400Mode endp ; ; Affiche en plein écran les barres de couleur inclinées dans la page spécifiée ;. ; ; Entrée: ; DI = adresse de départ de la page ; BL = 1 pour incliner les barres vers le bas et vers la droite, -1 pour ; les incliner vers le bas et vers la gauche, 0 pour les mettre ; à la verticale. ; ColorBarsUp proc near mov ax,VGA_SEGMENT mov es,ax ;pointe sur la mémoire vidéo sub bh,bh ;commence à la couleur 0 mov si,SCREEN_HEIGHT ;nombre de rangées à traiter mov dx,SC_INDEX mov al,MAP_MASK out dx,al ;le registre Index SC pointe sur le ;registre Map Mask inc dx ;DX pointe sur le registre Data SC RowLoop: mov cx,SCREEN_WIDTH/4 ;il y a 4 pixels à chaque adresse, aussi ; chaque rangée de 320 pixels est large de 80 octets ; dans chaque plan push bx ;sauve la couleur de départ de la ;rangée ColumnLoop: MAP_SELECT = 1 rept 4 ;fait les 4 pixels à cette adresse ;avec un code en ligne mov al,MAP_SELECT out dx,al ;sélectionne les plans 0, 1, 2, et 3 ; l'un après l'autre mov es:[di],bh ;écrit le pixel de ce plan inc bh ;paramètre la couleur pour le ;prochain pixel MAP_SELECT = MAP_SELECT shl 1 endm inc di ;pointe sur l'adresse contenant les ;4 prochains pixels loop ColumnLoop ;traite tous les autres pixels ;de cette ligne pop bx ;récupère la couleur de départ de la ;rangée add bh,bl ;sélectionne la couleur de départ de ;la prochaine rangée (contrôle ;l'inclinaison des barres de couleur) dec si ;décompte les lignes sur l'écran jnz RowLoop ret ColorBarsUp endp ; ; Attend la prochaine touche clavier et la retourne dans AX. ; GetNextKey proc near WaitKey: mov ah,1 int 16h jz WaitKey ;attend la prochaine touche clavier ;disponible sub ah,ah int 16h ret GetNextKey endp ; Code ends ; end Start