.386P .MODEL FLAT _DATA Segment dword public 'data' Assume cs:_TEXT, ds:_DATA ; ---- Variables exportées ---- public LFB_Selecteur public LFB_Adresse public LFB_Taille ; ---- Déclaration des variables ---- LFB_Selecteur dw 0 ; Sélecteur utilisé par le mapping du LFB LFB_Adresse dd 0 ; Adresse où est mappée le LFB LFB_Taille dd 0 ; Taille de la mémoire LFB Handle_temporaire dw 0 ; Handle de bloc mémoire DOS utilisé temporairement _DATA ENDS _TEXT Segment dword public 'code' Assume cs:_TEXT, ds:_DATA ; ---- Fonctions exportées ---- ; -- Fonctions VESA -- public Get_VESA_info public Get_VESA_mode_info public Get_VESA_protected_mode_WinFuncPtr public Set_VESA_mode public Initialiser_le_LFB public Fermer_le_LFB public Pixel_VESA_LFB public Lit_pixel_VESA_LFB public Effacer_tout_l_ecran_VESA_LFB public Block_VESA_LFB public Pixel_Preview_Normal_VESA_LFB public Pixel_Preview_Loupe_VESA_LFB public Ligne_horizontale_XOR_VESA_LFB public Ligne_verticale_XOR_VESA_LFB public Display_brush_Color_VESA_LFB public Display_brush_Mono_VESA_LFB public Clear_brush_VESA_LFB public Remap_screen_VESA_LFB public Afficher_partie_de_l_ecran_VESA_LFB public Afficher_une_ligne_a_l_ecran_VESA_LFB public Lire_une_ligne_a_l_ecran_VESA_LFB public Afficher_partie_de_l_ecran_zoomee_VESA_LFB public Display_brush_Color_Zoom_VESA_LFB public Display_brush_Mono_Zoom_VESA_LFB public Clear_brush_Zoom_VESA_LFB ; ---- Fonctions importées ---- ; -- Fonctions DPMI -- extrn Physical_address_mapping :near extrn Free_physical_address_mapping:near extrn Lock_linear_region :near extrn Unlock_linear_region :near extrn Allocate_ldt_descriptor :near extrn Free_ldt_descriptor :near extrn Set_segment_base_address :near extrn Set_segment_limit :near extrn Set_descriptor_access_rights :near extrn Get_segment_base_address :near ; -- Autres variables externes -- extrn Brosse:dword extrn Principal_Ecran:dword 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 extrn VESA_WinFuncPtr:dword ; -- Procédures externes -- extrn Zoomer_une_ligne:near ; - -- --- ----\/\ Lecture des informations VESA : /\/---- --- -- - Convertir_adresse_MR_MP proc near ; EDI = Adresse d'une adresse à corriger push eax push ecx mov eax,[edi] ; EAX = adresse à corriger mov ecx,eax shr eax,16 shl eax,4 and ecx,0FFFFh add eax,ecx mov [edi],eax pop ecx pop eax ret Convertir_adresse_MR_MP endp Get_VESA_info proc near push ebp mov ebp,esp arg Buffer:dword push ebx push esi push edi ; On commence par allouer un buffer en mode réel de 1024+64 octets mov ax,0100h ; "DPMI : Allocate Dos memory blocks" mov bx,68d ; BX = (1024+64)/16 = 68 paragraphes int 31h jc GVI_Erreur ; On sauve l'handle du buffer dans la pile push dx ; On place dans EDX l'adresse du buffer xor edx,edx mov dx,ax shl edx,4 ; On nettoie ce(s) buffer(s) mov edi,edx ; On place en EDX xor eax,eax ; ... la valeur 0 mov ecx,0110h ; ... sur 1024+64 positions rep stosd ; !!! Maintenant !!! ; On demande les infos VESA: (AX=4F00, ES:DI=Adresse du buffer) mov edi,edx ; Adresse des valeurs des registres à passer à l'interruption add edx,40h ; EDX=segment du buffer d'infos VESA shr edx,4 mov dword ptr[edi+1Ch],00004F00h ; EAX passé à l'interruption mov dword ptr[edi+00h],00000000h ; EDI passé à l'interruption mov word ptr[edi+22h],dx ; ES passé à l'interruption shl edx,4 mov dword ptr[edx],32454256h ; valeur hexa de "VBE2" mov ax,0300h ; Service DPMI simuler une interruption en mode réel mov bl,10h ; Interruption à appeler (int vidéo) xor bh,bh ; Flags de mode d'appel d'interruption xor cx,cx ; Nb d'elements de la pile à passer int 31h ; Appel de l'interruption du DPMI ; On place dans EBX la valeur EAX de retour de l'interruption mov ebx,dword ptr[edi+1Ch] ; On recopie le buffer du mode réel vers le mode protégé mov ecx,256 ; (256 dword = 1024 octets) mov esi,edx mov edi,Buffer rep movsd ; Puis on corrige chacune des adresses: mov edi,Buffer add edi,06h call Convertir_adresse_MR_MP ; Fabricant add edi,08h call Convertir_adresse_MR_MP ; Liste des modes add edi,08h call Convertir_adresse_MR_MP ; Vendeur add edi,04h call Convertir_adresse_MR_MP ; Produit add edi,04h call Convertir_adresse_MR_MP ; Révision ; On libŠre le buffer en mode réel de 1024+64 octets mov ax,0101h ; "DPMI : Free Dos memory blocks" pop dx ; DX = handle du buffer int 31h jnc GVI_Pas_d_erreur GVI_Erreur: mov bx,0FF00h GVI_Pas_d_erreur: mov ax,bx pop edi pop esi pop ebx mov esp,ebp pop ebp ret Get_VESA_info endp Get_VESA_mode_info proc near push ebp mov ebp,esp arg Mode:word,Buffer:dword push ebx push esi push edi ; On commence par allouer un buffer en mode réel de 256+64 octets mov ax,0100h ; "DPMI : Allocate Dos memory blocks" mov bx,20d ; BX = (256+64)/16 = 20 paragraphes int 31h jc GVMI_Erreur ; On sauve l'handle du buffer dans la pile push dx ; On place dans EDX l'adresse du buffer xor edx,edx mov dx,ax shl edx,4 ; On nettoie ce(s) buffer(s) mov edi,edx ; On place en EDX xor eax,eax ; ... la valeur 0 mov ecx,0080d ; ... sur 256+64 positions rep stosd ; !!! Maintenant !!! ; On demande les infos VESA: (AX=4F01, CX=Mode, ES:DI=Adresse du buffer) mov edi,edx ; Adresse des valeurs des registres à passer à l'interruption add edx,40h ; EDX=segment du buffer d'infos VESA shr edx,4 mov ax,Mode ; ECX=Mode vidéo dont ont recherche les informations mov dword ptr[edi+1Ch],00004F01h ; EAX passé à l'interruption mov word ptr[edi+18h],ax ; ECX passé à l'interruption mov dword ptr[edi+00h],00000000h ; EDI passé à l'interruption mov word ptr[edi+22h],dx ; ES passé à l'interruption shl edx,4 mov ax,0300h ; Service DPMI simuler une interruption en mode réel mov bl,10h ; Interruption à appeler (int vidéo) xor bh,bh ; Flags de mode d'appel d'interruption xor cx,cx ; Nb d'elements de la pile à passer int 31h ; Appel de l'interruption du DPMI ; On place dans EBX la valeur EAX de retour de l'interruption mov ebx,dword ptr[edi+1Ch] ; On recopie le buffer du mode réel vers le mode protégé mov ecx,64 ; (64 dword = 256 octets) mov esi,edx mov edi,Buffer rep movsd ; Puis on corrige chacune des adresses: mov edi,Buffer add edi,0Ch call Convertir_adresse_MR_MP ; Adresse WinFuncPtr (Mode réel) ; On libŠre le buffer en mode réel de 256+64 octets mov ax,0101h ; "DPMI : Free Dos memory blocks" pop dx ; DX = handle du buffer int 31h jnc GVMI_Pas_d_erreur GVMI_Erreur: mov bx,0FF00h GVMI_Pas_d_erreur: mov ax,bx pop edi pop esi pop ebx mov esp,ebp pop ebp ret Get_VESA_mode_info endp ; Renvoie dans EAX l'adresse de la fonction WinFuncPtr du mode protégé Get_VESA_protected_mode_WinFuncPtr proc near push ebx push edi mov VESA_WinFuncPtr,00000000h ; On commence par allouer un buffer en mode réel de 64 octets mov ax,0100h ; "DPMI : Allocate Dos memory blocks" mov bx,4d ; BX = 64/16 = 4 paragraphes int 31h jc GVPMW_Erreur_d_allocation_de_memoire ; On sauve l'handle du buffer mov Handle_temporaire,dx ; On place dans EDX l'adresse du buffer xor edx,edx mov dx,ax shl edx,4 ; On nettoie ce buffer mov edi,edx ; On place en EDX xor eax,eax ; ... la valeur 0 mov ecx,0016d ; ... sur 64 positions rep stosd ; !!! Maintenant !!! ; On demande les infos VESA PMI: (AX=4F0A, BX=0) mov ax,0300h ; Service DPMI simuler une interruption en mode réel mov bl,10h ; Interruption à appeler (int vidéo) xor bh,bh ; Flags de mode d'appel d'interruption xor cx,cx ; Nb d'elements de la pile à passer mov edi,edx ; Adresse des valeurs des registres à passer à l'interruption mov dword ptr[edi+1Ch],00004F0Ah ; EAX passé à l'interruption mov dword ptr[edi+10h],00000000h ; EBX passé à l'interruption int 31h ; Appel de l'interruption du DPMI ; On vérifie que la valeur de AX de retour soit = 004Fh mov eax,dword ptr[edi+1Ch] cmp ax,004Fh jne GVPMW_Fonction_VESA_non_supportee ; On sauve l'adresse dans VESA_WinFuncPtr xor eax,eax xor ecx,ecx mov ax,word ptr[edi+34] ; ES retourné par l'interruption mov cx,word ptr[edi+00] ; DI retourné par l'interruption shl eax,4 add eax,ecx mov cx,[eax] add eax,ecx mov VESA_WinFuncPtr,eax GVPMW_Fonction_VESA_non_supportee: ; On libŠre le buffer en mode réel de 64 octets mov ax,0101h ; "DPMI : Free Dos memory blocks" mov dx,Handle_temporaire ; DX = handle du buffer int 31h GVPMW_Erreur_d_allocation_de_memoire: pop edi pop ebx ret Get_VESA_protected_mode_WinFuncPtr endp ; - -- --- ----\/\ Passage dans un mode vidéo VESA : /\/---- --- -- - Set_VESA_mode proc near push ebp mov ebp,esp arg Mode:word push ebx mov ax,4F02h mov bx,Mode int 10h pop ebx mov esp,ebp pop ebp ret Set_VESA_mode endp ; - -- --- ----\/\ Initialiser le LFB d'un mode VESA 2.0 : /\/---- --- -- - Initialiser_le_LFB proc near push ebp mov ebp,esp arg Adresse_physique:dword,Taille:dword push ebx push esi push edi ; Mémorisation de la taille mov eax,Taille mov LFB_Taille,eax ; Allocation d'un descripteur LDT pour le mapping du LFB mov eax,Offset LFB_Selecteur push eax mov eax,1 push eax call Allocate_ldt_descriptor add esp,8 or ax,ax jnz Initialiser_le_LFB_Erreur_d_allocation_du_descripteur ; Modification des droits d'accŠs du descripteur mov eax,00008092h push eax mov ax,LFB_Selecteur push eax call Set_descriptor_access_rights add esp,8 or ax,ax jnz Initialiser_le_LFB_Erreur_changement_des_droits_du_descripteur ; Mapping de l'adresse physique mov eax,Offset LFB_Adresse push eax mov eax,LFB_Taille push eax mov eax,Adresse_physique push eax call Physical_address_mapping add esp,12 or ax,ax jnz Initialiser_le_LFB_Erreur_mapping_de_l_adresse_physique ; Assignation de l'adresse de base du segment mov eax,[eax] mov eax,LFB_Adresse push eax mov ax,LFB_Selecteur push eax call Set_segment_base_address add esp,8 or ax,ax jnz Initialiser_le_LFB_Erreur_assignation_de_l_adresse_de_base_du_segment ; Assignation de la limite du segment mov eax,LFB_Taille dec eax push eax mov ax,LFB_Selecteur push eax call Set_segment_limit add esp,8 or ax,ax jnz Initialiser_le_LFB_Erreur_assignation_de_la_limite_du_segment ; Vérouillage de la mémoire linéaire mov eax,LFB_Taille push eax mov eax,LFB_Adresse push eax call Lock_linear_region add esp,8 or ax,ax jnz Initialiser_le_LFB_Erreur_verouillage_de_la_memoire_lineaire ; On renvoie un code d'erreur nul xor eax,eax jmp Initialiser_le_LFB_Fin_du_traitement Initialiser_le_LFB_Erreur_d_allocation_du_descripteur: Initialiser_le_LFB_Erreur_changement_des_droits_du_descripteur: Initialiser_le_LFB_Erreur_mapping_de_l_adresse_physique: Initialiser_le_LFB_Erreur_assignation_de_l_adresse_de_base_du_segment: Initialiser_le_LFB_Erreur_assignation_de_la_limite_du_segment: Initialiser_le_LFB_Erreur_verouillage_de_la_memoire_lineaire: mov eax,1 Initialiser_le_LFB_Fin_du_traitement: pop edi pop esi pop ebx mov esp,ebp pop ebp ret Initialiser_le_LFB endp ; - -- --- ----\/\ Fermer le LFB d'un mode VESA 2.0 : /\/---- --- -- - Fermer_le_LFB proc near ; Dévérouillage de la mémoire linéaire mov eax,LFB_Taille push eax mov eax,LFB_Adresse push eax call Unlock_linear_region add esp,8 or ax,ax jnz Fermer_le_LFB_Erreur_deverouillage_de_la_memoire_lineaire ; Démapping de l'adresse physique mov eax,LFB_Adresse push eax call Free_physical_address_mapping add esp,4 or ax,ax jnz Fermer_le_LFB_Erreur_demapping_de_l_adresse_physique ; Libération du descripteur LDT pour le mapping du LFB mov ax,LFB_Selecteur push eax call Free_ldt_descriptor add esp,4 or ax,ax jnz Fermer_le_LFB_Erreur_de_liberation_du_descripteur ; On renvoie un code d'erreur nul xor eax,eax jmp Fermer_le_LFB_Fin_du_traitement Fermer_le_LFB_Erreur_deverouillage_de_la_memoire_lineaire: Fermer_le_LFB_Erreur_demapping_de_l_adresse_physique: Fermer_le_LFB_Erreur_de_liberation_du_descripteur: mov eax,1 Fermer_le_LFB_Fin_du_traitement: ret Fermer_le_LFB endp Pixel_VESA_LFB proc near push ebp mov ebp,esp arg X:word,Y:word,Couleur:byte xor eax,eax xor edx,edx xor ecx,ecx mov ax,Largeur_ecran mov dx,Y mov cx,X mul edx add eax,ecx mov cl,Couleur add eax,LFB_Adresse mov [eax],cl mov esp,ebp pop ebp ret Pixel_VESA_LFB endp Lit_pixel_VESA_LFB proc near push ebp mov ebp,esp arg X:word,Y:word xor eax,eax xor edx,edx xor ecx,ecx mov ax,Largeur_ecran mov dx,Y mov cx,X mul edx add eax,ecx add eax,LFB_Adresse mov al,[eax] mov esp,ebp pop ebp ret Lit_pixel_VESA_LFB endp Effacer_tout_l_ecran_VESA_LFB proc near push ebp mov ebp,esp arg Couleur:byte push edi ; On place EDI en début d'écran: mov edi,LFB_Adresse ; On met ECX à Largeur_ecran*Menu_Ordonnee/4: xor eax,eax xor edx,edx mov ax,Largeur_ecran mov dx,Menu_Ordonnee mul edx shr eax,2 mov ecx,eax ; 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_VESA_LFB endp ; - -- --- ----\/\ Afficher un bloc de couleur en FLAT : /\/---- --- -- - Block_VESA_LFB proc near push ebp mov ebp,esp arg Pos_X:word,Pos_Y:word,Largeur:word,Hauteur:word,Couleur:byte push ebx push esi push edi ; Calculer dans EDI les coordonnées (Pos_X,Pos_Y) dans la destination xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Pos_Y mov bx,Largeur_ecran mov cx,Pos_X mul ebx mov edi,LFB_Adresse add eax,ecx add edi,eax ; On met dans EAX 4 fois la couleur mov cl,Couleur mov ch,cl mov ax,cx shl eax,16 mov ax,cx ; On place dans DX le nb de lignes à traiter mov dx,Hauteur ; On met dans EBX la distance entre 2 lignes de destination xor ebx,ebx mov bx,Largeur_ecran sub bx,Largeur ; On met dans ESI la largeur à traiter: xor esi,esi mov si,Largeur Block_VESA_LFB_Pour_chaque_ligne: ; On place dans CX le nb de pixels à traiter sur la ligne mov ecx,esi ; On fait une copie de la ligne shr cx,1 jnc Block_VESA_LFB_Multiple_de_2 stosb Block_VESA_LFB_Multiple_de_2: shr cx,1 jnc Block_VESA_LFB_Multiple_de_4 stosw Block_VESA_LFB_Multiple_de_4: repne stosd ; On passe à la ligne suivante add edi,ebx dec dx jnz Block_VESA_LFB_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Block_VESA_LFB endp ; -- Affichage d'un pixel dans l'écran, par rapport au décalage de l'image ; dans l'écran, en mode normal (pas en mode loupe) -- ; Note: si on modifie cette procédure, il faudra penser à faire également la ; modif dans la procédure Pixel_Preview_Loupe_VESA_LFB. Pixel_Preview_Normal_VESA_LFB 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_LFB mov esp,ebp pop ebp ret Pixel_Preview_Normal_VESA_LFB endp ; -- Affichage d'un pixel dans l'écran, par rapport au décalage de l'image ; dans l'écran, en mode loupe -- Pixel_Preview_Loupe_VESA_LFB 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ée mov dl,Couleur ; Ca ne co–te pas trop mov cx,Y ; en code de recopier mov ax,X ; le contenu de la sub cx,Principal_Decalage_Y ; procédure sub ax,Principal_Decalage_X ; Pixel_Preview_Normal_VESA_LFB push edx ; et ‡a fait gagner du push ecx ; temps, et ce temps est push eax ; assez précieux vu que call Pixel_VESA_LFB ; c'est appelé TRES souvent. add esp,12 ; 3 paramŠtres dword ; On regarde si on peut afficher le pixel également dans la loupe mov ax,Y cmp ax,Limite_Haut_Zoom jb Pixel_Preview_Loupe_VESA_LFB_Fin cmp ax,Limite_visible_Bas_Zoom ja Pixel_Preview_Loupe_VESA_LFB_Fin mov ax,X cmp ax,Limite_Gauche_Zoom jb Pixel_Preview_Loupe_VESA_LFB_Fin cmp ax,Limite_visible_Droite_Zoom ja Pixel_Preview_Loupe_VESA_LFB_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_LFB_Tronque_en_hauteur mov cx,Loupe_Facteur push ecx jmp Pixel_Preview_Loupe_VESA_LFB_Traitement_de_la_largeur Pixel_Preview_Loupe_VESA_LFB_Tronque_en_hauteur: mov cx,dx neg cx add cx,Menu_Ordonnee push ecx ; On s'occupe de la largeur: Pixel_Preview_Loupe_VESA_LFB_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_LFB add esp,20 ; 20 = 5 paramŠtres de type dword Pixel_Preview_Loupe_VESA_LFB_Fin: pop ebx mov esp,ebp pop ebp ret Pixel_Preview_Loupe_VESA_LFB endp ; - -- ---\/\ Afficher une ligne horizontale XOR en VESA LFB : /\/--- -- - Ligne_horizontale_XOR_VESA_LFB proc near push ebp mov ebp,esp arg Pos_X:word,Pos_Y:word,Largeur:word push ebx push edi ; On calcule la valeur initiale de EDI: xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Pos_Y mov bx,Largeur_ecran mov cx,Pos_X mul ebx mov edi,LFB_Adresse add eax,ecx add edi,eax ; On met dans ECX le nombre de pixels à traiter: xor ecx,ecx mov cx,Largeur shr cx,1 jnc Ligne_horizontale_XOR_VESA_LFB_CX_multiple_de_2 not byte ptr[edi] ; On commence par se débarrasser du 1er byte inc edi ; en cas d'imparité Ligne_horizontale_XOR_VESA_LFB_CX_multiple_de_2: shr cx,1 jnc Ligne_horizontale_XOR_VESA_LFB_CX_multiple_de_4 not word ptr[edi] ; On se débarrasse des 2Šme et 3Šme bytes en add edi,2 ; cas de "non-multiplicité-de-4" Ligne_horizontale_XOR_VESA_LFB_CX_multiple_de_4: or cx,cx jz Ligne_horizontale_XOR_VESA_LFB_Fin ; copie 32 bits Ligne_horizontale_XOR_VESA_LFB_Copie_32_bits: not dword ptr[edi] add edi,4 dec cx jnz Ligne_horizontale_XOR_VESA_LFB_Copie_32_bits Ligne_horizontale_XOR_VESA_LFB_Fin: pop edi pop ebx mov esp,ebp pop ebp ret Ligne_horizontale_XOR_VESA_LFB endp ; - -- ---\/\ Afficher une ligne verticale XOR en VESA LFB : /\/--- -- - Ligne_verticale_XOR_VESA_LFB proc near push ebp mov ebp,esp arg Pos_X:word,Pos_Y:word,Hauteur:word ; On calcule la valeur initiale de EDX: xor eax,eax xor edx,edx xor ecx,ecx mov ax,Pos_Y mov dx,Largeur_ecran mov cx,Pos_X mul edx mov edx,LFB_Adresse add eax,ecx add edx,eax ; On met dans EAX la distance entre deux lignes: xor eax,eax mov ax,Largeur_ecran ; On met dans CX le nombre de lignes à traiter mov cx,Hauteur Ligne_verticale_XOR_VESA_LFB_Boucle: not byte ptr[edx] add edx,eax dec cx jnz Ligne_verticale_XOR_VESA_LFB_Boucle mov esp,ebp pop ebp ret Ligne_verticale_XOR_VESA_LFB endp ; Afficher une partie de la brosse en couleur en VESA LFB Display_brush_Color_VESA_LFB 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ées (Pos_X,Pos_Y) à l'écran xor eax,eax xor edx,edx xor ecx,ecx mov ax,Pos_Y mov dx,Largeur_ecran mov cx,Pos_X mul edx mov edi,LFB_Adresse add eax,ecx add edi,eax ; Calculer dans ESI les coordonné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 à 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 à l'écran xor eax,eax mov ax,Largeur_ecran sub ax,Largeur Display_brush_Color_VESA_LFB_Pour_chaque_ligne: ; On place dans CX le nb de pixels à traiter sur la ligne mov cx,Largeur Display_brush_Color_VESA_LFB_Pour_chaque_pixel: ; On lit le contenu de la brosse mov bl,[esi] ; Gestion de la transparence cmp bl,bh je Display_brush_Color_VESA_LFB_Pas_de_copie ; On affiche le pixel de la brosse à l'écran mov [edi],bl Display_brush_Color_VESA_LFB_Pas_de_copie: ; On passe au pixel suivant inc esi inc edi dec cx jnz Display_brush_Color_VESA_LFB_Pour_chaque_pixel ; On passe à la ligne suivante mov cx,Largeur_brosse add edi,eax sub cx,Largeur add esi,ecx dec dx jnz Display_brush_Color_VESA_LFB_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Display_brush_Color_VESA_LFB endp ; Afficher une partie de la brosse en monochrome en VESA LFB Display_brush_Mono_VESA_LFB 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ées (Pos_X,Pos_Y) à l'écran xor eax,eax xor edx,edx xor ecx,ecx mov ax,Pos_Y mov dx,Largeur_ecran mov cx,Pos_X mul edx mov edi,LFB_Adresse add eax,ecx add edi,eax ; Calculer dans ESI les coordonné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 à 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 à l'écran xor eax,eax mov ax,Largeur_ecran sub ax,Largeur Display_brush_Mono_VESA_LFB_Pour_chaque_ligne: ; On place dans CX le nb de pixels à traiter sur la ligne mov cx,Largeur Display_brush_Mono_VESA_LFB_Pour_chaque_pixel: ; On vérifie que le contenu de la brosse ne soit pas transparent cmp [esi],bh je Display_brush_Mono_VESA_LFB_Pas_de_copie ; On affiche le pixel de la brosse à l'écran mov [edi],bl Display_brush_Mono_VESA_LFB_Pas_de_copie: ; On passe au pixel suivant inc esi inc edi dec cx jnz Display_brush_Mono_VESA_LFB_Pour_chaque_pixel ; On passe à la ligne suivante mov cx,Largeur_brosse add edi,eax sub cx,Largeur add esi,ecx dec dx jnz Display_brush_Mono_VESA_LFB_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Display_brush_Mono_VESA_LFB endp ; Effacer la partie de la brosse affichée à l'écran en VESA LFB Clear_brush_VESA_LFB 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ées (Pos_X,Pos_Y) à l'écran xor eax,eax xor edx,edx xor ecx,ecx mov ax,Pos_Y mov dx,Largeur_ecran mov cx,Pos_X mul edx mov edi,LFB_Adresse add eax,ecx add edi,eax ; Calculer dans ESI les coordonné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 à traiter mov dx,Hauteur ; On met dans EBX la distance entre 2 lignes à l'écran xor ebx,ebx mov bx,Largeur_ecran 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_VESA_LFB_Pour_chaque_ligne: ; On place dans CX le nb de pixels à traiter sur la ligne mov cx,Largeur ; On fait une copie de la ligne shr cx,1 jnc Clear_brush_VESA_LFB_Multiple_de_2 movsb Clear_brush_VESA_LFB_Multiple_de_2: shr cx,1 jnc Clear_brush_VESA_LFB_Multiple_de_4 movsw Clear_brush_VESA_LFB_Multiple_de_4: rep movsd ; On passe à la ligne suivante add esi,eax add edi,ebx dec dx jnz Clear_brush_VESA_LFB_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Clear_brush_VESA_LFB endp ; Remapper une partie de l'écran en VESA LFB Remap_screen_VESA_LFB 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ées (Pos_X,Pos_Y) à l'écran xor eax,eax xor edx,edx xor ecx,ecx mov ax,Pos_Y mov dx,Largeur_ecran mov cx,Pos_X mul edx mov edi,LFB_Adresse add eax,ecx add edi,eax ; On place dans DX le nb de lignes à 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 xor esi,esi mov si,Largeur_ecran sub si,Largeur Remap_screen_VESA_LFB_Pour_chaque_ligne: ; On place dans CX le nb de pixels à traiter sur la ligne mov cx,Largeur Remap_screen_VESA_LFB_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_VESA_LFB_Pour_chaque_pixel ; On passe à la ligne suivante add edi,esi dec dx jnz Remap_screen_VESA_LFB_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Remap_screen_VESA_LFB endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Afficher une partie de l'image tel quel sur l'écran Afficher_partie_de_l_ecran_VESA_LFB proc near push ebp mov ebp,esp arg Largeur:word,Hauteur:word,Largeur_image:word push ebx push esi push edi ; Calculer dans EDI les coordonnées (0,0) dans la destination mov edi,LFB_Adresse ; Calculer dans ESI les coordonnées (Pos_X_source,Pos_Y_source) ; dans la source 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 place dans DX le nb de lignes à traiter mov dx,Hauteur ; On met dans EBX la distance entre 2 lignes de la destination xor ebx,ebx mov bx,Largeur_ecran sub bx,Largeur ; On met dans EAX la distance entre 2 lignes de la source xor eax,eax mov ax,Largeur_image sub ax,Largeur ; On nettoie la partie haute de ECX: xor ecx,ecx Afficher_partie_de_l_ecran_VESA_LFB_Pour_chaque_ligne: ; On place dans CX le nb de pixels à traiter sur la ligne mov cx,Largeur ; On fait une copie de la ligne shr cx,1 jnc Afficher_partie_de_l_ecran_VESA_LFB_Multiple_de_2 movsb Afficher_partie_de_l_ecran_VESA_LFB_Multiple_de_2: shr cx,1 jnc Afficher_partie_de_l_ecran_VESA_LFB_Multiple_de_4 movsw Afficher_partie_de_l_ecran_VESA_LFB_Multiple_de_4: rep movsd ; On passe à la ligne suivante add esi,eax add edi,ebx dec dx jnz Afficher_partie_de_l_ecran_VESA_LFB_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Afficher_partie_de_l_ecran_VESA_LFB endp ; Afficher une ligne à l'écran Afficher_une_ligne_a_l_ecran_VESA_LFB 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 met dans ESI l'adresse de la ligne à copier: mov esi,Ligne ; On calcule la valeur initiale de EDI: xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Pos_Y mov bx,Largeur_ecran mov cx,Pos_X mul ebx mov edi,LFB_Adresse add eax,ecx add edi,eax ; On met dans ECX le nombre de pixels à traiter: xor ecx,ecx mov cx,Largeur ; On les traite au mieux par copie 8/16/32 bits shr cx,1 jnc Afficher_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_2 movsb Afficher_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_2: shr cx,1 jnc Afficher_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_4 movsw Afficher_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_4: rep movsd pop edi pop esi pop ebx mov esp,ebp pop ebp ret Afficher_une_ligne_a_l_ecran_VESA_LFB endp ; Lire une ligne à l'écran et la stocker dans un buffer Lire_une_ligne_a_l_ecran_VESA_LFB 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: xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Pos_Y mov bx,Largeur_ecran mov cx,Pos_X mul ebx mov esi,LFB_Adresse add eax,ecx add esi,eax ; On met dans EDI l'adresse de la ligne à copier: mov edi,Ligne ; On met dans ECX le nombre de pixels à traiter: xor ecx,ecx mov cx,Largeur ; On les traite au mieux par copie 8/16/32 bits shr cx,1 jnc Lire_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_2 movsb Lire_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_2: shr cx,1 jnc Lire_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_4 movsw Lire_une_ligne_a_l_ecran_VESA_LFB_ECX_multiple_de_4: rep movsd pop edi pop esi pop ebx mov esp,ebp pop ebp ret Lire_une_ligne_a_l_ecran_VESA_LFB endp ; Afficher une partie de l'image zoomée à l'écran Afficher_partie_de_l_ecran_zoomee_VESA_LFB proc near push ebp mov ebp,esp arg Largeur:word,Hauteur:word,Largeur_image:word,Buffer:dword ; Largeur = Largeur non zoomée ; Hauteur = Hauteur zoomé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_LFB_Pour_chaque_ligne_a_zoomer: ; On eclate la ligne à zoomer: push dx mov ax,Loupe_Facteur mov cx,Largeur push ecx ; Largeur push eax ; Facteur push Buffer ; Ligne zoomée push esi ; Ligne originale call Zoomer_une_ligne add esp,16 pop dx ; On l'affiche Facteur fois à l'écran (sur des lignes consécutives): mov cx,Loupe_Facteur APDLEZ_VESA_LFB_Pour_chaque_ligne: ; On affiche la ligne zoomé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_LFB add esp,16 pop dx pop cx ; On passe à la ligne suivante inc dx ; -> On vérifie qu'on ne soit cmp dx,Hauteur ; pas arrivé à la ligne je APDLEZ_VESA_LFB_Menu_Ordonnee_atteinte ; terminale dec cx ; -> ou que l'on ai terminé de jnz APDLEZ_VESA_LFB_Pour_chaque_ligne ; traiter la ligne à zoomer ; On passe à la ligne à zoomer suivante: ; sans oublier de passer à la ligne image suivante add esi,ebx jmp APDLEZ_VESA_LFB_Pour_chaque_ligne_a_zoomer APDLEZ_VESA_LFB_Menu_Ordonnee_atteinte: pop edi pop esi pop ebx mov esp,ebp pop ebp ret Afficher_partie_de_l_ecran_zoomee_VESA_LFB endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Afficher une ligne transparente en VESA LFB Afficher_une_ligne_transparente_a_l_ecran_VESA_LFB 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 met dans ESI l'adresse de la ligne à copier: mov esi,Ligne ; On calcule la valeur initiale de EDI: xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Pos_Y mov bx,Largeur_ecran mov cx,Pos_X mul ebx mov edi,LFB_Adresse add eax,ecx add edi,eax ; On met dans AH la couleur de transparence: mov ah,Couleur_transparence ; On met dans CX le nombre de pixels à traiter: mov cx,Largeur ; Pour chaque pixel de la ligne AULTALE_VESA_LFB_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_VESA_LFB_Pas_de_copie ; Et on la copie dans la destination mov [edi],al AULTALE_VESA_LFB_Pas_de_copie: inc edi ; MAJ du Pointeur de destination ; Hop! et un de moins dec cx jnz AULTALE_VESA_LFB_Pour_chaque_pixel pop edi pop esi pop ebx mov esp,ebp pop ebp ret Afficher_une_ligne_transparente_a_l_ecran_VESA_LFB endp ; Afficher une ligne transparente en VESA LFB Afficher_une_ligne_transparente_mono_a_l_ecran_VESA_LFB 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 met dans ESI l'adresse de la ligne à copier: mov esi,Ligne ; On calcule la valeur initiale de EDI: xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Pos_Y mov bx,Largeur_ecran mov cx,Pos_X mul ebx mov edi,LFB_Adresse add eax,ecx add edi,eax ; On met dans AL la couleur de transparence: mov al,Couleur_transparence ; On met dans DL la couleur à utiliser: mov dl,Couleur ; On met dans CX le nombre de pixels à traiter: mov cx,Largeur ; Pour chaque pixel de la ligne AULTMALE_VESA_LFB_Pour_chaque_pixel: ; On vérifie que la source soit <> de la couleur de transparence cmp al,[esi] je AULTMALE_VESA_LFB_Pas_de_copie ; Et on copie la couleur dans la destination mov [edi],dl AULTMALE_VESA_LFB_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_VESA_LFB_Pour_chaque_pixel pop edi pop esi pop ebx mov esp,ebp pop ebp ret Afficher_une_ligne_transparente_mono_a_l_ecran_VESA_LFB endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Afficher une partie de la brosse zoomée en couleur en VESA LFB Display_brush_Color_Zoom_VESA_LFB 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é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_LFB_Pour_chaque_ligne_a_zoomer: ; On eclate la ligne à zoomer: push dx mov ax,Loupe_Facteur mov cx,Largeur push ecx ; Largeur push eax ; Facteur push Buffer ; Ligne zoomé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 à l'avance les derniers paramŠtres qui ne changent jamais le ; long de la mˆme ligne zoomée: mov al,Couleur_de_transparence push eax ; Couleur de transparence push Buffer ; Ligne push edi ; Largeur*Facteur ; On l'affiche Facteur fois à l'écran (sur des lignes consécutives): mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appelée DBCZ_VESA_LFB_Pour_chaque_ligne: ; On affiche la ligne zoomée mov ax,Pos_X push esi ; Pos_Y push eax ; Pos_X call Afficher_une_ligne_transparente_a_l_ecran_VESA_LFB add esp,8 ; (Pos_X & Pos_Y) ; On passe à la ligne suivante inc si ; -> On vérifie qu'on ne soit cmp si,Pos_Y_Fin ; pas arrivé à la ligne je DBCZ_VESA_LFB_Hauteur_atteinte ; terminale dec bx ; -> ou que l'on ai terminé de jnz DBCZ_VESA_LFB_Pour_chaque_ligne ; traiter la ligne à zoomer ; On passe à la ligne à zoomer suivante: ; sans oublier de passer à la ligne brosse suivante ; On commence par retirer les paramŠtres précédemment passé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éorie, la partie haute de EBX est propre add esi,ebx jmp DBCZ_VESA_LFB_Pour_chaque_ligne_a_zoomer DBCZ_VESA_LFB_Hauteur_atteinte: ; On ramŠne la pile dans un é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_LFB endp ; Afficher une partie de la brosse zoomée en monochrome en VESA LFB Display_brush_Mono_Zoom_VESA_LFB 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é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_LFB_Pour_chaque_ligne_a_zoomer: ; On eclate la ligne à zoomer: push dx mov ax,Loupe_Facteur mov cx,Largeur push ecx ; Largeur push eax ; Facteur push Buffer ; Ligne zoomé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 à l'avance les derniers paramètres qui ne changent jamais ; le long de la même ligne zoomé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 à l'écran (sur des lignes consécutives): mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appelée DBMZ_VESA_LFB_Pour_chaque_ligne: ; On affiche la ligne zoomée mov ax,Pos_X push esi ; Pos_Y push eax ; Pos_X call Afficher_une_ligne_transparente_mono_a_l_ecran_VESA_LFB add esp,8 ; (Pos_X+Pos_Y) ; On passe à la ligne suivante inc si ; -> On vérifie qu'on ne soit cmp si,Pos_Y_Fin ; pas arrivé à la ligne je DBMZ_VESA_LFB_Hauteur_atteinte ; terminale dec bx ; -> ou que l'on ai terminé de jnz DBMZ_VESA_LFB_Pour_chaque_ligne ; traiter la ligne à zoomer ; On passe à la ligne à zoomer suivante: ; sans oublier de passer à la ligne brosse suivante ; On commence par retirer les paramŠtres précédemment passé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éorie, la partie haute de EBX est propre add esi,ebx jmp DBMZ_VESA_LFB_Pour_chaque_ligne_a_zoomer DBMZ_VESA_LFB_Hauteur_atteinte: ; On ramŠne la pile dans un é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_LFB endp ; Effacer une partie de la brosse zoomée en VESA LFB Clear_brush_Zoom_VESA_LFB 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é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_LFB_Pour_chaque_ligne_a_zoomer: ; On eclate la ligne à zoomer: push dx mov ax,Loupe_Facteur mov cx,Largeur push ecx ; Largeur push eax ; Facteur push Buffer ; Ligne zoomé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 à l'avance les derniers paramŠtres qui ne changent jamais le ; long de la mˆme ligne zoomée: push Buffer ; Ligne push edi ; Largeur*Facteur ; On l'affiche Facteur fois à l'écran (sur des lignes consécutives): mov bx,Loupe_Facteur ; BX n'est pas foutu en l'air par la routine appelée CBZ_VESA_LFB_Pour_chaque_ligne: ; On affiche la ligne zoomée mov ax,Pos_X push esi ; Pos_Y push eax ; Pos_X call Afficher_une_ligne_a_l_ecran_VESA_LFB add esp,8 ; (Pos_X+Pos_Y) ; On passe à la ligne suivante inc si ; -> On vérifie qu'on ne soit cmp si,Pos_Y_Fin ; pas arrivé à la ligne je CBZ_VESA_LFB_Hauteur_atteinte ; terminale dec bx ; -> ou que l'on ai terminé de jnz CBZ_VESA_LFB_Pour_chaque_ligne ; traiter la ligne à zoomer ; On passe à la ligne à zoomer suivante: ; sans oublier de passer à la ligne brosse suivante ; On commence par retirer les paramŠtres précédemment passé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éorie, la partie haute de EBX est propre add esi,ebx jmp CBZ_VESA_LFB_Pour_chaque_ligne_a_zoomer CBZ_VESA_LFB_Hauteur_atteinte: ; On ramŠne la pile dans un é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_LFB endp _TEXT ENDS END