1

#honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte#
Ben voila, j'ai essayé de faire un programme en C qui utilise une fonction faite en A68k, mais...
[smiley=2]Ca marche pas!!
Je le lance, et... rien ne se passe. Le programme affiche "Done", sans rien faire...confus
[nosmile]
Si quelqu'un sait d'où ça peut venir, je peux toujours montrer mes sources, c'était une fonction de sprite8 personalisée...

Edit: Et maintenant, je mets la version finale... Celle qui marche!!
[b]Voici d'abord la sous-fonction en A68k:[/b]
; Assembly Source File
; Created 11/02/03, 18:35:12

            section     ".data"

            INCLUDE     "OS.h"            ;fichier include pour les programmes en _nostub, contenant notamment les ROM_CALLs
            INCLUDE     "MyMacros.inc"    ;Mes Macros persos
            XDEF        _nostub           ;pas besoin de kernel
            XDEF        _ti89             ;Ce programme tourne sur TI-89.
            XDEF        _ti92plus         ;Ce programme tourne sur TI-92+.

            XDEF        img8or
            XDEF        image8or
            XDEF        imgAli8or

;#define img8or(x,y,dimy,image) (image8or(8-((x)&7),(x)>>3,(y),(dimy),(image))
;(fontion optimisée de passage de coordonnée à img8or)
img8or:
            SUBQ.l      #2,A7             ;Décale popur insérer un word
            MOVE.l      2(A7),D0          ;Prend l'adresse de retour
            MOVE.l      D0,(A7)           ;La replace en bas de la pile
            MOVE.w      6(A7),D0          ;prend x
            MOVEQ       #8,D1             ;pour soustraire à 8
            AND.w       #7,D0             ;modulo 8
            SUB.w       D0,D1             ;8-(x%8)
            AND.w       #7,D1             ;re-modulo 8 (décalage de 8 =0)
            MOVE.w      D1,4(A7)          ;Sauve decal où il faut sur la pile
            MOVE.w      6(A7),D0          ;reprend x
            ADDQ.w      #7,D0             ;Ajoute 7 pour mettre à l'échelle
            LSR.w       #3,D0             ;Divise par 8
            MOVE.w      D0,6(A7)          ;sauve coordx
            BRA         image8or          ;Passe à la fonction d'affichage


;void image8or(int décal, int coordx, int coordy,int dimy, const char *octets)
;params
I8decal     EQU         8
I8coordx    EQU         10
I8coordy    EQU         12
I8dimy      EQU         14
I8octets    EQU         16
;vars
cpty        EQUR        D7
maxy        EQUR        D6
decalr      EQUR        D5
x           EQUR        D4
;y          EQUR        D3
pt_image    EQUR        A4
pt_ecran    EQUR        A3

image8or:   LINK        A6,#0             ;Lie A6 à la pile
            MOVEM.l     D3-D7/A2-A5,-(A7) ;Sauve contexte
            MOVE.l      $C8,A5            ;Table des ROM_CALLs en A5
;--- Début du prog ---
;prends les params
            MOVE.w      I8decal(A6),decalr
            TST.w       decalr            ;SI decalr==0
            BEQ         imgAli8or_interne ;->Saute vers la fonction sans décalage
                                          ;(juste après la sauvegarde du contexte)
            MOVE.w      I8coordx(A6),x
            MOVE.w      I8dimy(A6),maxy
            MOVE.l      I8octets(A6),pt_image
;la fonction n'est pas clippée: on quitte si x==0
            TST.w       x                 ;SI(2) x!=0
            BEQ         I8Ofs002          ;ALORS(2)
;initialise les vars internes
            MOVEQ       #0,cpty
            LEA         LCD_MEM,pt_ecran
;calcul de la coordonnée y (multiplication par 30 sans MULU ni BOUCLE)
            MOVE.w      I8coordy(A6),D0   ;lit coordy
            MOVE.w      D0,D1             ;copie dans D1
            LSL.w       #5,D0             ;multiplie D0 par 32
            LSL.w       #1,D1             ;multiplie D1 par 2
            SUB.w       D1,D0             ;32-2=30!
            EXT.l       D0
            ADDA.l      D0,pt_ecran       ;Ajoute y*30 au pointeur ecran
            EXT.l       x
            ADDA.l      x,pt_ecran        ;Ajoute x
;boucle principale
I8Obcl001:
            MOVEQ       #0,D0             ;Nettoie DO
            MOVE.b      0(pt_image,cpty.w),D0   ;prend l'octet de l'image
            LSL.w       decalr,D0         ;Décale de décal pixels vers la gauche
;Ici les instructions qui déterminent le mode
            OR.b        D0,0(pt_ecran)    ;Affiche les pixels de droite
            LSR.w       #8,D0             ;Octet fort de D0.w en poids faible
            OR.b        D0,-1(pt_ecran)   ;Affiche les pixels de gauche

            LEA         30(pt_ecran),pt_ecran   ;Passe à la ligne suivante
            ADDQ.w      #1,cpty           ;incrémente y
            CMP.w       cpty,maxy         ;SI y<maxy
            BNE         I8Obcl001         ;->on reboucle

I8Ofs002:                                 ;FINSI(2)
;--- Sortie du Prog ---
            MOVEM.l     (A7)+,D3-D7/A2-A5 ;Rappelle contexte
            UNLK        A6                ;Libère A6
            RTS                           ;Retour
;--- Fin du programme ---

;void imgAli8or(int decal_ignored,int coordx, int coordy,int dimy, const char *octets)
imgAli8or:  LINK        A6,#0             ;Lie A6 à la pile
            MOVEM.l     D3-D7/A2-A5,-(A7) ;Sauve contexte
            MOVE.l      $C8,A5            ;Table des ROM_CALLs en A5
;--- Début du prog ---
imgAli8or_interne:
;prends les params
            MOVE.w      I8coordx(A6),x
            MOVE.w      I8dimy(A6),maxy
            MOVE.l      I8octets(A6),pt_image
            MOVE.w      I8coordy(A6),D0   ;lit coordy
IA8OSuite:
;initialise les vars internes
            MOVEQ       #0,cpty
            LEA         LCD_MEM,pt_ecran
;calcul de la coordonnée y (multiplication par 30 sans MULU ni BOUCLE)
            ;coordy est toujours dans D0
            MOVE.w      D0,D1             ;copie dans D1
            LSL.w       #5,D0             ;multiplie D0 par 32
            LSL.w       #1,D1             ;multiplie D1 par 2
            SUB.w       D1,D0             ;32-2=30!
            EXT.l       D0
            ADDA.l      D0,pt_ecran       ;Ajoute y*30 au pointeur ecran
            EXT.l       x
            ADDA.l      x,pt_ecran        ;Ajoute x
;boucle principale
IA8Obcl001:
            MOVE.b      0(pt_image,cpty.w),D0    ;prend l'octet de l'image
;Ici l'instruction qui détermine le mode
            OR.b        D0,0(pt_ecran)    ;affiche

            LEA         30(pt_ecran),pt_ecran   ;Passe à la ligne suivante

            ADDQ.w      #1,cpty           ;incrémente y
            CMP.w       cpty,maxy         ;SI y<maxy
            BNE         IA8Obcl001        ;->on reboucle
;--- Sortie du Prog ---
            MOVEM.l     (A7)+,D3-D7/A2-A5 ;Rappelle contexte
            UNLK        A6                ;Libère A6
            RTS                           ;Retour
;--- Fin du programme ---

#honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte#
[b]Et le programme en C qui l'utilise:[/b]
// C Source File
// Created 11/02/03; 19:30:47

#define USE_TI89              // Compile for TI-89
#define USE_TI92PLUS          // Compile for TI-92 Plus
#define USE_V200              // Compile for V200

#define OPTIMIZE_ROM_CALLS    // Use ROM Call Optimization

//#define SAVE_SCREEN           // Save/Restore LCD Contents

#include <kbd.h>
#include <statline.h>
#include <graph.h>
#include <alloc.h>
#include <mem.h>

void img8or(int x, int coordy,int dimy, const char *octets) __attribute__((stkparm));
void image8or(int decal, int coordx, int coordy,int dimy, const char *octets) __attribute__((stkparm));
void imgAli8or(int decal_ignored,int coordx, int coordy,int dimy, const char *octets) __attribute__((stkparm));

#define MAT_DIMX 6
#define MAT_DIMY 4

// Main Function
void _main(void)
{
char mypic[8][8]={	{0x0F,0x30,0x40,0x48,0x90,0x98,0x9C,0xCF},
					{0xF0,0x0C,0x02,0x12,0x09,0x19,0x39,0xF3},
					{0x63,0x78,0x3F,0x4F,0x84,0x9A,0x62,0x01},
					{0xC6,0x1E,0xFC,0xF2,0x21,0x59,0x46,0x80},
					{0xCF,0x30,0xC0,0xC8,0x90,0x98,0x9C,0xCF},
					{0xF3,0x0C,0x03,0x13,0x09,0x19,0x39,0xF3},
					{0x81,0xC2,0xD4,0xE8,0xD4,0xE8,0xBE,0x7F},
					{0xC3,0x00,0x00,0x3C,0xC3,0x00,0x00,0x3C}};
char my_mat[MAT_DIMY][MAT_DIMX]={{1,2,0,0,0,0},{3,5,2,7,7,7},{0,3,4,7,8,8},{0,0,0,7,8,8}};
char *pt_ecransauv=NULL;
int i,j;
pt_ecransauv=HeapAllocPtr(3840);
if(pt_ecransauv)
	{
	memcpy(pt_ecransauv,LCD_MEM,3840);
	ClrScr();
	for(i=0;i<MAT_DIMY;i++)
		{
		for(j=0;j<MAT_DIMX;j++)
			{
			if(my_mat[i][j])
				img8or(8*j+2,8*i+2,8,mypic[(int)my_mat[i][j]-1]);
			}
		}
	ngetchx();
	memcpy(LCD_MEM,pt_ecransauv,3840);
	HeapFreePtr(pt_ecransauv);
	ST_helpMsg("fini.");
	}
else
	ST_helpMsg("Impossible de sauver l'écran.");
}


Je ne comprend vraiment pas pourquoi il ne se passe rien...

Edit: #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte#
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

2

manuel.gif gni

http://tigcc.ticalc.org/doc/a68k.html
Je cite:
Note: If you want to use A68k assembly and C at the same time, you have to put the following directive at the start of each assembly file: section ".data"


Et puis, pas la peine d'exporter _nostub, _ti89 et _ti92plus dans ta source en assembleur, c'est déjà fait dans le programme C.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3

sick
J'ai cherché dans les "how to...", pas dans A68k lui-même tsss
Enfin merci
#honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte# #honte#
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

4

rotfl
avatar
Membre fondateur de la Ligue Anti-MacIntoc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Un expert est quelqu'un qui en sait de plus en plus sur de moins en moins
de choses, jusqu'à ce qu'il connaisse absolument tout à propos de rien.

5

Mais finalement, elle n'est pas trop lente, ma fonction de sprite8, ou on peut faire Largement plus rapidewhat
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

6

largement je sais pas, mais plus rapide, oui. smile

7

Link> Attends, ton code A68k de 3 pages c'est une routine pour afficher un sprite 8x8 dans un cas général ou dans ton cas particulier?
Parce que ça me paraît extrêmement compliqué. Déjà je comprends pas le fait que tu sauves tous les registres et que tu mettes la table des ROMCALLs...
Et puis sache qu'un code bien commenté vaut mieux dans le cas de petites fonctions comme ça que de mettre des EQU et EQUR.
C'est franchement illisible avec les noms que tu as donné aux registres, etc.
avatar
;)

8

BiHi->Je suivrai tes conseils
Et en fait, image8or est une routine de sprite8 en OR qui saute à une routine plus rapide si le décalage par rapport à l'octet est nul.
img8or est une routine à laquelle on passe directement la coordonnée X, et qui la convertit en X/8 et décalage pour appeler image8or

Quand à la sauvegarde des registres et la table des ROM_CALLS, c'est un réflexe, je peux facilement les enlever comme je ne m'en sert pas...
Mais pour des raisons de pile, les deux fonctions doivent sauvegarder les mêmes registres. Mais il est vrai que je peux en sauvegarder moins...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

9

CMP.w       cpty,maxy         ;SI y<maxy
BNE         IA8Obcl001        ;->on reboucle


tres lent ça...

10

G pas trop le choix, cpty sert aussi au décalage du pointeur vers l'image à afficher...
mais c'est peut-être plus rapide d'incrémenter directement le pointeur et de faire un DBF sur le compteur?confus
Et si je fais un XOR pour vérifier s'ils sont égaux, sera-ce plus rapide que le CMP?!
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

11

essaye d'operer au maximum sur les registres, pas sur des données smile

12

Link> Rah je sais pas il est imbuvable le code...
Franchement, si tu veux faire un truc rapide et surtout beaucoup plus petit, évite de penser en langage C. Ca se fait en 20 lignes une routine de sprite8, et c'est vraiment petit. Pas besoin d'"optimiser" en faisant 2 cas différents. Je pense déjà que tu devrais passer les paramètres par registre, et puis repenser à l'implémentation de l'algo.
Cherche plus simple. Il te faut:
1 - chercher l'octet de "départ du dessin"
2 - calculer le décallage qu'il faudra faire à droite et à gauche
3 - décaller à droite la ligne du sprite courant
   - l'afficher (or, eor, and) à l'octet courant
   - décaller à gauche la même ligne du sprite
   - l'afficher à l'octet suivant
   - sauter une ligne sur l'écran, passer à la ligne suivante du sprite, boucler en 3.
Ca c'est l'idée générale, tu la connais, mais ensuite l'optimisation se fait un peu partout, pour faire un code assez rapide...
avatar
;)

13

Nerick->cpty et maxy sont des registres. j'ai mis des EQUR, mais ce n'est pas sur que le code y gagne en lisibilité...

MAIS sinon, ma manip pour multiplier coordy par 30, n'est-elle pas encore plus lente qu'un MULU?! j'ai des doutes... Personne n'a l'adresse d'une table de durée des instructions?!
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

14

http://www.ticalc.org/pub/text/68k/timing.txt
Et ne t'inquiètes pas, la manipulation pour multiplier par 30 et beaucoup plus rapide qu'un mulu.
Maintenant on peut encore faire mieux! grin
Au lieu de faire y*32-y*2, fais plutôt y*2*(16-1), c'est mieux.
Pour faire y*2, au lieu de faire lsl.w #1,dn fais plutôt add.w dn,dn.
Tu verras que c'est plus rapide dans le lien que je t'ai passé.
avatar
;)

15

Au lieu de faire y*32-y*2, fais plutôt y*2*(16-1), c'est mieux

comment ça?

16

ben au lieu de:
 
 move.w  d0,d1 ;d0=d1=y
 lsl.w   #5,d0 ;d0=32*y
 lsl.w   #1,d1 ;d1=2*y
 sub.w   d1,d0 ;d0=30*y

tu fais:
 add.w   d0,d0 ;d0=2*y
 move.w  d0,d1 ;d1=d0=2*y
 lsl.w   #4,d0 ;d0=16*2*y=32*y
 sub.w   d1,d0 ;d0=30*y

Je crois que c'est mieux.
avatar
;)

17

ah ue ok, bah c ce que je fais d'habitude en fait smile
je crois que c mieux parceque ya un décalage a gauche en moins (#4 au lieu de #5)
et les décalages prennent d'autant plus de cycle que la donnée est décalée (oula)

18

Ya 2 décalage en moins

lsl.w #5,d0
lsl.w #1,d1

contre

lsl.w #4,d0
!


PS: Au jugé d'oeuil, la seconde méthode semble plus rapide (meme si c'est pas phénoménal)
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

19

BiHi->l'autre routine de sprite8 est censée pouvoir être appelée directement, c'est pour cela que je bascule vers la fonction rapide si je peux...

Bon, je vais suivre mos conseils sur le MULU, et nettoyer un peu mes fonctions(au wc les ROM_CALLs) mais j'ai la flemme de poser ici... Et en plus cela ne servirait pas à grand chose...
Salut!
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

20

[nosmile]
/*********************************************************************/
Je remonte ce topic pour ma seconde tentative qui ne marche pas:
j'ai eu beau chercher dans la doc, je ne trouve toujours pas et je suis déja prêt à être ridiculisé par une réponse Evidente...

Cette fois, j'ai mis des données dans mon fichier asm, sous cette forme:  XDEF img1  XDEF img2  XDEF str1 img1 DC.w $1234,$5678,et 14 autres words img2 DC.w $9ABC,$DEF0, et encore 14 words str1 DC.b 'ca marche pas!',0
(et cette fois-ci je n'ai pas oublié le section ".data" devant...)
Et dans mon fichier C, je l'introduis comme suit:
extern short *img1;
extern short *img2;
extern char *str1;

et le problème, c'est que img1 et img2 contiennent non pas deux pointeurs différents de 32, mais les valeurs pointées $12345678 et $9ABCDEF0 (j'affiche avec printf("%08LX",(long)img1); )

Et quand je regarde le code asm GNU généré, je vois mes "ptr=img1" convertis en "move.l img1,destination", je pense qu'il devrait y avoir un # devant...

J'ai surement oublié de regarder quelque part, mais où?
(au fait, j'utilise TIGCC v0.94 final)
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

21

met ptr=&img1 alors je dirais.
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.

22

ça résoudrait sans doute le problème, mais c'est bizarre, il me semblait que XDEF exportait une adresse, et j'ai décléré img1 en short *, c'est quand même bizarre...
Mais je peux toujours essayer...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

23

extern short img1;
extern short img2;
extern char str1[];
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

24

finalement, avant de voir la réponse de kevin, j'ai mis les img en short et je passe leur adresse...
mais ce que je ne comprends pas c'est dans la réponse de Kevin: les img sont des tableaux de short, str1 un tableau de char, alors pourquoi sont-ils appelés différement?
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

25

Link
: mais ce que je ne comprends pas c'est dans la réponse de Kevin: les img sont des tableaux de short, str1 un tableau de char, alors pourquoi sont-ils appelés différement?

Ah oui, c'est vrai, il faudrait mettre:
extern short img1[];
extern short img2[];
extern char str1[];

C'est plus correct.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

26

Et la, je peux faire directement DrawIcon(img1), vu que les tableaux sont pris comme des pointeurs, non?

Enfin c'est stupide de poser la quesiton, je vais tester, voilà tout...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

27

Link
: Et la, je peux faire directement DrawIcon(img1), vu que les tableaux sont pris comme des pointeurs, non?

Oui.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité