; Routine de remplissage de rectangle en Mode X (320x240, en 256 couleurs). ; Fonctionne sur tous les VGA. Emploie l'approche lente qui sélectionne ; explicitement le plan de chaque pixel. 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 la mémoire vidéo en mode X SCREEN_WIDTH equ 80 ;largeur d'é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 afficher le pixel parms ends .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 push si ;préserve les variables registre de l'appelant push di 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 ; 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 inc dx ; DX pointe sur le registre SC Data mov cl,byte ptr [bp+StartX] and cl,011b ;CL = plan du premier pixel du rectangle mov al,01h shl al,cl ;ne paramètre que le bit du plan du pixel à 1 mov ah,byte ptr [bp+Color] ;couleur de remplissage mov bx,[bp+EndY] sub bx,[bp+StartY] ;BX = hauteur du rectangle jle FillDone ;saute si hauteur est à 0 ou négative mov si,[bp+EndX] sub si,[bp+StartX] ;CX = largeur du rectangle jle FillDone ;saute si largeur est à 0 ou négative FillRowsLoop: push ax ;mémorise le masque du plan pour le bord gauche push di ;mémorise l'offset de départ de la ligne d'affichage mov cx,si ;compte le nombre de pixels dans cette ligne d'affichage FillScanLineLoop: out dx,al ;paramètre le plan pour ce pixel mov es:[di],ah ;affiche le pixel shl al,1 ;ajuste le masque de plan pour le bit du prochain and al,01111b ; pixel, modulo 4 jnz AddressSet ;avance l'adresse si nous sommes passés du inc di ; plan 3 au plan 0 mov al,00001b ;paramètre le bit de masque de plan pour le plan 0 AddressSet: loop FillScanLineLoop pop di ;retrouve l'offset de départ de la ligne d'affichage add di,SCREEN_WIDTH ;pointe sur le début de la prochaine ligne ; d'affichage du rectangle pop ax ;retrouve le masque de plan pour le bord gauche dec bx ;décompte les lignes d'affichage jnz FillRowsLoop FillDone: pop di ;restaure les variables registre de l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret _FillRectangleX endp end