; Routine de copie de mémoire système à mémoire vidéo en Mode X (320x240, en 256 ;couleurs). Emploie l'approche de changement de plan pour chaque pixel copié; ; ce qui est plus lent que de copier tous les pixels dans un plan, puis tous les ; pixels du prochain plan, etc., mais c'est plus simple; ; Copie sans inclure la colonne; en SourceEndX et la rangée en SourceEndY. ; Aucun clipping n'est effectué. ; Testé avec TASM 4.0 par Jim Mischel 12/16/94. ; Appelable en C near comme suit: ; ; void CopySystemToScreenX(int SourceStartX, int SourceStartY, ; int SourceEndX, int SourceEndY, int DestStartX, ; int DestStartY, char* SourcePtr, unsigned int DestPageBase, ; int SourceBitmapWidth, int DestBitmapWidth); SC_INDEX equ 03c4h ;port registre Sequence Controller Index MAP_MASK equ 02h ;index dans SC du registre Map Mask SCREEN_SEG equ 0a000h ;segment de la mémoire vidéo en Mode X parms struc dw 2 dup (?) ;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 droit de la source ; (la rangée en EndX n'est pas copiée) SourceEndY dw ? ;coordonnée Y du coin inférieur droit de la source ; (la colonne en EndY n'est pas copiée) DestStartX dw ? ;coordonnée X du coin supérieur gauche de destination 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 DestBitmapWidth dw ? ;nombre de pixels dans la bitmap destination ; (doit être un multiple de 4) parms ends RectWidth equ -2 ;stockage local pour la largeur du rectangle LeftMask equ -4 ;stockage local pour masque de plan du bord gauche du rectangle STACK_FRAME_SIZE equ 4 .model small .code public _CopySystemToScreenX _CopySystemToScreenX 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 locales push si ;préserve les variables registre de l'appelant push di cld mov ax,SCREEN_SEG ; ES pointe sur la mémoire vidéo mov es,ax mov ax,[bp+SourceBitmapWidth] mul [bp+SourceStartY] ;ligne d'affichage supérieure du rectangle ;source add ax,[bp+SourceStartX] add ax,[bp+SourcePtr] ;offset du premier pixel du rectangle mov si,ax ; source dans DS mov ax,[bp+DestBitmapWidth] shr ax,1 ;convertit la largeur en adresses shr ax,1 mov [bp+DestBitmapWidth],ax ;mémorise la largeur de l'adresse mul [bp+DestStartY] ;ligne d'affichage supérieure du rectangle de ;destination mov di,[bp+DestStartX] mov cx,di shr di,1 ;X/4 = offset du premier pixel du rectangle shr di,1 ;destination dans la ligne d'affichage add di,ax ;offset du premier pixel du rectangle destination ;dans la page add di,[bp+DestPageBase] ;offset du premier pixel du rectangle ;destination dans la mémoire vidéo and cl,011b ;CL = premier plan du pixel de destination mov al,11h ; shl al,cl ;paramètre le bit pour le plan du premier pixel mov [bp+LeftMask],al ; dans chacun des quatre bits à 1 mov cx,[bp+SourceEndX] ;calcule le nombre de pixels sub cx,[bp+SourceStartX] ;dans le rectangle jle CopyDone ;saute si la largeur est 0 ou négative mov [bp+RectWidth],cx mov bx,[bp+SourceEndY] sub bx,[bp+SourceStartY] ;BX = hauteur du rectangle jle CopyDone ;saute si la hauteur est 0 ou négative mov dx,SC_INDEX ;pointe sur le registre SC Index mov al,MAP_MASK out dx,al ;le registre SC Index pointe sur Map Mask inc dx ;DX pointe sur le registre SC Data CopyRowsLoop: mov ax,[bp+LeftMask] mov cx,[bp+RectWidth] push si ;mémorise l'offset de départ dans la source push di ;mémorise l'offset de départ dans la destination CopyScanLineLoop: out dx,al ;paramètre le plan pour ce pixel movsb ;copie le pixel à l'écran rol al,1 ;paramètre le masque pour le prochain plan du ;pixel cmc ;avance l'adresse destination seulement si nous sbb di,0 ;passons du plan 3 au plan 0 ;(autrement annuler INC DI fait par MOVSB) loop CopyScanLineLoop pop di ;retrouve l'offset de départ de destination add di,[bp+DestBitmapWidth] ;pointe sur le début de la prochaine ;ligne d'affichage de destination pop si ;retrouve l'offset de départ de source add si,[bp+SourceBitmapWidth] ;pointe sur le début de la prochaine ;ligne d'affichage de source dec bx ;décompte les lignes d'affichage jnz CopyRowsLoop CopyDone: pop di ;restaure les variables registre de l'appelant pop si mov sp,bp ;abandonne le stockage des variables locales pop bp ;restaure la stack frame de l'appelant ret _CopySystemToScreenX endp end