; Routines d'animation de bas niveau. ; Testé avec TASM 4.0 par Jim Mischel 12/16/94. SCREEN_WIDTH equ 80 ;largeur de l'écran en octets INPUT_STATUS_1 equ 03dah ;registre Input Status 1 CRTC_INDEX equ 03d4h ;registre Index CRT Controller START_ADDRESS_HIGH equ 0ch ;octet de poids fort de l'adresse de départ de la bitmap START_ADDRESS_LOW equ 0dh ;octet de poids faible de l'adresse de départ de la bitmap GC_INDEX equ 03ceh ;registre Index Graphics Controller SET_RESET equ 0 ;index du registre Set/Reset GC G_MODE equ 5 ;index du registre Mode GC .model small .data BIOS8x8Ptr dd ? ;pointe sur la police 8x8 BIOS ; Tables utilisées pour précalculer les masques gauche et droit de clipping.LeftMask db 0ffh, 07fh, 03fh, 01fh, 00fh, 007h, 003h, 001h RightMask db 080h, 0c0h, 0e0h, 0f0h, 0f8h, 0fch, 0feh, 0ffh .code ; Affiche le rectangle plein spécifié dans la couleur spécifiée. ; Suppose que l'affichage est en mode 12h. Ne fait pas de clipping et suppose ; que les coordonnées du rectangle sont valides. ; ; Appelable en C near comme suit: void DrawRect(int LeftX, int TopY, int RightX, ; int BottomY, int Color, unsigned int ScrnOffset, ; unsigned int ScrnSegment); DrawRectParms struc dw 2 dup (?) ; BP empilé et adresse de retour LeftX dw ? ;coordonnée X du coté gauche du rectangle TopY dw ? ;coordonnée Y du coté supérieur du rectangle RightX dw ? ;coordonnée X du coté droit du rectangle BottomY dw ? ;coordonnée Y du coté inférieur du rectangle Color dw ? ;couleur d'affichage du rectangle (seuls les ;4 bits inférieurs importent) ScrnOffset dw ? ;offset de la base de la bitmap dans laquelle afficher ScrnSegment dw ? ;segment de la base de la bitmap dans laquelle afficher DrawRectParms ends public _DrawRect _DrawRect proc near push bp ;préserve la stack frame de l'appelant mov bp,sp ;pointe sur la stack frame locale push si ;préserve les variables registre de l'appelant push di cld mov dx,GC_INDEX mov al,SET_RESET mov ah,byte ptr Color[bp] out dx,ax ;paramètre la couleur d'affichage mov ax,G_MODE + (0300h) out dx,ax ;paramètre le mode write 3 les di,dword ptr ScrnOffset[bp] ;pointe sur le début de la bitmap mov ax,SCREEN_WIDTH mul TopY[bp] ;pointe sur le début de la ligne add di,ax ; d'affichage supérieure à remplir mov ax,LeftX[bp] mov bx,ax shr ax,1 ;/8 = offset d'octet depuis la gauche de l'écran shr ax,1 shr ax,1 add di,ax ;pointe sur le coin supérieur gauche de la zone ;à remplir and bx,7 ;isole l'adresse intrapixel mov dl,LeftMask[bx] ;paramètre le masque de clipping du coté gauche mov bx,RightX[bp] mov si,bx and bx,7 ;isole l'adresse intrapixel du edge droit mov dh,RightMask[bx] ; paramètre le masque de clipping du coté droit mov bx,LeftX[bp] and bx,NOT 7 ;adresse intrapixel du coté gauche sub si,bx shr si,1 shr si,1 shr si,1 ;nombre d'octets traversant un rectangle - 1 jnz MasksSet ;s'il y a un seul octet, and dl,dh ; combiner les masques MasksSet: mov bx,BottomY[bp] sub bx,TopY[bp] ;nombre de lignes d'affichage à remplir - 1 FillLoop: push di ;mémorise l'offset de départ de la ligne mov al,dl ;masque de clipping du coté gauche xchg es:[di],al ;affiche le coté gauche inc di ;pointe sur le prochain octet mov cx,si ;nombre d'octets gauches dec cx ; - 1 js LineDone ;s'il n'y a qu'un octet en travers jz DrawRightEdge ;il n'y a pas d'octets au milieu s'il y a 2 ;octets en travers mov al,0ffh rep stosb ;affiche les octets DrawRightEdge: mov al,dh ;masque de clipping du coté droit xchg es:[di],al ;affiche le coté droit LineDone: pop di ;retrouve l'offset du début de la ligne add di,SCREEN_WIDTH ;pointe sur la prochaine ligne dec bx ;décompte les lignes d'affichage jns FillLoop pop di ;restaure les variables registre de l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret _DrawRect endp ; Présente la page à l'offset spécifié dans la bitmap. La page est ; affichée quand cette routine retourne. ; ; Appelable en C near comme suit: void ShowPage(unsigned int StartOffset); ShowPageParms struc dw 2 dup (?) ; BP empilé et adresse de retour StartOffset dw ? ;offset dans la bitmap de la page à afficher ShowPageParms ends public _ShowPage _ShowPage proc near push bp ;préserve la stack frame de l'appelant mov bp,sp ;pointe sur la stack frame locale ; Attend que l'autorisation de l'affichage soit actif (statut actif low), pour ; s'assurer que les deux moitiés de l'adresse de départ prennent place dans la ; même trame. mov bl,START_ADDRESS_LOW ;précharge pour la permutation mov bh,byte ptr StartOffset[bp] ;plus rapide une fois mov cl,START_ADDRESS_HIGH ;l'autorisation de l'affichage détectée mov ch,byte ptr StartOffset+1[bp] mov dx,INPUT_STATUS_1 WaitDE: in al,dx test al,01h jnz WaitDE ;autorisation de l'affichage activée low (0 = activé) ; Paramètre l'offset de départ dans la mémoire vidéo de la page à afficher. mov dx,CRTC_INDEX mov ax,bx out dx,ax ;adresse de départ low mov ax,cx out dx,ax ;adresse de départ high ; A présent attend vertical sync, l'autre page sera ainsi invisible quand ;nous commencerons à l'affciher. mov dx,INPUT_STATUS_1 WaitVS: in al,dx test al,08h jz WaitVS ;vertical sync active(1 = active) pop bp ;restaure la stack frame de l'appelant ret _ShowPage endp ; Affiche l'image spécifiée à l'emplacement spécifié dans la bitmap ; spécifiée, dans la couleur désirée. ; ; Appelable en C near comme suit: void DrawImage(int LeftX, int TopY, ; image **RotationTable, int Color, unsigned int ScrnOffset, ; unsigned int ScrnSegment); DrawImageParms struc dw 2 dup (?) ; BP empilé et adresse de retour DILeftX dw ? ;coordonnée X du coté gauche de l'image DITopY dw ? ;coordonnée Y du coté supérieur de l'image RotationTable dw ? ;pointeur sur la table de pointeurs sur les ; rotations d'image DIColor dw ? ;couleur d'affichage de l'image (les ; 4 bits inférieurs importent) DIScrnOffset dw ? ;offset de la base de la bitmap dans laquelle afficher DIScrnSegment dw ? ;segment de la base de la bitmap dans laquelle afficher DrawImageParms ends image struc WidthInBytes dw ? Height dw ? BitPattern dw ? image ends public _DrawImage _DrawImage proc near push bp ;préserve la stack frame de l'appelant mov bp,sp ;pointe sur la stack frame locale push si ;préserve les variables registre de l'appelant push di cld mov dx,GC_INDEX mov al,SET_RESET mov ah,byte ptr DIColor[bp] out dx,ax ;paramètre la couleur d'affichage mov ax,G_MODE + (0300h) out dx,ax ;paramètre le mode write 3 les di,dword ptr DIScrnOffset[bp] ;pointe sur le début de la bitmap mov ax,SCREEN_WIDTH mul DITopY[bp] ;pointe sur le début de la ligne add di,ax ; d'affichage supérieure à afficher mov ax,DILeftX[bp] mov bx,ax shr ax,1 ;/8 = offset d'octet depuis la gauche de ;l'écran shr ax,1 shr ax,1 add di,ax ;pointe sur le coin supérieur gauche de ;la zone ;à afficher and bx,7 ;isole l'adresse intrapixel shl bx,1 ;*2 pour pré-calculer un mot add bx,RotationTable[bp] ;pointe sur la structure de l'image mov bx,[bx] ; pour la rotation intraoctet mov dx,[bx].WidthInBytes ;largeur de l'image mov si,[bx].BitPattern ;pointeur sur les octets du motif de l'image mov bx,[bx].Height ;hauteur de l'image DrawImageLoop: push di ;mémorise l'offset de départ de la ligne mov cx,dx ;nombre d'octets en travers DrawImageLineLoop: lodsb ;récupère le prochain octet de l'image xchg es:[di],al ;affiche le prochain octet de l'image inc di ;pointe sur l'octet d'écran suivant loop DrawImageLineLoop pop di ;retrouve l'offset de départ de la ligne add di,SCREEN_WIDTH ;pointe sur la prochaine ligne dec bx ;décompte les lignes d'affichage jnz DrawImageLoop pop di ;restaure les variables registre de l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret _DrawImage endp ; Appelable en C near comme suit: void TextUp(char *Text, int LeftX, int TopY, ; unsigned int ScrnOffset, unsigned int ScrnSegment); TextUpParms struc dw 2 dup (?) ; BP empilé et adresse de retour Text dw ? ;pointeur sur le texte à afficher TULeftX dw ? ;coordonnée X du coté gauche du rectangle ; (doit être un multiple de 8) TUTopY dw ? ;coordonnée Y du coté supérieur du rectangle TUScrnOffset dw ? ;offset de la base de la bitmap dans laquelle afficher TUScrnSegment dw ? ;segment de la base de la bitmap dans ;laquelle afficher TextUpParms ends public _TextUp _TextUp proc near push bp ;préserve la stack frame de l'appelant mov bp,sp ;pointe sur la stack frame locale push si ;préserve les variables registre de l'appelant push di cld mov dx,GC_INDEX mov ax,G_MODE + (0000h) out dx,ax ;paramètre le mode write 0 les di,dword ptr TUScrnOffset[bp] ;pointe sur le début de la bitmap mov ax,SCREEN_WIDTH mul TUTopY[bp] ;pointe sur le début de la ligne add di,ax ; d'affichage supérieur où commence ;le texte mov ax,TULeftX[bp] mov bx,ax shr ax,1 ;/8 = offset d'octet depuis la gauche de l'écran shr ax,1 shr ax,1 add di,ax ;pointe sur le coin supérieur gauche du premier caractère mov si,Text[bp] ;pointe sur le texte à afficher TextUpLoop: lodsb ;récupère le prochain caractère à afficher and al,al jz TextUpDone ;fini si l'octet est nul push si ;préserve le pointeur de la chaîne de texte push di ;préserve l'offset d'écran du caractère push ds ;préserve le segment des données par défaut call CharUp ;affiche ce caractère pop ds ;restaure le segment des données par défaut pop di ;retrouve l'offset d'écran du caractère pop si ;retrouve le pointeur de la chaîne de texte inc di ;pointe sur l'emplacement de départ du prochain caractère jmp TextUpLoop TextUpDone: pop di ;restaure les variables registre de l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret CharUp: ;affiche le caractère dans AL à ES:DI lds si,[BIOS8x8Ptr] ;pointe sur le début de la police 8x8 mov bl,al sub bh,bh shl bx,1 shl bx,1 shl bx,1 ;*8 pour pré-calculer l'offset du caractère dans ;la police add si,bx ;DS:SI pointe sur les données du caractère dans ;la police mov cx,8 ;les caractères sont 8 de haut CharUpLoop: movsb ;copie l'octet du motif du prochain caractère add di,SCREEN_WIDTH-1 ;pointe sur le prochain octet de destination loop CharUpLoop ret _TextUp endp ; Paramètre le pointeur sur la police 8x8 BIOS. ; ; Appelable en C near comme suit: extern void SetBIOS8x8Font(void); public _SetBIOS8x8Font _SetBIOS8x8Font proc near push bp ;préserve la stack frame de l'appelant push si ;préserve les variables registre de push di ;l'appelant et le segment des données push ds ;(suppose que BIOS ne préserve rien) mov ah,11h ;fonction génératrice de caractères BIOS mov al,30h ;sous-fonction information BIOS mov bh,3 ;pointeur de requête de police 8x8 int 10h ;invoque les services vidéo BIOS mov word ptr [BIOS8x8Ptr],bp ;stocke le pointeur mov word ptr [BIOS8x8Ptr+2],es pop ds pop di ;restaure les variables registre de l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret _SetBIOS8x8Font endp end