; Routine de copie de sprite de mémoire vidéo à mémoire vidéo en Mode X (32Ox240, ; 256 couleurs ). Fonctionne sur tous les VGA. Emploie l'approche de lecture 4 ; pixels à la fois de la source aux latches, puis écrit les latches dans la ; destination, en utilisant le registre Map Mask pour faire le masque. Copie, ; sans la compter la colonne en SourceEndX et la rangée en SourceEndY. Aucun ; clipping n'est effectué. Les résultats ne sont pas garantis, si la source et ; la destination se chevauchent. ; Appelable en C near comme suit: void CopyScreenToScreenMaskedX(int SourceStartX. .int SourceStartY, int SourceEndX, int SourceEndY. int DestStartX, int DestStartY. MaskedImage * Source, unsigned int DestPageBase, int DestBitmapWidth); SC_INDEX equ 03c4h ;port du registre Index Sequence Controller MAP_MASK equ 02h ;index dans SC du registre Map Mask GC_INDEX equ 03ceh ;port du registre Index Graphics Controller BIT_MASK equ 08h ;index dans GC du registre Bit Mask SCREEN_SEG equ 0a000h ;segment de la mémoire vidéo en mode X parms struc dw 2dup ? ;BP empilé et adresse de retour SourceStartX dw ? ;coordonnée X du coin supérieur gauche de la ;source SourceStartY dw ? ;coordonnée Y du coin supérieur gauche de la ;source SourceEndX dw ? ;coordonnée X du coin inférieur gauche droit de ;la source (la colonne en SourceEndX n'est pas ;copiée) SourceEndY dw ? ;coordonnée Y du coin inférieur droit de la ;source (la rangée en SourceEndY n'est pas ;copiée) DestStartX dw ? ;coordonnée X du coin supérieur gauche de la ;destination DestStartY dw ? ;coordonnée Y du coin supérieur gauche de la ;destination Source dw ? ;pointeur sur la structure MaskedImage 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 DestBitmapWidth dw ? ;nombre de pixels dans la bitmap (doit être un ;multiple de 4) parms ends SourceNextScanOffset equ -2 ;stockage local de la distance entre la fin ;d'une ligne d'affichage source et le début ;de la suivante DestNextScanOffset equ -4 ;stockage local de la distance entre la fin ;d'une ligne d'affichage destination et le ;début de la suivante RectAddrWidth equ -6 ;stockage local de la largeur d'adresse du ;rectangle RectHeight equ -8 ;stockage local de la hauteur du rectangle SourceBitmapWidth equ -10 ;stockage local de la largeur de la bitmap ;source (dans les adresses) STACK FRAME-SIZE equ 10 MaskedImage struc Alignments dw 4 dup(?) ;pointeurs sur AlignedMaskedImage pour les ;quatre alignements possibles de l'image ;destination Maskedlmage ends AlignedMaskedImage struc ImageWidth dw ? ;largeur de l'image dans les adresses (ainsi que la ;largeur du masque en octets) ImagePtr dw ? ;offset de l'image bitmap dans la mémoire ;vidéo MaskPtr dw ? :pointeur sur le masque de la bitmap dans DS AlignedMaskedImage ends .model small .code public -CopyScreenToScreenMaskedX -CopyScreenToscreenMaskedX 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 aux variables registre push si ;préserve les variables registre de l'appelant push di cld mov dx.GC_INDEX ;positionne le masque de bits pour sélectionner ;tous les bits mov ax,00000h+BIT_MASK ;dans les latches et aucun dans le processeur out dx.ax ;afin que nous puissions écrire directement le ;contenu des latches directement en mémoire mov ax.SCREEN-SEG ;ES pointe sur la mémoire vidéo mov es.ax mov ax,[bp+DestBitmapWidthl shr ax,l ;convertit en largeur dans les adresses shr ax,1 mul [bp+DestStartY] ;ligne d'affichage supérieure du rectangle de ;destination mov di,[bp+DestStartX] mov si,di shr di,1 ;X/4 = offset du premier pixel du rectangle de shr di,l ;destination dans la ligne d'affichage add di.ax ;offset du premier pixel du rectangle de ;destination dans la page add di,Ebp+DestPageBasel ;offset du premier pixel du rectangle de ;dans la mémoire vidéo. A présent, pré- ;calcule l'image qui est alignée pour ;correspondre à l'alignement du coté gauche de ;la destination and si,3 ;DestStartX modulo 4 mov cx.si ;met de coté l'alignement shl si.1 ;prépare le pré-calcul de mot mov bx,[bp+Sourcel ;pointe sur la structure source MaskedImage mov bx.[bx+Alignments+sil;pointe sur la structure AlignedMaskedImage ;courante pour l'alignement du coté gauche ;courant mov ax,[bx+ImageWidthl ;largeur de l'image dans les adresses mov Lbp+SourceBitmapWidthl,ax ;mémorise la largeur de l'image dans les ;adresses mul [bp+SourceStartY] ;ligne d'affichage supérieure du ;rectangle source mov si,[bp+SourceStartX] shr si,l ;X/4 = adresse du premier pixel du shr si,l ;rectangle source dans la ligned'affichage add si,ax ;offset du premier pixel du rectangle ;source dans l'image mov ax,si add si,[bx+MaskPtr] ;pointe sur l'offset du masque du premier ;pixel de masque dans DS mov bx,[bx+ImagePtr] ;offset du premier pixel du rectangle ;source add bx,ax ;dans la mémoire vidéo mov ax,[bpSourceStartX] ;calcule le nombre d'adresses à travers add ax,cx ;le rectangle, en décalant si nécessaire add cx.[bp+SourceEndX] ;pour prendre en compte l'alignement cmp cx,ax jle CopyDone ;saute si la largeur est nulle ou négative add cx,3 and ax,not 011b sub cx,ax shr cx,l shr cx,l ;nombre d'adresses à travers le rectangle ;à copier mov ax,[bp+SourceEndY] sub ax,[bp+SourceStartY] ;AX = hauteur du rectangle jle CopyDone ;saute si la hauteur est nulle ou négative mov [bp+RectHeight],ax mov ax,[bp+DestBitmapWidth] shr ax.1 ;convertit en largeur dans les adresses shr ax.1 sub ax,cx ;distance entre la fin d'une ligne ;d'affichage destination et le début de la ;suivante mov [bp+DestNextScanOffset],ax mov ax,[bp+SourceBitmapWidth] ;largeur dans les adresses sub ax,cx ;distance entre la fin d'une ligne ;d'affichage source et lé début de la ;suivante mov [bp+SourceNextScanOffset],ax mov [bp+RectAddrWidth],cx ;mémorise la largeur dans les adresses mov dx,SC_INDEX mov al,MAP MASK out dx,al ;le registre Index de SC pointe sur Map ;Mask inc dx ;pointe sur le registre Data SC CopyRowsLoop: mov cx,[bp+RectAddrWidth] ;largeur CopyScanLineLoop: Lodsb ;récupère le masque de ce jeu de quatre pixels ;et avance le pointeur du masque out dx.al ;paramètre le masque mov al,es[bs] ;charge depuis la source les latches avec le jeu ;des quatre pixels mov es:[di],al ;copie le jeu des quatre pixels dans la ;destination inc bx ;avance le pointeur source inc di ;avance le pointeur destination dec cx :décompte les jeux de quatre pixels jnz CopyScanLineLoop mov ax,[bp+SourceNextScanOffset] add si,ax ;pointe sur le début de la source, add bx,ax ;du masque add di,[bp+DestNextScanOffset] ;et des lignes de destination suivants dec word ptr [bp+RectHeight] ; décompte les lignes d'affichage jnz CopyRowsLoop CopyDone: mov dx,GC-INDEX+l ;restaure le masque de bits par défaut mov al,0ffh ;lequel sélectionne tous les bits dans le CPU out dx.al ;et aucun dans les Latches (l'index de GC pointe ;toujours sur Bit Mask) POP di ;restaure les variables registre de l'appelant POP si mov sp,bp ;libère la mémoire alloué aux variables locales POP bp ;restaure la stack frame de l'appelant ret -CopyScreenToScreenMaskedX endp end