Donc le but de ce programme c'est d'afficher un mobile à l'écran (ici un petit bonhomme) de le faire bouger avec rafraichissment de l'image et quand il arrive au bord de l'écran de rebondir avec la règle de réflexion type billard :
sin(i)=n*sin(r)
Il y pas mal de trucs interressants : gestion de timer, d'interruption du mode graphique et utilisation du coprocesseur. C'est une application console donc pas de super présentation mais ça a le mérite d'être amusant (à faire en tout cas)
En soi le programme ne sert pas à grand chose... ou peut-être en écran de veille.
Mais je pense que ça peut permettre d'aider des gens qui voudrait faire des trucs similaires. En plus on m'a pas mal aidé ici pour ce programme et je voudrais donc poster cette source pour remercier tout le monde et leur montrer à quoi cela a servit.
Source / Exemple :
;*******************************************************
;* projet assembleur *
;* Déplacement d'un mobile à l'écran *
;* Avec gestion des rebonds sur les bords par la régle *
;* de réflexion : sin(i)=n*sin(r) *
;* *
;* par Mister patate et sa little lady *
;* 2004 *
;*******************************************************
name prog
.MODEL SMALL
;****** utilisation coprocesseur
.486
;****** segment de pile
.STACK 100h
;****************************************************
;****** segment de données(db:octet-dw:16bits) ****
;****************************************************
.DATA
couleur_cadre db ?
couleur db ?
x dw 70 ;coordonnées de départ
y dw 150
v dq 1.8 ;vitesse de l'objet
teta dq 4.2 ;angle initial de la trajectoire (directement en radian)
n dq 1.0 ;coefficient d'amortissement des bords (pour les rebonds)
pos dw ? ;stockage de la position instantanée
d_x dw ? ;variation instantanée de position
d_y dw ?
ctr dw 0 ;compteur fin de programme
;constantes du programme
largeur dq 320.0 ;largeur écran
PiSur2 dq 1.570796327
troisPiSur2 dq 4.712388980
controle dw ?
masque dw 0100000100000000b
ancienne_it dd ? ;sauvegarde de l'ancienne configuration d'interruption
;*****************************
;***** segment de code *****
;*****************************
.CODE
;**** sous-programme d'interruption ****
Inter: mov bx,8 ;mise à 8 be BX -> flag d'interruption
mov al,020h ;acquitement
out 20h,al
iret
;**** sous programme de calcul de la nouvelle position ****
calcul : push bx
push ax
push cx
mov bx,0
fld teta[bx] ;charegement de téta
fsin
fld v
fmul ST(0),ST(1)
fistp d_y ;d_y = V*sin (teta)
lea bx,d_y
mov ax,[bx]
lea bx,y
add ax,[bx]
mov [bx],ax ;y = y + V*sin (teta)
mov bx,0
fld teta[bx]
fcos
fld v
fmul ST(0),ST(1)
fistp d_x ;d_x = V*cos (teta)
lea bx,d_x
mov ax,[bx]
lea bx,x
add ax,[bx]
mov [bx],ax ;x = x + d_x
;calcul de position
mov bx,0
ffree ST(0)
ffree ST(1)
fild x[bx]
fild y[bx]
fld largeur[bx]
fmul ST(0),ST(1) ;ST(0)=320*y
fadd ST(0),ST(2) ;ST(0)=320*y+x
fistp dword ptr[pos] ;recupération de pos=y*320+x
ffree ST(0)
ffree ST(1)
pop cx
pop bx
pop ax
ret
;**** sous programme pour dessiner le bonhomme ****
smile : push bx
push ax
lea bx,pos
mov di,[bx]
mov ax,0A000h ;ecriture d'un point
mov es,ax
mov al,couleur ; choix de la couleur
mov es:[di],al
add di,1
mov es:[di],al
add di,1
mov es:[di],al
sub di,639
mov es:[di],al
add di,321
mov es:[di],al
add di,321
mov es:[di],al
add di,322
mov es:[di],al
add di,1
mov es:[di],al
add di,315
mov es:[di],al
add di,6
mov es:[di],al
add di,313
mov es:[di],al
add di,3
mov es:[di],al
add di,2
mov es:[di],al
add di,3
mov es:[di],al
add di,312
mov es:[di],al
add di,8
mov es:[di],al
add di,312
mov es:[di],al
add di,2
mov es:[di],al
add di,4
mov es:[di],al
add di,2
mov es:[di],al
add di,313
mov es:[di],al
add di,2
mov es:[di],al
add di,1
mov es:[di],al
add di,1
mov es:[di],al
add di,3
mov es:[di],al
add di,314
mov es:[di],al
add di,6
mov es:[di],al
add di,315
mov es:[di],al
add di,1
mov es:[di],al
add di,1
mov es:[di],al
add di,1
mov es:[di],al
add di,1
mov es:[di],al
pop bx
pop ax
ret
;********* AFFICHAGE CADRE ROUGE *******
cadre :
;*** première ligne ***
mov couleur_cadre,5
mov di,0
bendan : mov ax,0A000h
mov es,ax
mov al,couleur_cadre ; choix de la couleur
mov es:[di],al
inc di
cmp di,320
jne bendan
;*** seconde ligne ***
mov di,63680
ben : mov ax,0A000h
mov es,ax
mov al,couleur_cadre ; choix de la couleur
mov es:[di],al
inc di
cmp di,64000
jne ben
;*** colonne de gauche ***
mov di,320
mop : mov ax,0A000h
mov es,ax
mov al,couleur_cadre ; choix de la couleur
mov es:[di],al
add di,320
cmp di,63680
jne mop
;*** colonne de droite ***
mov di,639
mip : mov ax,0A000h
mov es,ax
mov al,couleur_cadre ; choix de la couleur
mov es:[di],al
add di,320
cmp di,63999
jne mip
ret
;**** calcul du changement d'angle pendant un rebond ****
;calcul coprocesseur
calculangle: mov bx,0
fsin
fld n[bx]
fxch ST(1)
fdiv ST(0),ST(1) ;ST(0)=sin(teta)/n
fld ST(0) ;copie de ST(0) dans ST(1)
fmul ST(0),ST(0) ;ST(0)=(sin(teta)/n)²
fld1
fsub ST(0),ST(1)
fsqrt ;ST(0)=sqrt(1-(sin(teta)/n)²) | ST(2)=sin(teta)/n
fxch ST(2)
fld ST(2)
fpatan ;r=arctan(ST(1)/ST(0))
ret
;********************************************
rebond_haut : mov bx,0
fld teta[bx]
fcom troisPiSur2 ;comparaison pour différencier les sous-cas
fstsw controle ;copie du mot de contrôle du coprocesseur
mov ax,controle
mov bx,masque ;masquage pour ne conserver que les bits C0 et C3
and ax,bx
jz cas1 ;saut conditionnel
mov bx,0 ;teta<troisPiSur2
fld troisPiSur2 ;calcul de i à partir de teta
fsub ST(0),ST(1)
ffree ST(1)
call calculangle
fld PiSur2 ;calcul de teta à partir de r
fadd ST(0),ST(1)
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
cas1 : mov bx,0 ;teta>troisPiSur2
fld troisPiSur2
fxch ST(1)
fsub ST(0),ST(1)
ffree ST(1)
call calculangle
fld PiSur2
fsub ST(0),ST(1)
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
;********************************************
rebond_bas : mov bx,0
fld teta[bx]
fcom PiSur2
fstsw controle
mov ax,controle
mov bx,masque
and ax,bx
jz cas2
mov bx,0 ;teta<PiSur2
fld PiSur2
fsub ST(0),ST(1)
ffree ST(1)
call calculangle
fld troisPiSur2
fadd ST(0),ST(1)
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
cas2 : mov bx,0 ;teta>PiSur2
fld PiSur2
fsub ST(1),ST(0)
fxch ST(1)
ffree ST(1)
call calculangle
fld troisPiSur2
fsub ST(0),ST(1)
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
;********************************************
rebond_droite : mov bx,0
fld teta[bx]
fcom PiSur2
fstsw controle
mov ax,controle
mov bx,masque
and ax,bx
jz cas3
mov bx,0 ;teta<PiSur2
call calculangle
fldpi
fsub ST(0),ST(1)
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
cas3 : mov bx,0 ;teta>PiSur2
fldpi
fld1
fadd ST(0),ST(0)
fmul ST(0),ST(1)
fsub ST(0),ST(2)
ffree ST(1)
ffree ST(2)
call calculangle
fldpi
fadd ST(0),ST(1)
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
;********************************************
rebond_gauche : mov bx,0
fld teta[bx]
fldpi
fcom ST(1)
fstsw controle
mov ax,controle
mov bx,masque
and ax,bx
jz cas4
mov bx,0 ;teta>Pi
fxch ST(1)
fsub ST(0),ST(1)
ffree ST(1)
call calculangle
fldpi
fld1
fadd ST(0),ST(0)
fmul ST(0),ST(1)
fsub ST(0),ST(2)
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
cas4 : mov bx,0 ;teta<Pi
fsub ST(0),ST(1)
ffree ST(1)
call calculangle
fstp qword ptr[teta] ;charge ST(0) dans teta
jmp new
;**************************************
;**** début du programme principal ****
;**************************************
DEBUT: mov ax,@data ;récupération de l'adresse de segment
mov ds,ax
;***** initialisation du mode graphique 320*200 et 256 couleurs ****
mov ah,00h
mov al,13h ;choix du mode video 13h<=>320*200*256
int 10h
call cadre
;*** configuration pour l'interruption par le timer ***
mov al,020h ;acquitement éventuelle inerruption précédente
out 20h,al
mov bx,offset ancienne_it ;sauvegarde ancienne config
mov eax,gs:[8*4]
mov [bx],eax
mov ax,03ch ;configuration du TIMER 36h ou 03c h
out 43h,ax
mov al,08ch ;configuration N0
out 40h,al
mov al,0bah
out 40h,al
mov ax,cs ;installation du sous-programme d'interruption
shl eax,16
mov ax,offset Inter
mov bx,8*4
mov gs:[bx],eax
in al,21h ;activation de IRQ0
and al,0feh
out 21h,al
;mise à zéro du compteur d'interruption
mov bx,0
boucle : cmp bx,8 ;boucle d'attente d'interruption
je affichage
jmp boucle
affichage : mov couleur,0 ;dessin en noir pour effacer le vieux bonhomme
call smile
call cadre
call calcul ;calcul prochaine position
mov couleur,4 ;dessin du nouveau bonhomme
call smile
inc ctr
cmp x,308 ;tests rebond
jae rebond_droite
cmp y,2
jbe rebond_haut
cmp y,189
jae rebond_bas
cmp x,1
jbe rebond_gauche
new : ffree ST(0) ;libération des registres coprocesseurs
ffree ST(1) ;éventuellement utilisés pour le calcul d'un rebond
ffree ST(2)
ffree ST(3)
ffree ST(4)
cmp ctr,1000 ;CONDITION DE FIN
je FIN
mov bx,0h ;remise à zéro de bx pour le repérage du flag d'interruption
jmp boucle
;**** fonction de fin de programme ****
FIN: in al,21h ;desactivation de IRQ0
or al,01h
out 21h,al
mov eax,offset ancienne_it ;restauration ancienne config
mov gs:[8*4],eax
mov ax,4c00h
int 21h
end DEBUT
Conclusion :
Pour toute remarques n'hésiter pas à m'envoyer un message par le forum. Sinon pour les gens que ça interesse j'ai une autre version avec deux mobiles.
Comme ça a intéressé les gesn j'ai mis dans le zip : le code et l'EXE des versions à 1 et 2 mobiles...
Pour répondre à la question posée : non il n'y a pas de gestion du clavier pour quitter c'est au bout d'un certein nombre de dessin que le programme termine tout seul (1000 je crois soit 40 sec.). En je ne sais pas faire l'intrruption clavier mais ça m'interresse...
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.