; Routine de remplissage d'un rectangle en Mode X (320x240, en 256 couleurs). ; Fonctionne sur tous les VGA. Emploie une approche de rapidité moyenne qui ; qui sélectionne chaque plan une seule fois par rectangle; ce qui donne un ; effet de fondu des rectangles. Les remplit sans inclure la colonne en EndX ; et la rangée en EndY. Aucun clipping n'est effectué. ; Testé avec TASM 4.0 par Jim Mischel 12/16/94. ; Appelable en C near comme suit: ; ; void FillRectangleX(int StartX, int StartY, int EndX, int EndY, ; unsigned int PageBase, int Color); SC_INDEX equ 03c4h ;Sequence Controller Index MAP_MASK equ 02h ;index dans SC du registre Map Mask SCREEN_SEG equ 0a000h ;segment de a mémoire vidéo en mode X SCREEN_WIDTH equ 80 ;largeur de l'écran en octets d'une ligne d'affichage ; à l'autre parms struc dw 2 dup (?) ; BP empilé et adresse de retour StartX dw ? ;coordonnée X du coin supérieur gauche du rectangle StartY dw ? ;coordonnée Y du coin supérieur gauche du rectangle EndX dw ? ;coordonnée X du coin inférieur droit du rectangle ; (la rangée en EndX n'est pas remplie) EndY dw ? ;coordonnée Y du coin inférieur droit du rectangle ; (la colonne en EndY n'est pas remplie) PageBase dw ? ; offset de base dans la mémoire vidéo de la page dans ; laquelle remplir le rectangle Color dw ? ;couleur dans laquelle remplir le pixel parms ends StartOffset equ -2 ; stockage local pour l'offset de départ du rectangle Width equ -4 ;stockage local pour la largeur de l'adresse du rectangle Height equ -6 ;stockage local pour la hauteur du rectangle PlaneInfo equ -8 ;stockage local pour le numéro de plan et masque de plan STACK_FRAME_SIZE equ 8 .model small .code public _FillRectangleX _FillRectangleX 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_WIDTH mul [bp+StartY] ;offset dans la page de la ligne d'affichage du rectangle supérieur mov di,[bp+StartX] shr di,1 shr di,1 ;X/4 = offset du premier pixel du rectangle dans ; la ligne d'affichage add di,ax ;offset du premier pixel du rectangle dans la page add di,[bp+PageBase] ;offset du premier pixel du rectangle dans ; la mémoire vidéo mov ax,SCREEN_SEG mov es,ax ; ES:DI pointe sur l'adresse du premier pixel mov [bp+StartOffset],di ; du rectangle mov dx,SC_INDEX ;paramètre Sequence Controller Index pour mov al,MAP_MASK ; pointer sur le registre Map Mask out dx,al mov bx,[bp+EndY] sub bx,[bp+StartY] ;BX = hauteur du rectangle jle FillDone ;saute si hauteur est 0 ou négative mov [bp+Height],bx mov dx,[bp+EndX] mov cx,[bp+StartX] cmp dx,cx jle FillDone ;saute si largeur est 0 ou négative dec dx and cx,not 011b sub dx,cx shr dx,1 shr dx,1 inc dx ;nombre d'adresses dans le rectangle à remplir mov [bp+Width],dx mov word ptr [bp+PlaneInfo],0001h ;octet de poids faible = masque de plan du plan 0, ; octet de poids fort= numéro de plan du plan 0 FillPlanesLoop: mov ax,word ptr [bp+PlaneInfo] mov dx,SC_INDEX+1 ; DX pointe sur le registre SC Data out dx,al ;paramètre le plan pour ce pixel mov di,[bp+StartOffset] ;ES:DI pointe sur le début du rectangle mov dx,[bp+Width] mov cl,byte ptr [bp+StartX] and cl,011b ;numéro de plan du premier pixel dans l'octet initial cmp ah,cl ;affichons-nous ce plan dans l'octet initial? jae InitAddrSet ;oui dec dx ;non, sautons l'octet initial jz FillLoopBottom ;sautons ce plan s'il ne contient pas de pixel inc di InitAddrSet: mov cl,byte ptr [bp+EndX] dec cl and cl,011b ;numéro de plan du dernier pixel dans l'octet final cmp ah,cl ;affichons-nous ce plan dans l'octet final? jbe WidthSet ;oui dec dx ;non, sautons l'octet final jz FillLoopBottom ;sautons ce plan s'il ne contient pas de pixel WidthSet: mov si,SCREEN_WIDTH sub si,dx ;distance entre la fin d'une ligne d'affichage ; et le début de la prochaine mov bx,[bp+Height] ;nombre de lignes à remplir mov al,byte ptr [bp+Color] ;couleur de remplissage FillRowsLoop: mov cx,dx ;nombre d'octets dans la ligne d'affichage rep stosb ;remplit la ligne d'affichage dans ce plan add di,si ;pointe sur le début de la prochaine ligne ; d'affichage du rectangle dec bx ;décompte les lignes d'affichage jnz FillRowsLoop FillLoopBottom: mov ax,word ptr [bp+PlaneInfo] shl al,1 ;paramètre le bit du plan sur le prochain plan inc ah ;incrémente le numéro de plan mov word ptr [bp+PlaneInfo],ax cmp ah,4 ;avons-nous fait tous les plans? jnz FillPlanesLoop ;continue s'il reste d'autres plans FillDone: pop di ;restaure les variables registre de l'appelant pop si mov sp,bp ;abandonne le stockage pour les variables locales pop bp ;restaure la stack frame de l'appelant ret _FillRectangleX endp end