Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » libcarrot - une alternative bonne pour la santé à fxlib
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

libcarrot - une alternative bonne pour la santé à fxlib

Posté le 13/03/2017 01:28

Disclaimer : ceci n'est absolument pas destiné à être un gros projet ou quoi, simplement un support de hacking rapide. Si vous voulez suivre un projet qui vaut beaucoup plus le coup que celui-ci, jetez un coup d'oeil à gint.

Jusqu'ici, pour développer pour fx-9860G et dérivées, il y avait deux pillules libs : la fxlib, apparue en 2006 avec le SDK officiel de CASIO et intégrée à ce dernier, et gint, une lib qui prend le contrôle sur la machine pour avoir un contrôle beaucoup plus poussé sur ce dernier. Idéalement, il faudrait utiliser gint pour tout projet, mais voilà : gint est un projet qui date d'il y a deux ans (il me semble), et même si son développeur, Lephenixnoir, continue de l'écrire, certaines fonctionnalités pourtant utiles manquent encore à l'appel, tels que la communication USB. Jusqu'ici, pour du hacking rapide, j'essayais de me servir de la fxlib (donc du système, qui propose déjà un support pour son propre matériel), seulement, elle aussi a des failles : son portage pour GNU/Linux a quelques ratés (notamment la fonction sprintf), et elle ne respecte que le standard C89 alors qu'avec GCC, il est possible de développer en C11, donc il manque des fonctions, headers et macros.

La libcarrot est une réponse à ces problèmes. Elle utilise le système pour interagir avec le matériel, mais réimplémente certaines fonctions histoire de ne pas être trop lent non plus. Son but est d'être C11-compliant, mais ça ne sera clairement pas immédiat, puisque j'implémenterai ces fonctionnalités-là en fonction de mes besoins. Elle incluera aussi une compatibilité avec des libs populaires, telles que la fxlib ou la MonochromeLib.

Mon but avec la libcarrot est d'avoir une lib qui permette de faire une app rapidement, principalement pour pouvoir hacker facilement (e.g. faire une app qui utilise la libp7 pour afficher les infos d'une autre calculatrice branchée via série).

Vous pouvez retrouver les sources ici :
https://github.com/cakeisalie5/libcarrot

C'est un projet très jeune, donc pour le moment, rien n'est prêt. Je fais ce topic pour que les efforts ne se dilapident pas en projets similaires, et je ne pense pas avoir vu de projet similaire avant pour la fx-9860G (contrairement à, par exemple, la libfxcg pour la Prizm).


Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 13/03/2017 16:46 | #


Oh, ben voilà qui pallie le défaut majeur de gint (enfin après celui de ne pas encore être sorti ). Je pourrai m'en inspirer pour implémenter la comm' ?
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 13/03/2017 16:47 | #


Je te conseille pas. Non pas que je copie/colle les noms en uppercase de Simon Lothar inspirés des noms de fonctions de CASIO, mais un peu beaucoup quand même.

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 13/03/2017 22:54 | #


Super, bon projet !

A mon avis pour être utilisé, il faut pouvoir tester rapidement son prog. C'est l'avantage du SDK : il y a un émulateur. Si le transfert à lieu automatiquement après la compilation c'est parfait ! 8)
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 22/03/2017 01:16 | #


C'est assez facile à mettre en place Ninestars, avec P7.
Autrement, j'ai mis en place un SDK basique directement dans le projet de la lib, dont il n'y a pas besoin de s'y connaître particulièrement en Makefile pour faire son propre projet utilisant la libcarrot ; pour un projet basique (n'utilisant aucune autre lib), un Makefile d'exemple se trouve sur la page du projet (section Example Makefile using the SDK).

Et du coup, j'ai pu faire un Hello World exploitant ce SDK -- rien de transcendant, juste "I am Groot" puis on attend une key pour quitter. Et à part quelques pixels qui partent en cacahuète (j'étudierai le pourquoi de ça plus tard), c'est fonctionnel, je devrais pouvoir organiser les contributions dans pas très longtemps.

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 22/03/2017 07:41 | #


Comment ça quelques pixels qui partent en cacahuète ? Normamement tu ne devrais pas avoir de choses de ce genre... ^^'
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 22/03/2017 13:01 | #


Je ne sais pas du tout d'où ça vient encore. En tous les cas, voici mon add-in de test.

Ajouté le 16/04/2017 à 23:38 :
Je bosse pas mal sur la reproduction des *machine.h en ce moment, et de transformer les built-ins du compilateur d'Hitachi en macros pour GCC, histoire d'asseoir la domination de la communauté. Les *machine.h, en gros, c'est de l'assembleur SuperH en C (Hitachi/Renesas donne un nom stylé à ça, je l'ai plus en tête). Le problème, c'est que la majorité des macros des *machine.h de la libc d'Hitachi mènent en réalité aux built-ins correspondants dans le compilateur C/C++ d'Hitachi, et que ces built-ins ne sont pas dans GCC -- pour les rendre accessibles avec celui-ci, il faut donc jouer de macros et de fonctions inlines utilisant asm().

Ce soir, je viens vous montrer le résultat d'une expérience autour du portage de la macro macw(p1, p2, count), une macro plutôt problématique. En effet, cette macro, en plus de commencer clrmat et de sauver MACL dans la stack, exécute count fois l'instruction MAC.W @<p1>+, @<p2>+ : copier | log complet
          main.c    29            unsigned short a = macw((void*)0x01, (void*)0x02, 20);
    00000002 E302                   MOV         #2,R3
    00000004 4F12                   STS.L       MACL,@-R15
    00000006 E201                   MOV         #1,R2
    00000008 0028                   CLRMAC
    0000000A 432F                   MAC.W       @R2+,@R3+
    0000000C 432F                   MAC.W       @R2+,@R3+
    0000000E 432F                   MAC.W       @R2+,@R3+
    00000010 432F                   MAC.W       @R2+,@R3+
    00000012 432F                   MAC.W       @R2+,@R3+
    00000014 432F                   MAC.W       @R2+,@R3+
    00000016 432F                   MAC.W       @R2+,@R3+
    00000018 432F                   MAC.W       @R2+,@R3+
    0000001A 432F                   MAC.W       @R2+,@R3+
    0000001C 432F                   MAC.W       @R2+,@R3+
    0000001E 432F                   MAC.W       @R2+,@R3+
    00000020 432F                   MAC.W       @R2+,@R3+
    00000022 432F                   MAC.W       @R2+,@R3+
    00000024 432F                   MAC.W       @R2+,@R3+
    00000026 432F                   MAC.W       @R2+,@R3+
    00000028 432F                   MAC.W       @R2+,@R3+
    0000002A 432F                   MAC.W       @R2+,@R3+
    0000002C 432F                   MAC.W       @R2+,@R3+

Mon premier réflexe a été d'utiliser une boucle dans une fonction inline (puisqu'on ne peut pas utiliser une macro pour répeter une string par rapport à une valeur définie dans une autre macro, hélas), pensant que GCC optimiserait ça, mais non, puisque le count est passé en argument. J'ai donc cherché à générer une lambda générée avec un count bien précis pour l'appeler, et heureusement, il y a une extension GCC pour ça. Seulement, GCC n'optimisait pas encore la boucle, mais il y a un attribut pour ça, optimize("unroll-loops") ! De plus, macl n'était pas sauvegardé dans la stack, j'ai donc ajouté ça manuellement (ouais, c'est pas génial).

Vous l'attendiez, voici donc la macro : copier
#  define macw(_PTR1, _PTR2, _COUNT) ({__unroll_loops inline \
  uint16_t __fn__(uint16_t *__p1, uint16_t *__p2) { \
    asm("sts.l macl, @-r15\r\n" "clrmac"); \
    int __count; for (__count = 0; __count < (_COUNT); __count++) \
        asm("mac.w @%0+, @%1+"::"r"(__p1), "r"(__p2)); \
    uint32_t __mul; asm("sts macl, %0":"=r"(__mul)); \
    asm("lds.l @r15+, macl"); \
    return (__mul); } __fn__; })(_PTR1, _PTR2);

Et voici ce que cette macro me génère avec macw((void*)0x01, (void*)0x02, 5); :
Disassembly of section .text:

00000000 <___fn__.1028.constprop.0>:
   0:    4f 12           sts.l    macl,@-r15
   2:    00 28           clrmac    
   4:    e1 01           mov    #1,r1
   6:    e2 02           mov    #2,r2
   8:    42 1f           mac.w    @r1+,@r2+
   a:    42 1f           mac.w    @r1+,@r2+
   c:    42 1f           mac.w    @r1+,@r2+
   e:    42 1f           mac.w    @r1+,@r2+
  10:    42 1f           mac.w    @r1+,@r2+
  12:    00 1a           sts    macl,r0
  14:    4f 16           lds.l    @r15+,macl
  16:    00 0b           rts    
  18:    60 0d           extu.w    r0,r0
  1a:    00 09           nop    

0000001c <_lol>:
  1c:    d0 03           mov.l    2c <_lol+0x10>,r0    ! 0 <___fn__.1028.constprop.0>
  1e:    4f 22           sts.l    pr,@-r15
  20:    40 0b           jsr    @r0
  22:    00 09           nop    
  24:    4f 26           lds.l    @r15+,pr
  26:    00 0b           rts    
  28:    00 09           nop    
  2a:    00 09           nop    
  2c:    00 00           .word 0x0000

Soit un résultat pas trop éloigné de ce que j'obtiens avec le compilo d'Hitachi. Je ne sais pas encore si cela était bien utile (la boucle aurait peut-être suffi ?), mais je reste bien content de ce que je suis parvenu à faire. Qu'en pensez-vous ?

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 17/04/2017 09:38 | #


Wow, t'as complètement cracké. Je suis en train de rédiger un article sur tous les trucs funs qu'on peut faire avec de l'assembleur sur calto (pour optimiser des fonctions classiques ou des trucs du genre), et j'ai pas mal touché à l'instruction mac en fait. J'ai cherché pas mal de moyens de forcer gcc à la générer, mais en vain.

Je dois admettre que ta macro a de la gueule, c'est plutôt bien joué parce que le défi technique était pas tout petit. Par contre ton formatage est illisible, tu pouvais pas indenter un peu tout ça ?

J'ai quelques remarques à faire sur cette fonction, et je vais tenter d'en faire une analyse pertinente :

→ Tu as certes réinitialisé mach avec l'instruction clrmac, mais je voudrais citer un problème portentiel : la documentation indique : « mac.w @rm+, @rn+ : (rn) × (rm) + mac → mac (16×16 + 64 → 64 bits) ». En l'occurrence, le registre mach est affecté, en particulier en cas d'overflow de macl. Contrairement à toi, la macro d'origine n'était pas négligente sur ce point : la sauvegarde de macl n'est pas suffisante car les multiplications et optimisations réalisées par le compilateur peuvent déplacer ton assembleur inline en plein milieu d'une multiplication (en particulier car les accès au multiplicateur détruisent la concurrence possible avec le processeur, le fameux « 2 to 5 cycles »), ce qui peut introduire des bugs si tu le modifies par overflow.

→ De manière beaucoup moins subtile, tu as réinitialisé mach et tu ne l'as mis nulle part dans les clobbers. C'est le bug assuré quand tu te serviras de ta macro en conditions réelles. Ne pas le réinitialiser n'étant pas une solution à cause du problème ci-dessus, et le mettre dans les clobbers me semblant stupide vu le coût de la sauvegarde/restauration, je suggérerais d'opter pour le sauvegarder.

→ Le multiplicateur tourne relativement indépendamment du processeur. La multiplication prend 5 cycles à réaliser, mais le processeur n'est utilisé que pendant les deux premiers et est donc disponible pour n'importe quelle opération pendant les trois autres. Enchaîner les opérations sur le multiplicateur et les accès aux registres force une attente qui aurait pu être productive. La boucle ne peut pas être améliorée, mais tu pourrais profiter de l'espace entre chaque mac.w pour incrémenter un peu tes pointeurs... je te laisse deviner une application intéressante de cette technique (un peu de suspense ) mais ça a un rapport avec le stride d'array.

→ Tu peux faire un peu mieux dans l'épilogue de ta fonction. mac est un registre 64 bits donc toute troncature à 32 ou à 16 bits est une valeur valide sur la taille réduite. Le stockage de macl est une telle troncature qui te fournit un résultat signé valide sur 32 bits. Ton extension non-signée est non seulement fausse quand le résultat est négatif (car elle ajoute des 0 et génère une résultat positif) mais en plus elle réduit fortement la plage de valeurs sur laquelle ta fonction va marcher sans overflow. Une extension non-signée limite le produit scalaire (-- oups, j'ai cité une application intéressant pas très loin de l'autre...) à 65535 et c'est vite atteint. Alors qu'en gardant la valeur initiale de macl, tu offres deux extensions possibles de ta fonction : la gestion du signe, et le résultat sur 32 bits. Finalement ton nop ne sert à rien ici, même pas à gérer l'alignement puisque le nombre de mac.w est variable. Ce qui me donne :
mac.w   @r1+, @r2+
sts     macl, r0
lds.l   @r15+, macl
rts
lds.l   @r15+, mach

Voilà, j'espère que j'ai été utile et que j'ai pas raconté de bêtises.

Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 17/04/2017 14:44 | #


J'ai essayé de répondre à ces problématiques dans la nouvelle version de la macro, avec son résultat :

#  define macw(_PTR1, _PTR2, _COUNT) ({__asm_inline \
  uint32_t __fn__(uint16_t *__p1, uint16_t *__p2) { \
    uint32_t __macl, __mach; \
    asm("sts macl, %0\r\n" "sts mach, %1":"=r"(__macl), "=r"(__mach)); \
    asm("clrmac"); \
    int __count; for (__count = 0; __count < (_COUNT); __count++) \
        asm("mac.w @%0+, @%1+"::"r"(__p1), "r"(__p2)); \
    uint32_t __mul; asm("sts macl, %0":"=r"(__mul)); \
    asm("lds %0, macl"::"r"(__macl)); \
    asm("lds %0, mach"::"r"(__mach)); \
    return (__mul); } __fn__; })(_PTR1, _PTR2);

Je rencontre encore quelques soucis. Le premier concerne __asm_inline, défini dans sys/cdefs.h (anciennement compiler.h). C'est une macro que j'ai faite spécialement pour les fonctions inlines présentes dans machine.h (et sous-headers). Avec un compilateur GCC-like (__GNUC__ défini), elle est définie ainsi :

#  define __asm_inline __attribute__((optimize("unroll-loops")))

Seulement, cela fait une fonction non-inline. En ajoutant always_inline avant optimize dans le même __attribute__, aucun changement, seulement, en ajoutant always_inline après, on obtient bel et bien du code intégré à la fonction... mais avec une boucle (optimize ineffectif).

Second souci, même sans always_inline, pour certains grands nombres genre vingt, GCC met quand même en place une boucle (deux tours de boucles avec dix MAC.W dedans). Troisième souci, je n'arrive pas à obtenir cette optimisation au niveau du ret, GCC refuse de mettre le second lds après.

Je compte envoyer un mail concernant ça sur la mailing-list gcc-help de GCC aussitôt que possible (il faut auparavant que Tutanota, mon provider mail, règle un souci avec son interface).

Pour ce qui concerne le stride d'array, je ne comprends pas bien où tu veux en venir. J'ai au début cru que tu voulais dire que je pourrais profiter de ce temps pour adapter les valeurs 16-bits dans des valeurs 32-bits pour les passer à un MAC.L qui serait plus rapide, mais en vérifiant dans le manuel, ça ne serait pas worth it... donc je n'ai pas compris, désolé. x)

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 17/04/2017 14:51 | #


Tu devrais utiliser une contrainte ="rm" pour le stockage de macl et mach. Le compilateur saura bien décider de ce qui est le plus optimisé. Pour l'optimisation du rts, c'est pas bien grave - mieux vaut laisser gcc faire.

Non, ce que je propose, c'est d'incrémenter un pointeur pendant la multiplication, par exemple...
mac.w   @r1+, @r2+
add     #6, r1
mac.w   @r1+, @r2+
add     #6, r1
// etc...

Du coup ça permet d'additionner sur un tableau avec un stride. Il y a un intérêt important à faire ça...
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 17/04/2017 23:28 | #


Honnêtement, je suis plutôt satisfait du "r". x)
J'avoue ne pas avoir compris le coup du "add #6, r1". Après, pour le moment, je reste fidèle à ce que fait le compilateur d'Hitachi. On verra après pour les améliorations.

Du coup, aujourd'hui, nouvelle histoire les enfants : trapa_svc. En gros, cette macro fait un trapa avec arguments. Elle prend 2 à 6 arguments : la valeur immédiate du trapa, la valeur du registre r0, puis les registres r4 à r7 (heureusement, tout ce qui est après n'est pas géré). Voici toutes les utilisations : copier
               main.c          9          a = trapa_svc(1, 2);
    00000000 E002                   MOV         #2,R0      ; H'00000002
    00000002 C301                   TRAPA       #1
               main.c         10          a = trapa_svc(1, 2, 3);
    00000004 E002                   MOV         #2,R0      ; H'00000002
    00000006 E403                   MOV         #3,R4      ; H'00000003
    00000008 C301                   TRAPA       #1
               main.c         11          a = trapa_svc(1, 2, 3, 4);
    0000000A E002                   MOV         #2,R0      ; H'00000002
    0000000C E403                   MOV         #3,R4      ; H'00000003
    0000000E E504                   MOV         #4,R5      ; H'00000004
    00000010 C301                   TRAPA       #1
               main.c         12          a = trapa_svc(1, 2, 3, 4, 5);
    00000012 E002                   MOV         #2,R0      ; H'00000002
    00000014 E403                   MOV         #3,R4      ; H'00000003
    00000016 E504                   MOV         #4,R5      ; H'00000004
    00000018 E605                   MOV         #5,R6      ; H'00000005
    0000001A C301                   TRAPA       #1
               main.c         13          a = trapa_svc(1, 2, 3, 4, 5, 6);
    0000001C E002                   MOV         #2,R0      ; H'00000002
    0000001E E403                   MOV         #3,R4      ; H'00000003
    00000020 E504                   MOV         #4,R5      ; H'00000004
    00000022 E605                   MOV         #5,R6      ; H'00000005
    00000024 E706                   MOV         #6,R7      ; H'00000006
    00000026 C301                   TRAPA       #1

Allons bons, du code différent selon le nombre d'arguments ? Mais cela est impossible à gérer avec GCC, voyons !
... eh bien c'est ce que s'est dit votre serviteur au début. Et puis, je me suis dit qu'on pourrait peut-être tout simplement faire différentes fonctions, type __trapa_svc_2, __trapa_svc_3, ..., __trapa_svc_6, et qu'on pourrait les appeler en fonction de la taille de __VA_ARGS__ (macro à utiliser lorsque vous avez une variable argument list dans une macro, type ACHETEZ_MON_MACRO(_BASE, ...)). Donc j'ai cherché, et effectivement, une technique existe pour GCC ! Du coup, je l'ai intégrée dans sys/cdefs.h (anciennement compiler.h) sous le joli nom de __count_va_args.

Après avoir dû jouer de fonctions intermédiaires de concaténation utilisant, au dernier appel, l'opérateur ## (c'est totalement du trial and error, je dois bien l'avouer), et après avoir mis en place mes fonctions inline comme il faut, je suis confronté à une erreur d'assembleur. De ma grace habituelle, je galère à l'afficher (en fait il faut juste rajouter -S aux options du compilateur, le fichier d'output sera en plain text, ici obj/ptdr.c.o puisque j'ai eu la flemme de changer le nom), mais je réussis finalement, et je chope un trapa #r1. Eh oui, l'instruction trapa prend une valeur immédiate, ce qui veut dire que je vais encore une fois devoir générer des lambda. Youpi !


Moi qui danse parce que c'est l'éclate la plus totale

Alors on génère les macros, on utilise "i" au lieu de "r" pour le code, et on est bon ! Je règle juste le problème du "mov r0, r0" en déclarant une variable locale à la fonction avec le mot clé register représentant r0, et ça marche. (on dirait que c'était simple comme ça, mais en fait non j'ai galéré)

Du coup, mais elle va bien entendu de soi, voici la macro et tout ce qui va avec :
#  define __make_trapa_svc_1(_CODE) ({__asm_inline \
  int __fn__(uint32_t __r0) { \
    register int __ret asm ("r0"); \
    asm("mov %1, r0\r\n" \
        "trapa %0" \
        :: "i"(_CODE), "r"(__r0)); \
    return (__ret); } \
    __fn__; })
#  define __make_trapa_svc_2(_CODE) ({__asm_inline \
  int __fn__(uint32_t __r0, uint32_t __r4) { \
    register int __ret asm ("r0"); \
    asm("mov %1, r0\r\n" \
        "mov %2, r4\r\n" \
        "trapa %0" \
        :: "i"(_CODE), "r"(__r0), "r"(__r4)); \
    return (__ret); } \
    __fn__; })
#  define __make_trapa_svc_3(_CODE) ({__asm_inline \
  int __fn__(uint32_t __r0, uint32_t __r4, uint32_t __r5) { \
    register int __ret asm ("r0"); \
    asm("mov %1, r0\r\n" \
        "mov %2, r4\r\n" \
        "mov %3, r5\r\n" \
        "trapa %0" \
        :: "i"(_CODE), "r"(__r0), "r"(__r4), "r"(__r5)); \
    return (__ret); } \
    __fn__; })
#  define __make_trapa_svc_4(_CODE) ({__asm_inline \
  int __fn__(uint32_t __r0, uint32_t __r4, uint32_t __r5, uint32_t __r6) { \
    register int __ret asm ("r0"); \
    asm("mov %1, r0\r\n" \
        "mov %2, r4\r\n" \
        "mov %3, r5\r\n" \
        "mov %4, r6\r\n" \
        "trapa %0" \
        :: "i"(_CODE), "r"(__r0), "r"(__r4), "r"(__r5), "r"(__r6)); \
    return (__ret); } \
    __fn__; })
#  define __make_trapa_svc_5(_CODE) ({__asm_inline \
  int __fn__(uint32_t __r0, uint32_t __r4, uint32_t __r5, uint32_t __r6, \
  uint32_t __r7) { \
    register int __ret asm ("r0"); \
    asm("mov %1, r0\r\n" \
        "mov %2, r4\r\n" \
        "mov %3, r5\r\n" \
        "mov %4, r6\r\n" \
        "mov %5, r7\r\n" \
        "trapa %0" \
        :: "i"(_CODE), "r"(__r0), "r"(__r4), "r"(__r5), "r"(__r6), "r"(__r7)); \
    return (__ret); } \
    __fn__; })

# define __trapa_svc_concat2(X, Y) X ## Y
# define __trapa_svc_concat(X, Y) __trapa_svc_concat2(X, Y)

# define trapa_svc(_CODE, _R0, ...) \
    __trapa_svc_(_CODE, _R0, ##__VA_ARGS__)
# define __trapa_svc_(_CODE, ...) \
    __trapa_svc_concat(__make_trapa_svc_, __count_va_args(__VA_ARGS__))(_CODE) \
        (__VA_ARGS__)

Tout ça est pushed sur le git de la libcarrot du coup.
A bientôt pour de nouvelles galères !

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 18/04/2017 00:49 | #


Je n'ai pas bien compris ce qu'est le trapa
Intelligide Hors ligne Membre de CreativeCalc Points: 49 Défis: 5 Message

Citer : Posté le 18/04/2017 07:59 | #


It's a trapa !
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 18/04/2017 11:29 | #


En gros, sur un OS bien foutu (donc pas CASIOWIN), le trapa sert à faire un syscall (provoque une exception pour que le kernel la catche et fasse une action), et cette macro sert à faire un syscall avec arguments. Tu trouveras plus de détails dans le manuel.

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 18/04/2017 14:33 | #


En fait Cake a déjà tout dit, c'est dans le trapa_svc. Dans les systèmes d'exploitation, il est commun de distinguer plusieurs types d'interruptions :
→ Les interruptions causées par les périphériques externes ;
→ Les déroutements causés par des erreurs dans le programme ;
→ Les appels au superviseur, aka supervisor calls (svc) ;
Donc, on sent tout de suite que le trapa avec arguments c'est fait pour implémenter des syscalls ! ^^'

Cakeisalie5 a écrit :
Mon but avec la libcarrot est d'avoir une lib qui permette de faire une app rapidement, principalement pour pouvoir hacker facilement [...]

J'ai jamais vu personne d'autre que Kuhee exécuter trapa en vrai. Mais bon, bien joué o/

En vrai, ce serait tellement plus propre dans un builtin ce truc. T'es totalement fou de le faire en assembleur inline :')
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 21/04/2017 02:14 | #


Un topic dédié a été publié sur Code Walrus. Comme je souhaite me concentrer sur le projet P7, je commence à chercher activement un nouveau développeur/mainteneur pour ce projet. Si vous pensez avoir les compétences et le temps, n'hésitez pas à postuler.

Ajouté le 27/04/2017 à 02:01 :
Bon, puisque je n'ai pas (encore ?) de réponse pour la reprise, je continue de m'amuser dessus, notamment pour tout ce qui est implémentation des fixed-point (que je découvre par la même occasion), avec toute la compatibilité chiante qu'il faut ajouter derrière. J'améliore aussi tout ce qui est détection de la machine avec GCC (en reproduisant les macros du compilateur d'Hitachi), et gestion de la compatibilité des macros de machine.h, e.g. ceci. Je suis pas loin d'obtenir un machine.h avec les mêmes fonctionnalités que celui d'Hitachi/Renesas, fonctionnel sous GCC, et ça c'est quand même plutôt cool.

Ajouté le 05/05/2017 à 03:15 :
Bon, du coup, je continue à développer ce projet, mais dans un sens légèrement différent : j'en fais une libc générale pour SuperH/J-Core, avec des extensions genre la fxlib. Il faudra alors faire genre ./configure --extensions=fxlib,ensigdsp par exemple. Tout ça sera organisé dans des sous-dossiers, et je vais en profiter pour faire une doc dédiée à chaque truc.

Pour le moment, je galère sur trouver une bonne organisation des utilitaires de construction. En effet, il faudra probablement que je fasse un fxmake (ou un autre nom décentré des calculatrices CASIO pour être plus généraliste sur le SuperH/J-Core, type jmake ou quelque chose qui n'existe pas, de préférence) qui crée un Makefile sous Linux, et un rules.mk compatible avec Hmake sous Windows. Mais je ne sais pas encore comment je vais m'organiser pour la construction de libs (dont la libcarrot, du coup), et l'utilisation de libs.

Donc c'est un peu le flou le temps que je détermine comment faire un bousin propre. Désolé de ça.

Ajouté le 08/05/2017 à 23:44 :
Bon, je reprends le projet, parce que je compte en faire quelque chose d'un peu plus évolué, à savoir une libc modulable pour toutes les plateformes que je veux implémenter (c'est toujours mieux de faire ça que de refaire une libc pour chaque plateforme). Je fais un gros commit, puis je devrais reprendre la lib sur mon compte Github, puisque son intérêt devrait dépasser la calculatrice CASIO (concernant à la libcasio qui arrivera un jour, par exemple).

Ajouté le 12/05/2017 à 01:19 :
Je commence à pouvoir build la libcarrot avec le compilateur d'Hitachi ! Je continue le portage. Voici un log pour vous donner une idée de comment ça avance
G:\libcarrot>python tool --tools=hitachi "--tooldir=C:\Program Files\CASIO\fx-9860G SDK\OS\SH\BIN"
[all/core] CC ctype\funcs.c
[all/core] CC ctype\tab.c
[all/core] CC stdio\stdout.c
[all/core] CC stdio\fprintf.c
arch\all\core\src\stdio\fprintf.c(49) : C2214 (E) Integer required for "%"
arch\all\core\src\stdio\fprintf.c(49) : C2222 (E) Type not compatible for "="
arch\all\core\src\stdio\fprintf.c(68) : C2214 (E) Integer required for "%"
arch\all\core\src\stdio\fprintf.c(68) : C2222 (E) Type not compatible for "="

(vous pouvez voir comment ça évolue sur le dépôt git)

Ajouté le 19/05/2017 à 02:40 :
Graou, les libs produites par ce SDK sont dans un format propriétaire, magic string "HLIB" (0x484C4942). Je sais pas comment le gars qui a produit fxlib.a a procédé, j'ai dû rater l'utilitaire de Renesas qui faisait ça. En tous les cas, voilà qui va bien me faire chier pour la production de la libcarrot avec les utilitaires de Renesas.

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 19/05/2017 09:48 | #


Ah ces gens qui n'ont pas lu tout Casiopeia… Ces deux réponses devraient t'intéresser du coup.

http://www.casiopeia.net/forum/viewtopic.php?f=21&t=1472#p12770

http://casiopeia.net/forum/viewtopic.php?f=22&t=1586&start=10#p13605
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 19/05/2017 10:22 | #


Effectivement, j'avais pas ces sources là ! Thx !
(du coup j'ai trouvé ça et ça)

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 115 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