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).
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' ?
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.
Mon blog ⋅ Mes autres projets
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)
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.
Mon blog ⋅ Mes autres projets
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... ^^'
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
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
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); :
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 ?
Mon blog ⋅ Mes autres projets
Citer : Posté le 17/04/2017 09:38 | #
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 :
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.
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 :
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 :
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)
Mon blog ⋅ Mes autres projets
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...
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...
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
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 :
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 !
Mon blog ⋅ Mes autres projets
Citer : Posté le 18/04/2017 00:49 | #
Je n'ai pas bien compris ce qu'est le trapa
Citer : Posté le 18/04/2017 07:59 | #
It's a trapa !
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.
Mon blog ⋅ Mes autres projets
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 ! ^^'
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 :')
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
[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.
Mon blog ⋅ Mes autres projets
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
Citer : Posté le 19/05/2017 10:22 | #
Effectivement, j'avais pas ces sources là ! Thx !
(du coup j'ai trouvé ça et ça)
Mon blog ⋅ Mes autres projets