[SDK Graph 85] Les syscalls
Posté le 16/06/2009 03:59
Je voudrais vous parler du travail d'
Andreas Bertheussen (neurOn sur casiokingdom) et
Simon Lothar (SimLo).
Ils ont étudié le système d'exploitation de la Graph 85, et ont trouvé le moyen d'appeler de nombreuses fonctions incluses dans le système (ce qu'il appellent
syscall en anglais).
Ils ont fait une documentation que je vous recommande fortement :
http://downloads.sourceforge.net/fxsdk/fxreverse-docs-1.pdf
Tous les syscalls ne sont pas référencés dans cette doc, mais je vous ai fait une liste de ceux que j'ai utilisé ainsi que ceux de la doc (en fichier joint)
Dans le fichier joint il y a :
-
fxreverse-doc-1.pdf : La doc de neurOn et SimLo
-
syscall.src : un fichier asm contenant de nombreux syscalls
-
syscall.h : un fichier contenant les headers de tous les syscalls déclarés dans syscall.src, ainsi qu'une aide (en français) pour chacun d'entre eux (pratique pour les anglophobes que la doc repousse)
-
main.c : le fichier main d'un petit addin de démonstration des syscalls
-
SYSCALL.G1A : l'addin de démonstration en question.
Cet addin permet de lancer n'importe quelle application de la calculatrice. Il y a une liste des applications système comme RUN ou PRGM, et on peut aussi choisir une autre application (un addin par exemple) en entrant un numéro (0 pour RUN, 1 pour STAT, etc). Attention, le syscall StartAnyApp ne fonctionne pas sur l'émulateur.
Dans ce programme j'utilise aussi les syscalls pour gérer le curseur (on peut le faire clignoter, et lui mettre les style SHIFT ou ALPHA comme dans RUN).
VRam_Base est un syscall très utile pour les fonctions de dessins, il donne l'adresse de la VRAM quelque soit l'OS et fonctionne aussi sur l'émulateur.
Tient j'ai oublié de préciser, ces fonctions ne prennent pas de place dans votre addin, puisqu'elles sont dans le système d'exploitation.
EDIT 2012
Une documentation bien plus complète est maintenant disponible, elle rassemble non seulement les syscalls de la Prizm et de la G85 (beaucoup plus que l'ancienne doc) mais aussi des techniques et des bouts de codes utiles.
Téléchargez-la :
fx_calculators_SuperH_based.chm
Fichier joint
Citer : Posté le 24/04/2012 17:05 | #
je déterre, mais comment initialiser un syscall ? Je veut dire comment creer une fonction l'appelant ?
Citer : Posté le 24/04/2012 19:00 | #
- SYSCALL.G1A : l'addin de démonstration en question
Citer : Posté le 24/04/2012 19:01 | #
Le mieux est de le faire en asm, tel que c'est fait dans le fichier d'exemple du topic.
SimLo avait également proposé un code C :
int (*SysCall)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
JMP @R2
MOV.L @R15,R0
.word 0x0000
.long 0x80010070
Citer : Posté le 13/01/2013 19:10 | #
J'ai compris ton code pierrotll mais je ne comprends pas un truc :
Quand je fais ceci :
static int (*SysCall)(int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
int time_getTicks()
{
return (*SysCall)(0, 0, 0, 0, 0x3B);
}
int Keyboard_PRGM_GetKey();
{
return (*SysCall)(0, 0, 0, 0, 0x6C4);
}
Eh bien la premiere me renvoie bien le nombre de ticks de la RTC, mais la seconde ne me renvoie pas de pointer vers un buffer CBD (ce qu'elle est sensée faire) mais une erreur : TLB ERROR!! et elle plante à 200%
Ajouté le 13/01/2013 à 19:12 :
PS : désoler de deterrer mais je suis en détresse la D:
Citer : Posté le 13/01/2013 19:23 | #
c'est pas reellement du deterrage, c'est aussi un topic d'aide aux syscall
envie de plonger dans la mer pour ramasser des tresors? => ballon sea
envie de sauver l'univers dans un jeu avec une longue durée de vie? => saviors of the future
un add-in addictif avec plein de secret et de trophées => evasion survival
un shmup bien dur et sadique => saviors 2
merci a tout le monde pour son soutien
zelda prizm de smashmaster (en esperant qu'il puisse le finir)
les tests de marmotti
un RPG de dark storm
(dont je connais le nom, mais pas vous )Arcuz !Citer : Posté le 13/01/2013 20:18 | #
ouais bon... en attendant de l'aide je continue mes recherches et apparemment la fonction renvoie un pointeur vers un buffer de 12 octets, donc j'ai fait ça :
static int (*SysCall)(int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
int time_getTicks()
{
return (*SysCall)(0, 0, 0, 0, 0x3B);
}
void Keyboard_PRGM_GetKey(unsigned char* pointer)
{
*pointer = (*SysCall)(0, 0, 0, 0, 0x6C4);
}
int PRGM_GetKey()
{
unsigned char buffer[12];
Keyboard_PRGM_GetKey( &buffer );
return ( buffer[1] & 0x0F ) * 10 + ( ( buffer[2] & 0xF0 ) >> 4 );
}
Citer : Posté le 13/01/2013 22:53 | #
Oula, non. Le syscall Keyboard_PRGM_GetKey prend en paramètre un buffer de 12 octets (et non pas 4 zéros) et retourne 1 ou 0 (si AC/ON est enfoncée)
Cf la doc : http://www.casiopeia.net/forum/downloads.php?view=detail&df_id=72
Citer : Posté le 14/01/2013 12:52 | #
Un buffer direct ou bien un pointeur vers un buffer?
Et je le mets en R4, R5, R6, ou R7? Desolé j'ai lu la doc encore et encore mais j'y arrive pas ....
Citer : Posté le 14/01/2013 21:47 | #
Le code présent dans la doc :
unsigned char buffer[12];
Keyboard_PRGM_GetKey( buffer );
return ( buffer[1] & 0x0F ) * 10 + ( ( buffer[2] & 0xF0 ) >> 4 );
}
Si tu veux déclarer le syscall en C, tu peux l'écrire ainsi :
static int (*SysCall)(int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
int Keyboard_PRGM_GetKey(unsigned char* pointer)
{
return (*SysCall)(pointer, 0, 0, 0, 0x6C4);
}
Mais en général il est préférable de déclarer ses syscalls en asm, le code C est une bidouille pas très propre.
Citer : Posté le 15/01/2013 01:12 | #
Merci beaucoup! en lisant la doc j'avais compris qu'il fallait donner un pointeur vers un buffer en paramètre mais j'avais pas bien compris ou est ce que je le récupérais! grâce à ton exemple j'ai compris! j'ai pas mon Pc la mais je vais tester ce syscall aussi tôt que possible! et merci encore
Ajouté le 15/01/2013 à 01:16 :
PS: je déclare mes syscalls en c pour le moment parce que j\'ai pas encore jeté un œil à l\'assembleur pour les super h. mais il me semble qu\'on a du code compilé dans l\'array, donc à priori une fois que c\'est passé dans la moulinette du compilateur la calto y voit que du feu je me trompe?
Ajouté le 30/01/2013 à 21:59 :
Bon alors j\'ai testé ce syscal et il ne marche pas! ca ne compile pas... Pour etre au plus pres posible de la doc j\'ai fait ca :
unsigned char hnibble:4;
unsigned char lnibble:4;
} TBCDbyte;
typedef struct{
unsigned short exponent:12;
unsigned short mantissa0:4;
TBCDbyte mantissa[7];
char flags;
short info;
} TBCDvalue;
//SYSCALLS
int temp1;
static int SysCallCode[] = {0xD201422B,0x60F20000,0x80010070};
static int (*SysCall)(int* R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
int time_getTicks()
{
return (*SysCall)(0, 0, 0, 0, 0x3B);
}
int Keyboard_PRGM_GetKey(TBCDvalue*pointer)
{
return (*SysCall)(*pointer, 0, 0, 0, 0x6C4);
}
int PRGM_GetKey()
{
TBCDvalue buffer;
Keyboard_PRGM_GetKey( &buffer );
return ( buffer.mantissa0 * 10 + buffer.mantissa[0].hnibble );
}
C\'est pour utiliser exactement la structure demandée cette fois ca compile, mais j\'ai une TLB error encore.... pfff je laisse tomber cette sycall.
Citer : Posté le 31/01/2013 19:53 | #
Selon la doc, le syscall 0x6C4 (Keyboard_PRGM_GetKey) demande un pointeur sur une structure TBCDvalue. Toi tu lui envoies une structure.
Si tu me demandais une adresse et que je te mettais une maison entière entre les mains, toi aussi tu dirais System error
Rappel sur les pointeurs :
Déclaration avec une étoile : int *p;
Ensuite :
- p => adresse
- *p => donnée pointée
Donc :
{
return (*SysCall)(pointer, 0, 0, 0, 0x6C4);
}
Ajouté le 31/01/2013 à 19:55 :
Et je m’aperçois que c\'est déjà ce que j\'avais dit dans mon précédent post.
Citer : Posté le 01/02/2013 15:02 | #
Oui.... mais ca compile pas quand j'ecris ca.... il me dit impossible de convertir le parametre 1 on un truc du genre...
Citer : Posté le 01/02/2013 19:34 | #
Oui, parce que dans la déclaration de Syscall tu as précisé des types de paramètres qui ne correspondent pas. Tu peux faire un cast en int ou en void*, mais le plus propre reste d'utiliser un fichier asm pour les syscalls.
Citer : Posté le 02/02/2013 16:40 | #
Ben c'est bien un pointeur int* R4, non? Je comprends tes explication, par contre je comprends pas pourquoi mon code est faux.... Si j'etais un compilateur pour fx, ca passerait sans probleme
Citer : Posté le 02/02/2013 17:36 | #
Un pointeur sur int est considéré différend d'un pointeurs sur autre chose, et c'est bien normal.
Citer : Posté le 17/02/2015 00:06 | #
Le nouveau lien est mort ...