; Programme pour illustrer une utilisation du mode write 2 du VGA et d'EGA en ; animant l'image d'un "A" affichée en copiant une bitmap linéaire ; située en mémoire système dans la bitmap plane de la mémoire VGA ou EGA. ; Assemblé avec TASM 4.0, lié avec TLINK 6.10 ; Testé par Jim Mischel 11/21/94 ; Stack segment para stack 'STACK' db 512 dup(0) Stack ends SCREEN_WIDTH_IN_BYTES equ 80 DISPLAY_MEMORY_SEGMENT equ 0a000h SC_INDEX equ 3c4h ;registre Index de Sequence Controller MAP_MASK equ 2 ;index du registre Map Mask GC_INDEX equ 03ceh ;registre Index de Graphics Controller GRAPHICS_MODE equ 5 ;index du registre Graphics Mode BIT_MASK equ 8 ;index du registre Bit Mask Data segment para common 'DATA' ; ; Emplacement courant de "A" animé dans l'écran. ; CurrentX dw ? CurrentY dw ? RemainingLength dw ? ; ; Image d'un "A" jaune sur un fond bleu clair ; AImage label byte dw 13, 13 ;largeur, hauteur en pixels db 000h, 000h, 000h, 000h, 000h, 000h, 000h db 009h, 099h, 099h, 099h, 099h, 099h, 000h db 009h, 099h, 099h, 099h, 099h, 099h, 000h db 009h, 099h, 099h, 0e9h, 099h, 099h, 000h db 009h, 099h, 09eh, 0eeh, 099h, 099h, 000h db 009h, 099h, 0eeh, 09eh, 0e9h, 099h, 000h db 009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h db 009h, 09eh, 0eeh, 0eeh, 0eeh, 099h, 000h db 009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h db 009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h db 009h, 099h, 099h, 099h, 099h, 099h, 000h db 009h, 099h, 099h, 099h, 099h, 099h, 000h db 000h, 000h, 000h, 000h, 000h, 000h, 000h Data ends Code segment para public 'CODE' assume cs:Code, ds:Data Start proc near mov ax,Data mov ds,ax mov ax,10h int 10h ;sélectionne le mode vidéo 10h (640x350) ; ; Prépare l'animation. ; mov [CurrentX],0 mov [CurrentY],200 mov [RemainingLength],600 ;se déplace 600 fois ; ; Anime, en répétant RemainingLength fois. Il n'est pas nécessaire ; d'effacer l'ancienne image, la frange d'un pixel autour de l'image ; efface la partie de l'ancienne image non recouverte par la nouvelle image. ; AnimationLoop: mov bx,[CurrentX] mov cx,[CurrentY] mov si,offset AImage call DrawFromChunkyBitmap ;Affiche l'image "A" inc [CurrentX] ;déplace un pixel vers la droite mov cx,0 ;délai aussi nous ne déplaçons pas DelayLoop: ;l'image trop vite; l'ajuste en fonction ;des besoins loop DelayLoop dec [RemainingLength] jnz AnimationLoop ; ; Attend une touche clavier avant de revenir en mode texte et de finir. ; mov ah,01h int 21h mov ax,03h int 10h mov ah,4ch int 21h Start endp ; ; Affiche une image à l'emplacement spécifié dans la mémoire VGA/EGA. ; ; Entrée: ; BX = emplacement X de l'écran auquel afficher le coin supérieur gauche ; de l'image ; CX = emplacement Y de l'écran auquel afficher le coin supérieur gauche ; de l'image ; DS:SI = pointeur sur l'image à afficher, comme suit: ; word en 0: largeur de l'image, en pixels ; word en 2: hauteur de l'image, en pixels ; octet en 4: msb/lsb = premier & deuxième pixels, ; à répéter pour le reste de la ligne d'affichage ; de l'image, puis pour toutes les lignes d'affichage. ; on ajoute jusqu'a 4 bits aux images dont la largeur est ; impaire pour que chaque ligne d'affichage est un d'octet de large ; ; AX, BX, CX, DX, SI, DI, ES sont détruits. ; DrawFromChunkyBitmap proc near cld ; ; Sélectionne le mode write 2. ; mov dx,GC_INDEX mov al,GRAPHICS_MODE out dx,al inc dx mov al,02h out dx,al ; ; Active l'écriture des 4 plans. ; mov dx,SC_INDEX mov al,MAP_MASK out dx,al inc dx mov al,0fh out dx,al ; ; pointe ES:DI sur l'octet de la mémoire vidéo dans lequel le premier pixel ; de l'image se place, avec AH configuré en tant que masque de bit pour ; accéder à ce pixel dans l'octet adressé. ; mov ax,SCREEN_WIDTH_IN_BYTES mul cx ;offset du début de la ligne d'affichage du haut mov di,ax mov cl,bl and cl,111b mov ah,80h ;positionne AH sur le masque de bit pour le pixel shr ah,cl ; initial shr bx,1 shr bx,1 shr bx,1 ;X en octets add di,bx ;offset de l'octet supérieur gauche de l'image mov bx,DISPLAY_MEMORY_SEGMENT mov es,bx ;ES:DI pointe sur l'octet sur lequel la partie ;supérieure gauche de l'image se place ; ; Récupère la largeur et la hauteur de l'image. ; mov cx,[si] ;récupère la largeur inc si inc si mov bx,[si] ;récupère la hauteur inc si inc si mov dx,GC_INDEX mov al,BIT_MASK out dx,al ;laisse le registre Index GC pointer inc dx ; sur le registre Bit Mask RowLoop: push ax ;préserve le masque de bit de la colonne gauche push cx ;préserve la largeur push di ;préserve l'offset de destination ColumnLoop: mov al,ah out dx,al ;positionne le masque de bit pour afficher ce ;pixel mov al,es:[di] ;charge les latches mov al,[si] ;récupère les deux prochains pixels shr al,1 shr al,1 shr al,1 shr al,1 ;déplace le premier pixel dans lsb stosb ;affiche le premier pixel ror ah,1 ;déplace le masque à l'emplacement du prochain ;pixel jc CheckMorePixels ;le prochain pixel est-il dans l'octet adjacent? dec di ;non CheckMorePixels: dec cx ;vérifie s'il n'y a pas d'autres pixels jz AdvanceToNextScanLine ; dans l'image mov al,ah out dx,al ;positionne le masque de bit pour afficher ce pixel mov al,es:[di] ;charge les latches lodsb ;re-récupère les deux pixels ;et avance le pointeur sur les deux ;prochains pixels stosb ;affiche le second des deux pixels ror ah,1 ;déplace le masque à l'emplacement du prochain pixel jc CheckMorePixels2;le prochain pixel est-il dans l'octet adjacent? dec di ;non CheckMorePixels2: loop ColumnLoop ;vérifie s'il n'y a pas d'autres pixels ; dans l'image jmp short CheckMoreScanLines AdvanceToNextScanLine: inc si ;avance au début de la prochaine ;ligne d'affichage dans l'image CheckMoreScanLines: pop di ;récupère l'offset de destination pop cx ;récupère la largeur pop ax ;récupère le masque de bit de la colonne gauche add di,SCREEN_WIDTH_IN_BYTES ;pointe sur le début de la prochaine ligne ;d'affichage de l'image dec bx ;vérifie s'il n'y a pas d'autres lignes d'affichage jnz RowLoop ;dans l'image ret DrawFromChunkyBitmap endp Code ends end Start