Vous n'êtes pas identifié.
Hier j'ai essayé de faire une fonction clear() a partir de disp_bmp() de Superna ( je ne sais pô si c'est plus rapide qu'une fonction originale clear )... J'ai donc fait :
void clear(int segm) { char bmp_clear[1024]={0x0}; asm{ mov ax,segm mov es,ax mov si,bmp_clear xor di,di mov cx,0x200 cld rep movsw }}
Tout a bien marché sauf a la fin du programme, au moment de quitter, ca m'a affiché des tas de pixels n&b au lieu d'un ecran blanc puis fin du programme!
J'ai alors fait :
#define clear(a) disp_bmp(bmp_clear,a) int a; char bmp_clear[1024]={0x0}; void disp_bmp(BMPTabType BmpTab,int segm) // par Superna, affiche une image { asm{ mov ax,segm mov es,ax mov si,BmpTab xor di,di mov cx,0x200 cld rep movsw }}
Et la tout marche!
Pourquoi? Je vous pose la question!
Et tiens puisque je parle de disp_bmp et que je commence juste a apprendre l'assembleur...
Je ne comprends pô ce que veut dire "xor di,di"...
Et sinon, pourquoi faut t'il d'abord placer le segment dans ax avant de le mettre dans es... Ne peut - on pas le mettre directement ?
Hors ligne
Je ne sais pas d'ou vient ton probleme graphique, mais pour le reste:
:arrow: xor di,di sert a effacer le contenu de di ( plus rapide que mov di,0 )
:arrow: on doit passer par ax pour ecrire dans es car on ne peut jamais ecrire directement une adresse dans les registres es et ds
Hors ligne
déjà je pense que la syntaxe char bmp_clear[1024]={0x0} c pas bon
ca ne doit pas initialiser les 1024 octets
donc ca marche pour la deuxième sol car ton tabeau est une var globale donc mis dans l'exe et init à 0 (TC3 le fait mais tous les compilateur C/C++)
la première ne marchera pas, parfois si, mais les valeurs de ton tableau prendrons l'état de la pile, c pour ca que tu as des merdes sur l'écran.
Hors ligne
la meilleur fonction pour effacer l'eccran c'est celle de 2072 ultra rapide et marche tres bien mais il faut que je la retrouve
Hors ligne
cette fonction efface des page (page >=0) de 1024 octets void clearpage(short page) { asm { pushf; push es; push di; push cx; push ax; mov ax,page; shl ax,6; add ax,0x1A20; mov es, ax; xor di, di; mov cx, 1024; shr cx,1; xor ax, ax; cld; rep stosw; pop ax; pop cx; pop di; pop es; popf; } return; }
Hors ligne
Bon alors, je continue mes problemes, meme si ca n'a rien n'a voir avec le sujet...
J'ai fais une fonction pour tester n'importe quelle touche...Seulement une erreur est survenue (comme d'habitude!).
Voici la fonction :
// teste si une touche de coordonnees y,x est pressee. // fonction inspiree du tutorial de Whyp et des fonctions // extraites de Space invader de Superna int testkey(int y,int x) { int recv=(!x?1:1<<(7-x)); asm{ mov ax,0 shl ax,y // c'est a cette ligne que le compilateur dit: out 0x13,ax // "invalid combinaison of opcode and operands" in al,0x13 } if (_AL&recv) return 1; return 0;}
J'ai reussi a faire marcher la fonction en effacant "shl ax,y", en modifiant "mov ax,0" par "mov ax,y", et en rajouttant "y=1<<y" apres "int recv=(!x?1:1<<(7-x))".
Mais bon comme cela m'intrigue et que j'aimerais comprendre pourquoi la fonction ci-dessus ne marche pas, je pose la question a qq de meilleur que moi.
Hors ligne
invalid combinaison of opcode and operands ca veut dire que par exemple tu as écrit un mot 16 bits dans un octet (8 bits) !
out ne fonctionne qu' avec des octets !
donc tu dois faire ca :
out 0x13,al out 0x14,ah
ou un truc comme ca ...
Hors ligne
Hors ligne
C'est le shl ax,y qui va pas, a mon avis tu devrais essayer de faire
asm{ mov ax,0 mov bx,y shl ax,bx out 0x13,ax in al,0x13 }
Ou quelque chose du genre...
Hors ligne
Non ni l'une ni l'autre des solutions que vous me proposez ne marche !
J'avais déja essayé...
Hors ligne
au lieu de in al,0x13 met in ax,0x13
Hors ligne
en effet
shl
ne peut marcher qu'avec cl ou une constante
donc fait mov cl,y (avec y de type unsigned char)
et shl ax,cl
// teste si une touche de coordonnees y,x est pressee. // fonction inspiree du tutorial de Whyp et des fonctions // extraites de Space invader de Superna //c trés bien ça !!! int testkey(short y,unsigned char x) { int recv=(!x?1:1<<(7-x)); asm{ mov ax,y out 0x13,ax in al,0x13 } if (_AL&recv) return 1; return 0;}
mais a quoi correspond ce int recv=(!x?1:1<<(7-x)); ?
je comprends pas
oké
tu envoie la ligne dans le port avec le numero de ligne
tu dois envoyer dans le port 2^y
donc faire une relation de puissance
c plus complexe que ça
ensuite tu fait 2^x et tu fait
un et logique entre al et 2^x et si c 1 alors la touche est appuyée
engros :
testkey(x,y){ x=2^x; y=2^y; out 0x13,y; in al,0x13; and al,x if (al==0) return pas bon; return bon; }
Hors ligne
Bon alors voila :
int recv=(!x?1:1<<(7-x));
Ca veut dire que : si x==0 alors met 0x1 dans recv sinon recv prends la valeur du decalage de la colonne...
Soit (avec des valeurs binaires):
si x=0 -> envoie 00000001 dans recv (uniquement pour la touche AC/on)
si x=1 -> envoie 2^6 dans recv, soit 01000000 (pour F1 par exemple)
si x=2 -> envoie 2^5 dans recv, soit 00100000 (pour F2 par exemple)
si x=3 -> envoie 2^4 dans recv, soit 00010000 (pour F3 par exemple)
si x=4 -> envoie 2^3 dans recv, soit 00001000 (pour F4 par exemple)
si x=5 -> envoie 2^2 dans recv, soit 00000100 (pour F5 par exemple)
si x=6 -> envoie 2^1 dans recv, soit 00000010 (pour F6 par exemple)
Ensuite j'ecris la colonne de la touche dans le port...
al recoie la valeur...
Si je veux tester F1 et que j'appuie sur F1 et F3 (par exemple), al aura cette valeur 01010000...
Ensuite j'applique AND a al et recv, et si il reste une valeur (que la touche F1 est pressée) alors revoie 1...
Donc je ne pense pô que ta fonction marche, a moins d'echanger les valeurs de x!
Voilou
Hors ligne
en fait tu t'es cassé la tête
voiila la fonction qui marche
tt en asm :
unsigned char testkey(unsigned char x,unsigned char y){ asm{ //on fait 2^y mov ax,1 mov cl,y shl ax,cl //on fait 2^x mov bl,1 mov cl,x shl bl,cl //on met dans le port out 0x13,ax //on attends mov cx,10 } lp: asm{ dec cx jnz lp //on prends les touches appuyées in al,0x13 and al,bl //et on verifie si la touche x est appuyée if(al==0) return 0; return 1;}
elle marche techniquement
(fait avec le tuto de whyp et mes connaissances sur le probleme)
Hors ligne
en effet 2^y en asm allume le bit correspondant a y
tu connais le binaire?
10001 -> d17
10001 -> 2^4+2^0 -> 16+1 -> 17
donc si tu met 1 et tu decale par y ou x ça marche
donc il faut
envoyer un mot avec le(s) bit correspondant aux lignes a tester allumés
attanedre un peu
recuperer l'octet
les bits allumés correspondent aux touches allumées
voila
voir : http://perso.wanadoo.fr/graph100/progra … tiples.htm
Hors ligne
Au lieu de la boucle, essaye de mettre une instruction hlt ça devrait suffire, non ?
Hors ligne
Au fait pourquoi a-t-il fallu fermer l'accolade avec le label lp et en rouvrir une apres?
La mise en place des labels est pourtant la meme en asm qu'en c... non?
( d'ailleurs il faut au moins fermer l'accolade apres and al,bl !)
Hors ligne
Je croi ke tc3 il aime pa les label a l'intérieur de balises asm...
Hors ligne
nop!nop!nop!
Je suis certain de ma fonction...
Le "int recv=(!x?1:1<<(7-x));" sert en fait a faire correspondre le x ac la colonne, cad :
si x==0 -> teste AC/on
si x==1 -> teste colonne de F1
si x==2 -> teste colonne de F2
si x==3 -> teste colonne de F3 etc...
Alors que ta fonction, pour tester F1 -> x==6, pour tester F2 -> x==5...
J'ai mis ca juste par preference (j'aime mieux de gauche a droite)!
Par contre, ta fonction ne marche pô, pour une raison :
La valeur de y peut aller de 0 a 10...Donc, comme pour faire le decalage, tu dois passer par cl (8 bits seulement), tu ne peux pas faire un decalage de 10 (1024>8 bits), et donc toutes les touches du haut (F1, SHIFT...etc) ne peuvent pô etre testées (d'ailleurs je pense que ca fait, tout planter en fait et qu'on ne peut tester aucune touche).
Vala donc pour résumer, voici une fonction qui marche parfaitement pour tester toutes les touches (multiples):
char testkey(unsigned int y,unsigned int x) { int recv=(!x?1:1<<(7-x)); // a remplacer par "int recv=1<<x" si on prefere de droite a gauche y=1<<y; asm{ mov ax,y out 0x13,ax in al,0x13 } if (_AL&recv) return 1; return 0;}
Mais cela ne résouds pô mon probleme, comment faire le decalage de y en asm sachant que y va de 0 a 10 donc ki faut faire un decalage de 10...
Tiens par contre, Superna, quel est l'interet d'attendre entre l'envoi et la reception de la valeur du port? De ralentir un peu la fonction?
Hors ligne
non
les fonctions en c sont extrement lente, je crains ce genre de fonctions que tu me fais la
seroieux cele que je t'ai donnée est bextrememnt rapide
au moins 200% plus rapide car moins de truc complexe a faire
tc3 va te traduire en asm ce truc en un code d'au moins 10 fois plus de code
et avec space invaders, j'ai pu tester les ports
en effet, sans attente, ça foirais, sautais
et la valuer dans Si est 5 est ça rtoule perfect
pour 2072, j'ai essayé la ft hlt, serieux c trop long, ça marchais trés trés lentement car sous Si je testais les touches quasiment tt le temps
voila
Hors ligne
nop!nop!nop!
Par contre, ta fonction ne marche pô, pour une raison :
La valeur de y peut aller de 0 a 10...Donc, comme pour faire le decalage, tu dois passer par cl (8 bits seulement), tu ne peux pas faire un decalage de 10 (1024>8 bits), et donc toutes les touches du haut (F1, SHIFT...etc) ne peuvent pô etre testées (d'ailleurs je pense que ca fait, tout planter en fait et qu'on ne peut tester aucune touche).
?
ques tu raconte
pour l'operande
shl ??,cl
c'est ?? qui est decalé et la j'ai pris ax qui peut contenir 10bits
cl est le nombre de decalage, il peut il y en avoir au max 16
et oui a quoi ça sert de decaler un mot de 16 bits plus de 16 fois?
note que le decalage est un nombre normal
en fait la traduction serait :
decale_a_gauche ax,du_nombre_inscrit_dans_cl
donc en c ax<<cl
etr la je n'ai pas tort car j'utilise ça dans les fts graphiques qui ne plantent pas
Hors ligne
@ superna : peut etre... mais g pô réussi a compiler ta fonction...donc je ne sais pô... Mais je ne savais pô pour shl (mais ca m'etonnais qd meme qu'on ne puisse decaler sur 16 bits)
@ x-thunder28 : pour multiplier :tu fais "mul s" où s est le nombre qui multiplie ax ( ou alors imul ka le meme effet mais avec les entiers signés)
pour diviser : tu fais "div s" où s est le nombre qui divise ax... le quotient se trouve dans al et le reste dans ah ( ou alors idiv )...je crois que c'est ca
Hors ligne
"Swifter
@ x-thunder28 : pour multiplier :tu fais "mul s" où s est le nombre qui multiplie ax ( ou alors imul ka le meme effet mais avec les entiers signés)
pour diviser : tu fais "div s" où s est le nombre qui divise ax... le quotient se trouve dans al et le reste dans ah ( ou alors idiv )...je crois que c'est ca[/quote a écrit:
mul et div ne marche pas !
Faut -il rajouter quelque chose au code ???
Anciennement X-thunder28
Cats shall rule teh world!
Hors ligne
Sisi c'est ca, mais la syntaxe est particulière...
Si je me souviens bien tu mets le facteur dans multiplication dans cx et tu fais
mul ax
comme équivalent de _AX*=_CX en C mais je suis plus sur du tout!
Hors ligne