;Routine d'affichage sprites de mémoire système à mémoire vidéo en Mode X (320x240 en ;256 couleurs). N'est pas vraiment rapide; les images pour lesquelles la performance ;compte devraient être stockées dans la mémoire off-screen et copiées à l'écran ;par les latches. Fonctionne sur tous les VGA. Copie sans l'inclure jusqu'à la ;colonne en SourceEndX et la rangée en SourceEndY. Aucun clipping n'est effectué. ;Le Masque et l'image source sont au format octet par pixel, et doivent ;être de même largeur et résider aux mêmes coordonnées dans leurs bitmap respectives. ;Testé avec TASM, appelable en * C near comme suit: ; ; void CopySystemToScreenMaskedX(int SourceStartX, int SourceStartY, int SourceEndX, int SourceEndY. int DestStartX, int DestStartY, char * SourcePtr, unsigned int DestPageBase, int SourceBitmapWidth, int DestBitmapWidth, char * MaskPtr) ; Sc_iNDEX equ 03c4h ;port du registre Index Sequence Controller MAP_MAK equ 02h ;index du registre Map Mask dans SC. SCREEN_SEG equ OaOOOh ;segment de la mémoire vidéo en mode X parms struc dw 2 dup ;BP et adresse de retour empilés SourceStartX dw ? ;coordonnée X du coin supérieur gauche de la source ;(la source est dans la mémoire système) SourceStartY dw ? ;coordonnée Y du coin supérieur gauche de la source SourceEndX dw ? ;coordonnée X du coin inférieur droit de la source ;(la colonne en EndX n'est pas copiée) SourceEndY dw ? ;coordonnée Y du coin inférieur droit de la source ;(la rangée en EndY n'est pas copiée) DestStartX dw ? ;coordonnée X du coin supérieur gauche de destination ;(la destination est dans la mémoire vidéo) DestStartY dw ? ;coordonnée Y du coin supérieur gauche de destination SourcePtr dw ? ;pointeur dans DS sur le début de la bitmap dans ;laquelle réside la source DestPageBase dw ? ;offset de base dans la mémoire vidéo de la page dans ;laquelle réside la destination SourceBitmapWidth dw ? ;nombre de pixels dans la bitmap source (doit être la ;largeur du masque DestBitmapWidth dw ? ;nombre de pixels dans la bitmap destination (doit ;être multiple de 4) MaskPtr dw ? ;pointeur dans DS sur le début de la bitmap dans ;laquelle le masque réside (format octet par pixel, ;comme l'image source les octets 0 signifient ne pas ;copier le pixel source correspondant, octets ;signifient copier) parms ends RectWidth equ -2 ;stockage local de la largeur du rectangle RectHeight equ -4 ;stockage local de la hauteur du rectangle LeftMask equ -6 :stockage local pour le masque de plan du coté gauche ;du rectangle STACK FRAME SIZE equ 6 .model small .code public_CopySystemToScreenMaskedX _CopySystemToScreenMaskedX proc near push bp ;préserve la stack frame de l'appelant mov bp,sp ;pointe sur la stack frame locale sub sp.STACK_FRAME_SIZE ;alloue de l'espace pour les variables locales push si ;préserve les variables registre de l'appelant push di mov ax,SCREEN-SEG ; ES pointe sur la mémoire vidéo mov es.ax mov ax,[bp+SourceBitmapWidth] mul Ebp+SourceStartY] ; ligne d'affichage du haut du rectangle source add ax,[bp+SourceStartX] mov bx,ax add ax,[bp+SourcePtr] ;offset du premier pixel du rectangle source mov si.ax ; dans DS add bx,[bp+MaskPtr] ;offset du premier pixel du masque dans DS mov ax,[bp+DestBitmapWidth] shr ax,1 ;convertit en largeur dans les adresses shr ax,l mov [bp+DestBitmapWidth],ax ;mémorise la largeur de l'adresse mul [bp+DestStartY] ;ligne d'affichage du haut du rectangle destination mov di,[bp+DestStartX] mov cx.di shr di,l ;X/4 = offset du premier pixel du rectangle destination shr di,1 ;dans la ligne d'affichage add di,ax ;offset du premier pixel du rectangle destination dans page add di,[bp+DestPageBasel ;offset du premier pixel du rectangle destination ;dans la mémoire vidéo and cl.Ollb ;CL = plan du premier pixel destination mov al,llh ;les quatre bits supérieurs apparaissent quand le plan ;passe de 3 à 0 shl al,ci ;paramètre le bit pour le plan du premier pixel destination mov [bp+LeftMaskl.al ;dans les tous les quatre bits supérieurs à 1 mov ax.[bp+SourceEndX] ;calcule le nombre de pixels sub ax,[bp+SourceStartXI ;dans le rectangle jle CopyDone ;saute si la largeur est nulle ou négative mov [bp+RectWidth].ax sub word ptr [bp+SourceBitmapWidth],ax ;distance entre la fin d'une ligne ;d'affichage source et le début d'une autre mov ax,[bp+SourceEndYl sub ax,[bp+SourceStartY] ;hauteur du rectangle jle CopyDone ;saute si la hauteur est nulle ou négative mov [bp+RectHeight],ax mov dx.SC_INDEX ;pointe sur le registre Index SC mov AT,MAP_MASK out dx.al ;registre Index SC pointe sur Map Mask inc dx ; DX pointe sur le registre Data SC CopyRowsLoop: mov aT,[bp+LeftMask] mov cx,[bp+RectWidthl] push di ; mémorise l'offset de départ dans destination CopyScanLineLoop- cmp byte ptr [bx],O ;ce pixel est-il masqué? jz MaskOff ;non, ne pas l'afficher ;oui, afficher ce pixel out dx,al ;paramètre le plan pour ce pixel mov ah,[si] ;récupère le pixel source mov es:[di],ah ;copie le pixel à l'écran MaskOff: inc bx ;avance le pointeur du masque inc si ;avance le pointeur de la source rol al,1 ;paramètre le masque pour le plan du prochain pixel adc di,O ;avance l'adresse destination seulement si l'on passe ;du plan 3 au plan 0 loop CopyScanLineLoop pop di ;retrouve l'offset du début de destination add di,[bp+DestBitmapWidth] ;pointe sur le début de la prochaine ligne ; d'affichage destination add si,[bp+SourceBitmapWidth] ;pointe sur le début de la prochaine ligne ;d'affichage source add bx,[bp+SourceBitmapWidth] ;pointe sur le début de la prochaine ligne ; d'affichage du masque jnz CopyRowsLoop COPYDone: pop di ;restaure les variables registre de l'appelant pop si mov sp,bp ;libère les variables locales pop bp ;restaure la stack frame de l'appelant ret _CopySystemToScreenMaskedX endp end