Yves Rizoud 5fd1e42ea0 Copyright notices in source files
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@217 416bcca6-2ee7-4201-b75f-2eb2f807beb1
2008-10-08 19:40:47 +00:00

6923 lines
149 KiB
NASM
Raw Blame History

; Grafx2 - The Ultimate 256-color bitmap paint program
;
; Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
;
; Grafx2 is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; version 2
; of the License.
;
; Grafx2 is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Grafx2; if not, see <http://www.gnu.org/licenses/> or
; write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
.386P
.MODEL FLAT
_TEXT Segment dword public 'code'
Assume cs:_TEXT, ds:_DATA
; -- Fonctions MCGA --
public Set_mode_MCGA
public Pixel_MCGA
public Lit_pixel_MCGA
public Effacer_tout_l_ecran_MCGA
public Block_MCGA
public Pixel_Preview_Normal_MCGA
public Pixel_Preview_Loupe_MCGA
public Ligne_horizontale_XOR_MCGA
public Ligne_verticale_XOR_MCGA
; -- Fonctions Mode X --
public Set_mode_X
public Pixel_mode_X
public Lit_pixel_mode_X
public Effacer_tout_l_ecran_mode_X
public Block_mode_X
public Pixel_Preview_Normal_mode_X
public Pixel_Preview_Loupe_mode_X
public Ligne_horizontale_XOR_mode_X
public Ligne_verticale_XOR_mode_X
; -- Fonctions VESA --
public VESA_Change_banque_Fenetre_A
public VESA_Change_banque_Fenetre_B
public VESA_Change_banque_Fenetre_A_et_B
public VESA_Change_banque_Fenetre_A_FAST
public VESA_Change_banque_Fenetre_B_FAST
public VESA_Change_banque_Fenetre_A_et_B_FAST
;public Support_VESA
;public Mode_VESA_supporte
public Initialiser_mode_video_VESA
public Retoucher_CRTC
public Pixel_VESA
public Lit_pixel_VESA
public Effacer_tout_l_ecran_VESA
public Block_VESA
public Pixel_Preview_Normal_VESA
public Pixel_Preview_Loupe_VESA
public Ligne_horizontale_XOR_VESA
public Ligne_verticale_XOR_VESA
public Display_brush_Color_MCGA
public Display_brush_Mono_MCGA
public Clear_brush_MCGA
public Display_brush_Color_VESA
public Display_brush_Mono_VESA
public Clear_brush_VESA
public Display_brush_Color_mode_X
public Display_brush_Mono_mode_X
public Clear_brush_mode_X
public Remap_screen_MCGA
public Remap_screen_mode_X
public Remap_screen_VESA
public Afficher_partie_de_l_ecran_MCGA
public Afficher_une_ligne_a_l_ecran_MCGA
public Lire_une_ligne_a_l_ecran_MCGA
public Afficher_partie_de_l_ecran_zoomee_MCGA
public Afficher_partie_de_l_ecran_mode_X
public Afficher_une_ligne_a_l_ecran_mode_X
public Lire_une_ligne_a_l_ecran_mode_X
public Afficher_partie_de_l_ecran_zoomee_mode_X
public Afficher_partie_de_l_ecran_VESA
public Afficher_une_ligne_a_l_ecran_VESA
public Lire_une_ligne_a_l_ecran_VESA
public Afficher_partie_de_l_ecran_zoomee_VESA
public Display_brush_Color_Zoom_MCGA
public Display_brush_Mono_Zoom_MCGA
public Clear_brush_Zoom_MCGA
public Display_brush_Color_Zoom_mode_X
public Display_brush_Mono_Zoom_mode_X
public Clear_brush_Zoom_mode_X
public Display_brush_Color_Zoom_VESA
public Display_brush_Mono_Zoom_VESA
public Clear_brush_Zoom_VESA
; -- Variables externes relatives au Mode X --
extrn Mode_X_Ptr :dword
extrn MODE_X_Decalage_synchro :dword
extrn MODE_X_Largeur_de_ligne :word
extrn MODE_X_Valeur_initiale_de_esi:dword
extrn MODE_X_Valeur_initiale_de_edi:dword
; -- Variables externes relatives au VESA --
extrn Granularite :byte
extrn Mode_X_Ptr :dataptr ; Table de modification des registres du CRTC
extrn VESA_Erreur :byte
extrn VESA_WinFuncPtr :dword
extrn VESA_Liste_des_modes :dword
extrn VESA_Decalage_synchro :dword
extrn VESA_Largeur_ecran_en_dword :word
extrn VESA_Banque_en_cours :byte
extrn VESA_Derniere_banque_Fenetre_A_utilisee:byte
extrn VESA_Derniere_banque_Fenetre_B_utilisee:byte
extrn VESA_Change_banque_lecture :dword
extrn VESA_Change_banque_ecriture :dword
extrn VESA_Change_banque_lect_ecr :dword
extrn VESA_Version_Unite :byte
extrn VESA_Version_Decimale :byte
extrn VESA_Constructeur :dword
extrn VESA_Taille_memoire :word
; -- Autres variables externes --
extrn Brosse:dword
extrn Principal_Ecran:dword
extrn Principal_Largeur_image:word
extrn Principal_Hauteur_image:word
extrn Principal_Decalage_X:word
extrn Principal_Decalage_Y:word
extrn Largeur_ecran:word
extrn Hauteur_ecran:word
extrn Menu_Ordonnee:word
extrn Principal_X_Zoom:word
extrn Table_mul_facteur_zoom:dataptr ; Table de multiplication par le facteur
extrn Loupe_Decalage_X:word
extrn Loupe_Decalage_Y:word
extrn Loupe_Facteur :word
extrn Limite_Haut_Zoom :word
extrn Limite_Gauche_Zoom :word
extrn Limite_visible_Bas_Zoom :word
extrn Limite_visible_Droite_Zoom:word
; -- Proc<6F>dures externes --
extrn Zoomer_une_ligne:near
; ***************************************************************************
; ***************************************************************************
; ********************************** MCGA ***********************************
; ***************************************************************************
; ***************************************************************************
Set_mode_MCGA proc near
pushad
mov ax,13h
int 10h
popad
ret
Set_mode_MCGA endp
Pixel_MCGA proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
mov eax,0A0140h
mov cl,Couleur
mul Y
add ax,X
mov [eax],cl
mov esp,ebp
pop ebp
ret
Pixel_MCGA endp
Lit_pixel_MCGA proc near
push ebp
mov ebp,esp
arg X:word,Y:word
mov eax,0A0140h
mul Y
add ax,X
mov al,[eax]
mov esp,ebp
pop ebp
ret
Lit_pixel_MCGA endp
Effacer_tout_l_ecran_MCGA proc near
push ebp
mov ebp,esp
arg Couleur:byte
push edi
; On place EDI en d<>but d'<27>cran:
mov edi,0A0000h
; On met (E)CX <20> 320*Menu_Ordonnee/4: ( *80 <=> <<6 + <<4)
xor ecx,ecx
mov ax,Menu_Ordonnee
mov cx,ax
shl ax,6
shl cx,4
add cx,ax
; On met dans EAX 4 fois la couleur:
mov dl,Couleur
mov dh,dl
mov ax,dx
shl eax,16
mov ax,dx
rep stosd
pop edi
mov esp,ebp
pop ebp
ret
Effacer_tout_l_ecran_MCGA endp
Block_MCGA proc near
push ebp
mov ebp,esp
arg Debut_X:word, Debut_Y:word, Largeur:word, Hauteur:word, Couleur:byte
push esi
push edi
; On met dans EDI la position de d<>part du dessin de block
mov edi,0A0000h
mov ax,Debut_Y
mov dx,ax
shl ax,8
add ax,Debut_X
shl dx,6
add ax,dx
mov di,ax
; On met dans SI l'incr<63>mentation de DI <20> chaque ligne
mov si,320
sub si,Largeur
; On remplit EAX avec 4 fois la couleur
mov dl,Couleur
mov dh,dl
mov ax,dx
shl eax,16
mov ax,dx
mov dx,Hauteur
xor ecx,ecx
Block_MCGA_Pour_chaque_ligne:
mov cx,Largeur ; CX = Nb pixels <20> afficher sur la ligne
shr cx,1
jnc Block_MCGA_Pair
stosb ; On commence par se d<>barrasser du 1er byte
; en cas d'imparit<69>}
Block_MCGA_Pair:
shr cx,1
jnc Block_MCGA_test_de_superiorite_a_3
stosw ; On se d<>barrasse des 2<>me et 3<>me bytes en
; cas de "non-multiplicit<69>-de-4"
Block_MCGA_test_de_superiorite_a_3:
; copie 32 bits
rep stosd
add di,si
dec dx
jnz Block_MCGA_Pour_chaque_ligne
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Block_MCGA endp
; -- Affichage d'un pixel dans l'<27>cran, par rapport au d<>calage de l'image
; dans l'<27>cran, en mode normal (pas en mode loupe) --
; Note: si on modifie cette proc<6F>dure, il faudra penser <20> faire <20>galement la
; modif dans la proc<6F>dure Pixel_Preview_Loupe_MCGA.
Pixel_Preview_Normal_MCGA proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
mov dl,Couleur
mov cx,Y
mov ax,X
sub cx,Principal_Decalage_Y
sub ax,Principal_Decalage_X
push edx
push ecx
push eax
call Pixel_MCGA
mov esp,ebp
pop ebp
ret
Pixel_Preview_Normal_MCGA endp
; -- Affichage d'un pixel dans l'<27>cran, par rapport au d<>calage de l'image
; dans l'<27>cran, en mode loupe --
Pixel_Preview_Loupe_MCGA proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
push ebx
; On affiche d'abord le pixel dans la partie non-zoom<6F>e
mov dl,Couleur ; Ca ne co<63>te pas trop
mov cx,Y ; en code de recopier
mov ax,X ; le contenu de la
sub cx,Principal_Decalage_Y ; proc<6F>dure
sub ax,Principal_Decalage_X ; Pixel_Preview_Normal_MCGA
push edx ; et <20>a fait gagner du
push ecx ; temps, et ce temps est
push eax ; assez pr<70>cieux vu que
call Pixel_MCGA ; c'est appel<65> TRES souvent.
add esp,12 ; 3 param<61>tres dword
; On regarde si on peut afficher le pixel <20>galement dans la loupe
mov ax,Y
cmp ax,Limite_Haut_Zoom
jb Pixel_Preview_Loupe_MCGA_Fin
cmp ax,Limite_visible_Bas_Zoom
ja Pixel_Preview_Loupe_MCGA_Fin
mov ax,X
cmp ax,Limite_Gauche_Zoom
jb Pixel_Preview_Loupe_MCGA_Fin
cmp ax,Limite_visible_Droite_Zoom
ja Pixel_Preview_Loupe_MCGA_Fin
; On passe la couleur
mov al,Couleur
mov edx,Table_mul_facteur_zoom ; On pointe sur la table de x (OPTI)
push eax
; On calcule dans EAX (X) et ECX (Y) le d<>marrage du bloc:
xor eax,eax
xor ecx,ecx
mov ax,X
mov cx,Y
sub ax,Loupe_Decalage_X
sub cx,Loupe_Decalage_Y
mov ax,[edx+2*eax]
mov cx,[edx+2*ecx]
; On sauve ces valeurs dans BX (X) et DX (Y):
mov bx,ax
mov dx,cx
; On s'occupe de la hauteur:
add cx,Loupe_Facteur
cmp cx,Menu_Ordonnee
ja Pixel_Preview_Loupe_MCGA_Tronque_en_hauteur
mov cx,Loupe_Facteur
push ecx
jmp Pixel_Preview_Loupe_MCGA_Traitement_de_la_largeur
Pixel_Preview_Loupe_MCGA_Tronque_en_hauteur:
mov cx,dx
neg cx
add cx,Menu_Ordonnee
push ecx
; On s'occupe de la largeur:
Pixel_Preview_Loupe_MCGA_Traitement_de_la_largeur:
add bx,Principal_X_Zoom
mov ax,Loupe_Facteur
push eax
; On passe le d<>but en Y:
push edx
; On passe le d<>but en X:
push ebx
call Block_MCGA
add esp,20 ; 20 = 5 param<61>tres de type dword
pop ebx
Pixel_Preview_Loupe_MCGA_Fin:
mov esp,ebp
pop ebp
ret
Pixel_Preview_Loupe_MCGA endp
Ligne_horizontale_XOR_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word, Pos_Y:word, Largeur:word
push edi
; On met dans EDI la position de d<>part du dessin de la ligne
mov edi,0A0000h
mov ax,Pos_Y
mov dx,ax
shl ax,8
add ax,Pos_X
shl dx,6
add ax,dx
mov di,ax
mov cx,Largeur ; CX = Nb pixels <20> afficher sur la ligne
shr cx,1
jnc LH_MCGA_Pair
not byte ptr[edi] ; On commence par se d<>barrasser du 1er byte
inc edi ; en cas d'imparit<69>
LH_MCGA_Pair:
shr cx,1
jnc LH_MCGA_test_de_superiorite_a_3
not word ptr[edi] ; On se d<>barrasse des 2<>me et 3<>me bytes en
add edi,2 ; cas de "non-multiplicit<69>-de-4"
LH_MCGA_test_de_superiorite_a_3:
or cx,cx
jz LH_MCGA_Fin
; copie 32 bits
LH_MCGA_Copie_32_bits:
not dword ptr[edi]
add edi,4
dec cx
jnz LH_MCGA_Copie_32_bits
LH_MCGA_Fin:
pop edi
mov esp,ebp
pop ebp
ret
Ligne_horizontale_XOR_MCGA endp
Ligne_verticale_XOR_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word, Pos_Y:word, Hauteur:word
; On met dans EDX la position de d<>part du dessin de la ligne
mov edx,0A0000h
mov ax,Pos_Y
mov cx,ax
shl ax,8
add ax,Pos_X
shl cx,6
add ax,cx
mov dx,ax
mov cx,Hauteur ; CX = Nb pixels <20> afficher sur la ligne
LV_MCGA_Boucle:
not byte ptr[edx]
add dx,320
dec cx
jnz LV_MCGA_Boucle
mov esp,ebp
pop ebp
ret
Ligne_verticale_XOR_MCGA endp
; ***************************************************************************
; ***************************************************************************
; ********************************* MODE X **********************************
; ***************************************************************************
; ***************************************************************************
Set_mode_X proc near
pushad
mov ax,13h
int 10h
mov dx,3C6h ; \
xor al,al ; -+-> Palette Off
out dx,al ; /
mov dx,3C4h
mov ax,0604h
out dx,ax
mov ax,0100h
out dx,ax
mov al,01h ; \
out dx,al ; +
inc dx ; |
in al,dx ; |
mov ah,al ; |
mov al,01h ; |
push ax ; |
mov al,ah ; |
or al,20h ; +-> Screen Off
out dx,al ; /
mov esi,Mode_X_Ptr
cld
lodsb
or al,al
jz DontSetDot
mov dx,3C2h
out dx,al
DontSetDot:
mov dx,3C4h
mov ax,0300h
out dx,ax
mov dx,3D4h
mov al,11h
out dx,al
inc dx
in al,dx
and al,7Fh
out dx,al
dec dx
lodsb
xor ecx,ecx
mov cl,al
rep outsw
mov ax,Largeur_ecran
shr ax,3
mov ah,al
mov al,13h
out dx,ax
mov dx,3C4h
mov ax,0F02h
out dx,ax
mov edi,0A0000h
xor eax,eax
mov ecx,4000h
rep stosd
; On calcule le d<>calage qu'il y a entre la fin de l'<27>cran et le d<>but
; de la ligne suivante:
;
; Decalage = (Largeur_image - Largeur_ecran)
xor ebx,ebx
mov bx,Principal_Largeur_image
sub bx,Largeur_ecran
mov MODE_X_Decalage_synchro,ebx
; On calcule la largeur logique d'une ligne:
;
; Largeur_de_ligne = Largeur_ecran shr 2
mov ax,Largeur_ecran
shr ax,2
mov MODE_X_Largeur_de_ligne,ax
mov dx,3C4h ; \
pop ax ; -+-> Screen On
out dx,ax ; /
mov dx,3C6h ; \
mov al,0FFh ; -+-> Palette On
out dx,al ; /
popad
ret
Set_mode_X endp
Pixel_mode_X proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
pushad
mov dx,3C4h
mov ax,102h
mov bx,X
mov cx,bx
and cl,03d
shl ah,cl
out dx,ax
xor eax,eax
mov ax,MODE_X_Largeur_de_ligne
mul Y
add eax,0A0000h
shr bx,2
add ax,bx
mov bl,Couleur
mov [eax],bl
popad
mov esp,ebp
pop ebp
ret
Pixel_mode_X endp
Lit_pixel_mode_X proc near
push ebp
mov ebp,esp
arg X:word,Y:word
push bx
mov bx,X
mov cx,bx
and cl,03d
mov dx,3CEh
mov al,04h
mov ah,cl
out dx,ax
xor eax,eax
mov ax,MODE_X_Largeur_de_ligne
mul Y
add eax,0A0000h
shr bx,02d
add ax,bx
mov al,[eax]
pop bx
mov esp,ebp
pop ebp
ret
Lit_pixel_mode_X endp
Effacer_tout_l_ecran_mode_X proc near
push ebp
mov ebp,esp
arg Couleur:byte
pushad
; On fait passer la carte VGA en mode <20>criture sur 4 plans simultan<61>s
mov dx,3C4h
mov ax,0F02h
out dx,ax
; On place EDI en d<>but d'<27>cran:
mov edi,0A0000h
; On met EBX <20> 4 fois la couleur:
mov al,Couleur
mov ah,al
mov bx,ax
shl ebx,16
mov bx,ax
; On calcule le nb de dwords visibles dans l'image
mov ax,Menu_ordonnee
mul MODE_X_Largeur_de_ligne
shr ax,2
mov cx,ax
jnc @@Pas_de_probleme
mov [edi],bx
add edi,2
@@Pas_de_probleme:
@@Boucle:
mov [edi],ebx
add edi,4
dec cx
jnz @@Boucle
popad
mov esp,ebp
pop ebp
ret
Effacer_tout_l_ecran_mode_X endp
Block_mode_X proc near
push ebp
mov ebp,esp
arg Debut_X:word,Debut_Y:word,Largeur:word,Hauteur:word,Couleur:byte
pushad
; On met dans CL le plan initial
mov bx,Debut_X
mov cl,bl
and cl,00000011b
; On met dans CH la couleur
mov ch,Couleur
; On met dans ESI la valeur initiale de EDI
mov ax,Debut_Y
mul MODE_X_Largeur_de_ligne
shr bx,2
add ax,bx
mov esi,0A0000h
mov si,ax
mov bx,Largeur ; BX = Nb de colonnes <20> afficher
mov dx,3C4h ; DX = Port du CRTC (chngt de plan)
Block_mode_X_Pour_chaque_colonne:
; On passe dans le plan d<>tenu par CL
mov ax,102h
shl ah,cl
out dx,ax
; On dessine la colonne en partant de ESI, et sur Hauteur pixels
mov edi,esi
mov ax,Hauteur ; AX = Nb de pixels <20> dessiner
Block_mode_X_Pour_chaque_ligne_du_block:
; On recopie un pixel de la couleur demand<6E>e
mov [edi],ch
; On passe <20> la ligne suivante
add di,MODE_X_Largeur_de_ligne
dec ax
jnz Block_mode_X_Pour_chaque_ligne_du_block
; On change de colonne:
dec bx ; Si plus de colonnes <20> traiter
jz Block_mode_X_Fin_de_traitement ; -> On arr<72>te le traitement
inc cl ; Sinon, on se prepare <20> passer au plan
and cl,00000011b ; suivant. Si Plan <> 0
jnz Block_mode_X_Pour_chaque_colonne ; -> On reprend simplement
inc esi ; Sinon, on incr<63>mente l'adresse
jmp Block_mode_X_Pour_chaque_colonne ; et on reprend
Block_mode_X_Fin_de_traitement:
popad
mov esp,ebp
pop ebp
ret
Block_mode_X endp
; -- Affichage d'un pixel dans l'<27>cran, par rapport au d<>calage de l'image
; dans l'<27>cran, en mode normal (pas en mode loupe) --
; Note: si on modifie cette proc<6F>dure, il faudra penser <20> faire <20>galement la
; modif dans la proc<6F>dure Pixel_Preview_Loupe_mode_X.
Pixel_Preview_Normal_mode_X proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
mov dl,Couleur
mov cx,Y
mov ax,X
sub cx,Principal_Decalage_Y
sub ax,Principal_Decalage_X
push edx
push ecx
push eax
call Pixel_mode_X
mov esp,ebp
pop ebp
ret
Pixel_Preview_Normal_mode_X endp
; -- Affichage d'un pixel dans l'<27>cran, par rapport au d<>calage de l'image
; dans l'<27>cran, en mode loupe --
Pixel_Preview_Loupe_mode_X proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
push ebx
; On affiche d'abord le pixel dans la partie non-zoom<6F>e
mov dl,Couleur ; Ca ne co<63>te pas trop
mov cx,Y ; en code de recopier
mov ax,X ; le contenu de la
sub cx,Principal_Decalage_Y ; proc<6F>dure
sub ax,Principal_Decalage_X ; Pixel_Preview_Normal_mode_X
push edx ; et <20>a fait gagner du
push ecx ; temps, et ce temps est
push eax ; assez pr<70>cieux vu que
call Pixel_mode_X ; c'est appel<65> TRES souvent.
add esp,12 ; 3 param<61>tres dword
; On regarde si on peut afficher le pixel <20>galement dans la loupe
mov ax,Y
cmp ax,Limite_Haut_Zoom
jb Pixel_Preview_Loupe_mode_X_Fin
cmp ax,Limite_visible_Bas_Zoom
ja Pixel_Preview_Loupe_mode_X_Fin
mov ax,X
cmp ax,Limite_Gauche_Zoom
jb Pixel_Preview_Loupe_mode_X_Fin
cmp ax,Limite_visible_Droite_Zoom
ja Pixel_Preview_Loupe_mode_X_Fin
; On passe la couleur
mov al,Couleur
mov edx,Table_mul_facteur_zoom ; On pointe sur la table de x (OPTI)
push eax
; On calcule dans EAX (X) et ECX (Y) le d<>marrage du bloc:
xor eax,eax
xor ecx,ecx
mov ax,X
mov cx,Y
sub ax,Loupe_Decalage_X
sub cx,Loupe_Decalage_Y
mov ax,[edx+2*eax]
mov cx,[edx+2*ecx]
; On sauve ces valeurs dans BX (X) et DX (Y):
mov bx,ax
mov dx,cx
; On s'occupe de la hauteur:
add cx,Loupe_Facteur
cmp cx,Menu_Ordonnee
ja Pixel_Preview_Loupe_mode_X_Tronque_en_hauteur
mov cx,Loupe_Facteur
push ecx
jmp Pixel_Preview_Loupe_mode_X_Traitement_de_la_largeur
Pixel_Preview_Loupe_mode_X_Tronque_en_hauteur:
mov cx,dx
neg cx
add cx,Menu_Ordonnee
push ecx
; On s'occupe de la largeur:
Pixel_Preview_Loupe_mode_X_Traitement_de_la_largeur:
add bx,Principal_X_Zoom
mov ax,Loupe_Facteur
push eax
; On passe le d<>but en Y:
push edx
; On passe le d<>but en X:
push ebx
call Block_mode_X
add esp,20 ; 20 = 5 param<61>tres de type dword
pop ebx
Pixel_Preview_Loupe_mode_X_Fin:
mov esp,ebp
pop ebp
ret
Pixel_Preview_Loupe_mode_X endp
Ligne_horizontale_XOR_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word, Pos_Y:word, Largeur:word
push ebx
push esi
push edi
; On met dans CL le plan initial
mov bx,Pos_X
mov cl,bl
and cl,00000011b
; On met dans ESI la valeur initiale de EDI
; (ESI=D<>but de ligne, EDI=Position dans la ligne)
mov esi,0A0000h
mov ax,Pos_Y
mul MODE_X_Largeur_de_ligne
shr bx,2
add ax,bx
mov si,ax
; On met dans BX la coordonn<6E>e de fin +1
mov bx,Pos_X
add bx,Largeur
; On place dans CH le nb de plans <20> traiter
mov ch,4
LH_Pour_chaque_plan:
; On initialise EDI
mov edi,esi
; On passe dans le plan d<>tenu par CL
; Plan d'<27>criture:
mov dx,3C4h ; DX = Port du CRTC (chngt de plan)
mov ax,102h
shl ah,cl
out dx,ax
; Plan de lecture:
mov dx,3CEh ; DX = Port du TS (enfin, je crois)
mov ah,cl
mov al,04h
out dx,ax
; On met dans AX la coordonn<6E>e de d<>part
mov ax,Pos_X
LH_Boucle:
cmp ax,bx
jae LH_Fin_de_traitement
not byte ptr[edi] ; On inverse le pixel courant
inc edi ; On passe <20> la coordonn<6E>e +4
add ax,4
jmp LH_Boucle
LH_Fin_de_traitement:
; On pr<70>pare CL pour le prochain plan:
inc cl
and cl,00000011b
jnz LH_On_repasse_pas_dans_le_plan_0
; On pr<70>pare ESI pour le prochain plan:
inc esi
LH_On_repasse_pas_dans_le_plan_0:
; On pr<70>pare la coordonn<6E>e de d<>part pour le prochain plan:
inc Pos_X
; On regarde s'il reste un plan <20> traiter:
dec ch
jnz LH_Pour_chaque_plan
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Ligne_horizontale_XOR_mode_X endp
Ligne_verticale_XOR_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word, Pos_Y:word, Hauteur:word
; On met dans CL le plan initial
mov cx,Pos_X
and cl,00000011b
; On passe dans le plan d<>tenu par CL
; Plan d'<27>criture:
mov dx,3C4h ; DX = Port du CRTC (chngt de plan)
mov ax,102h
shl ah,cl
out dx,ax
; Plan de lecture:
mov dx,3CEh ; DX = Port du TS (enfin, je crois)
mov ah,cl
mov al,04h
out dx,ax
; On met dans EDX la coordonn<6E>e initiale
mov edx,0A0000h
mov cx,Pos_X
mov ax,Pos_Y
mul MODE_X_Largeur_de_ligne
shr cx,2
add ax,cx
mov dx,ax
; On place dans CX le nb de pixels <20> traiter
mov cx,Hauteur
; On place dans AX la distance qu'il y a d'une ligne <20> l'autre:
mov ax,Mode_X_Largeur_de_ligne
LV_Pour_chaque_ligne:
not byte ptr[edx]
add dx,ax
dec cx
jnz LV_Pour_chaque_ligne
mov esp,ebp
pop ebp
ret
Ligne_verticale_XOR_mode_X endp
; ***************************************************************************
; ***************************************************************************
; ********************************** VESA ***********************************
; ***************************************************************************
; ***************************************************************************
VESA_Change_banque_Fenetre_A_FAST proc near
; Param<61>tre en entr<74>e:
; AL = Banque sur laquelle aller dans la fen<65>tre A
cmp al,VESA_Derniere_banque_Fenetre_A_utilisee
je VESA_Change_banque_Fenetre_A_FAST_Pas_besoin_de_changer
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
xor bx,bx
shl dx,cl
mov ax,4F05h
call [VESA_WinFuncPtr]
popad
mov VESA_Derniere_banque_Fenetre_A_utilisee,al
VESA_Change_banque_Fenetre_A_FAST_Pas_besoin_de_changer:
ret
VESA_Change_banque_Fenetre_A_FAST endp
VESA_Change_banque_Fenetre_B_FAST proc near
; Param<61>tre en entr<74>e:
; AL = Banque sur laquelle aller dans la fen<65>tre B
cmp al,VESA_Derniere_banque_Fenetre_B_utilisee
je VESA_Change_banque_Fenetre_B_FAST_Pas_besoin_de_changer
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
mov bx,1
shl dx,cl
mov ax,4F05h
call [VESA_WinFuncPtr]
popad
mov VESA_Derniere_banque_Fenetre_B_utilisee,al
VESA_Change_banque_Fenetre_B_FAST_Pas_besoin_de_changer:
ret
VESA_Change_banque_Fenetre_B_FAST endp
VESA_Change_banque_Fenetre_A_et_B_FAST proc near
; Param<61>tre en entr<74>e:
; AL = Banque sur laquelle aller dans les fen<65>tres A et B
cmp al,VESA_Derniere_banque_Fenetre_A_utilisee
je VESA_Change_banque_Fenetre_A_et_B_FAST_Pas_besoin_de_changer_A
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
xor bx,bx
shl dx,cl
mov ax,4F05h
call [VESA_WinFuncPtr]
popad
mov VESA_Derniere_banque_Fenetre_A_utilisee,al
VESA_Change_banque_Fenetre_A_et_B_FAST_Pas_besoin_de_changer_A:
cmp al,VESA_Derniere_banque_Fenetre_B_utilisee
je VESA_Change_banque_Fenetre_A_et_B_FAST_Pas_besoin_de_changer_B
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
mov bx,1
shl dx,cl
mov ax,4F05h
call [VESA_WinFuncPtr]
popad
mov VESA_Derniere_banque_Fenetre_B_utilisee,al
VESA_Change_banque_Fenetre_A_et_B_FAST_Pas_besoin_de_changer_B:
ret
VESA_Change_banque_Fenetre_A_et_B_FAST endp
VESA_Change_banque_Fenetre_A proc near
; Param<61>tre en entr<74>e:
; AL = Banque sur laquelle aller dans la fen<65>tre A
cmp al,VESA_Derniere_banque_Fenetre_A_utilisee
je VESA_Change_banque_Fenetre_A_Pas_besoin_de_changer
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
xor bx,bx
shl dx,cl
mov ax,4F05h
int 10h
popad
mov VESA_Derniere_banque_Fenetre_A_utilisee,al
VESA_Change_banque_Fenetre_A_Pas_besoin_de_changer:
ret
VESA_Change_banque_Fenetre_A endp
VESA_Change_banque_Fenetre_B proc near
; Param<61>tre en entr<74>e:
; AL = Banque sur laquelle aller dans la fen<65>tre B
cmp al,VESA_Derniere_banque_Fenetre_B_utilisee
je VESA_Change_banque_Fenetre_B_Pas_besoin_de_changer
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
mov bx,1
shl dx,cl
mov ax,4F05h
int 10h
popad
mov VESA_Derniere_banque_Fenetre_B_utilisee,al
VESA_Change_banque_Fenetre_B_Pas_besoin_de_changer:
ret
VESA_Change_banque_Fenetre_B endp
VESA_Change_banque_Fenetre_A_et_B proc near
; Param<61>tre en entr<74>e:
; AL = Banque sur laquelle aller dans les fen<65>tres A et B
cmp al,VESA_Derniere_banque_Fenetre_A_utilisee
je VESA_Change_banque_Fenetre_A_et_B_Pas_besoin_de_changer_A
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
xor bx,bx
shl dx,cl
mov ax,4F05h
int 10h
popad
mov VESA_Derniere_banque_Fenetre_A_utilisee,al
VESA_Change_banque_Fenetre_A_et_B_Pas_besoin_de_changer_A:
cmp al,VESA_Derniere_banque_Fenetre_B_utilisee
je VESA_Change_banque_Fenetre_A_et_B_Pas_besoin_de_changer_B
pushad
xor ah,ah
mov cl,Granularite
mov dx,ax
mov bx,1
shl dx,cl
mov ax,4F05h
int 10h
popad
mov VESA_Derniere_banque_Fenetre_B_utilisee,al
VESA_Change_banque_Fenetre_A_et_B_Pas_besoin_de_changer_B:
ret
VESA_Change_banque_Fenetre_A_et_B endp
;; - -- --- ----\/\ Detection du support VESA sur la machine: /\/---- --- -- -
;
;Support_VESA proc near
;
; pushad
;
; ; On pr<70>suppose qu'il n'y a pas d'erreur (pour l'instant)
;
; mov VESA_Erreur,0
;
; ; On passe en mode graphique, o<> nous attend un super buffer de 64Ko
;
; mov ax,0013h
; int 10h
; mov dx,03C6h ; On <20>teint la palette
; xor al,al
; out dx,al
;
; ; On demande les infos VESA: (AX=4F00, ES:DI=Adresse du buffer)
;
; mov ax,0300h ; Service DPMI simuler une interruption en mode r<>el
; mov bl,10h ; Interruption <20> appeler (int vid<69>o)
; xor bh,bh ; Etat des flags pass<73> <20> l'interruption
; xor cx,cx ; Nb d'elements de la pile <20> passer
; mov edi,0A8000h ; Adresse des valeurs des registres <20> passer <20> l'interruption
; mov dword ptr[edi+28],00004F00h ; EAX pass<73> <20> l'interruption
; mov dword ptr[edi+00],00000000h ; EDI pass<73> <20> l'interruption
; mov word ptr[edi+34],0A000h ; ES pass<73> <20> l'interruption
; mov edx,0A0000h
; mov dword ptr[edx],32454256h ; valeur hexa de "VBE2"
; int 31h ; Appel de l'interruption du DPMI
;
; ; Si AX <> 004F => Echec
;
; mov eax,dword ptr[edi+28]
; cmp ax,004Fh
; je Support_VESA_Pas_d_echec
;
; ; L'appel <20> l'interruption a <20>chou<6F>
;
; Support_VESA_Echec:
;
; mov VESA_Erreur,1
; jmp Support_VESA_Fin_traitement
;
; Support_VESA_Pas_d_echec:
;
; ; L'appel <20> l'interruption n'a pas <20>chou<6F>
;
; ; On v<>rifie que la signature soit bien <20>gale <20> VESA:
;
; mov esi,0A0000h
; cmp byte ptr[esi+0],'V'
; jne Support_VESA_Echec
;
; cmp byte ptr[esi+1],'E'
; jne Support_VESA_Echec
;
; cmp byte ptr[esi+2],'S'
; jne Support_VESA_Echec
;
; cmp byte ptr[esi+3],'A'
; jne Support_VESA_Echec
;
; ; La signature est bien pr<70>sente
;
; ; On enregistre l'adresse de la liste des modes VESA support<72>s:
;
; xor ebx,ebx
; xor eax,eax
; mov bx,[esi+16] ; (Lst_Seg)
; mov ax,[esi+14] ; (Lst_Ofs)
; shl ebx,4
; add ebx,eax
; mov VESA_Liste_des_modes,ebx
;
; ; On enregistre le num<75>ro de version de VESA
;
; mov ax,word ptr[esi+4]
; mov VESA_Version_Unite,ah
; mov VESA_Version_Decimale,al
;
; ; On enregistre l'adresse de la cha<68>ne du constructeur
;
; xor ebx,ebx
; xor eax,eax
; mov bx,word ptr[esi+8]
; mov ax,word ptr[esi+6]
; shl ebx,4
; add ebx,eax
; mov VESA_Constructeur,ebx
;
; ; On enregistre la taille totale de m<>moire vid<69>o
;
; mov ax,[esi+18]
; mov VESA_Taille_memoire,ax
;
;
; Support_VESA_Fin_Traitement:
;
; popad
;
; ret
;
;Support_VESA endp
;
;
;
;; - -- --- -----\/\ Detection du support VESA pour un mode: /\/----- --- -- -
;
;Mode_VESA_supporte proc near
;
; push ebp
; mov ebp,esp
;
; arg Mode:word
;
; pushad
;
; ; On pressupose qu'il n'y a pas d'erreur (pour l'instant)
; ; On se servira de la valeur de SI comme code d'erreur pour faciliter le
; ; d<>bugging
;
; mov si,4 ; Code d'erreur de base
; mov VESA_Erreur,0
;
; ; On va commencer par regarder si le mode n'est pas dans la liste de ceux
; ; support<72>s par la carte. Pour cela, il nous faut redemander cette liste
; ; car certaines cartes la "perdent" d'un appel sur l'autre.
;
; ; On passe en mode graphique, o<> nous attend un super buffer de 64Ko
;
; mov ax,0013h
; int 10h
; mov dx,03C6h ; On <20>teint la palette
; xor al,al
; out dx,al
;
; ; On demande les infos VESA: (AX=4F00, ES:DI=Adresse du buffer)
;
; mov ax,0300h ; Service DPMI simuler une interruption en mode r<>el
; mov bl,10h ; Interruption <20> appeler (int vid<69>o)
; xor bh,bh ; Etat des flags pass<73> <20> l'interruption
; xor cx,cx ; Nb d'elements de la pile <20> passer
; mov edi,0A8000h ; Adresse des valeurs des registres <20> passer <20> l'interruption
; mov dword ptr[edi+28],00004F00h ; EAX pass<73> <20> l'interruption
; mov dword ptr[edi+00],00000000h ; EDI pass<73> <20> l'interruption
; mov word ptr[edi+34],0A000h ; ES pass<73> <20> l'interruption
; mov edx,0A0000h
; mov dword ptr[edx],32454256h ; valeur hexa de "VBE2"
; int 31h ; Appel de l'interruption du DPMI
;
; ; Si AX <> 004F => Echec
;
; mov eax,dword ptr[edi+28]
; cmp ax,004Fh
; jne Mode_VESA_supporte_Echec
;
; ; On enregistre l'adresse de la liste des modes VESA support<72>s dans EDI
;
; mov edi,0A0000h
; xor ebx,ebx
; xor eax,eax
; mov bx,[edi+16] ; (Lst_Seg)
; mov ax,[edi+14] ; (Lst_Ofs)
; shl ebx,4
; add ebx,eax
; mov edi,ebx
;
; ; Et on parcours la liste pour chercher le mode demand<6E>
;
; mov ax,Mode
;
; Mode_VESA_supporte_Boucle:
;
; cmp [edi],ax
; je Mode_VESA_supporte_Fin_boucle
;
; cmp word ptr[edi],0FFFFh
; je Mode_VESA_supporte_Fin_boucle
;
; add edi,2
; jmp Mode_VESA_supporte_Boucle
;
; Mode_VESA_supporte_Fin_boucle:
;
; ; Si le mode en cours = FFFF => Echec
;
; mov si,5 ; Nouveau code d'erreur
;
; cmp word ptr[edi],ax
; je Mode_VESA_supporte_Pas_echec
;
; ; Ce mode vid<69>o VESA n'est pas support<72>:
;
; Mode_VESA_supporte_Echec:
;
; mov ax,si
; mov VESA_Erreur,al
; jmp Mode_VESA_supporte_Fin_traitement
;
; Mode_VESA_supporte_Pas_echec:
;
; ; Ce mode vid<69>o VESA est un <20>l<EFBFBD>ment de la liste:
;
; ; On passe en mode graphique, o<> nous attend un super buffer de 64Ko (c00l)
;
; mov ax,0013h
; int 10h
; mov dx,03C6h ; On <20>teint la palette
; xor al,al
; out dx,al
;
; ; On demande les infos VESA du mode: (AX=4F01, CX=Mode, ES:DI=Adresse du buffer)
;
; mov ax,0300h ; Service DPMI simuler une interruption en mode r<>el
; mov bl,10h ; Interruption <20> appeler (int vid<69>o)
; xor bh,bh ; Etat des flags pass<73> <20> l'interruption
; xor cx,cx ; Nb d'elements de la pile <20> passer
; mov edi,0A8000h ; Adresse des valeurs des registres <20> passer <20> l'interruption
; mov dword ptr[edi+28],00004F01h ; AX pass<73> <20> l'interruption
; xor edx,edx
; mov dx,Mode
; mov dword ptr[edi+24],edx ; ECX pass<73> <20> l'interruption
; mov dword ptr[edi+00],00000000h ; EDI pass<73> <20> l'interruption
; mov word ptr[edi+34],0A000h ; ES pass<73> <20> l'interruption
; int 31h ; Appel de l'interruption du DPMI
;
; ; Si AX <> 004F => Echec
;
; mov si,6 ; Nouveau code d'erreur
;
; mov eax,dword ptr[edi+28]
; cmp ax,004Fh
; jne Mode_VESA_supporte_Echec
;
; ; L'appel <20> l'interruption n'a pas <20>chou<6F>
;
; ; On v<>rifie l'utilit<69> des deux fen<65>tres:
;
; mov edi,0A0000h
; mov al,[edi+2]
; and al,7
; cmp al,7
; jne Mode_VESA_supporte_Fenetre_A_insuffisante
;
; mov VESA_Erreur,0
; jmp Mode_VESA_supporte_Traitement_fenetres_termine
;
; Mode_VESA_supporte_Fenetre_A_insuffisante:
;
; mov al,[edi+3]
; and al,7
; cmp al,7
; jne Mode_VESA_supporte_Fenetre_B_insuffisante
;
; mov VESA_Erreur,1
; jmp Mode_VESA_supporte_Traitement_fenetres_termine
;
; Mode_VESA_supporte_Fenetre_B_insuffisante:
;
; mov al,[edi+2]
; test al,1
; jz Mode_VESA_supporte_Pas_fenetres_par_defaut
;
; mov VESA_Erreur,2
; jmp Mode_VESA_supporte_Traitement_fenetres_termine
;
; Mode_VESA_supporte_Pas_fenetres_par_defaut:
;
; test al,2
; jz Mode_VESA_supporte_Fenetre_A_pas_lisible
;
; mov VESA_Erreur,3
; jmp Mode_VESA_supporte_Traitement_fenetres_termine
;
; Mode_VESA_supporte_Fenetre_A_pas_lisible:
;
; mov VESA_Erreur,2
;
; Mode_VESA_supporte_Traitement_fenetres_termine:
;
; ; On v<>rifie que la taille des fen<65>tres soit bien de 64Ko:
;
; mov si,7 ; Nouveau code d'erreur
;
; cmp word ptr[edi+6],64
; jne Mode_VESA_supporte_Echec
;
; ; On lit la valeur de granularite:
;
; mov ax,[edi+4]
;
; ; Et on en d<>duit un facteur de granularite:
;
; ; Test si granularite = 64:
;
; cmp ax,64
; jne Mode_VESA_supporte_Gran_pas_64
;
; mov Granularite,0
; jmp Mode_VESA_supporte_Fin_traitement_granularite
;
; Mode_VESA_supporte_Gran_pas_64:
;
; ; Test si granularite = 32:
;
; cmp ax,32
; jne Mode_VESA_supporte_Gran_pas_32
;
; mov Granularite,1
; jmp Mode_VESA_supporte_Fin_traitement_granularite
;
; Mode_VESA_supporte_Gran_pas_32:
;
; ; Test si granularite = 16:
;
; cmp ax,16
; jne Mode_VESA_supporte_Gran_pas_16
;
; mov Granularite,2
; jmp Mode_VESA_supporte_Fin_traitement_granularite
;
; Mode_VESA_supporte_Gran_pas_16:
;
; ; Test si granularite = 8:
;
; cmp ax,8
; jne Mode_VESA_supporte_Gran_pas_8
;
; mov Granularite,3
; jmp Mode_VESA_supporte_Fin_traitement_granularite
;
; Mode_VESA_supporte_Gran_pas_8:
;
; ; Test si granularite = 4:
;
; cmp ax,4
; jne Mode_VESA_supporte_Gran_pas_4
;
; mov Granularite,4
; jmp Mode_VESA_supporte_Fin_traitement_granularite
;
; Mode_VESA_supporte_Gran_pas_4:
;
; ; Test si granularite = 2:
;
; cmp ax,2
; jne Mode_VESA_supporte_Gran_pas_2
;
; mov Granularite,5
; jmp Mode_VESA_supporte_Fin_traitement_granularite
;
; Mode_VESA_supporte_Gran_pas_2:
;
; ; Test si granularite = 1:
;
; cmp ax,1
; jne Mode_VESA_supporte_Gran_pas_1
;
; mov Granularite,6
; jmp Mode_VESA_supporte_Fin_traitement_granularite
;
; Mode_VESA_supporte_Gran_pas_1:
;
; mov VESA_Erreur,4
;
; Mode_VESA_supporte_Fin_traitement_granularite:
;
;
;
; mov VESA_WinFuncPtr,00000000h
;
; ; On passe en mode graphique, o<> nous attend un super buffer de 64Ko (c00l)
;
; mov ax,0013h
; int 10h
; mov dx,03C6h ; On <20>teint la palette
; xor al,al
; out dx,al
;
; ; On demande le code de changement de banque
;
; mov ax,0300h ; Service DPMI simuler une interruption en mode r<>el
; mov bl,10h ; Interruption <20> appeler (int vid<69>o)
; xor bh,bh ; Etat des flags pass<73> <20> l'interruption
; xor cx,cx ; Nb d'elements de la pile <20> passer
; mov edi,0A8000h ; Adresse des valeurs des registres <20> passer <20> l'interruption
; mov dword ptr[edi+28],00004F0Ah ; EAX pass<73> <20> l'interruption
; mov dword ptr[edi+16],00000000h ; EBX pass<73> <20> l'interruption
; int 31h ; Appel de l'interruption du DPMI
;
; ; Si AX <> 004F => Echec
;
; mov si,8 ; Nouveau code d'erreur
;
; mov eax,dword ptr[edi+28]
; cmp ax,004Fh
; jne Mode_VESA_supporte_Fin_traitement
;
; ; On note l'adresse du handler software de changement de banque
;
; xor eax,eax
; xor ecx,ecx
; mov ax,word ptr[edi+34] ; ES retourn<72> par l'interruption
; mov cx,word ptr[edi+00] ; DI retourn<72> par l'interruption
; shl eax,4
; add eax,ecx
; mov cx,[eax]
; add eax,ecx
; mov VESA_WinFuncPtr,eax
;
; Mode_VESA_supporte_Fin_traitement:
;
;
; popad
;
; mov esp,ebp
; pop ebp
;
; ret
;
;Mode_VESA_supporte endp
; -- Initialisation du Mode Graphique VESA --
Initialiser_mode_video_VESA proc near
push ebp
mov ebp,esp
arg Video_mode:word
push ebx
mov VESA_Derniere_banque_Fenetre_A_utilisee,0
mov VESA_Derniere_banque_Fenetre_B_utilisee,0
mov ax,4F02h
mov bx,Video_mode
int 10h
; On donne la largeur logique de l'<27>cran car certaines cartes vid<69>o la
; reconnaissent mal... (va savoir pourquoi!?)
mov ax,4F06h
xor bl,bl
mov cx,Largeur_ecran
int 10h
; On calcule la distance d'octet en m<>moire qu'il y a entre la fin d'une
; ligne d'image <20> l'<27>cran et le d<>but de la suivante <20> l'<27>cran:
;
; Decalage = (Largeur_image - Largeur_ecran)
xor ebx,ebx
mov bx,Principal_Largeur_image
sub bx,Largeur_ecran
mov VESA_Decalage_synchro,ebx
; On calcule la largeur d'une ligne de l'<27>cran en dword:
;
; Largeur en dword = Largeur_ecran shr 2
mov ax,Largeur_ecran
shr ax,2
mov VESA_Largeur_ecran_en_dword,ax
pop ebx
mov esp,ebp
pop ebp
ret
Initialiser_mode_video_VESA endp
; - --/\/ Retoucher les registres du CRTC pour redimensionner l'<27>cran \/\-- -
Retoucher_CRTC proc near
pushad
mov esi,Mode_X_Ptr
cld
lodsb
or al,al
jz NoThankYou
mov dx,3C2h
out dx,al
NoThankYou:
mov dx,3D4h
mov al,11h
out dx,al
inc dx
in al,dx
and al,7Fh
out dx,al
dec dx
lodsb
xor ecx,ecx
mov cl,al
rep outsw
popad
ret
Retoucher_CRTC endp
; -- Affichage d'un point graphique en X,Y --
Pixel_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Couleur:byte
mov edx,0A0000h
mov cl,Couleur
mov ax,Pos_Y
mul Largeur_ecran
add ax,Pos_X
adc dx,0
xchg dx,ax
call [VESA_Change_banque_ecriture]
mov [edx],cl
mov esp,ebp
pop ebp
ret
Pixel_VESA endp
; -- R<>cup<75>ration d'un point graphique en X,Y --
Lit_pixel_VESA proc near
push ebp
mov ebp,esp
ARG Pos_X:word,Pos_Y:word
xor eax,eax
mov edx,0A0000h
mov ax,Pos_Y
mul Largeur_ecran
add ax,Pos_X
adc dx,0
xchg dx,ax
call [VESA_Change_banque_lecture]
mov al,byte ptr[edx]
mov esp,ebp
pop ebp
ret
Lit_pixel_VESA endp
Effacer_tout_l_ecran_VESA proc near
push ebp
mov ebp,esp
arg Couleur:byte
pushad
; On met dans EBX 4 fois la couleur
mov al,Couleur
mov ah,al
mov bx,ax
shl ebx,16
mov bx,ax
; On calcule l'endroit jusqu'o<> on efface l'ecran
mov ax,Menu_ordonnee
mul Largeur_ecran
; DX = Derni<6E>re banque touch<63>e
; AX = Derni<6E>re position touch<63>e
shr ax,2 ; On divise AX par 4 puisqu'on travaille avec des dword
Pour_chaque_banque:
; On passe <20> la banque DL
xchg dx,ax
call [VESA_Change_banque_ecriture]
xchg dx,ax
; On se positionne en d<>but de banque:
mov edi,0A0000h
; On efface AX mots:
mov cx,ax
; On met dans EAX 4 fois la couleur:
mov eax,ebx
Boucle:
mov [edi],eax
add edi,4
dec cx
jnz Boucle
mov ax,4000h ; On demande pour la prochaine banque un remplissage sur
; toute sa taille
dec dl
jns Pour_chaque_banque
popad
mov esp,ebp
pop ebp
ret
Effacer_tout_l_ecran_VESA endp
Block_VESA proc near
push ebp
mov ebp,esp
arg Debut_X:word,Debut_Y:word,Largeur:word,Hauteur:word,Couleur:byte
push ebx
push esi
push edi
; On place dans ESI 4 fois la couleur
mov cl,Couleur
mov ch,cl
mov si,cx
shl esi,16
mov si,cx
; On calcule dans EDI la premi<6D>re coordonn<6E>e du bloc:
mov ax,Debut_Y
mul Largeur_ecran
add ax,Debut_X
adc dx,0
mov edi,0A0000h
mov di,ax
; On m<>morise la banque n<>cessaire
mov VESA_Banque_en_cours,dl
; On passe dans cette banque
mov al,dl
call [VESA_Change_banque_ecriture]
; On met dans BX le nombre de ligne <20> traiter:
mov bx,Hauteur
; On met dans DX le d<>calage qu'il faudra effectuer en fin de ligne sur DI
; pour qu'il pointe sur la nouvelle ligne
mov dx,Largeur_ecran
sub dx,Largeur
xor ecx,ecx
Block_VESA_Pour_chaque_ligne:
; On regarde si la totalit<69> de la ligne loge dans la banque:
mov cx,di
add cx,Largeur
jc Block_VESA_Ligne_rompue
; A ce stade, on sait que la ligne loge enti<74>rement sur l'<27>cran
; On va donc placer dans EAX 4 fois la couleur
mov eax,esi
; On place dans CX le nb de pixels <20> afficher sur la ligne
mov cx,Largeur
; On commence par afficher les "d<>chets" de d<>but de ligne
shr cx,1
jnc Block_VESA_Ininterrompue_Largeur_paire
stosb
Block_VESA_Ininterrompue_Largeur_paire:
shr cx,1
jnc Block_VESA_Ininterrompue_Largeur_multiple_de_4
stosw
Block_VESA_Ininterrompue_Largeur_multiple_de_4:
; On affiche ce qui reste de la ligne
rep stosd
; On regarde si ce n'<27>tait pas la derni<6E>re ligne
dec bx
jz Block_VESA_Fin_de_traitement
; Sinon,
; Maintenant que la ligne est affich<63>e, on regarde si le changement de
; ligne ne d<>clenche pas un changement de banque:
add di,dx
jnc Block_VESA_Pour_chaque_ligne
; Si le changement de banque est n<>cessaire, on s'en fait un:
inc VESA_Banque_en_cours
mov al,VESA_Banque_en_cours
call [VESA_Change_banque_ecriture]
jmp Block_VESA_Pour_chaque_ligne
Block_VESA_Ligne_rompue:
; A ce stade, on sait que la ligne ne loge pas enti<74>rement sur l'<27>cran
; On m<>morise dans la pile ce qu'il restera <20> afficher <20> la droite de la
; rupture:
push cx
; On place dans EAX 4 fois la couleur
mov eax,esi
; On met dans CX le nb de pixels affichables avant la rupture
mov cx,di
neg cx
; On commence par afficher les "d<>chets" de d<>but de ligne
shr cx,1
jnc Block_VESA_Interrompue_Largeur_gauche_paire
stosb
Block_VESA_Interrompue_Largeur_gauche_paire:
shr cx,1
jnc Block_VESA_Interrompue_Largeur_gauche_multiple_de_4
stosw
Block_VESA_Interrompue_Largeur_gauche_multiple_de_4:
; On affiche ce qui reste de la partie gauche de la ligne
rep stosd
; On change de banque:
inc VESA_Banque_en_cours
mov al,VESA_Banque_en_cours
call [VESA_Change_banque_ecriture]
mov eax,esi
; On replace EDI en d<>but de banque
mov edi,0A0000h
; On restaure le nb de pixels <20> afficher <20> droite de la rupture
pop cx
; On commence par afficher les "d<>chets" de d<>but de ligne
shr cx,1
jnc Block_VESA_Interrompue_Largeur_droite_paire
stosb
Block_VESA_Interrompue_Largeur_droite_paire:
shr cx,1
jnc Block_VESA_Interrompue_Largeur_droite_multiple_de_4
stosw
Block_VESA_Interrompue_Largeur_droite_multiple_de_4:
; On affiche ce qui reste de la partie droite de la ligne
rep stosd
; On regarde si ce n'<27>tait pas la derni<6E>re ligne
; (on peut se permettre de supposer qu'apr<70>s ce changement de banque,
; on ne cours qu'un risque proche de 0 qu'un nouveau changement de
; banque survienne lors du changement de ligne - pour ne pas dire que
; c'est une chose impossible)
add di,dx
dec bx
jnz Block_VESA_Pour_chaque_ligne
Block_VESA_Fin_de_traitement:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Block_VESA endp
; -- Affichage d'un pixel dans l'<27>cran, par rapport au d<>calage de l'image
; dans l'<27>cran, en mode normal (pas en mode loupe) --
; Note: si on modifie cette proc<6F>dure, il faudra penser <20> faire <20>galement la
; modif dans la proc<6F>dure Pixel_Preview_Loupe_VESA.
Pixel_Preview_Normal_VESA proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
mov dl,Couleur
mov cx,Y
mov ax,X
sub cx,Principal_Decalage_Y
sub ax,Principal_Decalage_X
push edx
push ecx
push eax
call Pixel_VESA
mov esp,ebp
pop ebp
ret
Pixel_Preview_Normal_VESA endp
; -- Affichage d'un pixel dans l'<27>cran, par rapport au d<>calage de l'image
; dans l'<27>cran, en mode loupe --
Pixel_Preview_Loupe_VESA proc near
push ebp
mov ebp,esp
arg X:word,Y:word,Couleur:byte
push ebx
; On affiche d'abord le pixel dans la partie non-zoom<6F>e
mov dl,Couleur ; Ca ne co<63>te pas trop
mov cx,Y ; en code de recopier
mov ax,X ; le contenu de la
sub cx,Principal_Decalage_Y ; proc<6F>dure
sub ax,Principal_Decalage_X ; Pixel_Preview_Normal_VESA
push edx ; et <20>a fait gagner du
push ecx ; temps, et ce temps est
push eax ; assez pr<70>cieux vu que
call Pixel_VESA ; c'est appel<65> TRES souvent.
add esp,12 ; 3 param<61>tres dword
; On regarde si on peut afficher le pixel <20>galement dans la loupe
mov ax,Y
cmp ax,Limite_Haut_Zoom
jb Pixel_Preview_Loupe_VESA_Fin
cmp ax,Limite_visible_Bas_Zoom
ja Pixel_Preview_Loupe_VESA_Fin
mov ax,X
cmp ax,Limite_Gauche_Zoom
jb Pixel_Preview_Loupe_VESA_Fin
cmp ax,Limite_visible_Droite_Zoom
ja Pixel_Preview_Loupe_VESA_Fin
; On passe la couleur
mov al,Couleur
mov edx,Table_mul_facteur_zoom ; On pointe sur la table de x (OPTI)
push eax
; On calcule dans EAX (X) et ECX (Y) le d<>marrage du bloc:
xor eax,eax
xor ecx,ecx
mov ax,X
mov cx,Y
sub ax,Loupe_Decalage_X
sub cx,Loupe_Decalage_Y
mov ax,[edx+2*eax]
mov cx,[edx+2*ecx]
; On sauve ces valeurs dans BX (X) et DX (Y):
mov bx,ax
mov dx,cx
; On s'occupe de la hauteur:
add cx,Loupe_Facteur
cmp cx,Menu_Ordonnee
ja Pixel_Preview_Loupe_VESA_Tronque_en_hauteur
mov cx,Loupe_Facteur
push ecx
jmp Pixel_Preview_Loupe_VESA_Traitement_de_la_largeur
Pixel_Preview_Loupe_VESA_Tronque_en_hauteur:
mov cx,dx
neg cx
add cx,Menu_Ordonnee
push ecx
; On s'occupe de la largeur:
Pixel_Preview_Loupe_VESA_Traitement_de_la_largeur:
add bx,Principal_X_Zoom
mov ax,Loupe_Facteur
push eax
; On passe le d<>but en Y:
push edx
; On passe le d<>but en X:
push ebx
call Block_VESA
add esp,20 ; 20 = 5 param<61>tres de type dword
pop ebx
Pixel_Preview_Loupe_VESA_Fin:
mov esp,ebp
pop ebp
ret
Pixel_Preview_Loupe_VESA endp
Ligne_horizontale_XOR_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word, Pos_Y:word, Largeur:word
mov edx,0A0000h
mov ax,Pos_Y
mul Largeur_ecran
add ax,Pos_X
adc dx,0
xchg dx,ax
call [VESA_Change_banque_lect_ecr]
mov cx,Largeur
LH_VESA_Boucle:
not byte ptr[edx]
inc dx
jnz LH_VESA_Pas_de_changement_de_banque
inc al
call [VESA_Change_banque_lect_ecr]
LH_VESA_Pas_de_changement_de_banque:
dec cx
jnz LH_VESA_Boucle
mov esp,ebp
pop ebp
ret
Ligne_horizontale_XOR_VESA endp
Ligne_verticale_XOR_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word, Pos_Y:word, Hauteur:word
push ebx
mov bx,Largeur_ecran
mov edx,0A0000h
mov ax,Pos_Y
mul bx
add ax,Pos_X
adc dx,0
xchg dx,ax
call [VESA_Change_banque_lect_ecr]
mov cx,Hauteur
LV_VESA_Boucle:
not byte ptr[edx]
add dx,bx
jnc LV_VESA_Pas_de_changement_de_banque
inc al
call [VESA_Change_banque_lect_ecr]
LV_VESA_Pas_de_changement_de_banque:
dec cx
jnz LV_VESA_Boucle
pop ebx
mov esp,ebp
pop ebp
ret
Ligne_verticale_XOR_VESA endp
; Afficher une partie de la brosse en couleur en MCGA
Display_brush_Color_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Largeur_brosse:word
push ebx
push esi
push edi
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov di,Pos_Y ; |
mov bx,di ; |
shl di,8 ; |- DI <- Pos_Y * 320
shl bx,6 ; |
add di,bx ; |
add di,Pos_X
; Calculer dans ESI les coordonn<6E>es (Decalage_X,Decalage_Y) dans la brosse
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On place dans DX le nb de lignes <20> traiter
mov dx,Hauteur
; On place dans BH la couleur de transparence
mov bh,Couleur_de_transparence
; On place dans EAX la distance entre deux lignes <20> l'<27>cran
mov eax,320
sub ax,Largeur
Display_brush_Color_MCGA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,Largeur
Display_brush_Color_MCGA_Pour_chaque_pixel:
; On lit le contenu de la brosse
mov bl,[esi]
; Gestion de la transparence
cmp bl,bh
je Display_brush_Color_MCGA_Pas_de_copie
; On affiche le pixel de la brosse <20> l'<27>cran
mov [edi],bl
Display_brush_Color_MCGA_Pas_de_copie:
; On passe au pixel suivant
inc esi
inc edi
dec cx
jnz Display_brush_Color_MCGA_Pour_chaque_pixel
; On passe <20> la ligne suivante
mov cx,Largeur_brosse
add edi,eax
sub cx,Largeur
add esi,ecx
dec dx
jnz Display_brush_Color_MCGA_Pour_chaque_ligne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Color_MCGA endp
; Afficher une partie de la brosse en monochrome en MCGA
Display_brush_Mono_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Couleur:byte,Largeur_brosse:word
push ebx
push esi
push edi
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov di,Pos_Y ; |
mov bx,di ; |
shl di,8 ; |- DI <- Pos_Y * 320
shl bx,6 ; |
add di,bx ; |
add di,Pos_X
; Calculer dans ESI les coordonn<6E>es (Decalage_X,Decalage_Y) dans la brosse
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On place dans DX le nb de lignes <20> traiter
mov dx,Hauteur
; On place dans BH la couleur de transparence
mov bh,Couleur_de_transparence
; On place dans BL la couleur de coloriage
mov bl,Couleur
; On place dans EAX la distance entre 2 lignes <20> l'<27>cran
mov eax,320
sub ax,Largeur
Display_brush_Mono_MCGA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,Largeur
Display_brush_Mono_MCGA_Pour_chaque_pixel:
; On v<>rifie que le contenu de la brosse ne soit pas transparent
cmp [esi],bh
je Display_brush_Mono_MCGA_Pas_de_copie
; On affiche le pixel de la brosse <20> l'<27>cran
mov [edi],bl
Display_brush_Mono_MCGA_Pas_de_copie:
; On passe au pixel suivant
inc esi
inc edi
dec cx
jnz Display_brush_Mono_MCGA_Pour_chaque_pixel
; On passe <20> la ligne suivante
mov cx,Largeur_brosse
add edi,eax
sub cx,Largeur
add esi,ecx
dec dx
jnz Display_brush_Mono_MCGA_Pour_chaque_ligne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Mono_MCGA endp
; Effacer la partie de la brosse affich<63>e <20> l'<27>cran en MCGA
Clear_brush_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Largeur_image:word
push ebx
push esi
push edi
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov ax,Pos_Y ; |
mov di,ax ; |
shl ax,6 ; |- DI <- Pos_Y * 320
shl di,8 ; |
add di,ax ; |
add di,Pos_X
; Calculer dans ESI les coordonn<6E>es
; (Pos_X+Principal_Decalage_X,Pos_Y+Principal_Decalage_Y) dans l'image
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Pos_Y
mov bx,Largeur_image
mov cx,Pos_X
add ax,Principal_Decalage_Y
add cx,Principal_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On place dans DX le nb de lignes <20> traiter
mov dx,Hauteur
; On met dans EBX la distance entre 2 lignes <20> l'<27>cran
mov ebx,320
sub bx,Largeur
; On met dans EAX la distance entre 2 lignes dans l'image
xor eax,eax
mov ax,Largeur_image
sub ax,Largeur
; On nettoie la partie haute de ECX:
xor ecx,ecx
Clear_brush_MCGA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,Largeur
; On fait une copie de la ligne
shr cx,1
jnc Clear_brush_MCGA_Multiple_de_2
movsb
Clear_brush_MCGA_Multiple_de_2:
shr cx,1
jnc Clear_brush_MCGA_Multiple_de_4
movsw
Clear_brush_MCGA_Multiple_de_4:
rep movsd
; On passe <20> la ligne suivante
add esi,eax
add edi,ebx
dec dx
jnz Clear_brush_MCGA_Pour_chaque_ligne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Clear_brush_MCGA endp
; Afficher une partie de la brosse en couleur en VESA
Display_brush_Color_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Largeur_brosse:word
push ebx
push esi
push edi
; Calculer dans ESI les coordonn<6E>es (Decalage_X,Decalage_Y) dans la brosse
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov ax,Pos_Y
mul Largeur_ecran
add ax,Pos_X
adc dx,0
mov di,ax
; On passe dans la banque n<>cessaire (et on la m<>morise dans AL)
mov al,dl
call [VESA_Change_banque_ecriture]
; On place dans AH la couleur de transparence
mov ah,Couleur_de_transparence
; On place dans BX la diff<66>rence <20> l'<27>cran entre 2 lignes:
mov bx,Largeur_ecran
sub bx,Largeur
Display_brush_Color_VESA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,Largeur
Display_brush_Color_VESA_Pour_chaque_pixel:
; On lit le contenu de la brosse
mov dl,[esi]
; Gestion de la transparence
cmp dl,ah
je Display_brush_Color_VESA_Pas_de_copie
; On affiche le pixel de la brosse <20> l'<27>cran
mov [edi],dl
Display_brush_Color_VESA_Pas_de_copie:
; On passe au pixel suivant
inc esi
inc di
jz Display_brush_Color_VESA_Debordement_1
dec cx
jnz Display_brush_Color_VESA_Pour_chaque_pixel
jmp Display_brush_Color_VESA_Fin_de_ligne
Display_brush_Color_VESA_Debordement_1:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_ecriture]
dec cx
jnz Display_brush_Color_VESA_Pour_chaque_pixel
Display_brush_Color_VESA_Fin_de_ligne:
; On passe <20> la ligne suivante
mov cx,Largeur_brosse
sub cx,Largeur
add esi,ecx
add di,bx
jc Display_brush_Color_VESA_Debordement_2
dec Hauteur
jnz Display_brush_Color_VESA_Pour_chaque_ligne
jmp Display_brush_Color_VESA_Fin_de_traitement
Display_brush_Color_VESA_Debordement_2:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_ecriture]
dec Hauteur
jnz Display_brush_Color_VESA_Pour_chaque_ligne
Display_brush_Color_VESA_Fin_de_traitement:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Color_VESA endp
; Afficher une partie de la brosse en monochrome en VESA
Display_brush_Mono_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Couleur:byte,Largeur_brosse:word
push ebx
push esi
push edi
; Calculer dans ESI les coordonn<6E>es (Decalage_X,Decalage_Y) dans la brosse
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov ax,Pos_Y
mul Largeur_ecran
add ax,Pos_X
adc dx,0
mov di,ax
; On passe dans la banque n<>cessaire (et on la m<>morise dans AL)
mov al,dl
call [VESA_Change_banque_ecriture]
; On place dans AH la couleur de transparence
mov ah,Couleur_de_transparence
; On place dans DL la couleur de coloriage
mov dl,Couleur
; On place dans BX la diff<66>rence <20> l'<27>cran entre 2 lignes:
mov bx,Largeur_ecran
sub bx,Largeur
Display_brush_Mono_VESA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,word ptr[Largeur]
Display_brush_Mono_VESA_Pour_chaque_pixel:
; On v<>rifie que le contenu de la brosse ne soit pas la couleur de
; transparence
cmp [esi],ah
je Display_brush_Mono_VESA_Pas_de_copie
; On affiche un pixel de la couleur <20> l'<27>cran
mov [edi],dl
Display_brush_Mono_VESA_Pas_de_copie:
; On passe au pixel suivant
inc esi
inc di
jz Display_brush_Mono_VESA_Debordement_1
dec cx
jnz Display_brush_Mono_VESA_Pour_chaque_pixel
jmp Display_brush_Mono_VESA_Fin_de_ligne
Display_brush_Mono_VESA_Debordement_1:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_ecriture]
dec cx
jnz Display_brush_Mono_VESA_Pour_chaque_pixel
Display_brush_Mono_VESA_Fin_de_ligne:
; On passe <20> la ligne suivante
mov cx,Largeur_brosse
sub cx,Largeur
add esi,ecx
add di,bx
jc Display_brush_Mono_VESA_Debordement_2
dec Hauteur
jnz Display_brush_Mono_VESA_Pour_chaque_ligne
jmp Display_brush_Mono_VESA_Fin_de_traitement
Display_brush_Mono_VESA_Debordement_2:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_ecriture]
dec Hauteur
jnz Display_brush_Mono_VESA_Pour_chaque_ligne
Display_brush_Mono_VESA_Fin_de_traitement:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Mono_VESA endp
; Effacer la partie de la brosse affich<63>e <20> l'<27>cran en VESA
Clear_brush_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Largeur_image:word
push ebx
push esi
push edi
; Calculer dans ESI les coordonn<6E>es
; (Pos_X+Principal_Decalage_X,Pos_Y+Principal_Decalage_Y) dans l'image
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Pos_Y
mov bx,Largeur_image
mov cx,Pos_X
add ax,Principal_Decalage_Y
add cx,Principal_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov ax,Pos_Y
mul Largeur_ecran
add ax,Pos_X
adc dx,0
mov di,ax
; On passe dans la banque n<>cessaire (et on la m<>morise dans AL)
mov al,dl
call [VESA_Change_banque_ecriture]
; On place dans DX la diff<66>rence entre 2 lignes <20> l'<27>cran
mov dx,Largeur_ecran
sub dx,Largeur
; On place dans EBX la diff<66>rence entre 2 lignes dans l'image
mov bx,Largeur_image
sub bx,Largeur
Clear_brush_VESA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,Largeur
Clear_brush_VESA_Pour_chaque_pixel:
; On recopie le pixel de l'image <20> l'<27>cran
mov ah,[esi]
inc esi
mov [edi],ah
inc di
jz Clear_brush_VESA_Debordement_1
dec cx
jnz Clear_brush_VESA_Pour_chaque_pixel
jmp Clear_brush_VESA_Fin_de_ligne
Clear_brush_VESA_Debordement_1:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_ecriture]
; ; On r<>ajuste EDI qui vient de sortir du segment vid<69>o
; mov edi,0A0000h
dec cx
jnz Clear_brush_VESA_Pour_chaque_pixel
Clear_brush_VESA_Fin_de_ligne:
; On passe <20> la ligne suivante
add esi,ebx
add di,dx
jc Clear_brush_VESA_Debordement_2
dec Hauteur
jnz Clear_brush_VESA_Pour_chaque_ligne
jmp Clear_brush_VESA_Fin_de_traitement
Clear_brush_VESA_Debordement_2:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_ecriture]
dec Hauteur
jnz Clear_brush_VESA_Pour_chaque_ligne
Clear_brush_VESA_Fin_de_traitement:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Clear_brush_VESA endp
; Afficher une partie de la brosse en couleur en mode X
Display_brush_Color_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Largeur_brosse:dword
push ebx
push esi
push edi
; On nettoye la partie haute de Largeur_brosse
and Largeur_brosse,0FFFFh
; Calculer dans ESI les coordonn<6E>es (Decalage_X,Decalage_Y) dans la brosse
xor ebx,ebx
xor ecx,ecx
mov eax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran et dans AX
; le plan (AH = 1, 2, 4 ou 8) et le n<> de registre de chgnt de plan
mov edi,0A0000h
mov ax,MODE_X_Largeur_de_ligne
mov cx,Pos_X
mul Pos_Y
mov dx,cx
shr dx,2
add ax,dx
mov di,ax
mov ax,0102h
and cx,03h
shl ah,cl
; On passe dans le plan de d<>part
;
; Pour passer dans le plan N (0-3) en <20>criture:
; out 3C4h,02h
; out 3C5h,1 shl N
;
mov dx,3C4h
out dx,ax
; On sauve la valeur initiale de EDI
mov MODE_X_Valeur_initiale_de_edi,edi
; On sauve la valeur initiale de ESI
mov MODE_X_Valeur_initiale_de_esi,esi
; On place dans BH la couleur de transparence
mov bh,Couleur_de_transparence
Display_brush_Color_mode_X_Pour_chaque_colonne:
; On place dans CX le nb de pixels <20> traiter sur la colonne
mov cx,Hauteur
; On place dans DX la distance entre 2 lignes <20> l'<27>cran
mov dx,MODE_X_Largeur_de_ligne
Display_brush_Color_mode_X_Pour_chaque_ligne:
; On lit le contenu de la brosse
mov bl,[esi]
; Gestion de la transparence
cmp bl,bh
je Display_brush_Color_mode_X_Pas_de_copie
; On affiche le pixel de la brosse <20> l'<27>cran
mov [edi],bl
Display_brush_Color_mode_X_Pas_de_copie:
; On passe <20> la ligne suivante
add esi,Largeur_brosse
add di,dx
dec cx
jnz Display_brush_Color_mode_X_Pour_chaque_ligne
; On passe <20> la colonne suivante
inc MODE_X_Valeur_initiale_de_esi
mov esi,MODE_X_Valeur_initiale_de_esi
add ah,ah
cmp ah,10h
jne Display_brush_Color_mode_X_Pas_de_reset_de_plan
inc MODE_X_Valeur_initiale_de_edi
mov ah,01h
Display_brush_Color_mode_X_Pas_de_reset_de_plan:
mov edi,MODE_X_Valeur_initiale_de_edi
; On passe dans le nouveau plan
;
; Pour passer dans le plan N (0-3) en <20>criture:
; out 3C4h,02h
; out 3C5h,1 shl N
;
mov dx,3C4h
out dx,ax
dec Largeur
jnz Display_brush_Color_mode_X_Pour_chaque_colonne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Color_mode_X endp
; Afficher une partie de la brosse en monochrome en mode X
Display_brush_Mono_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Couleur:byte,Largeur_brosse:dword
push ebx
push esi
push edi
; On nettoye la partie haute de Largeur_brosse
and Largeur_brosse,0FFFFh
; Calculer dans ESI les coordonn<6E>es (Decalage_X,Decalage_Y) dans la brosse
xor ebx,ebx
xor ecx,ecx
mov eax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran et dans AX
; le plan (AH = 1, 2, 4 ou 8) et le n<> de registre de chgnt de plan
mov edi,0A0000h
mov ax,MODE_X_Largeur_de_ligne
mov cx,Pos_X
mul Pos_Y
mov dx,cx
shr dx,2
add ax,dx
mov di,ax
mov ax,0102h
and cx,03h
shl ah,cl
; On passe dans le plan de d<>part
;
; Pour passer dans le plan N (0-3) en <20>criture:
; out 3C4h,02h
; out 3C5h,1 shl N
;
mov dx,3C4h
out dx,ax
; On sauve la valeur initiale de EDI
mov MODE_X_Valeur_initiale_de_edi,edi
; On sauve la valeur initiale de ESI
mov MODE_X_Valeur_initiale_de_esi,esi
; On place dans BH la couleur de transparence
mov bh,Couleur_de_transparence
; On place dans BL la couleur de coloriage
mov bl,Couleur
Display_brush_Mono_mode_X_Pour_chaque_colonne:
; On place dans CX le nb de pixels <20> traiter sur la colonne
mov cx,Hauteur
; On place dans DX la distance entre 2 lignes <20> l'<27>cran
mov dx,MODE_X_Largeur_de_ligne
Display_brush_Mono_mode_X_Pour_chaque_ligne:
; On v<>rifie que le contenu de la brosse ne soit pas transparent
cmp [esi],bh
je Display_brush_Mono_mode_X_Pas_de_copie
; On affiche le pixel de la brosse <20> l'<27>cran
mov [edi],bl
Display_brush_Mono_mode_X_Pas_de_copie:
; On passe <20> la ligne suivante
add esi,Largeur_brosse
add di,dx
dec cx
jnz Display_brush_Mono_mode_X_Pour_chaque_ligne
; On passe <20> la colonne suivante
inc MODE_X_Valeur_initiale_de_esi
mov esi,MODE_X_Valeur_initiale_de_esi
add ah,ah
cmp ah,10h
jne Display_brush_Mono_mode_X_Pas_de_reset_de_plan
inc MODE_X_Valeur_initiale_de_edi
mov ah,01h
Display_brush_Mono_mode_X_Pas_de_reset_de_plan:
mov edi,MODE_X_Valeur_initiale_de_edi
; On passe dans le nouveau plan
;
; Pour passer dans le plan N (0-3) en <20>criture:
; out 3C4h,02h
; out 3C5h,1 shl N
;
mov dx,3C4h
out dx,ax
dec Largeur
jnz Display_brush_Mono_mode_X_Pour_chaque_colonne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Mono_mode_X endp
; Effacer la partie visible de la brosse en mode X
Clear_brush_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Hauteur:word,Couleur_de_transparence:byte,Largeur_image:dword
push ebx
push esi
push edi
; On nettoye la partie haute de Largeur_image
and Largeur_image,0FFFFh
; Calculer dans ESI les coordonn<6E>es
; (Pos_X+Principal_Decalage_X,Pos_Y+Principal_Decalage_Y) dans l'image
xor eax,eax
xor ecx,ecx
mov ax,Pos_Y
mov ebx,Largeur_image
mov cx,Pos_X
add ax,Principal_Decalage_Y
add cx,Principal_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On sauve la valeur initiale de ESI
mov MODE_X_Valeur_initiale_de_esi,esi
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran et dans AX
; le plan (AH = 1, 2, 4 ou 8) et le n<> de registre de chgnt de plan
mov edi,0A0000h
mov ax,MODE_X_Largeur_de_ligne
mov cx,Pos_X
mul Pos_Y
mov dx,cx
shr dx,2
add ax,dx
mov di,ax
mov ax,0102h
and cx,03h
shl ah,cl
; On passe dans le plan de d<>part
;
; Pour passer dans le plan N (0-3) en <20>criture:
; out 3C4h,02h
; out 3C5h,1 shl N
;
mov dx,3C4h
out dx,ax
; On sauve la valeur initiale de EDI
mov MODE_X_Valeur_initiale_de_edi,edi
Clear_brush_mode_X_Pour_chaque_colonne:
; On place dans CX le nb de pixels <20> traiter sur la colonne
mov cx,Hauteur
; On place dans DX la distance entre 2 lignes <20> l'<27>cran
mov dx,MODE_X_Largeur_de_ligne
Clear_brush_mode_X_Pour_chaque_ligne:
; On copie le pixel de l'image vers l'<27>cran en passant <20> la ligne
; suivante
mov bl,[esi]
add esi,Largeur_image
mov [edi],bl
add di,dx
dec cx
jnz Clear_brush_mode_X_Pour_chaque_ligne
; On passe <20> la colonne suivante
inc MODE_X_Valeur_initiale_de_esi
mov esi,MODE_X_Valeur_initiale_de_esi
add ah,ah
cmp ah,10h
jne Clear_brush_mode_X_Pas_de_reset_de_plan
inc MODE_X_Valeur_initiale_de_edi
mov ah,01h
Clear_brush_mode_X_Pas_de_reset_de_plan:
mov edi,MODE_X_Valeur_initiale_de_edi
; On passe dans le nouveau plan
;
; Pour passer dans le plan N (0-3) en <20>criture:
; out 3C4h,02h
; out 3C5h,1 shl N
;
mov dx,3C4h
out dx,ax
dec Largeur
jnz Clear_brush_mode_X_Pour_chaque_colonne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Clear_brush_mode_X endp
; Remapper une partie de l'<27>cran en MCGA
Remap_screen_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Hauteur:word,Conversion:dword
push ebx
push esi
push edi
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov di,Pos_Y ; |
mov bx,di ; |
shl di,8 ; |_ DI <- (Pos_Y*320) + Pos_X
shl bx,6 ; |
add di,bx ; |
add di,Pos_X ; |
; On place dans DX le nb de lignes <20> traiter
mov dx,Hauteur
; On place dans EBX l'adresse de la table de conversion
mov ebx,Conversion
; On nettoie (entre autres) la partie haute de EAX
xor eax,eax
; On met dans ESI la distance entre la fin d'une ligne et le d<>but de la
; suivante
mov esi,320
sub si,Largeur
Remap_screen_MCGA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,Largeur
Remap_screen_MCGA_Pour_chaque_pixel:
mov al,[edi]
mov al,[ebx+eax]
mov [edi],al
; On passe au pixel suivant
inc edi
dec cx
jnz Remap_screen_MCGA_Pour_chaque_pixel
; On passe <20> la ligne suivante
add edi,esi
dec dx
jnz Remap_screen_MCGA_Pour_chaque_ligne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Remap_screen_MCGA endp
; Remapper une partie de l'<27>cran en mode X
Remap_screen_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Hauteur:word,Conversion:dword
push ebx
push esi
push edi
; On met dans CL le plan initial
mov bx,Pos_X
mov cl,bl
and cl,00000011b
; On met dans ESI la valeur initiale de EDI
; (ESI=D<>but de ligne, EDI=Position dans la ligne)
mov esi,0A0000h
mov ax,Pos_Y
mul MODE_X_Largeur_de_ligne
shr bx,2
add ax,bx
mov si,ax
; On met dans BX la coordonn<6E>e de fin +1 (horizontalement)
mov bx,Pos_X
add bx,Largeur
Remap_screen_mode_X_Pour_chaque_ligne:
; On place dans CH le nb de plans <20> traiter
mov ch,4
Remap_screen_mode_X_Pour_chaque_plan:
; On initialise EDI
mov edi,esi
; On passe dans le plan d<>tenu par CL
; Plan d'<27>criture:
mov dx,3C4h ; DX = Port du CRTC (chngt de plan)
mov ax,102h
shl ah,cl
out dx,ax
; Plan de lecture:
mov dx,3CEh ; DX = Port du TS (enfin, je crois)
mov ah,cl
mov al,04h
out dx,ax
; On met dans AX la coordonn<6E>e de d<>part
mov ax,Pos_X
Remap_screen_mode_X_Boucle:
cmp ax,bx
jae Remap_screen_mode_X_Fin_de_traitement
; On convertit le pixel courant
xor edx,edx
mov dl,[edi]
add edx,Conversion
mov dl,[edx]
mov [edi],dl
inc edi ; On passe <20> la coordonn<6E>e +4
add ax,4
jmp Remap_screen_mode_X_Boucle
Remap_screen_mode_X_Fin_de_traitement:
; On pr<70>pare CL pour le prochain plan:
inc cl
and cl,00000011b
jnz Remap_screen_mode_X_On_repasse_pas_dans_le_plan_0
; On pr<70>pare ESI pour le prochain plan:
inc esi
Remap_screen_mode_X_On_repasse_pas_dans_le_plan_0:
; On pr<70>pare la coordonn<6E>e de d<>part pour le prochain plan:
inc Pos_X
; On regarde s'il reste un plan <20> traiter:
dec ch
jnz Remap_screen_mode_X_Pour_chaque_plan
; On passe <20> la ligne suivante
dec si ; ESI a forc<72>ment ripp<70> sur la droite, on le corrige
add si,MODE_X_Largeur_de_ligne ; et on passe <20> la suivante
sub Pos_X,4 ; On fait de m<>me avec Pos_X
dec Hauteur
jnz Remap_screen_mode_X_Pour_chaque_ligne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Remap_screen_mode_X endp
; Remapper une partie de l'<27>cran en VESA
Remap_screen_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Hauteur:word,Conversion:dword
push ebx
push esi
push edi
; Calculer dans EDI les coordonn<6E>es (Pos_X,Pos_Y) <20> l'<27>cran
mov edi,0A0000h
mov ax,Pos_Y
mul Largeur_ecran
add ax,Pos_X
adc dx,0
mov di,ax
; On passe dans la banque n<>cessaire (et on la m<>morise dans AL)
mov al,dl
call [VESA_Change_banque_lect_ecr]
; On place dans EBX l'adresse de la table de conversion
mov ebx,Conversion
; On nettoie la partie haute de EDX
xor edx,edx
; On met dans SI la distance entre la fin d'une ligne et le d<>but de la
; suivante
mov si,Largeur_ecran
sub si,Largeur
Remap_screen_VESA_Pour_chaque_ligne:
; On place dans CX le nb de pixels <20> traiter sur la ligne
mov cx,Largeur
Remap_screen_VESA_Pour_chaque_pixel:
mov dl,[edi]
mov dl,[edx+ebx]
mov [edi],dl
; On passe au pixel suivant
inc di
jz Remap_screen_VESA_Debordement_1
dec cx
jnz Remap_screen_VESA_Pour_chaque_pixel
jmp Remap_screen_VESA_Fin_de_ligne
Remap_screen_VESA_Debordement_1:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_lect_ecr]
dec cx
jnz Remap_screen_VESA_Pour_chaque_pixel
Remap_screen_VESA_Fin_de_ligne:
; On passe <20> la ligne suivante
add di,si
jc Remap_screen_VESA_Debordement_2
dec Hauteur
jnz Remap_screen_VESA_Pour_chaque_ligne
jmp Remap_screen_VESA_Fin_de_traitement
Remap_screen_VESA_Debordement_2:
; On passe dans la banque suivante
inc al
call [VESA_Change_banque_lect_ecr]
dec Hauteur
jnz Remap_screen_VESA_Pour_chaque_ligne
Remap_screen_VESA_Fin_de_traitement:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Remap_screen_VESA endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Afficher une partie de l'image tel quel sur l'<27>cran
Afficher_partie_de_l_ecran_MCGA proc near
push ebp
mov ebp,esp
arg Largeur:word,Hauteur:word,Largeur_image:word
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Principal_Decalage_Y*Largeur_image)+Principal_Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Principal_Decalage_Y
mov cx,Principal_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h
mov edi,0A0000h
; On met dans EAX la distance qu'il y a entre le dernier pixel affich<63>
; d'une ligne et le premier pixel affich<63> de la ligne suivante DANS L'IMAGE
;
; EAX = Largeur_image-Largeur
xor eax,eax
mov ax,Largeur_image
sub ax,Largeur
; On met dans EBX la distance qu'il y a entre le dernier pixel affich<63>
; d'une ligne et le premier pixel affich<63> de la ligne suivante DANS L'ECRAN
;
; EBX = 320 - Largeur
mov ebx,320
sub bx,Largeur
; On met dans DX le nombre de lignes <20> traiter:
mov dx,Hauteur
; On nettoye la partie haute de ECX: (OPTIM.: VIRABLE CAR FAIT PLUS HAUT)
xor ecx,ecx
APDLE_MCGA_Pour_chaque_ligne:
; On met dans ECX le nombre de pixels <20> traiter:
mov cx,Largeur
; On les traite au mieux par copie 8/16/32 bits
shr cx,1
jnc APDLE_MCGA_ECX_multiple_de_2
movsb
APDLE_MCGA_ECX_multiple_de_2:
shr cx,1
jnc APDLE_MCGA_ECX_multiple_de_4
movsw
APDLE_MCGA_ECX_multiple_de_4:
rep movsd
; On passe <20> la ligne suivante
; sans oublier d'incr<63>menter correctement ESI et EDI
add esi,eax
add edi,ebx
dec dx
jnz APDLE_MCGA_Pour_chaque_ligne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_partie_de_l_ecran_MCGA endp
; Afficher une ligne <20> l'<27>cran
Afficher_une_ligne_a_l_ecran_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword
push esi
push edi
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h+((Pos_Y*320)+Pos_X)
mov ax,320
mov edi,0A0000h
mul Pos_Y
add ax,Pos_X
mov di,ax
; On met dans ECX le nombre de pixels <20> traiter:
xor ecx,ecx
mov cx,Largeur
; On les traite au mieux par copie 8/16/32 bits
shr cx,1
jnc AULALE_MCGA_ECX_multiple_de_2
movsb
AULALE_MCGA_ECX_multiple_de_2:
shr cx,1
jnc AULALE_MCGA_ECX_multiple_de_4
movsw
AULALE_MCGA_ECX_multiple_de_4:
rep movsd
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_a_l_ecran_MCGA endp
; Lire une ligne <20> l'<27>cran et la stocker dans un buffer
Lire_une_ligne_a_l_ecran_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword
push esi
push edi
; On met dans EDI l'adresse de la ligne <20> lire:
mov edi,Ligne
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=0A0000h+((Pos_Y*320)+Pos_X)
mov ax,320
mov esi,0A0000h
mul Pos_Y
add ax,Pos_X
mov si,ax
; On met dans ECX le nombre de pixels <20> traiter:
xor ecx,ecx
mov cx,Largeur
; On les traite au mieux par copie 8/16/32 bits
shr cx,1
jnc LULALE_MCGA_ECX_multiple_de_2
movsb
LULALE_MCGA_ECX_multiple_de_2:
shr cx,1
jnc LULALE_MCGA_ECX_multiple_de_4
movsw
LULALE_MCGA_ECX_multiple_de_4:
rep movsd
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Lire_une_ligne_a_l_ecran_MCGA endp
; Afficher une partie de l'image zoom<6F>e <20> l'<27>cran
Afficher_partie_de_l_ecran_zoomee_MCGA proc near
push ebp
mov ebp,esp
arg Largeur:word,Hauteur:word,Largeur_image:word,Buffer:dword
; Largeur = Largeur non zoom<6F>e
; Hauteur = Hauteur zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Loupe_Decalage_Y*Largeur_image)+Loupe_Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Loupe_Decalage_Y
mov cx,Loupe_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans EDX la ligne en cours de traitement:
xor edx,edx
; On met dans EBX la distance entre deux lignes d'image
xor ebx,ebx
mov bx,Largeur_image
APDLEZ_MCGA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov cx,Loupe_Facteur
APDLEZ_MCGA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
push cx
push dx
push Buffer ; Ligne
push edi ; Largeur*Facteur
push edx ; Pos_Y
mov ax,Principal_X_Zoom
push eax ; Pos_X
call Afficher_une_ligne_a_l_ecran_MCGA
add esp,16
pop dx
pop cx
; On passe <20> la ligne suivante
inc dx ; -> On v<>rifie qu'on ne soit
cmp dx,Hauteur ; pas arriv<69> <20> la ligne
je APDLEZ_MCGA_Menu_Ordonnee_atteinte ; terminale
dec cx ; -> ou que l'on ai termin<69> de
jnz APDLEZ_MCGA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne image suivante
add esi,ebx
jmp APDLEZ_MCGA_Pour_chaque_ligne_a_zoomer
APDLEZ_MCGA_Menu_Ordonnee_atteinte:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_partie_de_l_ecran_zoomee_MCGA endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Afficher une partie de l'image tel quel sur l'<27>cran
Afficher_partie_de_l_ecran_VESA proc near
push ebp
mov ebp,esp
arg Largeur:word,Hauteur:word,Largeur_image:word
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Principal_Decalage_Y*Largeur_image)+Principal_Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Principal_Decalage_Y
mov cx,Principal_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h
mov edi,0A0000h
; Et on passe dans la banque correspondante
xor al,al
call [VESA_Change_banque_ecriture]
; On met dans EBX la distance qu'il y a entre le dernier pixel affich<63>
; d'une ligne et le premier pixel affich<63> de la ligne suivante DANS L'IMAGE
;
; EBX = Largeur_image-Largeur
mov bx,Largeur_image
sub bx,Largeur
; On met dans DX le nombre de lignes <20> traiter:
mov dx,Hauteur
; On nettoye la partie haute de ECX: (OPTIM.: VIRABLE CAR FAIT PLUS HAUT)
xor ecx,ecx
APDLE_VESA_Pour_chaque_ligne:
; On met dans ECX le nombre de pixels <20> traiter:
mov cx,Largeur
; On regarde si la ligne loge totalement dans la banque en cours
add cx,di
jc APDLE_VESA_Debordement_de_ligne
; Si c'est le cas:
mov cx,Largeur ; correction de CX <20> cause du test
; On effectue une copie 8/16/32 bits
shr cx,1
jnc APDLE_VESA_Nobreak_ECX_multiple_de_2
movsb
APDLE_VESA_Nobreak_ECX_multiple_de_2:
shr cx,1
jnc APDLE_VESA_Nobreak_ECX_multiple_de_4
movsw
APDLE_VESA_Nobreak_ECX_multiple_de_4:
rep movsd
jmp APDLE_VESA_Fin_traitement_ligne
; Si ce n'est pas le cas (d<>bordement de la ligne)
APDLE_VESA_Debordement_de_ligne:
; A ce stade, on sait que la ligne ne loge pas enti<74>rement sur l'<27>cran
; On m<>morise dans la pile ce qu'il restera <20> afficher <20> la droite de la
; rupture:
push cx
; On met dans CX le nb de pixels affichables avant la rupture:
mov cx,di
neg cx
; On effectue une copie 8/16/32 bits de la partie gauche de la rupture:
shr cx,1
jnc APDLE_VESA_BreakLeft_ECX_multiple_de_2
movsb
APDLE_VESA_BreakLeft_ECX_multiple_de_2:
shr cx,1
jnc APDLE_VESA_BreakLeft_ECX_multiple_de_4
movsw
APDLE_VESA_BreakLeft_ECX_multiple_de_4:
rep movsd
; On change de banque:
inc al
call [VESA_Change_banque_ecriture]
; On replace EDI en d<>but de banque
mov edi,0A0000h
; On restaure le nb de pixels <20> afficher <20> droite de la rupture
pop cx
; On effectue une copie 8/16/32 bits de la partie droite de la rupture:
shr cx,1
jnc APDLE_VESA_BreakRight_ECX_multiple_de_2
movsb
APDLE_VESA_BreakRight_ECX_multiple_de_2:
shr cx,1
jnc APDLE_VESA_BreakRight_ECX_multiple_de_4
movsw
APDLE_VESA_BreakRight_ECX_multiple_de_4:
rep movsd
APDLE_VESA_Fin_traitement_ligne:
; Le traitement de la ligne est termin<69>, on change de ligne:
; On passe <20> la ligne suivante en incr<63>mentant correctement ESI et (E)DI:
mov cx,Largeur_ecran
add esi,ebx
sub cx,Largeur
add di,cx
jnc APDLE_VESA_Fin_traitement_ligne_Sans_cht_bnk
; Cas o<> le changement de ligne entra<72>ne un changement de banque:
inc al
call [VESA_Change_banque_ecriture]
APDLE_VESA_Fin_traitement_ligne_Sans_cht_bnk:
; On a fait le changement de ligne, on peut voir s'il reste des lignes <20>
; traiter:
dec dx
jnz APDLE_VESA_Pour_chaque_ligne
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_partie_de_l_ecran_VESA endp
; Afficher une ligne <20> l'<27>cran
Afficher_une_ligne_a_l_ecran_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword
push esi
push edi
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h+((Pos_Y*Largeur_ecran)+Pos_X)
mov ax,Largeur_ecran
mov edi,0A0000h
mul Pos_Y
add ax,Pos_X
adc dx,0
mov di,ax
; Et on passe dans la banque correspondante
mov al,dl
call [VESA_Change_banque_ecriture]
; On met dans ECX le nombre de pixels <20> traiter:
xor ecx,ecx
mov cx,Largeur
; On regarde si la ligne loge totalement dans la banque en cours
add cx,di
jc AULALE_VESA_Debordement_de_ligne
; Si c'est le cas:
mov cx,Largeur ; correction de CX <20> cause du test
; On effectue une copie 8/16/32 bits
shr cx,1
jnc AULALE_VESA_Nobreak_ECX_multiple_de_2
movsb
AULALE_VESA_Nobreak_ECX_multiple_de_2:
shr cx,1
jnc AULALE_VESA_Nobreak_ECX_multiple_de_4
movsw
AULALE_VESA_Nobreak_ECX_multiple_de_4:
rep movsd
jmp AULALE_VESA_Fin_traitement_ligne
; Si ce n'est pas le cas (d<>bordement de la ligne)
AULALE_VESA_Debordement_de_ligne:
; A ce stade, on sait que la ligne ne loge pas enti<74>rement sur l'<27>cran
; On m<>morise dans la pile ce qu'il restera <20> afficher <20> la droite de la
; rupture:
push cx
; On met dans CX le nb de pixels affichables avant la rupture:
mov cx,di
neg cx
; On effectue une copie 8/16/32 bits de la partie gauche de la rupture:
shr cx,1
jnc AULALE_VESA_BreakLeft_ECX_multiple_de_2
movsb
AULALE_VESA_BreakLeft_ECX_multiple_de_2:
shr cx,1
jnc AULALE_VESA_BreakLeft_ECX_multiple_de_4
movsw
AULALE_VESA_BreakLeft_ECX_multiple_de_4:
rep movsd
; On change de banque:
inc al
call [VESA_Change_banque_ecriture]
; On replace EDI en d<>but de banque
mov edi,0A0000h
; On restaure le nb de pixels <20> afficher <20> droite de la rupture
pop cx
; On effectue une copie 8/16/32 bits de la partie droite de la rupture:
shr cx,1
jnc AULALE_VESA_BreakRight_ECX_multiple_de_2
movsb
AULALE_VESA_BreakRight_ECX_multiple_de_2:
shr cx,1
jnc AULALE_VESA_BreakRight_ECX_multiple_de_4
movsw
AULALE_VESA_BreakRight_ECX_multiple_de_4:
rep movsd
AULALE_VESA_Fin_traitement_ligne:
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_a_l_ecran_VESA endp
; Lire une ligne <20> l'<27>cran et la stocker dans un buffer
Lire_une_ligne_a_l_ecran_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword
push esi
push edi
; On met dans EDI l'adresse de la ligne <20> lire:
mov edi,Ligne
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=0A0000h+((Pos_Y*Largeur_ecran)+Pos_X)
mov ax,Largeur_ecran
mov esi,0A0000h
mul Pos_Y
add ax,Pos_X
adc dx,0
mov si,ax
; Et on passe dans la banque correspondante
mov al,dl
call [VESA_Change_banque_ecriture]
; On met dans ECX le nombre de pixels <20> traiter:
xor ecx,ecx
mov cx,Largeur
; On regarde si la ligne loge totalement dans la banque en cours
add cx,si
jc LULALE_VESA_Debordement_de_ligne
; Si c'est le cas:
mov cx,Largeur ; correction de CX <20> cause du test
; On effectue une copie 8/16/32 bits
shr cx,1
jnc LULALE_VESA_Nobreak_ECX_multiple_de_2
movsb
LULALE_VESA_Nobreak_ECX_multiple_de_2:
shr cx,1
jnc LULALE_VESA_Nobreak_ECX_multiple_de_4
movsw
LULALE_VESA_Nobreak_ECX_multiple_de_4:
rep movsd
jmp LULALE_VESA_Fin_traitement_ligne
; Si ce n'est pas le cas (d<>bordement de la ligne)
LULALE_VESA_Debordement_de_ligne:
; A ce stade, on sait que la ligne ne loge pas enti<74>rement sur l'<27>cran
; On m<>morise dans la pile ce qu'il restera <20> afficher <20> la droite de la
; rupture:
push cx
; On met dans CX le nb de pixels affichables avant la rupture:
mov cx,si
neg cx
; On effectue une copie 8/16/32 bits de la partie gauche de la rupture:
shr cx,1
jnc LULALE_VESA_BreakLeft_ECX_multiple_de_2
movsb
LULALE_VESA_BreakLeft_ECX_multiple_de_2:
shr cx,1
jnc LULALE_VESA_BreakLeft_ECX_multiple_de_4
movsw
LULALE_VESA_BreakLeft_ECX_multiple_de_4:
rep movsd
; On change de banque:
inc al
call [VESA_Change_banque_ecriture]
; On replace ESI en d<>but de banque
mov esi,0A0000h
; On restaure le nb de pixels <20> afficher <20> droite de la rupture
pop cx
; On effectue une copie 8/16/32 bits de la partie droite de la rupture:
shr cx,1
jnc LULALE_VESA_BreakRight_ECX_multiple_de_2
movsb
LULALE_VESA_BreakRight_ECX_multiple_de_2:
shr cx,1
jnc LULALE_VESA_BreakRight_ECX_multiple_de_4
movsw
LULALE_VESA_BreakRight_ECX_multiple_de_4:
rep movsd
LULALE_VESA_Fin_traitement_ligne:
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Lire_une_ligne_a_l_ecran_VESA endp
; Afficher une partie de l'image zoom<6F>e <20> l'<27>cran
Afficher_partie_de_l_ecran_zoomee_VESA proc near
push ebp
mov ebp,esp
arg Largeur:word,Hauteur:word,Largeur_image:word,Buffer:dword
; Largeur = Largeur non zoom<6F>e
; Hauteur = Hauteur zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Loupe_Decalage_Y*Largeur_image)+Loupe_Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Loupe_Decalage_Y
mov cx,Loupe_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans EDX la ligne en cours de traitement:
xor edx,edx
; On met dans EBX la distance entre deux lignes d'image
xor ebx,ebx
mov bx,Largeur_image
APDLEZ_VESA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov cx,Loupe_Facteur
APDLEZ_VESA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
push cx
push dx
push Buffer ; Ligne
push edi ; Largeur*Facteur
push edx ; Pos_Y
mov ax,Principal_X_Zoom
push eax ; Pos_X
call Afficher_une_ligne_a_l_ecran_VESA
add esp,16
pop dx
pop cx
; On passe <20> la ligne suivante
inc dx ; -> On v<>rifie qu'on ne soit
cmp dx,Hauteur ; pas arriv<69> <20> la ligne
je APDLEZ_VESA_Menu_Ordonnee_atteinte ; terminale
dec cx ; -> ou que l'on ai termin<69> de
jnz APDLEZ_VESA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne image suivante
add esi,ebx
jmp APDLEZ_VESA_Pour_chaque_ligne_a_zoomer
APDLEZ_VESA_Menu_Ordonnee_atteinte:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_partie_de_l_ecran_zoomee_VESA endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Afficher une partie de l'image tel quel sur l'<27>cran
Afficher_partie_de_l_ecran_mode_X proc near
push ebp
mov ebp,esp
arg Largeur:word,Hauteur:word,Largeur_image:word
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Principal_Decalage_Y*Largeur_image)+Principal_Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Principal_Decalage_Y
mov bx,Largeur_image
mov cx,Principal_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On met dans EBX la distance qu'il y a entre la fin d'une ligne et le
; d<>but de la ligne suivante <20> l'<27>cran:
; = DEJA FAIT
; On met dans CX le n<> du 1er plan trait<69>:
mov ecx,3
APDLE_mode_X_Pour_chaque_plan:
; On passe dans le plan en question:
mov dx,3C4h
mov ax,102h
shl ah,cl
out dx,ax
push esi
push cx
; On fait pointer les ESI et EDI vers leurs bonnes positions:
add esi,ecx
mov edi,0A0000h
; Et on la garde bien au chaud dans un coin
mov MODE_X_Valeur_initiale_de_esi,esi
mov MODE_X_Valeur_initiale_de_edi,edi
; On lit le nombre de lignes <20> traiter:
mov dx,Hauteur
APDLE_mode_X_Pour_chaque_ligne:
; On restaure la valeur de CX
pop cx
push cx
APDLE_mode_X_Pour_chaque_pixel:
; On copie un pixel sur 4
mov eax,[esi]
mov [edi],al
add esi,4
inc edi
add cx,4
cmp cx,Largeur
jb APDLE_mode_X_Pour_chaque_pixel
; On saute la partie non visible de l'<27>cran:
mov esi,MODE_X_Valeur_initiale_de_esi
mov edi,MODE_X_Valeur_initiale_de_edi
add esi,ebx
add di,MODE_X_Largeur_de_ligne
mov MODE_X_Valeur_initiale_de_esi,esi
mov MODE_X_Valeur_initiale_de_edi,edi
dec dx
jnz APDLE_mode_X_Pour_chaque_ligne
pop cx ; CX = n<> du plan
pop esi
dec cx
jns APDLE_mode_X_Pour_chaque_plan
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_partie_de_l_ecran_mode_X endp
; Afficher une ligne <20> l'<27>cran
Afficher_une_ligne_a_l_ecran_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword
push ebx
push esi
push edi
; On calcule la valeur initiale de EDI et le plan de d<>part dans CL:
;
; Valeur initiale=0A0000h+((Pos_Y*320)+Pos_X)
xor eax,eax
xor ecx,ecx
xor edx,edx
mov ax,Largeur_ecran
mov dx,Pos_Y
mov cx,Pos_X
mul edx
mov edi,0A0000h
add eax,ecx
shr eax,2
and cx,3
mov di,ax
mov MODE_X_Valeur_initiale_de_edi,edi
; On met dans BX le n<> d'ordre du plan trait<69> (pas le n<> de plan):
xor ebx,ebx
AULALE_mode_X_Pour_chacun_des_plans:
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
add esi,ebx
; Et dans EDI l'adresse o<> recopier
mov edi,MODE_X_Valeur_initiale_de_edi
; On passe dans le plan en question:
mov dx,3C4h
mov ax,102h
shl ah,cl
out dx,ax
push cx
; On met dans CX la largeur d<>j<EFBFBD> trait<69>e:
mov cx,bx
AULALE_mode_X_Pour_chaque_pixel_du_plan:
; On v<>rifie qu'on ait pas d<>bord<72>:
cmp cx,Largeur
jae AULALE_mode_X_Fin_du_traitement_du_plan
; On copie un pixel:
mov eax,[esi]
mov [edi],al
add esi,4
inc edi
add cx,4
jmp AULALE_mode_X_Pour_chaque_pixel_du_plan
AULALE_mode_X_Fin_du_traitement_du_plan:
; On passe au plan suivant:
pop cx ; -> Mise <20> jour de la
inc cx ; valeur du plan
and cx,3 ;
jnz AULALE_mode_X_Pas_de_changement_de_plan ;
inc MODE_X_Valeur_initiale_de_edi ;
AULALE_mode_X_Pas_de_changement_de_plan: ;
inc bx ; -> Mise <20> jour du n<> d'ordre
cmp bx,4 ; du plan trait<69>
jne AULALE_mode_X_Pour_chacun_des_plans ;
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_a_l_ecran_mode_X endp
; Lire une ligne <20> l'<27>cran et la stocker dans un buffer
Lire_une_ligne_a_l_ecran_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI et le plan de d<>part dans CL:
;
; Valeur initiale=0A0000h+((Pos_Y*Largeur_ecran)+Pos_X)
xor eax,eax
xor ecx,ecx
xor edx,edx
mov ax,Largeur_ecran
mov dx,Pos_Y
mov cx,Pos_X
mul edx
mov esi,0A0000h
add eax,ecx
shr eax,2
and cx,3
mov si,ax
mov MODE_X_Valeur_initiale_de_esi,esi
; On met dans BX le n<> d'ordre du plan trait<69> (pas le n<> de plan):
xor ebx,ebx
LULALE_mode_X_Pour_chacun_des_plans:
; On met dans EDI l'adresse de la ligne o<> copier:
mov edi,Ligne
add edi,ebx
; Et dans ESI l'adresse <20> recopier
mov esi,MODE_X_Valeur_initiale_de_esi
; On passe dans le plan en question:
mov dx,3CEh ; DX = Port du TS (enfin, je crois)
mov ah,cl
mov al,04h
out dx,ax
push cx
; On met dans CX la largeur d<>j<EFBFBD> trait<69>e:
mov cx,bx
LULALE_mode_X_Pour_chaque_pixel_du_plan:
; On v<>rifie qu'on ait pas d<>bord<72>:
cmp cx,Largeur
jae LULALE_mode_X_Fin_du_traitement_du_plan
; On copie un pixel:
mov al,[esi]
mov [edi],al
inc esi
add edi,4
add cx,4
jmp LULALE_mode_X_Pour_chaque_pixel_du_plan
LULALE_mode_X_Fin_du_traitement_du_plan:
; On passe au plan suivant:
pop cx ; -> Mise <20> jour de la
inc cx ; valeur du plan
and cx,3 ;
jnz LULALE_mode_X_Pas_de_changement_de_plan ;
inc MODE_X_Valeur_initiale_de_esi ;
LULALE_mode_X_Pas_de_changement_de_plan: ;
inc bx ; -> Mise <20> jour du n<> d'ordre
cmp bx,4 ; du plan trait<69>
jne LULALE_mode_X_Pour_chacun_des_plans ;
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Lire_une_ligne_a_l_ecran_mode_X endp
; Afficher une partie de l'image zoom<6F>e <20> l'<27>cran
Afficher_partie_de_l_ecran_zoomee_mode_X proc near
push ebp
mov ebp,esp
arg Largeur:word,Hauteur:word,Largeur_image:word,Buffer:dword
; Largeur = Largeur non zoom<6F>e
; Hauteur = Hauteur zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Loupe_Decalage_Y*Largeur_image)+Loupe_Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Loupe_Decalage_Y
mov cx,Loupe_Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans EDX la ligne en cours de traitement:
xor edx,edx
; On met dans EBX la distance entre deux lignes d'image
xor ebx,ebx
mov bx,Largeur_image
APDLEZ_mode_X_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov cx,Loupe_Facteur
APDLEZ_mode_X_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
push cx
push dx
push Buffer ; Ligne
push edi ; Largeur*Facteur
push edx ; Pos_Y
mov ax,Principal_X_Zoom
push eax ; Pos_X
call Afficher_une_ligne_a_l_ecran_mode_X
add esp,16
pop dx
pop cx
; On passe <20> la ligne suivante
inc dx ; -> On v<>rifie qu'on ne soit
cmp dx,Hauteur ; pas arriv<69> <20> la ligne
je APDLEZ_mode_X_Menu_Ordonnee_atteinte ; terminale
dec cx ; -> ou que l'on ai termin<69> de
jnz APDLEZ_mode_X_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne image suivante
add esi,ebx
jmp APDLEZ_mode_X_Pour_chaque_ligne_a_zoomer
APDLEZ_mode_X_Menu_Ordonnee_atteinte:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_partie_de_l_ecran_zoomee_mode_X endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Afficher une ligne transparente en MCGA
Afficher_une_ligne_transparente_a_l_ecran_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword,Couleur_transparence:byte
push esi
push edi
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h+((Pos_Y*320)+Pos_X)
mov ax,320
mov edi,0A0000h
mul Pos_Y
add ax,Pos_X
mov di,ax
; On met dans AH la couleur de transparence:
mov ah,Couleur_transparence
; On met dans CX le nombre de pixels <20> traiter:
mov cx,Largeur
; Pour chaque pixel de la ligne
AULTALE_Pour_chaque_pixel:
; On lit la source
mov al,[esi]
inc esi ; MAJ du Pointeur de source
; On v<>rifie qu'elle soit <> de la couleur de transparence
cmp al,ah
je AULTALE_Pas_de_copie
; Et on la copie dans la destination
mov [edi],al
AULTALE_Pas_de_copie:
inc edi ; MAJ du Pointeur de destination
; Hop! et un de moins
dec cx
jnz AULTALE_Pour_chaque_pixel
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_transparente_a_l_ecran_MCGA endp
; Afficher une ligne transparente en MCGA
Afficher_une_ligne_transparente_mono_a_l_ecran_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword,Couleur_transparence:byte,Couleur:byte
push esi
push edi
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h+((Pos_Y*320)+Pos_X)
mov ax,320
mov edi,0A0000h
mul Pos_Y
add ax,Pos_X
mov di,ax
; On met dans AL la couleur de transparence:
mov al,Couleur_transparence
; On met dans DL la couleur <20> utiliser:
mov dl,Couleur
; On met dans CX le nombre de pixels <20> traiter:
mov cx,Largeur
; Pour chaque pixel de la ligne
AULTMALE_Pour_chaque_pixel:
; On v<>rifie que la source soit <> de la couleur de transparence
cmp al,[esi]
je AULTMALE_Pas_de_copie
; Et on copie la couleur dans la destination
mov [edi],dl
AULTMALE_Pas_de_copie:
inc esi ; MAJ du Pointeur de source
inc edi ; MAJ du Pointeur de destination
; Hop! et un de moins
dec cx
jnz AULTMALE_Pour_chaque_pixel
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_transparente_mono_a_l_ecran_MCGA endp
; Afficher une ligne transparente <20> l'<27>cran
Afficher_une_ligne_transparente_a_l_ecran_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword,Couleur_transparence:byte
push esi
push edi
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h+((Pos_Y*Largeur_ecran)+Pos_X)
mov ax,Largeur_ecran
mov edi,0A0000h
mul Pos_Y
add ax,Pos_X
adc dx,0
mov di,ax
; Et on passe dans la banque correspondante
mov al,dl
call [VESA_Change_banque_ecriture]
; On met dans ECX le nombre de pixels <20> traiter:
xor ecx,ecx
mov cx,Largeur
; On regarde si la ligne loge totalement dans la banque en cours
add cx,di
jc AULTALE_VESA_Debordement_de_ligne
; Si c'est le cas:
mov cx,Largeur ; correction de CX <20> cause du test
; On effectue une copie de CX octets avec gestion de transparence
mov dh,Couleur_transparence
AULTALE_VESA_No_break_Pour_chaque_pixel:
mov dl,[esi]
cmp dl,dh
je AULTALE_VESA_No_break_Pas_de_copie
mov [edi],dl
AULTALE_VESA_No_break_Pas_de_copie:
inc esi
inc edi
dec cx
jnz AULTALE_VESA_No_break_Pour_chaque_pixel
jmp AULTALE_VESA_Fin_traitement_ligne
; Si ce n'est pas le cas (d<>bordement de la ligne)
AULTALE_VESA_Debordement_de_ligne:
; A ce stade, on sait que la ligne ne loge pas enti<74>rement sur l'<27>cran
; On m<>morise dans la pile ce qu'il restera <20> afficher <20> la droite de la
; rupture:
push cx
; On met dans CX le nb de pixels affichables avant la rupture:
mov cx,di
neg cx
; On effectue une copie de CX octets avec gestion de transparence
mov dh,Couleur_transparence
AULTALE_VESA_BreakLeft_Pour_chaque_pixel:
mov dl,[esi]
cmp dl,dh
je AULTALE_VESA_BreakLeft_Pas_de_copie
mov [edi],dl
AULTALE_VESA_BreakLeft_Pas_de_copie:
inc esi
inc edi
dec cx
jnz AULTALE_VESA_BreakLeft_Pour_chaque_pixel
; On change de banque:
inc al
call [VESA_Change_banque_ecriture]
; On replace EDI en d<>but de banque
mov edi,0A0000h
; On restaure le nb de pixels <20> afficher <20> droite de la rupture
pop cx
or cx,cx
jz AULTALE_VESA_Fin_traitement_ligne
; On effectue une copie de CX octets avec gestion de transparence
; mov dh,Couleur_transparence ; LIGNE ECRITE PLUS HAUT, DH INCHANGE
AULTALE_VESA_BreakRight_Pour_chaque_pixel:
mov dl,[esi]
cmp dl,dh
je AULTALE_VESA_BreakRight_Pas_de_copie
mov [edi],dl
AULTALE_VESA_BreakRight_Pas_de_copie:
inc esi
inc edi
dec cx
jnz AULTALE_VESA_BreakRight_Pour_chaque_pixel
AULTALE_VESA_Fin_traitement_ligne:
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_transparente_a_l_ecran_VESA endp
; Afficher une ligne transparente mono <20> l'<27>cran
Afficher_une_ligne_transparente_mono_a_l_ecran_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword,Couleur_transparence:byte,Couleur:byte
push esi
push edi
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
; On calcule la valeur initiale de EDI:
;
; Valeur initiale=0A0000h+((Pos_Y*Largeur_ecran)+Pos_X)
mov ax,Largeur_ecran
mov edi,0A0000h
mul Pos_Y
add ax,Pos_X
adc dx,0
mov di,ax
; Et on passe dans la banque correspondante
mov al,dl
call [VESA_Change_banque_ecriture]
; On met dans ECX le nombre de pixels <20> traiter:
xor ecx,ecx
mov cx,Largeur
; On regarde si la ligne loge totalement dans la banque en cours
add cx,di
jc AULTMALE_VESA_Debordement_de_ligne
; Si c'est le cas:
mov cx,Largeur ; correction de CX <20> cause du test
; On effectue une copie de CX octets avec gestion de transparence
mov dl,Couleur_transparence
mov dh,Couleur
AULTMALE_VESA_No_break_Pour_chaque_pixel:
cmp dl,[esi]
je AULTMALE_VESA_No_break_Pas_de_copie
mov [edi],dh
AULTMALE_VESA_No_break_Pas_de_copie:
inc esi
inc edi
dec cx
jnz AULTMALE_VESA_No_break_Pour_chaque_pixel
jmp AULTMALE_VESA_Fin_traitement_ligne
; Si ce n'est pas le cas (d<>bordement de la ligne)
AULTMALE_VESA_Debordement_de_ligne:
; A ce stade, on sait que la ligne ne loge pas enti<74>rement sur l'<27>cran
; On m<>morise dans la pile ce qu'il restera <20> afficher <20> la droite de la
; rupture:
push cx
; On met dans CX le nb de pixels affichables avant la rupture:
mov cx,di
neg cx
; On effectue une copie de CX octets avec gestion de transparence
mov dl,Couleur_transparence
mov dh,Couleur
AULTMALE_VESA_BreakLeft_Pour_chaque_pixel:
cmp dl,[esi]
je AULTMALE_VESA_BreakLeft_Pas_de_copie
mov [edi],dh
AULTMALE_VESA_BreakLeft_Pas_de_copie:
inc esi
inc edi
dec cx
jnz AULTMALE_VESA_BreakLeft_Pour_chaque_pixel
; On change de banque:
inc al
call [VESA_Change_banque_ecriture]
; On replace EDI en d<>but de banque
mov edi,0A0000h
; On restaure le nb de pixels <20> afficher <20> droite de la rupture
pop cx
or cx,cx
jz AULTMALE_VESA_Fin_traitement_ligne
; On effectue une copie de CX octets avec gestion de transparence
; mov dl,Couleur_transparence ; LIGNE ECRITE PLUS HAUT, DL INCHANGE
; mov dh,Couleur ; LIGNE ECRITE PLUS HAUT, DH INCHANGE
AULTMALE_VESA_BreakRight_Pour_chaque_pixel:
cmp dl,[esi]
je AULTMALE_VESA_BreakRight_Pas_de_copie
mov [edi],dh
AULTMALE_VESA_BreakRight_Pas_de_copie:
inc esi
inc edi
dec cx
jnz AULTMALE_VESA_BreakRight_Pour_chaque_pixel
AULTMALE_VESA_Fin_traitement_ligne:
pop edi
pop esi
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_transparente_mono_a_l_ecran_VESA endp
; Afficher une ligne transparente <20> l'<27>cran
Afficher_une_ligne_transparente_a_l_ecran_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword,Couleur_transparence:byte
push ebx
push esi
push edi
; On calcule la valeur initiale de EDI et le plan de d<>part dans CL:
;
; Valeur initiale=0A0000h+((Pos_Y*320)+Pos_X)
xor eax,eax
xor ecx,ecx
xor edx,edx
mov ax,Largeur_ecran
mov dx,Pos_Y
mov cx,Pos_X
mul edx
mov edi,0A0000h
add eax,ecx
shr eax,2
and cx,3
mov di,ax
mov MODE_X_Valeur_initiale_de_edi,edi
; On met dans BX le n<> d'ordre du plan trait<69> (pas le n<> de plan):
xor ebx,ebx
AULTALE_mode_X_Pour_chacun_des_plans:
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
add esi,ebx
; Et dans EDI l'adresse o<> recopier
mov edi,MODE_X_Valeur_initiale_de_edi
; On passe dans le plan en question:
mov dx,3C4h
mov ax,102h
shl ah,cl
out dx,ax
push cx
; On met dans CX la largeur d<>j<EFBFBD> trait<69>e:
mov cx,bx
; On met dans AH la couleur de transparence
mov ah,Couleur_transparence
AULTALE_mode_X_Pour_chaque_pixel_du_plan:
; On v<>rifie qu'on ai pas d<>bord<72>:
cmp cx,Largeur
jae AULTALE_mode_X_Fin_du_traitement_du_plan
; On copie un pixel:
mov al,[esi]
cmp al,ah
je AULTALE_mode_X_Pas_de_copie
mov [edi],al
AULTALE_mode_X_Pas_de_copie:
add esi,4
inc edi
add cx,4
jmp AULTALE_mode_X_Pour_chaque_pixel_du_plan
AULTALE_mode_X_Fin_du_traitement_du_plan:
; On passe au plan suivant:
pop cx ; -> Mise <20> jour de la
inc cx ; valeur du plan
and cx,3 ;
jnz AULTALE_mode_X_Pas_de_changement_de_plan ;
inc MODE_X_Valeur_initiale_de_edi ;
AULTALE_mode_X_Pas_de_changement_de_plan: ;
inc bx ; -> Mise <20> jour du n<> d'ordre
cmp bx,4 ; du plan trait<69>
jne AULTALE_mode_X_Pour_chacun_des_plans ;
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_transparente_a_l_ecran_mode_X endp
; Afficher une ligne transparente mono <20> l'<27>cran
Afficher_une_ligne_transparente_mono_a_l_ecran_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Largeur:word,Ligne:dword,Couleur_transparence:byte,Couleur:byte
push ebx
push esi
push edi
; On calcule la valeur initiale de EDI et le plan de d<>part dans CL:
;
; Valeur initiale=0A0000h+((Pos_Y*320)+Pos_X)
xor eax,eax
xor ecx,ecx
xor edx,edx
mov ax,Largeur_ecran
mov dx,Pos_Y
mov cx,Pos_X
mul edx
mov edi,0A0000h
add eax,ecx
shr eax,2
and cx,3
mov di,ax
mov MODE_X_Valeur_initiale_de_edi,edi
; On met dans BX le n<> d'ordre du plan trait<69> (pas le n<> de plan):
xor ebx,ebx
AULTMALE_mode_X_Pour_chacun_des_plans:
; On met dans ESI l'adresse de la ligne <20> copier:
mov esi,Ligne
add esi,ebx
; Et dans EDI l'adresse o<> recopier
mov edi,MODE_X_Valeur_initiale_de_edi
; On passe dans le plan en question:
mov dx,3C4h
mov ax,102h
shl ah,cl
out dx,ax
push cx
; On met dans CX la largeur d<>j<EFBFBD> trait<69>e:
mov cx,bx
; On met dans AL la couleur de transparence
mov al,Couleur_transparence
; Et la couleur de coloriage dans AH
mov ah,Couleur
AULTMALE_mode_X_Pour_chaque_pixel_du_plan:
; On v<>rifie qu'on ai pas d<>bord<72>:
cmp cx,Largeur
jae AULTMALE_mode_X_Fin_du_traitement_du_plan
; On copie un pixel:
cmp al,[esi]
je AULTMALE_mode_X_Pas_de_copie
mov [edi],ah
AULTMALE_mode_X_Pas_de_copie:
add esi,4
inc edi
add cx,4
jmp AULTMALE_mode_X_Pour_chaque_pixel_du_plan
AULTMALE_mode_X_Fin_du_traitement_du_plan:
; On passe au plan suivant:
pop cx ; -> Mise <20> jour de la
inc cx ; valeur du plan
and cx,3 ;
jnz AULTMALE_mode_X_Pas_de_changement_de_plan ;
inc MODE_X_Valeur_initiale_de_edi ;
AULTMALE_mode_X_Pas_de_changement_de_plan: ;
inc bx ; -> Mise <20> jour du n<> d'ordre
cmp bx,4 ; du plan trait<69>
jne AULTMALE_mode_X_Pour_chacun_des_plans ;
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Afficher_une_ligne_transparente_mono_a_l_ecran_mode_X endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Afficher une partie de la brosse zoom<6F>e en couleur en MCGA
Display_brush_Color_Zoom_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Largeur_brosse:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Brosse+((Decalage_Y*Largeur_brosse)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
DBCZ_MCGA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
mov al,Couleur_de_transparence
push eax ; Couleur de transparence
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
DBCZ_MCGA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_transparente_a_l_ecran_MCGA
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je DBCZ_MCGA_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz DBCZ_MCGA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,12 ; (Largeur*Facteur + Ligne + Couleur de transparence)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_brosse ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp DBCZ_MCGA_Pour_chaque_ligne_a_zoomer
DBCZ_MCGA_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,16 ; (Largeur*Facteur + Ligne + Couleur de transparence + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Color_Zoom_MCGA endp
; Afficher une partie de la brosse zoom<6F>e en monochrome en MCGA
Display_brush_Mono_Zoom_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Couleur:byte,Largeur_brosse:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Brosse+((Decalage_Y*Largeur_brosse)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
DBMZ_MCGA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
mov al,Couleur
mov cl,Couleur_de_transparence
push eax ; Couleur d'affichage
push ecx ; Couleur de transparence
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
DBMZ_MCGA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_transparente_mono_a_l_ecran_MCGA
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je DBMZ_MCGA_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz DBMZ_MCGA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,16 ; (Largeur*Facteur + Ligne + Couleur de transparence + Couleur)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_brosse ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp DBMZ_MCGA_Pour_chaque_ligne_a_zoomer
DBMZ_MCGA_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,20 ; (Largeur*Facteur + Ligne + Couleur de transparence + Couleur + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Mono_Zoom_MCGA endp
; Effacer une partie de la brosse zoom<6F>e en MCGA
Clear_brush_Zoom_MCGA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Largeur_image:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Decalage_Y*Largeur_image)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
CBZ_MCGA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
CBZ_MCGA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_a_l_ecran_MCGA
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je CBZ_MCGA_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz CBZ_MCGA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,8 ; (Largeur*Facteur + Ligne)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_image ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp CBZ_MCGA_Pour_chaque_ligne_a_zoomer
CBZ_MCGA_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,12 ; (Largeur*Facteur + Ligne + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Clear_brush_Zoom_MCGA endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Afficher une partie de la brosse zoom<6F>e en couleur en mode X
Display_brush_Color_Zoom_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Largeur_brosse:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Brosse+((Decalage_Y*Largeur_brosse)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
DBCZ_mode_X_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
mov al,Couleur_de_transparence
push eax ; Couleur de transparence
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
DBCZ_mode_X_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_transparente_a_l_ecran_mode_X
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je DBCZ_mode_X_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz DBCZ_mode_X_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,12 ; (Largeur*Facteur + Ligne + Couleur de transparence)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_brosse ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp DBCZ_mode_X_Pour_chaque_ligne_a_zoomer
DBCZ_mode_X_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,16 ; (Largeur*Facteur + Ligne + Couleur de transparence + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Color_Zoom_mode_X endp
; Afficher une partie de la brosse zoom<6F>e en monochrome en mode X
Display_brush_Mono_Zoom_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Couleur:byte,Largeur_brosse:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Brosse+((Decalage_Y*Largeur_brosse)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
DBMZ_mode_X_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
mov al,Couleur
mov cl,Couleur_de_transparence
push eax ; Couleur d'affichage
push ecx ; Couleur de transparence
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
DBMZ_mode_X_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_transparente_mono_a_l_ecran_mode_X
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je DBMZ_mode_X_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz DBMZ_mode_X_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,16 ; (Largeur*Facteur + Ligne + Couleur de transparence + Couleur)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_brosse ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp DBMZ_mode_X_Pour_chaque_ligne_a_zoomer
DBMZ_mode_X_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,20 ; (Largeur*Facteur + Ligne + Couleur de transparence + Couleur + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Mono_Zoom_mode_X endp
; Effacer une partie de la brosse zoom<6F>e en mode X
Clear_brush_Zoom_mode_X proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Largeur_image:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Decalage_Y*Largeur_image)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
CBZ_mode_X_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
CBZ_mode_X_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_a_l_ecran_mode_X
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je CBZ_mode_X_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz CBZ_mode_X_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,8 ; (Largeur*Facteur + Ligne)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_image ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp CBZ_mode_X_Pour_chaque_ligne_a_zoomer
CBZ_mode_X_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,12 ; (Largeur*Facteur + Ligne + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Clear_brush_Zoom_mode_X endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Afficher une partie de la brosse zoom<6F>e en couleur en VESA
Display_brush_Color_Zoom_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Largeur_brosse:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Brosse+((Decalage_Y*Largeur_brosse)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
DBCZ_VESA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
mov al,Couleur_de_transparence
push eax ; Couleur de transparence
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
DBCZ_VESA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_transparente_a_l_ecran_VESA
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je DBCZ_VESA_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz DBCZ_VESA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,12 ; (Largeur*Facteur + Ligne + Couleur de transparence)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_brosse ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp DBCZ_VESA_Pour_chaque_ligne_a_zoomer
DBCZ_VESA_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,16 ; (Largeur*Facteur + Ligne + Couleur de transparence + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Color_Zoom_VESA endp
; Afficher une partie de la brosse zoom<6F>e en monochrome en VESA
Display_brush_Mono_Zoom_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Couleur:byte,Largeur_brosse:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Brosse+((Decalage_Y*Largeur_brosse)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_brosse
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Brosse
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
DBMZ_VESA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
mov al,Couleur
mov cl,Couleur_de_transparence
push eax ; Couleur d'affichage
push ecx ; Couleur de transparence
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
DBMZ_VESA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_transparente_mono_a_l_ecran_VESA
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je DBMZ_VESA_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz DBMZ_VESA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,16 ; (Largeur*Facteur + Ligne + Couleur de transparence + Couleur)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_brosse ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp DBMZ_VESA_Pour_chaque_ligne_a_zoomer
DBMZ_VESA_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,20 ; (Largeur*Facteur + Ligne + Couleur de transparence + Couleur + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Display_brush_Mono_Zoom_VESA endp
; Effacer une partie de la brosse zoom<6F>e en VESA
Clear_brush_Zoom_VESA proc near
push ebp
mov ebp,esp
arg Pos_X:word,Pos_Y:word,Decalage_X:word,Decalage_Y:word,Largeur:word,Pos_Y_Fin:word,Couleur_de_transparence:byte,Largeur_image:word,Buffer:dword
; Largeur_brosse=Largeur r<>elle de la brosse
; Largeur = Largeur non zoom<6F>e
push ebx
push esi
push edi
; On calcule la valeur initiale de ESI:
;
; Valeur initiale=Principal_Ecran+((Decalage_Y*Largeur_image)+Decalage_X)
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,Largeur_image
mov bx,Decalage_Y
mov cx,Decalage_X
mul ebx
mov esi,Principal_Ecran
add eax,ecx
add esi,eax
; On met dans DI la valeur Largeur*Facteur
mov ax,Largeur
mul Loupe_Facteur
mov di,ax
; On met dans DX la ligne en cours de traitement:
xor dx,Pos_Y
CBZ_VESA_Pour_chaque_ligne_a_zoomer:
; On eclate la ligne <20> zoomer:
push dx
mov ax,Loupe_Facteur
mov cx,Largeur
push ecx ; Largeur
push eax ; Facteur
push Buffer ; Ligne zoom<6F>e
push esi ; Ligne originale
call Zoomer_une_ligne
add esp,16
pop dx
; On sauve l'ancienne valeur de ESI:
push esi
; On place dans ESI la position courante en Y
mov esi,edx
; On empile <20> l'avance les derniers param<61>tres qui ne changent jamais le
; long de la m<>me ligne zoom<6F>e:
push Buffer ; Ligne
push edi ; Largeur*Facteur
; On l'affiche Facteur fois <20> l'<27>cran (sur des lignes cons<6E>cutives):
mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appel<65>e
CBZ_VESA_Pour_chaque_ligne:
; On affiche la ligne zoom<6F>e
mov ax,Pos_X
push esi ; Pos_Y
push eax ; Pos_X
call Afficher_une_ligne_a_l_ecran_VESA
add esp,8 ; (Pos_X+Pos_Y)
; On passe <20> la ligne suivante
inc si ; -> On v<>rifie qu'on ne soit
cmp si,Pos_Y_Fin ; pas arriv<69> <20> la ligne
je CBZ_VESA_Hauteur_atteinte ; terminale
dec bx ; -> ou que l'on ai termin<69> de
jnz CBZ_VESA_Pour_chaque_ligne ; traiter la ligne <20> zoomer
; On passe <20> la ligne <20> zoomer suivante:
; sans oublier de passer <20> la ligne brosse suivante
; On commence par retirer les param<61>tres pr<70>c<EFBFBD>demment pass<73>s
add esp,8 ; (Largeur*Facteur + Ligne)
; On sauve la ligne courante dans DX:
mov edx,esi
; On restaure l'ancienne valeur de ESI:
pop esi
mov bx,Largeur_image ; En th<74>orie, la partie haute de EBX est propre
add esi,ebx
jmp CBZ_VESA_Pour_chaque_ligne_a_zoomer
CBZ_VESA_Hauteur_atteinte:
; On ram<61>ne la pile dans un <20>tat normal
add esp,12 ; (Largeur*Facteur + Ligne + ESI)
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Clear_brush_Zoom_VESA endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_TEXT ENDS
END