./1
- Posted On the 2009-11-12 at 02:04 pm Member since 2001-06-18, 30576 posts
yop,

J'aimerais savoir comment faire une lib dynamique en C. Dans la doc, il ya ça :
You can produce an external library file by defining the global symbol _library, i.e. by putting int _library in your program.

Ca veut dire que je mets "int _library;" quelque part et c'est bon ? C'est tout ?!?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./2
- Posted On the 2009-11-12 at 02:07 pm Member since 2001-06-10, 35205 posts
Oui. (Enfin, il faut aussi définir USE_KERNEL évidemment, cf. options du projet si tu utilises l'EDI.)
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é
./3
- Posted On the 2009-11-12 at 02:42 pm Member since 2001-06-18, 30576 posts
Ok, merci. happy
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./4
- Posted On the 2009-11-12 at 02:59 pm Member since 2003-08-28, 8213 posts
Genre tu fais du C.
avatar « Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »
./5
- Posted On the 2009-11-12 at 02:59 pm Member since 2001-06-18, 30576 posts
Ouais grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./6
- Posted On the 2009-11-12 at 03:00 pm Member since 2001-06-18, 30576 posts
On s'endort presque à utiliser genlib en C, tout est déjà fait. grin
truc
void gl_main()
{
while( 1 )
{
// Manage non-graphical part
switch( Task )
{
}

// Wait for real screen swapping
glaux_ready();

// Manage graphical part
switch( Task )
{
}

// Wait for synchro
glaux_synchro( 1 );
glaux_swap();
}

}
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./7
- Posted On the 2009-11-12 at 03:05 pm Member since 2001-06-18, 30576 posts
Tiens ben pendant que j'y suis, une question.

Si j'ai deux fonctions, A et B, sans "return", mais dans lesquelles elles s'appellent mutuellement, est-ce que le programme va empiler des adresses de retour sur la pile ?
ie en assembleur, j'aurais fait des bra entre les fonctions, pas des bsr.
Ca se gère comment en C ? tout seul j'espère ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./8
- Posted On the 2009-11-12 at 03:09 pm - Edited by Kevin Kofler On the 2009-11-12 at 03:10 pm Member since 2001-06-10, 35205 posts
Ça va générer le bordel sur la pile effectivement, sauf dans les cas où une optimisation tailcall est possible.

Il vaut mieux travailler avec des boucles ou des goto dans ce cas.
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é
./9
- Posted On the 2009-11-12 at 03:10 pm Member since 2001-10-28, 7580 posts
Si l'optimiseur de flot de contrôle de GCC 1) sait faire cette optimisation sur les fonctions qui s'appellement mutuellement (attention à la terminaison de la récursivité grin) et 2) arrive dans ton cas à déterminer qu'il peut faire cette optimisation, alors il la fera.
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
- Posted On the 2009-11-12 at 03:13 pm - Edited by squalyl On the 2009-11-12 at 03:25 pm Member since 2001-06-16, 60208 posts
(cross, réponse à martial)

non. ça va s'appeler récursivement et remplir la pile.

ce que tu veux faire ça s'appelle des threads/couroutines/tâches, faut deux piles différentes et utiliser un truc de taskswitch préemptif style je-sais-plus-le-nm-du-truc-de-ximoon

alternativement ça peut se faire assez simplement (sisi trioui) avec setjmp

https://www.unsads.com/scm/svn/squalyl/asi/systeme/P3S/test/switcher-ti68k/
user guest
pass guest

(je sais plus si c'est complet, je sais plus si ça marche, mais le principe y est. Dommage j'avais un truc encore plus simple que ça, je le retrouve plus sad )

edit: ah le voila

#include <stdio.h>
#include <setjmp.h>

/*
| context switch presque portable avec setjmp, longjmp
| pour comprendre setjmp et longjmp voir la doc :
| http://www-ensimag.imag.fr/cours/Systeme/setjmp.longjmp
|
*/

#define K 1024
#define TAILLE_PILE 4*K

int mem [TAILLE_PILE]; /* memoire pour la pile du processus 1 */
int * deb_mem;
int proc_actif = 0;
jmp_buf buf_processus[2];

/*----------------------------------------------------------------------------*/
void ctxsw(actif, elu) {
if (setjmp(buf_processus[actif]) == 0) {
proc_actif = elu;
longjmp(buf_processus[elu], 1);
}
}
/*----------------------------------------------------------------------------*/
int choix_elu() {
if (proc_actif == 0) return 1; else return 0;
}
/*----------------------------------------------------------------------------*/
void resched() {
int proc_elu;
proc_elu = choix_elu();
ctxsw(proc_actif, proc_elu);
}
/*----------------------------------------------------------------------------*/
/*
| code execute par les 2 processus
|
*/
void code_processus(char * mess) {
int i;
while(1) {
printf ("%s", mess);
resched(); /* changement de processus */
}
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int main() {
deb_mem = mem; /* on pourrait faire un malloc a la place */
/*
| ici c'est le processus 0 qui s'exécute avec la pile allouée au lancement du programme C
*/
if (setjmp(buf_processus[1]) == 0) {
#ifdef LINUX
/*
| Initialisation de la pile pour le processus 1 (petit bricolage specifique pour linux/i386)
*/
buf_processus[1][0].__jmpbuf[JB_SP] = deb_mem + TAILLE_PILE;
#else
#ifdef SOLARIS
/*
| Initialisation de la pile pour le processus 1
| (petit bricolage specifique pour Solaris/Sparc)
*/
buf_processus[1][1] = (int) deb_mem + TAILLE_PILE - 16;
#else
#error "use -DLINUX or -DSOLARIS"
#endif
#endif
printf ("Je suis le processus 0 et je pars dans la boucle\n");
code_processus("je pense\n");
} else {
printf ("Je suis le processus 1 et je pars dans la boucle\n");
code_processus(" donc tu es\n");
}
}
- Posted On the 2009-11-12 at 03:21 pm Member since 2001-06-10, 35205 posts
Pour la TI, le code spécifique à la plateforme, c'est:
buf_processus[1]->A7 = (unsigned long) deb_mem + TAILLE_PILE;

Mais ce hack est vraiment sick! (Enfin, mon Task Switcher contient pire que ça, hein.)
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é
- Posted On the 2009-11-12 at 03:23 pm Member since 2001-06-16, 60208 posts
oui ce hack est mégamoche mais franchement tu connais d'autres moyens? c'est toujours la même histoire non? allocation de l'espace mémoire du nouveau processus, et changement de SP/PC plus autres registres (bien entendu sur pc c'est carrément plus compliqué avec les mmu et etc). SetJmp n'est qu'un outil userspace pratique pour les besoins de la démo.

d'ailleurs pour avoir testé ça marche très bien sur 68k.
- Posted On the 2009-11-12 at 03:28 pm - Edited by Folco On the 2009-11-12 at 03:30 pm Member since 2001-06-18, 30576 posts
Kevin Kofler (./8) :
Ça va générer le bordel sur la pile effectivement, sauf dans les cas où une optimisation tailcall est possible.

Il vaut mieux travailler avec des boucles ou des goto dans ce cas.

Ok, je vais m'organiser autrement.
squalyl (./10) :
ce que tu veux faire ça s'appelle des threads/couroutines/tâches, faut deux piles différentes et utiliser un truc de taskswitch préemptif style je-sais-plus-le-nm-du-truc-de-ximoon

alternativement ça peut se faire assez simplement (sisi /v31/gfx/s3/trioui.gif ) avec setjmp

Hmm t'as vraiment pas plus simple trilove

Regarde à quel point j'en suis techniquement :
	char * Buffer[10] ;

sprintf( Buffer , "unmap%u" , Level );

J'aurais voulu savoir si c'est valide. Il va bien y avoir un 0 à la fin de "unmap%u" ? cheeky Ou dois-je écrire "unamp%u\0" ?

PS -> Ca fait bien deux octets un int sur TI ?

edit :
	sprintf( Buffer , "unmap%hu" , Level );
MapDesc = LibsBegin( Buffer , 0 );

Faut inclure quoi pour avoir les ramcalls ? J'ai inclus tigcclib.h, j'ai fait un #define USE_KERNEL, mais il veut pas de mon LibsBegin cry
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 03:29 pm Member since 2001-06-10, 35205 posts
squalyl (./12) :
oui ce hack est mégamoche mais franchement tu connais d'autres moyens?

L'autre moyen, c'est de faire une seule fonction avec des goto, voire une simple boucle si le fonctionnement est suffisamment régulier.
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é
- Posted On the 2009-11-12 at 03:32 pm Member since 2001-06-10, 35205 posts
Folco (./13) :
Regarde à quel point j'en suis techniquement :
	char * Buffer[10] ;

sprintf( Buffer , "unmap%u" , Level );

J'aurais voulu savoir si c'est valide.

Non. Un %u peut faire jusqu'à 5 caractères ("65535"), plus les 5 du "unmap" plus le \0, ça fait 11, donc ton buffer est trop petit.

Il va bien y avoir un 0 à la fin de "unmap%u" ? cheeky

Oui. Mais il faut le compter dans ta taille du buffer aussi!

Ou dois-je écrire "unamp%u\0" ?

Non.

PS -> Ca fait bien deux octets un int sur TI ?

Oui.
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é
- Posted On the 2009-11-12 at 03:42 pm Member since 2001-06-18, 30576 posts
Merci pour tout. smile
En fait, mon argument "Level" ne peut dépasser 3 caractères, donc ça ira. C'est pour construire un nom de fichier.


Par contre, j'ai un problème qui me gave bien, ça fait patrie des trucs du C qui ressemblent pour moi à une machinerie assez obscure :
J'inclus "genlib.h". Dans la doc de genlib, c'est écrit ça :
And you don’t need to include tigcclib since genlib.h do it for you.

Et apparemment, tigcclib ne connait pas LibsBegin.

Je vais donc pour inclure kernel.h de PreOS, header kernel pour le C. Mais dans le header, je trouve ça :
#if defined(NOSTUB) || defined(KERNEL) || defined(DOORS)
# error "kernel.h" must not be included with tigcclib.h
#endif

Et c'est con, parce que dedans, il y a les définitions des romcalls. sad

Comment faire alors ? PpHd, c'est quoi les règles de l'art en la matière ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 03:47 pm Member since 2003-08-28, 8213 posts
./7 Euh je ne comprends pas pourquoi squalyl te parle de tout ça… trifus
Si effectivement tes fonctions s’appellent de façon croisée et non conditionnelle (à l’extérieur d’un if) ton programme ne terminera pas (enfin au moment du stack overflow seulement grin ).
Pour résoudre ça le mieux est de faire des boucles, et le moins mieux est d’utiliser goto.

[edit] : un dernier truc : teste ton code toutes les 10 lignes. Évite d’écrire des pages et des pages sans même voir si ça compile ou sans même tester si la fonctionnalité ajoutée fonctionne comme prévu.
avatar « Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »
- Posted On the 2009-11-12 at 03:50 pm Member since 2001-06-18, 30576 posts
Merci pour les tips. Pour ce qui est de la compilation, t'inquiète pas, je suis tellement skillé que je suis obligé de tester à chaque ligne. trioui
C'est vrai qu'en assembleur, je peux écrire beaucoup sans relire ou tester, mais là c'est pas la peine. grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 03:52 pm Member since 2001-10-28, 7580 posts
Un "int" fait 2 octets sur TI-68k (sauf si tu actives une option à la con du compilo, auquel cas les fonctions de la famille *printf ne vont plus fonctionner correctement, parce qu'elles supposent qu'un int fait 2 octets grin), mais 4 sur la plupart des plate-formes actuelles. Utiliser "int" n'a pas que des avantages.
Tu peux utiliser "short", "unsigned short", "int16_t" ou "uint16_t" (les deux derniers sont dans le header <stdint.h>, qui est inclus par <inttypes.h>) si tu veux une variable 16 bits (.w), et "long", "unsigned long", "int32_t" ou "uint32_t" si tu veux une variable 32 bits.
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
- Posted On the 2009-11-12 at 04:21 pm Member since 2001-06-18, 30576 posts
Bon, j'ai résoudru le problème de la pile : main est un scheduler qui appelle la fonction qui va bien :
schedule
void gl_main()
{
while(1)
{
// Schedule tasks
switch( NextTask )
{
case TASK_EXIT:
return;
case TASK_INTRO:
LoadIntro();
break;
case TASK_GAME:
LoadGame();
break;
}
CurTask = NextTask ;
InfiniteLoop();
}
}

Et dans InfiniteLoop(), on fait un return si CurTask a été mis à 0 par la tâche en cours.

C'est bien. smile
Enfin presque, faut que je trouve un moyen de faire passer une valeur d'une fonction à une autre maintenant...
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 05:09 pm Member since 2001-06-18, 30576 posts
Tiens, j'avais pas vu ce warning, j'en reste confus, bien que je fasse sûrement une erreur :
Le proto de sprintf :
short sprintf (char *buffer, const char *format, ...);

Mon code :
	char * Buffer[ 10 ] ;
const char * Filename = "unmap%u" ;

sprintf( Buffer , Filename , Level );

Level est un int. J'ai ce ouarningue :
game.c:17: warning: passing argument 1 of '(<U9e70> = &_ROM_CALL_53)' from incompatible pointer type

Pourquoi ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 05:17 pm Member since 2002-06-13, 39607 posts
Parceque ton buffer, tel que déclaré, est un tableau de pointeurs vers des "char". Ce que sprintf attend c'est juste un tableau de char (donc au choix "char Buffer[10]" ou "char* Buffer" selon que tu veux du statique ou du dynamique).
avatar I invited your best friend the companion cube. Of course, he couldn't come because you murdered him.
------------------------------------------
Mirari² :: It offers what you want, not what you need
3l33t :: Relax, we understand j00 ^^
- Posted On the 2009-11-12 at 05:22 pm Member since 2001-06-18, 30576 posts
Ah, parce que un tableau est un pointeur, donc "char Buffer[10 ] est un pointeur. Merci ! smile
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 05:26 pm Member since 2003-08-28, 8213 posts
Disons plutôt que, après la déclaration :
char buffer[10];

On a :
« buffer » est un « char * »
« buffer[n] » est un « char »
avatar « Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »
- Posted On the 2009-11-12 at 05:34 pm Member since 2001-06-18, 30576 posts
Ok, merci pour ça. happy
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 07:03 pm Member since 2001-06-11, 19256 posts
Folco (./16) :
Merci pour tout. smile
En fait, mon argument "Level" ne peut dépasser 3 caractères, donc ça ira. C'est pour construire un nom de fichier.


Par contre, j'ai un problème qui me gave bien, ça fait patrie des trucs du C qui ressemblent pour moi à une machinerie assez obscure :
J'inclus "genlib.h". Dans la doc de genlib, c'est écrit ça :
And you don’t need to include tigcclib since genlib.h do it for you.

Et apparemment, tigcclib ne connait pas LibsBegin.

Je vais donc pour inclure kernel.h de PreOS, header kernel pour le C. Mais dans le header, je trouve ça :
#if defined(NOSTUB) || defined(KERNEL) || defined(DOORS)
# error "kernel.h" must not be included with tigcclib.h
#endif

Et c'est con, parce que dedans, il y a les définitions des romcalls. sad

Comment faire alors ? PpHd, c'est quoi les règles de l'art en la matière ?


#include "kernel.h"
#include "genlib.h"

doit marcher.
- Posted On the 2009-11-12 at 07:03 pm Member since 2001-06-11, 19256 posts
Folco (./6) :
On s'endort presque à utiliser genlib en C, tout est déjà fait. grin
truc
void gl_main()
{
while( 1 )
{
// Manage non-graphical part
switch( Task )
{
}

// Wait for real screen swapping
glaux_ready();

// Manage graphical part
switch( Task )
{
}

// Wait for synchro
glaux_synchro( 1 );
glaux_swap();
}

}


C'est fait pour!
- Posted On the 2009-11-12 at 07:37 pm - Edited by Folco On the 2009-11-12 at 08:23 pm Member since 2001-06-18, 30576 posts
Merci ! Mais j'ai fait un testcase minimal qui ressemble à ./27, et j'obtiens ça :
/opt/gcc4ti/lib/tigcc.a: Error: Unresolved reference to `__main'.

C'est vrai que les headers C, c'est compliqué avec cette manière de pouvoir dé-définir des symboles...

En plus, quand je compile avec "-Wa,-l", il me dit
1. Que j'ai encore de l'espace à gagner avec le switch -l de GAS !!
2. Que les ramcalls peuvent pas être relatifs (sans blague) et qu'il les passe en absolu.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posted On the 2009-11-12 at 08:15 pm Member since 2001-06-11, 19256 posts
Ajoute #define _main __main tout en haut avant le premier include.
- Posted On the 2009-11-12 at 08:20 pm Member since 2001-06-18, 30576 posts
Miracle, ça marche, bien joué. smile

Pour faire propre, ce #define doit aller où ?

edit -> je veux dire, dans quel header grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.