Bon, je suis en train de patcher le patcher, mais j'ai une question : à quoi sert ce code, qui s'occupe des romcalls ?
        // handle F-LINE ROM_CALLs
        if (fline_ROM_CALLs && !strncmp(buffer,"\tjsr _ROM_CALL_",15) && strlen(buffer)<=18) {
          memmove(buffer+3,buffer+1,strlen(buffer)); // replace "jsr _ROM_CALL_"
          strncpy(buffer+1,".word _F_LINE+0x",16);     // with ".word _F_LINE+0x"
        } else {
          // add :l to ROM_CALLs
          char *p4=strstr(buffer,"_ROM_CALL_");
          while (p4) {
            char *p5=p4;
            p4+=10;
            while (isalnum(*p4)||*p4=='_'||*p4=='+'||*p4=='-'||*p4=='*'||*p4=='/') p4++;
            while (*p4==':'||isalpha(*p4)) memmove(p4,p4+1,strlen(p4)); // zap :w if it's there
            if (strlen(buffer)>32769) break; // avoid buffer overflow
            memmove(p4+2,p4,strlen(p4)+1);
            *(p4++)=':'; // add ":l"
            *(p4++)='l';
            if (!strncmp(p4,"(%pc)",5)||!strncmp(p4,"(%Pc)",5)||!strncmp(p4,"(%pC)",5)||!strncmp(p4,"(%PC)",5)) {
              memmove(p4,p4+5,strlen(p4+5)+1);
            } else if ((!strncmp(p4,",%pc)",5)||!strncmp(p4,",%Pc)",5)||!strncmp(p4,",%pC)",5)
                        ||!strncmp(p4,",%PC)",5))
                       &&(p5>buffer)&&(p5[-1]=='(')) {
              memmove(p4,p4+5,strlen(p4+5)+1);
              memmove(p5-1,p5,strlen(p5)+1);
            }
            p4=strstr(p4,"_ROM_CALL_");
          }
          p4=strstr(buffer,"__ld_calc_const_");
          while (p4) {
            char *p5=p4;
            p4+=16;
            while ((*p4>='0'&&*p4<='9')||(*p4>='a'&&*p4<='z')||(*p4>='A'&&*p4<='Z')||(*p4=='_')||(*p4==':')) p4++;
            if (!strncmp(p4,"(%pc)",5)||!strncmp(p4,"(%Pc)",5)||!strncmp(p4,"(%pC)",5)||!strncmp(p4,"(%PC)",5)) {
              memmove(p4,p4+5,strlen(p4+5)+1);
            } else if ((!strncmp(p4,",%pc)",5)||!strncmp(p4,",%Pc)",5)||!strncmp(p4,",%pC)",5)
                        ||!strncmp(p4,",%PC)",5))
                       &&(p5>buffer)&&(p5[-1]=='(')) {
              memmove(p4,p4+5,strlen(p4+5)+1);
              memmove(p5-1,p5,strlen(p5)+1);
            }
            p4=strstr(p4,"__ld_calc_const_");
          }
        }
Le if, ok, c'est le remplacement du relogement par un appel F-line.
Juste une incompréhension : pourquoi strlen(buffer)<=18 ?

Par contre, le else...

A quoi sert cette ligne ? while (isalnum(*p4)||*p4=='_'||*p4=='+'||*p4=='-'||*p4=='*'||*p4=='/') p4++;
Ou plutôt, dans quel cas on peut tomber sur un tel code ? isalnum() ok, mais les signes ??

while (*p4==':'||isalpha(*p4)) memmove(p4,p4+1,strlen(p4)); // zap :w if it's there
Là, il vaut mieux ne pas avoir trifouillé dans le .s à la main, parce que question algo c'est pas clean cheeky

Ensuite, par quel miracle pourrait-on avoir un romcall pc-relatif, avec offset ou non d'ailleurs ?

Enfin, que vient faire __ld_calc_const ?

Merci bien. smile

ps -> question d'ordre général : pourquoi des strncmp/strncpy plutôt que leur version sans 'n' ?
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Bon, un petit patchounet comme ça, ça irait ? tromb Fichier joint : patcher.diff
Et j'ai mis ça dans default.h :
#ifdef USE_FLINE_RAM_CALL
asm(".set _F_LINE_RAM_CALL,0xF000");
#endif
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Folco (./30) :
Juste une incompréhension : pourquoi strlen(buffer)<=18 ?
Parce que les numéros de ROM_CALL ont au maximum 3 chiffres hexa.
A quoi sert cette ligne ? while (isalnum(*p4)||*p4=='_'||*p4=='+'||*p4=='-'||*p4=='*'||*p4=='/') p4++;Ou plutôt, dans quel cas on peut tomber sur un tel code ? isalnum() ok, mais les signes ??
Par exemple, la définition de vcbprintf référence _ROM_CALL_53+32 (_ROM_CALL_53 étant sprintf). (À voir si GCC génère effectivement ce code, mais il pourrait en tout cas.)
while (*p4==':'||isalpha(*p4)) memmove(p4,p4+1,strlen(p4)); // zap :w if it's there
Là, il vaut mieux ne pas avoir trifouillé dans le .s à la main, parce que question algo c'est pas clean cheeky
Ça enlève tous les ':' et toutes les lettres, c'est clair que c'est un peu pourri. L'algorithme vient de Sebastian si je me rappelle bien.
Ensuite, par quel miracle pourrait-on avoir un romcall pc-relatif, avec offset ou non d'ailleurs ?
-mpcrel
Enfin, que vient faire __ld_calc_const ?
__ld_calc_const_… est essentiellement un _RAM_CALL en temps de linking. Ça permet d'avoir des binaires optimisés par modèle de calculatrice sans compiler 2 ou 3 fois. Le désavantage est que c'est évidemment incompatible on-calc et que l'optimisation n'est pas aussi bonne que si on compile plusieurs fois (parce que le linker ne peut pas faire de constant folding ni supprimer des branches de if qui ne conviennent pas). Bref, personnellement, je ne conseille pas d'utiliser ça.
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
Folco (./31) :
Bon, un petit patchounet comme ça, ça irait ? tromb Fichier joint : patcher.diff
Tes opérations sur la chaîne de caractères ne sont pas bonnes, ton strncpy écrase ta chaîne déplacée avec memmove.
Et j'ai mis ça dans default.h :
#ifdef USE_FLINE_RAM_CALL
Il manque le S pour être cohérent.
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
yep, j'ai déjà rectifié tout ça, mais merci.
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
	.file	"main.c"
#NO_APP
	.text
tigcc_compiled.:
	.text
#APP
	.xdef _ti89
	.text
	.xdef _ti89ti
	.text
	.xdef _ti92plus
	.text
	.xdef _v200
	.text
	.set _F_LINE_RAM_CALL,0xF000
	.text
	.set _A_LINE,0xA000
	.text
	.xdef _flag_2
#NO_APP
	.text
	.even
	.globl	_main
_main:
	link.w %fp,#-152
	movm.l #0x1034,-(%sp)
#APP
	bra .
#NO_APP
	lea (-150,%fp),%a4
	cmp.w #21071,50.w
	jbeq .L14
.L2:
	pea StrErrorOS
	jsr _ROM_CALL_E6:l
	moveq #1,%d0
	addq.l #4,%sp
	jbra .L5
.L14:
	cmp.w #130,48.w
	jble .L2
	pea -78(%fp)
	jsr _ROM_CALL_266:l
	move.w %d0,%d3
	addq.l #4,%sp
	jbne .L6
	move.l %a4,%a3
	move.l #262145,-(%sp)
	pea StrPdtlib
	lea PdtlibOffsets,%a2
	lea PdtlibFunctions,%a1
	moveq #1,%d1
	lea StrPdtlib,%a0
	.word _F_LINE_RAM_CALL+0x1D
	move.l %a0,8(%a3)
	move.l %a4,%a3
	addq.l #8,%sp
	tst.l 8(%a4)
	jbeq .L15
	move.l 64(%a4),%a5
	lea LibcOffsets,%a2
	lea LibcFunctions,%a1
	moveq #1,%d1
	lea StrLibc,%a0
	jbsr (%a5)
	move.l %a0,12(%a3)
	tst.l 12(%a4)
	jbne .L10
	move.l 8(%a4),%a0
	.word _F_LINE_RAM_CALL+0x1A
	moveq #3,%d0
	jbra .L5
.L15:
	moveq #2,%d0
	jbra .L5
.L10:
	move.w #1,2(%a4)
	lea (2,%a4),%a1
	move.l %a1,4(%a4)
	clr.l 124(%a4)
	move.l 44(%a4),%a2
	move.l 10(%fp),%a1
	move.w 8(%fp),%d0
	lea (128,%a4),%a0
	jbsr (%a2)
	jbsr CLIFirstPass
.L6:
	move.l 8(%a4),%a0
	.word _F_LINE_RAM_CALL+0x1A
	move.l 12(%a4),%a0
	.word _F_LINE_RAM_CALL+0x1A
	move.w %d3,%d0
.L5:
	movm.l -168(%fp),#0x2c08
	unlk %fp
	rts
#14#

Bon, j'ai toujours un "Unknown error" de PedroM au boot, faut que je fasse un test case et que je vosi où ça déconne.

edit -> bon, a priori et comme prévu, le unknown error se trouve entre la chaise et l'écran.
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Awwww, un problème de clavier ? tsss
grin
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Faut activer aussi USE_FLINE_ROM_CALLS. smile
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
Yep, c'est fait merci. J'ai recompilé depuis une copie fraiche de git, et ça fonctionne nickel. Faut voir ce qu'il reste à faire pour -mpcrel.

(en fait, il n'y avait pas USE_FLINE_ROM_CALLS à cause d'un copier/coller foireux sous emacs, pi j'ai été embêté aussi parce que cet imbécile de patcher avait oublié de s'auto-recompiler avant d'auto-remplacer le patcher d'origine dans /usr/local/share. J'ai fait très fort aujourd'hui trioui)
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Bon, voici la doc de LibsExec :
35-kernel::LibsExec(char *lib_name, WORD function, BYTE version, ...)	(Preos only)

	The parameters are pushed on the stack.
	It calls the function without modifying the registers, and it pops its argument 
	during the call (LIB_DESCRIPTOR, function, and version).
	BYTE doesn't follow the C convesion for char (Sorry). Uses macro instead.

	It relocs the library, calls the function and unreallocs the library.
	The parameters pushed on the stack are corrupted.
	If there is an error, the parameter 'lib_name' equals zero after the call.
On fait comment pour exprimer la dernière phrase en C, si tant est que ce soit possible ? cheeky
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
lib_name= null_ptr ? Sauf erreur ça doit mettre à 0 le pointeur sur la pile ?
(Pour tester s'il y a eu une erreur au retour en C, contre, je ne sais pas trop grin)
Du point de vue de LibsExec, oui, mais du point de vue du programme qui appelle LibsExec ? Il faut lire (sp).l en fait.
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Peut-être un truc du genre de :

kernel::libsExec("huhu", ...) ;

bool error ;
{
   char* dummy ;
   error= dummy == null_ptr ;
}
if ( error ) {
   throw up ;
}

?
Bien vu, mais c'est gore, et sûrement pas garanti grin
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Oh oui ça l'est (gore grin), mais je doute que tu puisses faire beaucoup mieux en C vu la consigne (sinon un asm{} ?)
À la rigueur tu peux faire une macro ou une fonction wrapper, ça évitera que quelqu'un intercale du code entre l'appel et la lecture de la pile cheeky
D'ailleurs il faut déclarer le bool avant, sinon SP ne pointe pas où il faut trinon (enfin, quoi que... pas sûr de comment est gérée la portée une fois compilé en asm, la seconde version est sans doute plus sûre)
bool error ;
kernel::libsExec("huhu", ...) ;
{
   char* dummy ;
   error= dummy == null_ptr ;
}
if ( error ) {
   throw up ;
}
Ce n'est pas conforme à la convention d'appel C, tu ne peux pas utiliser ça sans un wrapper (ce qui est problématique à cause des varargs) ou un bidouillage au patcher.

Tu peux par exemple rajouter quelque chose comme:
 tst.l (%sp)
 bne.s 0f
 .word _A_LINE+850  | ER_PRGM_NOT_FOUND
0:
dans le patcher (ce qui permet d'utiliser TRY).
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
Commande call : PpHd appelé(e) sur ce topic

A moins que tu nous fasses une splendide interface pour le C ? cheeky

(Merci quand même, Kevin hehe)
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Comme a dit Kevin, cette fonction n'est pas faite pour le C. J'ai pas mieux que la solution de Kevin (ou au lieu de faire un throw, stocker la valeur dans une variable globale).
Bah, tu pourrais proposer un kernel::LibsExecThrow (mais tu risques de devoir copier-coller presque toute la fonction).
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
Moué... Et si la fonction appelée est censé lever une exception en cas de problème ?
Le errCode permet de distinguer, sauf si le code d'erreur a le malheur de correspondre.
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
Bref, ça reste compliqué de toute façon. J'ai fait autrement, je m'en passe. smile
Merci pour tout. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
yop,

Mes soucis sont maintenant réglés avec les ramcalls en tant que fonction.
Par contre, quand je fais ça :
const char* GetSystemDir(void)
{
    return kernel_SystemDir;
}
Le code généré est celui-ci :
GetSystemDir:
        lea _RAM_CALL_2F,%a0
        rts
Ce qui est parfaitement juste en soi, mais comment le patcher ? Détecter le lea et le virer ? C'est pas un peu bourrin quand même ? grin
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Bah, je ferais l'inverse (garder la variable comme interface et utiliser un #define pour en faire un appel de fonction si USE_FLINE_RAM_CALLS), cf. ./25.
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
Ah ben oui c'est vrai, merci bien. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Est-ce que tigcc4ti comprend __attribute__ ((noreturn)) ?
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Oui. (Enfin, je peux te dire que TIGCC le comprend, pas si GCC4TI l'a cassé ou non. wink)
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
Ok, merci. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Mais putaing gcc :/
Comment faire pour compiler ça :
    short result;
    do {
        result = PARSE_CMDLINE(&CMDLINE, g, FirstPassSwitches,
                               DummyCallback,
                               SwitchFlags,
                               SwitchHelp,
                               SwitchVersion,
                               SwitchSwap,
                               SwitchConfig,
                               SwitchTrace,
                               SwitchVerbose);
        if (result == PDTLIB_EMPTY_SWITCH) {
            FPRINTF(STDERR, "blabla1\n");
            longjmp(SETJMP_BUF, ERROR_EMPTY_SWITCH);
        }

        #ifndef NDEBUG
        if ((result == PDTLIB_PARSING_STOPPED) || (result == PDTLIB_WRONG_RETURN_VALUE)) {
            FPRINTF(STDERR, "blabla2\n", GET_CURRENT_ARG(&CMDLINE));
            longjmp(SETJMP_BUF, ERROR_WRONG_RETURN_VALUE);
        }
        #endif // NDEBUG

    } while (result != PDTLIB_END_OF_PARSING);
en ça :
CLIFirstPass:
.L13:
        pea SwitchVerbose
        pea SwitchTrace
        pea SwitchConfig
        pea SwitchSwap
        pea SwitchVersion
        pea SwitchHelp
        pea SwitchFlags
        pea DummyCallback
        pea FirstPassSwitches
        move.l %a4,-(%sp)
        pea 146(%a4)
        move.l 54(%a4),%a0
        jbsr (%a0)
        lea (44,%sp),%sp
        cmp.w #3,%d0
        jbne .L4
        jbra .L16
.L15:
        pea SwitchVerbose
        pea SwitchTrace
        pea SwitchConfig
        pea SwitchSwap
        pea SwitchVersion
        pea SwitchHelp
        pea SwitchFlags
        pea DummyCallback
        pea FirstPassSwitches
        move.l %a4,-(%sp)
        pea 146(%a4)
        move.l 54(%a4),%a0
        jbsr (%a0)
        lea (44,%sp),%sp
        cmp.w #3,%d0
        jbne .L4
.L16:
        pea .LC0
        move.l 78(%a4),-(%sp)
        move.l 82(%a4),%a0
        jbsr (%a0)
        move.w #7,-(%sp)
        pea 90(%a4)
        .word _F_LINE+0x267
        lea (14,%sp),%sp
        jbra .L13
.L4:
        tst.w %d0
        jbne .L15
        rts
        .section        .data.FirstPassSwitches,"d"
FirstPassSwitches:
        .ascii "fflags\0hhelp\0Vversion\0\0swap\0gconfig\0ttrace\0vverbose\0\0\0"
C'est dingue quand même fou
Au passage, il se peut qu'il y ait deux relocs absolus là-dedans, si ça vous saute aux yeux faites-moi signe, perso j'en vois pas (si le linker fait bien son boulot évidemment)
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !