./1
- Posté le 27/08/2010 à 21:57 Membre depuis le 18/06/2001, 30216 messages
yop,


J'ai déjà discuté du sujet avec Lionel, mais ce que je voudrais semble assez balaise à réaliser de manière fiable. Je m'explique.

Le but est d'écrire du C sans relogement, et comprenant pourtant :
- des romcalls
- des ramcalls
- des appels à ram_throw (utilisation de ce header : http://www.yaronet.com/posts.php?sl=&s=123645&p=1&h=8#8 )

Pour les romcalls, tigcc sait faire ça. Reste le problème des ramcalls.
En assembleur, j'appelle les ramcalls de cette manière :
 pea     arg1
move.w arg2,-(sp)
move.b #3,d0
dc.w $F012
addq.l #6,sp

Le truc, c'est que je n'ai pas la moindre idée de comment écrire ça en C. Le dc.w passe encore, mais forcer le push d'un argument, on fait comment ? Et le pop ?
Faut tout se fader à chaque fois en assembleur inline ?

Mon but est justement de passer au C pour gagner en facilité/rapidité, et donc de ne plus me taper d'asm à la main...

Comment faire ?

Question ultime : y a-t-il un/des switches garantissant aucun relogement dans le binaire ? Ou faut-il s'attendre à devoir patcher les fichiers .s après compilation ?


Merci d'avance. si je savais faire ça, il y a longtemps que je serais passé au C pour mes projets.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./2
- Posté le 27/08/2010 à 22:18 Membre depuis le 10/06/2001, 30596 messages
Peut-être -mno-explicit-relocs ?
Pour le reste : une macro, à la rigueur ? C'est pas portable, mais de toute manière, tu ne porteras jamais ton programme, donc autant passer du temps sur le reste hehe
./3
- Posté le 27/08/2010 à 22:51 Membre depuis le 18/06/2001, 30216 messages
Suis-je bien sûr que ma macro construire à coup de asm() ne sera pas détruite par le compilo ou le linker ? Il interprête ça comment l'asm inline ? Typiquement pour lui, un dc.w $F0xy ne veut rien dire, ça ne lui posera pas de problème de l'insérer dans le code ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./4
- Posté le 28/08/2010 à 00:52 Membre depuis le 10/06/2001, 35018 messages
Ce n'est pas évident de faire ce genre de choses en C, c'est bien pour ça qu'on a des tas de bidouilles pour les ROM_CALLs F-Line en C.
avatar Mes 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é
./5
- Posté le 28/08/2010 à 01:10 Membre depuis le 18/06/2001, 30216 messages
Ah merde. C'est dur de faire une macro pour ça ? Le compilateur ou le linker risquent de me péter quelque chose si j'arrive à écrire les macros ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./6
- Posté le 28/08/2010 à 14:02 Membre depuis le 10/06/2001, 30596 messages
Je ne pense pas non, normalement avec de l'asm inline il ne devrait rien toucher.

Un truc du genre :
#define RAM_CALL asm { dc.w #$cafe }


(enfin je n'ai plus en tête la syntaxe pour l'asm inline, mais tu vois l'idée, quoi... cheeky)
./7
- Posté le 28/08/2010 à 14:35 Membre depuis le 18/06/2001, 30216 messages
Oué, pareil pour la syntaxe, mais ça ressemblerait plus à ça : #define truc asm(".word 0xabcd");
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./8
- Posté le 28/08/2010 à 15:13 Membre depuis le 28/10/2001, 7573 messages
Une possibilité que j'ai suggérée à Martial est l'utilisation des RAM_CALLs et RAM_throw F-Line comme des fonctions C tout à fait normales, puis le post-processing du source ASM produit par le compilo, pour remplacer le jbsr/jsr par un dc.w / .word.
La compilation en plusieurs étapes, il a l'habitude, ça n'est pas ça qui va le déranger.
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
./9
- Posté le 28/08/2010 à 15:31 Membre depuis le 18/06/2001, 30216 messages
Ouep, c'est sûr. Je me demandais juste s'il y avait plus simple grin

Mais ta solution reste parfaitement valable. En fait, j'aurais juste du C ou du C++ à écrire pour post-processer. Un langage de script serait mieux me dit-on, mais je sais pas faire embarrassed
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 28/08/2010 à 15:40 Membre depuis le 18/06/2001, 30216 messages
Et euh... y a-t-il un moyen pour copier du code dans la pile ? En fait, en asm, je rassemble les pointeurs de libcall/syscall dont j'ai besoin dans la pile, et je les fait précéder à tout hasard de $4EF9 embarrassed

Ca ressemble à ça :
pile améliorée
\RegTable:						; WARNING: will fail using functions > lib@00FF (should use word sized offsets)
moveq.l #0,d0
\RegLoop:
move.b (a1)+,d0
bne.s \Continue
tst.b (a1)
bne.s \Continue ; End of table: dc.b 0,0
rts
\Continue:
pea (a4)
RAMC RAM_kernel::LibsPtr
addq.l #4,sp
moveq.l #0,d0 ; PreOS bug: LibsPtr destroys d0
move.b (a2)+,d0
move.w #$4EF9,0(a6,d0.w)
move.l a0,2(a6,d0.w)
bra.s \RegLoop

avec les offsets qui vont bien pour obtenir les numéros des libcall/syscall et l'offset de leur pointeur dans la pile :
superbes tables
ButillibCallsTable:
dc.b BUTILLIB_InitCmdLine
dc.b BUTILLIB_GetCurrentArgPtr
dc.b BUTILLIB_GetNextArgPtr
dc.b BUTILLIB_IsArgSwitch
dc.b BUTILLIB_IsNextArg
dc.b BUTILLIB_GetFilePtr
dc.b BUTILLIB_CheckFileType
dc.b BUTILLIB_ExecSwitchRoutine
dc.b BUTILLIB_SkipDummyLines
dc.b BUTILLIB_SkipSpaces
dc.b BUTILLIB_SkipLine
dc.b BUTILLIB_GetFileHandle
dc.b BUTILLIB_GetPrevArgPtr
dc.b BUTILLIB_AdvanceToChar
dc.b 0,0
ButillibCallsOffsets:
dc.b INIT_CMDLINE
dc.b GET_CURRENT_ARG_PTR
dc.b GET_NEXT_ARG_PTR
dc.b IS_ARG_SWITCH
dc.b IS_NEXT_ARG
dc.b GET_FILE_PTR
dc.b CHECK_FILE_TYPE
dc.b EXEC_SWITCH_ROUTINE
dc.b SKIP_DUMMY_LINES
dc.b SKIP_SPACES
dc.b SKIP_LINE
dc.b GET_FILE_HANDLE
dc.b GET_PREV_ARG_PTR
dc.b ADVANCE_TO_CHAR

PedroMCallsTable:
dc.b PEDROM_stdin
dc.b PEDROM_printf
dc.b PEDROM_fprintf
dc.b 0,0
PedroMCallsOffsets:
dc.b STDERR
dc.b PRINTF
dc.b FPRINTF

Comme ça avec des appels en jsr non-relogés (et a6 pointeur de stack frame permanent) :
juuuuummmmmmp
		lea	CMDLINE(a6),a0				; Get CMDLINE*
jsr GET_NEXT_ARG_PTR(a6) ; Skip current arg
lea CMDLINE(a6),a0 ; Get CMDLINE*
jsr IS_ARG_SWITCH(a6) ; Check if the arg is an switch

Vala, ça me fait tout ce que je veux sans m'embêter. On saute dans la pile et ça rebondit vers la bonne fonction de dll ou de pedrom.

Mais... comment on fait ça en C ? grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 28/08/2010 à 22:35 Membre depuis le 16/06/2001, 60001 messages
on écrit la fonction trampoline() en asm inline? grin
- Posté le 29/08/2010 à 01:23 Membre depuis le 18/06/2001, 30216 messages
Oué, c'est exactemetn ça. En fait, c'est le contenu de cette fonction, le fait d'exécuter la struct {unsigned short opcode = 0x4EF9; void (*);} trampoline; qui risque d'être un peu chaud grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 29/08/2010 à 01:25 Membre depuis le 18/06/2001, 30216 messages
Non, je crois que le plus simple est la solution de Lionel, compiler sans faire d'objet ni linker, patcher les fichiers assembleur, et enfin assembler le résultat.
Ca doit pas être dur, c'est juste du parsing de texte, en C c'est très faisable embarrassed

(merde, je voulais éditer)
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 29/08/2010 à 01:34 Membre depuis le 27/04/2006, 43640 messages
Pourquoi ne pas proposer un patch pour GCC4TI qui intégrerait ça ?
Tu pourrais même appeler le switch pour l'activer "-folco" embarrassed
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
- Posté le 29/08/2010 à 02:37 Membre depuis le 10/06/2001, 35018 messages
C'est d'ailleurs comme ça que fonctionnent les ROM_CALLs en F-Line, aussi…
avatar Mes 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é
- Posté le 29/08/2010 à 08:26 Membre depuis le 28/10/2001, 7573 messages
./13: un script Perl qui lit le fichier en entier en un seul coup et une forêt de s///g ressemblerait à:
use strict;
use File::Path;

# Files not explicitely closed on exit, but Perl does it for us.
package main;
my $file;
my $file2;
my $filecontents;

$file = $ARGV[0];
$file2 = $ARGV[1];

# Sanitize input file names - optional.

# Slurp input file !
open(INFILE,"$file") or die "Can't open $file: $!";
read(INFILE, $filecontents, -s INFILE);
close INFILE;

$filecontents =~ s/jbsr\s+rename/.word 0xFnnn/g;
$filecontents =~ s/jbsr\s+unlink/.word 0xFmmm/g;
...

print $filecontents; # sur stdout
# ou bien
# open(OUTFILE, ">$file2") or die "Can't open $file2: $!";
# print OUTFILE, $filecontents;
# close OUTFILE;


En C/C++, c'est plus long à développer grin
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
- Posté le 29/08/2010 à 08:46 Membre depuis le 18/06/2001, 30216 messages
Zerosquare (./14) :
Pourquoi ne pas proposer un patch pour GCC4TI qui intégrerait ça ?

Pas con, mais faudrait que je me penche sur la structure de la bête sad
Zerosquare (./14) :
Tu pourrais même appeler le switch pour l'activer "-folco" /v31/gfx/s/redface.gif

rotfllove
Kevin Kofler (./15) :
C'est d'ailleurs comme ça que fonctionnent les ROM_CALLs en F-Line, aussi…

eek Je pensais que c'était moins "bricolage" que ça. Mais bon tant mieux, ça montre que ça marche.
Lionel Debroux (./16) :
un script Perl qui lit le fichier en entier en un seul coup et une forêt de s///g ressemblerait à:

Je ne connais pas Perl grin En C c'est évidemment plus long, mais pas sorcier non plus je pense ^^
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 29/08/2010 à 08:53 Membre depuis le 28/10/2001, 7573 messages
Je sais que tu ne connais pas Perl, c'est pour ça que je t'ai montré le corps d'un script qui ferait le boulot smile
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
- Posté le 29/08/2010 à 08:53 Membre depuis le 10/06/2001, 35018 messages
Lionel Debroux (./16) :
En C/C++, c'est plus long à développer grin

Pas vraiment (juste un petit peu), je dirais plutôt que c'est assez simple, et on peut se baser sur http://tigcc-linux.cvs.sourceforge.net/viewvc/tigcc-linux/tigcc-linux/sources/patcher/src/.

C'est aussi le logiciel à modifier pour intégrer ça à TIGCC/*nix (ou un fork, il y a peu de chances que ce soit accepté dans la version officielle!), TIGCC/W32 utilise actuellement du code Delphi pour faire la même chose.
avatar Mes 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é
- Posté le 29/08/2010 à 09:05 Membre depuis le 18/06/2001, 30216 messages
Ok, merci à vous deux.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 29/08/2010 à 16:57 Membre depuis le 18/06/2001, 30216 messages
Bon, je reprends, déjà merci pour tout. Le parsing de source me semble le plus adapté dans mon cas. Ca résoud donc le problème des ramcalls.



C'est possible d'écrire ça en C ?
butillib@000d:
subq.w #8,ARGIT(a0)

butillib@0002:
addq.w #4,ARGIT(a0)

butillib@0009:
move.w ARGIT(a0),d0
movea.l ARGV(a0),a0
movea.l 0(a0,d0.w),a0
rts

Ca revient à 3 exports dans la même fonction... A mon avis c'est mort, mais sait-on jamais cheeky
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 30/08/2010 à 14:23 Membre depuis le 10/06/2001, 35018 messages
Ce n'est pas possible, du moins pas sans des hacks affreux qui ont de fortes chances de ne pas avoir l'effet voulu.
avatar Mes 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é
- Posté le 30/08/2010 à 14:48 Membre depuis le 18/06/2001, 30216 messages
Je m'en doutais grin

Est-il alors vraiment impossible d'avoir du code C aussi optimal que de l'assembleur ? sad
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 30/08/2010 à 14:54 Membre depuis le 28/10/2001, 7573 messages
Pour un processeur comme le 68000 et dans certaines situations, oui, sans aucun doute possible.
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
- Posté le 30/08/2010 à 14:58 Membre depuis le 10/06/2001, 30596 messages
butillib@000d()
{
butillib@internal(d)
}


butillib@0002()
{
butillib@internal(2)
}

butillib@0009()
{
butillib@internal(9)
}



butillib@internal( enum e )
{
switch ( e ) {
case 000d:
subq.w #8,ARGIT(a0)
case 0002:
addq.w #4,ARGIT(a0)
case 0009:
move.w ARGIT(a0),d0
movea.l ARGV(a0),a0
movea.l 0(a0,d0.w),a0
default: erreur quelconque...
}
}



C'est pas vraiment la même chose, mais c'est pas loin.
- Posté le 30/08/2010 à 15:23 Membre depuis le 18/06/2001, 30216 messages
Ouep... Mais il y a un passage d'argument à faire. Je ne pense pas pouvoir faire mieux en C de toute façon, c'est clair...
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 30/08/2010 à 15:27 Membre depuis le 16/06/2001, 60001 messages
bah après ton assembleur, tu codes un compilo embarrassed

ou tu améliores gtc embarrassed
- Posté le 30/08/2010 à 15:58 Membre depuis le 18/06/2001, 30216 messages
squalyl (./27) :
après ton assembleur

gni


hem hem... pardon embarrassed
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 30/08/2010 à 18:49 Membre depuis le 18/06/2001, 30216 messages
Euh... j'arrive pas à écrire "pointeur sur une liste de pointeurs de fonction" dans un proto ... sad

Pointeur de fonction : void (*Ptr)()
Liste de pointeurs : (void (*Ptr)())[] => marche pas, expected declaration specifier
Pointeur sur pointeur : *(void (*Ptr)()) => marche pas, idem

Et des paquets de variantes, genre :
un pointeur de fonction : (*)
un pointeur de pointeur de fonction (*)*

Ca merdouille dans tous les sens grin
Ca s'exprime comment ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 30/08/2010 à 18:56 Membre depuis le 28/10/2001, 7573 messages
D'après la doc de TIGCC/GCC4TI,
int (*x[5])(); An array of pointers to a function which returns an integer

La version avec une taille indéfinie de tableau de cette écriture doit être
int (**x)()

Et un pointeur sur ce truc doit être
int (***x)()


(non testé)
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.