Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Idée de projet - add-in pour debug
YatisHors ligneMembrePoints: 337 Défis: 0 Message

Idée de projet - add-in pour debug

Posté le 28/05/2018 20:01

salut;
Je sais pas si vous programmez sur Casio mais si c’est le cas vous devez savoir à quel point programmer dessus c’est pratique: on programme un jeu, on le compile, on vérifie sur l’Émulateur si tout fonctionne, si tout fonctionne on le transfère sur la calto puis on peut transporter son jeu de partout.



Problématique
Si vous programmez un gros jeu il est possible que des petits bugs apparaissent APRÈS avoir compilé qui font planter la Casio.
Et pourtant le jeu fonctionnait sur l’Émulateur sauf que l’Émulateur ne sera jamais comme la console.
Et c’est là que ça devient méga chiant parce que, modifier un octet, compiler, connecter la calto et voir que ça ne fonctionne pas...on vient de perdre 5 minutes de notre vie à brasser de l’aire.
De plus si vos faites des jeux en multijoueur on ne peut pas vérifier via l’Émulateur, il faut donc tout se taper et c’est...long, trop long.



Idée
C’est pourquoi une idée m’est venue alors que j’écrivais la librairie “mySerail.h”.
Pourquoi ne pas créer un add-in qui récupère les données via le port USB puis exécute le jeu à la fin du transfère ?
Pour résumer éviter d’aller dans “LINK”, et attendre que la calto se connecte à l’ordi, attendre que l’add-in soit transféré.
En gros avoir un add-in de debug qui nous permet de ne pas avoir à toucher à la console pour tester ses programmes.



Théorie
Pour ça il nous faut une connexion directe entre la Casio et le PC...bon ya un port USB donc c’est rapide.
L’add-in se met directement en ‘Receive’ (elle attend un fichier).
Ensuite on vérifie s'il y a assez de place dans la RAM.
Si ya assez de place, on met tout le programme dans la RAM, puis on l’exécute. (c’est tellement simple à dire^^)
Pourquoi la RAM ?
C’est un add-in de debug je vous rappelle donc on s’en fout que le programme soit stocké dans la ROM.
De plus la RAM est rapide à écrire, bien plus rapide que le ROM.



Possible ?
Oui MAIS seulement des petits programmes car la ‘vrai’ RAM disponible sur SH4 est de 12 ko (d’après la doc de Lephenixoir) OU 64 ko (d’après le wiki).
Donc bon...
Oublions 2 secondes la taille de la RAM et le fait qu’il y en est pas autant sur les SH3 que sur le SH4.
1.On sait communiquer via le port USB (exemple : P7 de Cakeisalie5), du moins on sait communiquer PC->Casio par contre il me semble pas avoir entendu parler de syscall permettant de jouer avec le port USB (j’ai chercher mais je n'ai rien comprit ).

2.On sait exécuter du code Assembleur depuis la RAM (#sysCall) (gint fait ça merveilleusement bien aussi <3).

3.On sait faire des interfaces par dégueux.
Donc oui c’est possible !



Es-ce que j’ai commencer a faire un truc ?
Non, déjà parce que j'ai pas beaucoup de temps en ce moment et j’ai déjà plusieurs projets à finir.
C’est juste pour signaler que c’est théoriquement possible donc s'il y a des personnes intéressées par ce projet...bah allez-y ça pourrait être sympa et il y a sûrement beaucoup de choses à apprendre .


Pages : Précédente1, 2, 3
LephenixnoirEn ligneAdministrateurPoints: 13590 Défis: 136 Message

Citer : Posté le 14/12/2018 22:49 | #


Attention à ne pas mettre des ABSOLUTE() partout, tous les symboles b* et e* doivent en être exempts sinon tu ne sauras pas où copier dans la RAM !

Pas besoin de volatile durant ta copie, les données ne vont pas changer dans ton dos.

Si ça te dérange par j aimerait bien avoir une explication de cette section qui est géré bizarrement (au vu de la compilation ou on supprime la section (si j'ai bien suivie) et en plus on le force a etre à 0) ça a quel intérêt de la mettre a 0si on la deja supprimée cette section .bss ?

Pour caricaturer, on peut dire que c'est la section où on met tout ce qui est initialisé à 0. Il est absolument indispensable de la mentionner dans le linker script car c'est ce qui permet aux symboles dedans d'avoir des adresses assignées. Cependant, les valeurs à proprement parler ne sont que des 0, donc on ne garde pas cette section dans l'ELF. On la vire et on génère les zéros à la main au début de l'exécution.


Ah oui mais c'est le kernel de FiXos là, contrairement à ton add-in il ne rend pas la main au système à la fin de l'exécution. Tu ne peux pas te permettre autant de largesses si tu veux revoir un jour le menu principal...
Rise.
YatisHors ligneMembrePoints: 337 Défis: 0 Message

Citer : Posté le 24/12/2018 22:59 | #


Lephenixnoir a écrit :
Ah oui mais c'est le kernel de FiXos là, contrairement à ton add-in il ne rend pas la main au système à la fin de l'exécution. Tu ne peux pas te permettre autant de largesses si tu veux revoir un jour le menu principal...

Effectivement ça peut être problématique en effet

J'ai continué mon linker script, contrairement à avant, là j'arrive à compiler mais seulement j'ai un problème de taille. À la sortie mon .bin fait 132120097 octets, ce qui est légèrement beaucoup trop mon gout (je sais très bien qu'il y a un problème, surtout que pour l'instant l'add-in ne dépassent pas les 16 ko).
Je suppose que cela vient sois des ABSOLUTES() ou des AT() ou d'une section qui se multiplie, seulement, je ne suis absolument pas sur de moi.
Tu as une idée d'où ça peut venir ? (le.pretext je pense (?)).

voila le linker script.

OUTPUT_ARCH(sh3)
ENTRY(_bootstrap)

MEMORY
{
    rom    : o = 0x00300200, l = 512k
    ram    : o = 0x08100000, l = 8k
    my_ram    : o = 0x8800d000, l = 12k
}

SECTIONS
{
    .text    : {
        *(.pretext)
        *(.pretext.*)
        *(.text)
        *(.text.*)
        _etext = . ;
    } > rom
    .rodata    : AT(_etext) {
        *(.rodata)
        *(.rodata.*)
        _erodata = . ;
    } > rom



    .bss    : AT(_erodata) {
        _bbss_rom = ABSOLUTE (.) ;
        _bbss_ram = . ;
        *(.bss)
        *(.bss.*)
        _bss_size = SIZEOF(.bss) ;
        _ebss = ABSOLUTE (.) ;
    } > ram
    .data    : AT(_ebss) {
        _bdata_rom = ABSOLUTE (.) ;
        _bdata_ram = . ;
        *(.data)
        *(.data.*)
        _data_size = SIZEOF(.data) ;
        _edata = ABSOLUTE (.) ;
    } > ram


/*
* RAM section witch set my interupt handler.
* vbr + 0x100 -> exeption interupt.
* vbr + 0x400 -> tlb miss.
* vbr + 0x600 -> other interupt.
*/

    .glados    : AT(_edata) ALIGN(4) {
        . = ALIGN(0x100) ;
        _glados_vbr = . ;
        _bglados_rom = ABSOLUTE (.) ;
        _bglados_ram = . ;
        . = _glados_vbr + 0x100 ;
        *(.glados.exept)
        . = _glados_vbr + 0x400 ;
        *(.glados.tlb)
        . = _glados_vbr + 0x600 ;
        *(.glados.interupt)
        . = ALIGN(4) ;
        _glados_size = SIZEOF(.glados) ;
    } > my_ram
}


voila le crt0.c:

#include "../../include/stream.h"
extern int main(void);
extern void __save_stuff(void);
extern void __restore_stuff(void);

extern uint32_t bbss_ram;
extern uint32_t bbss_rom;
extern uint32_t bss_size;
extern uint32_t bdata_ram;
extern uint32_t bdata_rom;
extern uint32_t data_size;
extern uint32_t bglados_ram;
extern uint32_t bglados_rom;
extern uint32_t glados_size;
extern uint32_t glados_vbr;


__attribute__((section(".pretext"))) static void section_dump(void *bsection_ram,
void *bsection_rom, int section_size_dump)
{
    uint32_t *ram_section = (uint32_t*)bsection_ram;
    uint32_t *rom_section = (uint32_t*)bsection_rom;
    int i;

    i = -1;
    while (++i < section_size_dump)
        *ram_section++ = *rom_section++;
}

__attribute__((section(".pretext"))) int bootstrap(void)
{
    int exit;

    section_dump(&bbss_ram, &bbss_rom, bss_size);
    section_dump(&bdata_ram, &bdata_rom, data_size);
    section_dump(&bglados_ram, &bglados_rom, glados_size);
    init_stream();
    __save_stuff();
    exit = main();
    __restore_stuff();
    quit_stream();
    return (exit);
}


Ce que je trouve bizarre c'est que mon .elf fait 47 ko donc je comprends pas pourquoi le .bin est aussi volumineux >_<
LephenixnoirEn ligneAdministrateurPoints: 13590 Défis: 136 Message

Citer : Posté le 24/12/2018 23:11 | #


         _ebss = ABSOLUTE (.) ;

     .data    : AT(_ebss) {

Ça, c'est faux je pense. Utilise -Wl,-M pour voir la valeur du symbole : il est dans la RAM. .data : AT(_erodata + sizeof(.bss)) devrait marcher mieux.

L'ELF donne une liste de section/adresses. Le binaire n'a pas ce format-là, il doit reproduire tel quel la structure de la mémoire. Donc si tu as des données chargées de façon pas continue, il doit reproduire les trous.
Rise.
YatisHors ligneMembrePoints: 337 Défis: 0 Message

Citer : Posté le 26/12/2018 22:29 | #


Lephenixnoir a écrit :
Ça, c'est faux je pense. Utilise -Wl,-M pour voir la valeur du symbole : il est dans la RAM. .data : AT(_erodata + sizeof(.bss)) devrait marcher mieux.

Effectivement ça fonctionne, seulement maintenant j'ai une erreur.
Une erreur de copy (TARGET=00000001 PC=880023f94), avec les flags que tu m'as donné je trouvé rien à l'address PC (normal) mais surtout le TARGET signifie que le linkage n'a pas fonctionné (du moins je pense) mais je n'ai aucune idée d'où ça peut venir. Les sections sont aux bonnes address et bien alignées...
Mon crt0.c ne contient rien à part un return (0)... bref je sais absolument par où chercher ni quoi faire, dans le doute je mets mon linker car l'erreur viens forcement de lui.

OUTPUT_ARCH(sh3)
ENTRY(_bootstrap)

MEMORY
{
    rom    : o = 0x00300200, l = 512k
    ram    : o = 0x08100000, l = 8k
    my_ram    : o = 0x8800d000, l = 12k
}

SECTIONS
{
    .text    :  {
        *(.pretext)
        *(.pretext.*)
        *(.text)
        *(.text.*)
    } > rom
    .rodata    : {
        *(.rodata)
        *(.rodata.*)
        _erodata = ABSOLUTE (.) ;
    } > rom



    .bss    : AT(_erodata) {
        _bbss_rom = ABSOLUTE (.) ;
        _bbss_ram = . ;
        *(.bss)
        *(.bss.*)
        _bss_size = SIZEOF(.bss) ;
    } > ram
    .data    : AT(_erodata + SIZEOF(.bss)) {
        _bdata_rom = ABSOLUTE (.) ;
        _bdata_ram = . ;
        *(.data)
        *(.data.*)
        _data_size = SIZEOF(.data) ;
    } > ram


/*
* RAM section witch set my interupt handler.
* vbr + 0x100 -> exeption interupt.
* vbr + 0x400 -> tlb miss.
* vbr + 0x600 -> other interupt.
*/

    .glados    : AT(_erodata + SIZEOF(.bss) + SIZEOF(.data)) ALIGN(4) {
        . = ALIGN(0x100) ;
        _glados_vbr = . ;
        _bglados_rom = ABSOLUTE (.) ;
        _bglados_ram = . ;
        . = _glados_vbr + 0x100 ;
        *(.glados.exept)
        . = _glados_vbr + 0x400 ;
        *(.glados.tlb)
        . = _glados_vbr + 0x600 ;
        *(.glados.interupt)
        . = ALIGN(4) ;
        _glados_size = SIZEOF(.glados) ;
    } > my_ram
}
LephenixnoirEn ligneAdministrateurPoints: 13590 Défis: 136 Message

Citer : Posté le 26/12/2018 22:39 | #


J'insiste, encore et toujours, utilise -Wl,-M. Ça t'affiche une carte de la mémoire après linkage, la valeur de tous les symboles que tu as créés, et ça te permet de voir les erreurs d'alignement. Si tu n'y arrives pas, montre-moi l'erreur, mais sans ça tu ne t'en sortiras pas (et moi non plus) !

Alternativement tu peux utiliser readelf ou objdump mais tu aurais moins d'infos.
Rise.
YatisHors ligneMembrePoints: 337 Défis: 0 Message

Citer : Posté le 27/12/2018 21:19 | # | Fichier joint


Lephenixnoir a écrit :
J'insiste, encore et toujours, utilise -Wl,-M. Ça t'affiche une carte de la mémoire après linkage, la valeur de tous les symboles que tu as créés, et ça te permet de voir les erreurs d'alignement. Si tu n'y arrives pas, montre-moi l'erreur, mais sans ça tu ne t'en sortiras pas (et moi non plus) !

Après quelques heures de tests et débuggage je n'arrive définitivement pas à trouver la source du problème.
Surement un alignement qui foire, mais même en forçant l'alignement de chaque section je n'arrive à rien, toujours la même erreur.J'ai réduit mon add in le plus possible et voila la carte mémoire (en fichier joint).

EDIT: en mettant le fichier joint je suis re-tomber sur la ligne 79 et 183:
memory_map a écrit :

OUTPUT(test.elf elf32-sh)
.comment 0x0000000000000000 0x11
.comment 0x0000000000000000 0x11 src/core/bootstrap.o
0x12 (size before relaxing)

Aurais-je oublié la section .comment ? quel est le rôle de cette section ?
LephenixnoirEn ligneAdministrateurPoints: 13590 Défis: 136 Message

Citer : Posté le 27/12/2018 23:18 | #


La section .comment est inutile, elle ne contient que des petits commentaires genre "généré par GCC".

                0x0000000008100000                _bbss_rom = ABSOLUTE (.)

Clairement, ça c'est faux, ça devrait être égal à... _erodata. Ça n'explique pas le crash, mais c'est quelque chose. Pareil pour tous les autres symboles *_rom. D'ailleurs j'ai dis il y a pas longtemps...

Lephenixnoir a écrit :
Attention à ne pas mettre des ABSOLUTE() partout, tous les symboles b* et e* doivent en être exempts sinon tu ne sauras pas où copier dans la RAM !

Sinon, regarde mieux ce que t'a donné -Wl,-M. Le code d'entrée qui est exécuté n'est pas celui que tu crois. L'ordre compte
Rise.
YatisHors ligneMembrePoints: 337 Défis: 0 Message

Citer : Posté le 29/12/2018 20:07 | # | Fichier joint


Lephenixnoir a écrit :

                0x0000000008100000                _bbss_rom = ABSOLUTE (.)

Clairement, ça c'est faux, ça devrait être égal à... _erodata. Ça n'explique pas le crash, mais c'est quelque chose. Pareil pour tous les autres symboles *_rom. D'ailleurs j'ai dis il y a pas longtemps...

Mmmmm...après un début de relecture de info ld (qui m'a appris beaucoup de choses) j'utilise LOADADDR() au lieu de ABSOLUTE() car qui me donne l'addresse de dépars d'une section. (la LMA et non la VMA) (ce qui m'a fait réaliser que j'ai incroyablement rien compris de l'utilité de ABSOLUTE()... >_< ).
Du coup j'ai réécrit mon linker, ce qui donne ça;

OUTPUT_ARCH(sh3)
ENTRY(_bootstrap)

MEMORY
{
    rom    : o = 0x00300200, l = 512k
    ram    : o = 0x08100000, l = 8k
    my_ram    : o = 0x8800d000, l = 12k
}

SECTIONS
{
    .text    : ALIGN(4) {
        *(.pretext)
        *(.pretext.*)
        *(.text)
        *(.text.*)
    } > rom
    .rodata    : ALIGN(4) {
        *(.rodata)
        *(.rodata.*)
        _erodata = . ;
    } > rom



    .bss    : AT(_erodata){
        _bbss_ram = . ;
        *(.bss)
        *(.bss.*)
        *(COMMON)
        _bss_size = SIZEOF(.bss) ;
        _bbss_rom = LOADADDR(.bss) ;
    } > ram
    .data    : AT(_erodata + SIZEOF(.bss)) ALIGN (4){
        *(.data)
        *(.data.*)
        _data_size = SIZEOF(.data) ;
        _bdata_rom = LOADADDR(.data) ;
    } > ram


/*
* RAM section witch set my interupt handler.
* vbr + 0x100 -> exeption interupt.
* vbr + 0x400 -> tlb miss.
* vbr + 0x600 -> other interupt.
*/

    .glados    : AT(_erodata + SIZEOF(.bss) + SIZEOF(.data)) ALIGN(4) {
        . = ALIGN(0x100) ;
        _glados_vbr = . ;
        _bglados_ram = . ;
        . = _glados_vbr + 0x100 ;
        *(.glados.exept)
        . = _glados_vbr + 0x400 ;
        *(.glados.tlb)
        . = _glados_vbr + 0x600 ;
        *(.glados.interupt)
        . = ALIGN(4) ;
        _glados_size = SIZEOF(.glados) ;
        _bglados_rom = LOADADDR(.glados) ;
    } > my_ram
}

Le problème se trouve au niveau du dump de .data et de la mise à 0 de la section .bss, je plante toujours au même endroit, pour l'instant j'aimerait juste mettre .bss a 0 mais j'ai ce plantage (TARGET=00304000 ; PC =08100004).
Autant 08100004 ça correspond à la fin de la section .bss (ou au début de .data vu qu'elles se suivent) mais 00304000 correspond... à la fin de l'add-in visiblement.
Après plusieurs tests je me rend compte que c'est SIZEOF() qui foire >_< . Pourtant d'après la mémory map (fichier joint) le _bss_size me semble correcte (4o car il n'y a qu'une seule et même addresse dans .bss).
D'un autre côté j'ai essayé plusieurs façons d'avoir _bss_size:

(int32_t)&bss_size ------> plante à 00304000
(int32_t)bss_size --------> plante à 55555555

Et d'après info ld il faut bien faire la première façon, donc je ne sais pas pourquoi ça marche pô

Lephenixnoir a écrit :

Lephenixnoir a écrit :
Attention à ne pas mettre des ABSOLUTE() partout, tous les symboles b* et e* doivent en être exempts sinon tu ne sauras pas où copier dans la RAM !

Sinon, regarde mieux ce que t'a donné -Wl,-M. Le code d'entrée qui est exécuté n'est pas celui que tu crois. L'ordre compte

Merci ! <3 Effectivement, je n'avais pas fait gaffe mais section_dump() était placée avant bootstrap() (d'ailleurs je ne suis pas sur que crt0.s soit véritablement un bootstap xD )
Ce que je ne comprends pas c'est pourquoi il le linkait comme ça alors que j'avais mis ENTRY(_bootstrap) >_< m'enfin bon, l'important c'est que c'est réglé
Du coup si tu peux m'expliquer à quoi sert ABSOLUTE() parce que, pour le coup, je pensais que ça donnait la valeur de la LMA et non la VMA mais visiblement ce n'est pas le cas (je n'ai pas encore fini de lire info ld ).
LephenixnoirEn ligneAdministrateurPoints: 13590 Défis: 136 Message

Citer : Posté le 29/12/2018 21:55 | #


(ce qui m'a fait réaliser que j'ai incroyablement rien compris de l'utilité de ABSOLUTE()... >_< ).

De base quand tu définis un symbole à l'intérieur d'une section, sa valeur est prise relativement à l'adresse de la section. ABSOLUTE() change ça. C'est encore un peu obscur pour moi, par contre je peux te dire que quand tu fais objdump -t (affiche la liste des symboles), les symboles sont soit liés à une section (auquel cas le nom de la section s'affiche), soit absolus (auquel cas *ABS* est affiché). La différence me paraît subtile...

C'est bien la première façon qu'il faut faire, sache que la deuxième correspond à lire la mémoire à l'adresse bss_size.

Ce que je ne comprends pas c'est pourquoi il le linkait comme ça alors que j'avais mis ENTRY(_bootstrap) >_< m'enfin bon, l'important c'est que c'est réglé

Ah, oui, alors en fait ENTRY() ça marche pour les ELF, mais en binaire pur c'est vraiment le début du code qui est exécuté en premier. D'où l'intérêt d'avoir .pretext. Si tu as ENTRY() alors .pretext n'est pas nécessaire, tu peux tout mettre dans .text.

Tu as juste pour LOADADDR(), si tu as trop de doutes jette un oeil aux scripts de gint, qui... marchent (normalement, ça fait un moment que je les ai pas testés).

---

Je reviens sur le point principal, ton linker script. Actuellement tu peux simplifier par mal la chose : la section .bss n'a en effet pas besoin de résider dans la ROM (il n'y a que des zéros). Donc, par exemple, tu as des simplifications dans ce genre :

     .data    : AT(_erodata) ALIGN (4){

     .glados    : AT(_erodata + SIZEOF(.data)) ALIGN(4) {

Du reste la façon dont tu calcules tes adresses est juste, d'ailleurs le résultat de -Wl,-M le montre bien. Je vois deux problèmes potentiels :

                0x0000000000000021                _data_size = SIZEOF (.data)

Ceci n'est pas un multiple de 4.

.glados         0x000000008800d000      0x600 load address 0x0000000000303e71

Ceci n'est pas chargé à une adresse multiple de 4.

Tu peux régler tout ça avec les bons paramètres d'alignment, que je ne connais pas par coeur (c'est un peu compliqué parce que tu as des alignments internes et externes et j'ai parfois besoin de deux), là aussi les scripts de gint contiennent la solution.

Ajouté le 29/12/2018 à 21:57 :
Aussi : info ld est exactement la doc qu'il faut utiliser ici, bien joué.
Rise.
YatisHors ligneMembrePoints: 337 Défis: 0 Message

Citer : Posté le 06/01/2019 20:14 | # | Fichier joint


C'est bon j'ai réussi à lancer mon add in (Le problème venait de SIZEOF() et des quelques fonctions mal alignées ).

Maintenant j'aimerait mettre ma VBR à la place de celle de Casio (sans la perdre, pour pouvoir la restaurer avant de quitter l'add in). Au début j'ai simplement fait un ldc r4, VBR mais la calto plantait, puis je me suis dit "Ha, mais si ça se trouve, quand je mets ma VBR et qu'il y a une interruption pile à ce moment-là, la calto doit planter". Donc j'ai opté pour ce code:

    sts.l PR, @-r15
    mov.l SR_pause, r0
    stc SR, r3
    or r0, r3
    ldc r3, SR

    ldc r4, VBR

    mov.l SR_pause, r0
    not r0, r0
    and r0, r3
    ldc r3, SR
    lds.l @r15+, PR
    rts
    nop

.align 4
SR_pause    .long 0x10000000

Et Bingo ça a marché, plus de plantage. (EDIT: cela venait d'une fonction ma aligner ).
Je voulais être sûr que les interruptions fonctionnaient encore, donc je voulais mettre un compteur qui m'aurait donné une idée du nombre d'interruption par seconde .
Le problème c'est que le compteur s'incrémente jamais, et quand j'essaie de toucher au clavier (car je sais que se génère masse d'interruption) la calto plante >_< .
J'ai donc forcé le truc en mettant:

    rts
    ldc r4, VBR

et le compteur s'incrémente toujours pas pourtant je ne bloque pas les interruptions... je suis un peu à court d'idées je dois avouer
je suis sur qu'il me manque un truc tout bête pour ça fonctionne...

(j'ai mis en fichier le .c qui fonctionne pas ainsi que la memory map)
Désoler de demander autant d'aide
LephenixnoirEn ligneAdministrateurPoints: 13590 Défis: 136 Message

Citer : Posté le 06/01/2019 20:18 | #


Pas mal ta fonction, c'est propre. Il y a sans doute quelques autres flags que tu veux mettre dans SR (je n'ai plus les détails mais gint en active d'autres). Bien en tous cas

Ben c'est pas compliqué, quand tu appuies sur une touche ça lance ton gestionnaire d'interruptions, idem après un certain délai à cause de la RTC. L'interruption sera générée en continue tant que tu ne l'auras pas validée en mettant un bit de registre spécifique à 0. Quel bit et quel registre dépend de l'interruption en question.

Tu as donc deux choix :

1. Tu coupes l'interruption entre le moment où tu changes la VBR et le moment où tu remets les interruptions (et tu restaures en revenant au système)
2. Tu gères l'interruption.
Rise.
Pages : Précédente1, 2, 3

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2019 | Il y a 74 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