Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » [SDK Graph 85] Les syscalls
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

[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


Dark stormHors ligneMembre d'honneurPoints: 10765 Défis: 174 Message

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 ?
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Páranÿe quetë Quendya
LoulouxHors ligneAncien administrateurPoints: 7035 Défis: 61 Message

Citer : Posté le 24/04/2012 19:00 | #


Pierrotll a écrit :
- SYSCALL.G1A : l'addin de démonstration en question
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

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 SysCallCode[] = {0xD201422B,0x60F20000,0x80010070};
int (*SysCall)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
C'est tout de même un peu trash. En fait, le tableau SysCallCode contient du code compilé :
MOV.L @(1,PC),R2
JMP @R2
MOV.L @R15,R0
.word 0x0000
.long 0x80010070
Et SysCall est un pointeur de fonction qui pointe sur ce code.
Earth75Hors ligneMembrePoints: 53 Défis: 0 Message

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 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();
{
      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:
DodormeurHors ligneAncien rédacteurPoints: 3928 Défis: 82 Message

Citer : Posté le 13/01/2013 19:23 | #


c'est pas reellement du deterrage, c'est aussi un topic d'aide aux syscall
Pokemon !!!!!! => pokemon stadium/battle

mes meilleurs jeux
Cliquer pour enrouler
un jeu avec des niveaux de gris mais compatible SH4 (mais en monochrome pour les SH4) => bomberman
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

projets
Cliquer pour enrouler

pokemon
Cliquer pour enrouler



encodage des données de combat (sprite, attaques et nom)
   100%

systeme de combat
   100%

encodage des données de pokemon (niveau d'apprentisage et evolution)
   100%


moteur de la carte
   50%

level design
   1%

finition de pokemon jade
   42%

merci a tout le monde pour son soutien


projets que je soutiens
Cliquer pour enrouler
minecraft de limachi
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 !
Earth75Hors ligneMembrePoints: 53 Défis: 0 Message

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 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);
}

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 );
}
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

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
Earth75Hors ligneMembrePoints: 53 Défis: 0 Message

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 ....
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

Citer : Posté le 14/01/2013 21:47 | #


Le code présent dans la doc :
int PRGM_GetKey(){
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 SysCallCode[] = {0xD201422B,0x60F20000,0x80010070};
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.
Earth75Hors ligneMembrePoints: 53 Défis: 0 Message

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 :

typedef struct{
  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.
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

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 :
int Keyboard_PRGM_GetKey(TBCDvalue*pointer)
{
      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.
Earth75Hors ligneMembrePoints: 53 Défis: 0 Message

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...
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

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.
Earth75Hors ligneMembrePoints: 53 Défis: 0 Message

Citer : Posté le 02/02/2013 16:40 | #


static int (*SysCall)(int* R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;


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
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

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.
TheprogHors ligneMembrePoints: 1447 Défis: 20 Message

Citer : Posté le 17/02/2015 00:06 | #


Le nouveau lien est mort ...

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2019 | Il y a 50 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd