home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Jason Aller Floppy Collection
/
266.img
/
PBM-CMN2.ZIP
/
AFFICGA.INC
< prev
next >
Wrap
Text File
|
1990-06-07
|
39KB
|
1,010 lines
;************************************************
;* PINBALL 1990 (C) JOUBERT ALAIN pour LORICIEL *
;* fichier d'inclusion des routines d'affichage *
;* en mode CGA pour GEREAFFI.ASM *
;************************************************
AFFICHE_BALLE_CGA MACRO ; affiche la balle en mode CGA
local Balle_Mobile,LignDest_Impair,LignDest_Pair ; ----------------------------
local Suite,Ligne_Suivante,Mot_Suivant,Fin
SAUVE_FOND_CGA
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Balle ; ds:si pointe sur l'adresse de Struct_Balle
cmp [si].BallImmo,OUI ; la balle est-elle immobile ?
jne Balle_Mobile ; non
add sp,2 ; adresse mémoire graphique empilée dans SAUVE_FOND_CGA non dépilée
jmp Fin
Balle_Mobile:
mov di,[si].AdAfBall ; es:di pointe sur l'adresse d'affichage
mov si,[si].AdSpBall ; adresse du sprite de la balle dans si
lds ax,__Balle_Buffer ; ds:ax pointe sur l'adresse de __Balle_Buffer
add si,ax ; ds:si pointe sur l'adresse du 1er octet à afficher
xor dh,dh ; on initialise le compteur de lignes
pop bp ; on récupère l'adresse mémoire graphique sauvegardée dans SAUVE_BALLE_CGA
Ligne_Suivante:
cmp dh,ch ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,bx
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
Mot_Suivant:
mov ax,[si+192] ; mot masque
and es:[di],ax ; et logique entre le mot masque et l'emplacement à l'écran
mov ax,[si] ; mot sprite
or es:[di],ax ; ou logique entre le mot sprite et l'emplacement à l'écran
mov ax,[si+194] ; mot masque
and es:[di+2],ax ; et logique entre le mot masque et l'emplacement à l'écran
mov ax,[si+2] ; mot sprite
or es:[di+2],ax ; ou logique entre le mot sprite et l'emplacement à l'écran
add si,16 ; ligne source suivante
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ENDM
;----------------------------
AFFICHE_BISEAU_CGA MACRO ; affiche la porte métallique de sortie de rampe de lancement en mode CGA
local Ligne_Suivante,Fin ; -----------------------------------------------------------------------
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Balle ; ds:si pointe sur l'adresse de Struct_Balle
cmp [si].DansRamp,OUI ; la balle est-elle dans la rampe de lancement ?
jne Fin ; non
mov di,OFFSET TabPorMe ; ds:di pointe sur l'adresse de TabPorMe
mov bx,__NoFlipper
shl bx,1 ; table de mots
mov ax,[di+bx] ; ordonnée inférieure du biseau
cmp [si].CYB,ax ; la balle heurte t-elle la porte métallique ?
jg Fin ; non
lds si,__FlipTrav_Buffer ; ds:si pointe sur l'adresse de __Fliptrav_Buffer
sub ax,15 ; ordonnée supérieure du biseau
shl ax,1 ;┐
shl ax,1 ;│
shl ax,1 ;│
;│
mov bx,ax ;│
;│
shl bx,1 ;│
shl bx,1 ;│
;│
add ax,bx ;┘ ordonnée (en octets) supérieure du biseau * 40
mov di,ax
add di,54 ; es:di pointe sur l'adresse d'affichage
shl ax,1 ; ordonnée (en octets) supérieure du biseau * 80
add si,ax
add si,54 ; ds:si pointe sur le 1er mot à afficher
mov bp,GRAPH_IMPAIR ; adresse mémoire graphique lignes impaires
mov cx,4 ; on initialise le compteur de mots
xor dh,dh ; on initialise le compteur de lignes
xor bx,bx ; mise à zéro de l'index de recherche dans la table de masque
Ligne_Suivante:
cmp dh,16 ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,0200h
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
Octet_Suivant:
mov bl,[si] ; octet sprite
mov dl,cs:[MasqCGA+bx] ; octet masque
and es:[di],dl ; et logique entre l'octet masque et l'emplacement à l'écran
or es:[di],bl ; ou inclusif entre l'octet sprite et l'emplacement à l'écran
inc si ; octet source suivant
inc di ; octet destination suivant
loop Octet_Suivant
mov cx,4 ; nombre de mots par ligne
add si,76 ; ligne source suivante
sub di,4 ; on récupère le pointeur de ligne d'écran
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ENDM
;----------------------------
AFFICHE_CHAMP_CGA MACRO ; affiche un champignon en mode CGA
local LignDest_Impair,LignDest_Pair,Suite ; ---------------------------------
local Ligne_Suivante,Octet_Suivant,Fin
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Balle ; ds:si pointe sur l'adresse de Struct_Balle
cmp [si].AffiCham,AFFICHE ; y a t-il une autorisation d'affichage d'un champignon ?
je @F ; oui
jmp Fin ; non
@@: mov [si].AffiCham,NO_AFFICHE ; on évite un 2ème affichage
test [si].AdEcCham,8000h ; l'affichage débute t-il sur une ligne impaire ?
jz LignDest_Pair ; non
LignDest_Impair: ; ligne maitresse impaire
mov bp,GRAPH_PAIR + 0005h ; adresse mémoire graphique lignes paires dans bx
mov ax,0205h ; masque de permutation lignes paires/impaires dans ax
and [si].AdEcCham,7FFFh ; mise à zéro du bit de poids fort
jmp short Suite
LignDest_Pair: ; ligne maitresse paire
mov bp,GRAPH_IMPAIR ; début adresse mémoire graphique lignes impaires dans bx
mov ax,0200h ; masque de permutation lignes paires/impaires dans ax
Suite:
mov bl,[si].NbOcCham
mov cs:el,bl ; sauvegarde du nombre d'octets à afficher
mov bl,[si].NbLiCham
mov cs:eh,bl ; sauvegarde du nombre de lignes à afficher
mov di,[si].AdEcCham ; es:di pointe sur l'adresse d'affichage
mov si,[si].AdBuCham ; adresse dans __FlipTrav_Buffer
lds bx,__FlipTrav_Buffer ; ds:bx pointe sur l'adresse de __FlipTrav_Buffer
add si,bx ; ds:si pointe sur l'adresse du 1er mot à afficher
xor cx,cx
mov cl,cs:el ; on initialise le compteur d'octets
xor dh,dh ; on initialise le compteur de lignes
xor bx,bx ; mise à zéro de l'index de recherche dans la table de masque
Ligne_Suivante:
cmp dh,cs:eh ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,ax
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
Octet_Suivant:
mov bl,[si] ; octet sprite
mov dl,cs:[MasqCGA+bx] ; octet masque
and es:[di],dl ; et logique entre l'octet masque et l'emplacement à l'écran
or es:[di],bl ; ou inclusif entre l'octet sprite et l'emplacement à l'écran
inc si ; octet source suivant
inc di ; octet destination suivant
loop Octet_Suivant
mov cl,cs:el ; nombre d'octets par ligne
add si,80
sub si,cx ; ligne source suivante
sub di,cx ; on récupère le pointeur de ligne d'écran
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ENDM
;----------------------------
AFFICHE_FLIP_CGA MACRO ; affichage des flips en mode CGA
local LignDest_Pair,LignDest_Impair,Suite ; -------------------------------
local Ligne_Suivante,Fin
; en entrée: ax contient l'adresse du sprite du flip dans __Flips_Buffer
; di contient l'adresse du sprite du flip à l'écran
lds si,__Flips_Buffer ; ds:si pointe sur l'adresse de __Flips_Buffer
add si,ax ; ds:si pointe sur le 1er mot à afficher
test di,8000h ; l'affichage débute t-il sur une ligne impaire ?
jz LignDest_Pair ; non
LignDest_Impair: ; ligne maitresse impaire
mov bp,GRAPH_PAIR + 0005h ; adresse mémoire graphique lignes paires dans bx
mov ax,0205h ; masque de permutation lignes paires/impaires dans ax
and di,7FFFh ; mise à zéro du bit de poids fort
jmp short Suite
LignDest_Pair: ; ligne maitresse paire
mov bp,GRAPH_IMPAIR ; début adresse mémoire graphique lignes impaires dans bx
mov ax,0200h ; masque de permutation lignes paires/impaires dans ax
Suite:
mov cx,5 ; on initialise le compteur de mots
xor dh,dh ; on initialise le compteur de lignes
Ligne_Suivante:
cmp dh,28 ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,ax
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
rep movsw ; transfert __Flips_Buffer/écran
mov cx,5 ; nombre de mots par ligne
sub di,10 ; on récupère le pointeur de ligne d'écran
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ret
ENDM
;----------------------------
AFFICHE_PORTE_CGA MACRO ; affiche la porte de sortie en mode CGA
local Ligne_Suivante,Mot_Suivant,Fin ; --------------------------------------
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Porte ; ds:si pointe sur l'adresse de Struct_Porte
cmp [si].AffiPort,AFFICHE ; y a t-il une autorisation d'affiuchage de la porte ?
jne Fin ; non
mov [si].AffiPort,NO_AFFICHE ; on évite un 2ème affichage
mov di,[si].XPorte ; abcisse de la porte en pixels
shr di,1
shr di,1 ; abcisse en octets
add di,2*40 ; es:di pointe sur l'adresse d'affichage
lds si,__Sprites_Buffer ; ds:si pointe sur l'adresse de __Sprites_Buffer
add si,16*80+26 ; ds:si pointe sur le premier octet à afficher
mov bp,GRAPH_IMPAIR ; l'affichage débute sur une ligne paire
mov cx,3 ; on initialise le compteur de mots
xor dh,dh ; on initialise le compteur de lignes
Ligne_Suivante:
cmp dh,9 ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,0200h
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
Mot_Suivant:
mov ax,[si]
xor es:[di],ax ; transfert __Sprites_Buffer/écran
add si,2
add di,2
loop Mot_Suivant
mov cx,3 ; nombre de mots par ligne
sub di,6 ; on récupère le pointeur de ligne d'écran
add si,74
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ENDM
;----------------------------
AFFICHE_SCORE_CGA MACRO ; affiche le score en mode CGA
local Ligne_Suivante,Fin ; ----------------------------
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Score ; ds:si pointe sur l'adresse de Struct_Score
Affiche_Dizaines:
cmp [si].AffiDiza,OUI ; y a t-il une autorisation d'affichage des dizaines ?
jne Affiche_Centaines ; non
cmp [si].NombPass,1 ; est-ce le 1ier passage ?
je OK_Dizaines ; oui
cmp [si].NombPass,10 ; est-ce le 10iéme passage ?
je Plus_Dizaines ; oui
jmp Fin
Plus_Dizaines:
mov [si].AffiDiza,NON ; oui, on interdis l'affichage des dizaines
OK_Dizaines:
mov di,66*40+71 ; es:di pointe sur l'adresse d'affichage des dizaines
mov ax,[si].AdSpDiza ; adresse dans __Sprites_Buffert du sprite à afficher
call Affiche_Score
Affiche_Centaines:
cmp [si].AffiCent,OUI ; y a t-il une autorisation d'affichage des centaines ?
jne Affiche_Milliers ; non
cmp [si].NombPass,1 ; est-ce le 1ier passage ?
je OK_Centaines ; oui
cmp [si].NombPass,10 ; est-ce le 10iéme passage ?
je Plus_Centaines ; oui
jmp Fin
Plus_Centaines:
mov [si].AffiCent,NON ; oui, on interdis l'affichage des centaines
OK_Centaines:
mov di,66*40+67 ; es:di pointe sur l'adresse d'affichage à l'écran des milliers
mov ax,[si].AdSpCent ; adresse dans __Sprites_Buffer du sprite des centaines
call Affiche_Score
Affiche_Milliers:
cmp [si].AffiMill,OUI ; y a t-il une autorisation d'affichage des milliers ?
jne Affiche_Dix_Milliers ; non
cmp [si].NombPass,1 ; est-ce le 1ier passage ?
je OK_Milliers ; oui
cmp [si].NombPass,10 ; est-ce le 10iéme passage ?
je Plus_Milliers ; oui
jmp Fin
Plus_Milliers:
mov [si].AffiMill,NON ; oui, on interdis l'affichage des milliers
OK_Milliers:
mov di,66*40+63 ; es:di pointe sur l'adresse d'affichage à l'écran des milliers
mov ax,[si].AdSpMill ; adresse dans __Sprites_Buffer du sprites des milliers
call Affiche_Score
Affiche_Dix_Milliers:
cmp [si].AffiDimi,OUI ; y a t-il une autorisation d'affichage des millions ?
jne Fin ; non
cmp [si].NombPass,1 ; est-ce le 1ier passage ?
je OK_Dix_Milliers ; oui
cmp [si].NombPass,10 ; est-ce le 10iéme passage ?
je Plus_Dix_Milliers ; oui
jmp short Fin
Plus_Dix_Milliers:
mov [si].AffiDimi,NON ; oui, on interdis l'affichage des dizaines de milliers
OK_Dix_Milliers:
mov di,66*40+59 ; es:di pointe sur l'adresse d'affichage à l'écran des millions
mov ax,[si].AdSpDimi ; adresse dans __Sprites_buffer du sprite des dizaines de milliers
call Affiche_Score
Affiche_Cent_Milliers:
jmp Fin
Affiche_Score:
push si
push ds
cmp [si].NombPass,1 ; est-ce le premier passage ?
jne @F ; non
add ax,12 ; on pointe sur l'adresse dans __Sprites_Buffer des sprites intermédiaires
@@: lds si,__Sprites_Buffer ; ds:si pointe sur l'adresse de __Sprites_Buffer
add si,ax ; ds:si pointe sur l'adresse du sprite à afficher
mov bp,GRAPH_PAIR + 0005h ; adresse mémoire graphique lignes impaires
mov cx,2 ; on initialise le compteur de mots
xor dh,dh ; on initialise le compteur de lignes
Ligne_Suivante:
cmp dh,16 ; y a t-il une ligne à afficher ?
je retour ; non
inc dh ; oui, ligne suivante
xor bp,0205h
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
rep movsw ; affichage des mots sources
mov cx,2 ; nombre de mots par ligne
add si,76 ; ligne source suivante
sub di,4 ; on récupère le pointeur de ligne d'écran
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
retour:
pop ds
pop si
ret
Fin:
ENDM
;----------------------------
AFFICHE_RESSOR_CGA MACRO ; affiche le ressort de la rampe de lancement de la balle en mode CGA
local Ligne_Suivante,Fin ; -------------------------------------------------------------------
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Balle ; ds:si pointe sur l'adresse de Struct_Balle
cmp [si].DansRamp,OUI ; la balle est-elle dans la rampe de lancement ?
jne Fin ; non
mov ax,[si].ForcImpu
cmp [si].CYB,154 ; la balle est-elle en fond de rampe de lancement ?
je Balle_Immobile ; oui
xor ax,ax ; non, le ressort se détend
Balle_Immobile:
shr ax,1
neg ax
add ax,32 ; 32 - ForcImpu / 2
shl ax,1
shl ax,1
shl ax,1
shl ax,1 ; (32 - ForcImpu / 2) * 16
mov bx,ax
shl bx,1
shl bx,1 ; (32 - ForcImpu / 2) * 64
add ax,bx ; (32 - ForcImpu / 2) * 80
add ax,22 ; (32 - ForcImpu / 2) * 80 + 22
lds si,__Sprites_Buffer ; ds:si pointe sur l'adresse de __Fliptrav_Buffer
add si,ax ; ds:si pointe sur le 1er mot à afficher
mov di,184*40+55 ; es:di pointe sur l'adresse d'affichage
mov bp,GRAPH_PAIR + 0005h ; l'afficha<ge débute sur une ligne impaire
xor dh,dh ; on initialise le compteur de lignes
Ligne_Suivante:
cmp dh,15 ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,0205h
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
mov ax,[si]
mov es:[di],ax ; affiche le mot
add si,80 ; ligne source suivante
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ENDM
;----------------------------
AFFICHE_SPRITE_CGA MACRO ; affiche un sprite en mode CGA
local LignDest_Pair,LignDest_Impair,Suite,Fin ; -----------------------------
mov si,OFFSET Struct_Sprite
mov al,[si].NbOctSpr ; nombre d'octets par ligne
mov ah,[si].NbLigSpr ; nombre de lignes du sprite
mov bx,[si].PosX ; abscise (en pixels) du sprite à l'écran
mov dx,bx
and dx,3
shl dx,1 ; nombre de décalages à l'octet
shr bx,1
shr bx,1 ; abscise (en octets) du sprite à l'écran
mov bp,[si].PosY ; ordonnée du sprite à l'écran
mov cx,ds
mov es,cx
mov di,OFFSET Buffer_Sprite ; es:di pointe sur l'adresse du buffer de travail Buffer_Sprite
mov cs:fx,di ; on sauvegarde l'offset de l'adresse de Buffer_Sprite
mov cx,[si].AdrSprit ; offset du sprite dans __Sprites_Buffer
lds si,__Sprites_Buffer
add si,cx ; ds:si pointe sur le premier octet à recopier dans Buffer_Sprite
xor dh,dh ; on initialise le compteur de ligne
xor cx,cx
mov cl,al ; on initialise le compteur d'octets
Recopie_Ligne:
cmp dh,ah ; y a t-il une ligne à recopier ?
je Decale_Buffer ; non
inc dh ; oui, ligne suivante
rep movsb ; on recopie les octets du sprite dans le buffer de travail, pour chaque ligne
mov cl,al ; nombre d'octets par ligne
sub si,cx
add si,80 ; on pointe sur le début de la ligne suivante de __Sprite_Buffer
jmp short Recopie_Ligne
Decale_Buffer:
cmp dl,0 ; y a t-il un décalage du sprite à effectuer ?
je Fin_Decalage ; non
dec dl ; oui, décalage suivant
xor dh,dh ; on initialise le compteur de ligne
mov di,cs:fx ; ds:di pointe sur l'adresse de Buffer_Sprite
Decale_Ligne:
cmp dh,ah ; y a t-il une ligne à décaler ?
je Decale_Buffer ; non
inc dh ; ligne suivante
clc
Decale_Octet:
mov bh,es:[di]
rcr bh,1 ; on décale à droite l'octet de Buffer_Sprite
mov es:[di],bh
inc di ; octet suivant
loop Decale_Octet
mov cl,al ; nombre d'octets par ligne
jmp short Decale_Ligne
Fin_Decalage:
mov di,bp ; ordonnée du sprite à l'écran
test di,1
jz LignDest_Pair ; test de parité de la ligne destination
LignDest_Impair: ; ligne maitresse impaire
mov bp,GRAPH_PAIR + 0005h ; adresse mémoire graphique lignes paires
dec di ; ligne destination - 1
mov dx,0205h ; masque de permutation lignes paires/impaires
jmp short Suite
LignDest_Pair: ; ligne maitresse paire
mov bp,GRAPH_IMPAIR ; début adresse mémoire graphique lignes impaires
mov dx,0200h ; masque de permutation lignes paires/impaires
Suite:
mov cx,es
mov ds,cx ; ds = es
mov si,cs:fx ; ds:si pointe sur l'adresse de Buffer_Sprite
xor bh,bh ; bh a été utilisé dans Decale_Buffer
shl di,1
shl di,1
shl di,1 ; ordonnée destination * 8
mov cx,di
shl cx,1
shl cx,1 ; ordonnée destination * 32
add di,cx ; ordonnée destination * 40
add di,bx ; ordonnée destination * 40 + abcisse destination
xor cx,cx
mov cl,al ; on initialise le compteur d'octets
mov cs:eh,ah
xor ah,ah ; on initialise le compteur de ligne
call _syncro ; syncro trame
Affiche_Ligne:
cmp ah,cs:eh ; y a t-il une ligne à afficher ?
je Fin ; non
inc ah ; oui, ligne suivante
xor bp,dx
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
Affiche_Octet:
xor bx,bx ; mise à zéro de l'index de recherche dans la table de masque
cmp EffaSpri,OUI ; efface t-on le sprite ?
je Efface ; oui
mov bl,[si] ; octet sprite
mov bh,cs:[MasqCGA+bx] ; octet masque
and es:[di],bh ; et logique entre l'octet masque et l'emplacement à l'écran
or es:[di],bl ; ou inclusif entre l'octet et l'emplacement à l'écran
jmp short @F
Efface:
mov bl,[si]
xor es:[di],bl ; on efface le sprite
@@:
inc si ; octet source suivant
inc di ; octet destination suivant
loop Affiche_Octet
mov cl,al ; nombre d'octets par ligne
sub di,cx ; on récupère le pointeur de ligne d'écran
test ah,1
jnz Affiche_Ligne ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Affiche_Ligne
Fin:
ret
ENDM
;----------------------------
CALCUL_ADRESSE_CGA MACRO ; calcule l'adresse d'affichage ou d'effacement en mode CGA
; ---------------------------------------------------------
; en entrée: ax contient l'abcisse d'affichage ou d'effacement en pixels
; bx contient l'ordonnée d'affichage ou d'effacement
; en sortie: cx contient l'adresse d'affichage ou d'effacement
xor cx,cx
test bx,00000001b ; l'ordonnée est-elle impaire ?
jz Paire ; non
dec bx ; oui
mov ch,10000000b ; bit de poids fort à 1
Paire:
shl bx,1
shl bx,1
shl bx,1 ; ordonnée * 8
mov dx,bx
shl dx,1
shl dx,1 ; ordonnée * 32
add bx,dx ; ordonnée * 40
shr ax,1
shr ax,1 ; abcisse en octets (4 pixels / octet)
add ax,bx ; ordonnée * 40 + abcisse / 4
or cx,ax ; ordonnée * 40 + abcisse / 4 et bit de poids fort à jour
ret
ENDM
;----------------------------
EFFACE_BALLE_CGA MACRO ; restitue le fond à l'ancien emplacement de la balle en mode CGA
local LignDest_Impair,LignDest_Pair,Suite ; ---------------------------------------------------------------
local Ligne_Suivante,Fin
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Balle ; ds:si pointe sur l'adresse de Struct_Balle
test [si].AdEfBall,8000h ; l'effacement débute t-il sur une ligne impaire ?
jz LignDest_Pair ; non
LignDest_Impair: ; ligne maitresse impaire
mov bp,GRAPH_PAIR + 0005h ; adresse mémoire graphique lignes paires
mov bx,0205h ; masque de permutation lignes paires/impaires
and [si].AdEfBall,7FFFh ; mise à zéro du bit de poids fort
jmp short Suite
LignDest_Pair: ; ligne maitresse paire
mov bp,GRAPH_IMPAIR ; début adresse mémoire graphique lignes impaires
mov bx,0200h ; masque de permutation lignes paires/impaires
Suite:
mov ch,[si].NbLiEffa ; nombre de lignes à effacer
mov al,[si].NbLiAffi
mov [si].NbLiEffa,al ; le nombre de lignes à afficher à chaque tour
; est le nombre de lignes à effacer au tour suivant
mov di,[si].AdEfBall ; es:di pointe sur l'adresse d'effacement
mov si,OFFSET Buffer_Fond ; ds:si pointe sur l'adresse de Buffer_Sauve (qui contient le fond de sauvegarde)
xor dh,dh ; on initialise le compteur de lignes
call _syncro ; syncro trame
Ligne_Suivante:
cmp dh,ch ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,bx
mov es,bp ; es pointe alternativement la mémoire graphique paire et impaire
mov ax,[si]
mov es:[di],ax ; transfert buffer/écran
mov ax,[si+2]
mov es:[di+2],ax ; transfert buffer/écran
add si,4 ; ligne source suivante
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add di,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ENDM
;----------------------------
SAUVE_FOND_CGA MACRO ; sauvegarde le fond au nouvel emplacement de la balle, en mode CGA
local Balle_Mobile,Ligne_Suivante ; -----------------------------------------------------------------
local LignDest_Pair,LignDest_Impair,Suite,Fin
mov ax,SEG DONNEES
mov ds,ax ; on initialise le segment de données
mov si,OFFSET Struct_Balle ; ds:si pointe sur l'adresse de Struct_Balle
test [si].AdAfBall,8000h ; l'affichage débute t-il sur une ligne impaire ?
jz LignDest_Pair ; non
LignDest_Impair: ; ligne maitresse impaire
mov bp,GRAPH_PAIR + 0005h ; adresse mémoire graphique lignes paires
mov bx,0205h ; masque de permutation lignes paires/impaires
and [si].AdAfBall,7FFFh ; mise à zéro du bit de poids fort
jmp short Suite
LignDest_Pair: ; ligne maitresse paire
mov bp,GRAPH_IMPAIR ; début adresse mémoire graphique lignes impaires
mov bx,0200h ; masque de permutation lignes paires/impaires
Suite:
push bp ; on sauvegarde l'adresse mémoire graphique utilisée dans AFFICHE_BALLE_CGA
mov ch,[si].NbLiAffi ; nombre de lignes à sauvegarder
mov si,[si].AdAfBall ; ds:si pointe sur l'adresse de sauvegarde
mov ax,ds
mov es,ax
mov di,OFFSET Buffer_Fond ; es:di pointe sur l'adresse de Buffer_Sauve
xor dh,dh ; on initialise le compteur de lignes
Ligne_Suivante:
cmp dh,ch ; y a t-il une ligne à afficher ?
je Fin ; non
inc dh ; oui, ligne suivante
xor bp,bx
mov ds,bp ; es pointe alternativement la mémoire graphique paire et impaire
mov ax,[si]
mov es:[di],ax ; transfert écran/buffer
mov ax,[si+2] ; transfert écran/buffer
mov es:[di+2],ax
add di,4 ; ligne destination suivante
test dh,1
jnz Ligne_Suivante ; ligne suivante si balayage impair
add si,80 ; on pointe sur le début de la ligne suivante de l'écran
jmp short Ligne_Suivante
Fin:
ENDM