gint : un noyau pour développer des add-ins
Posté le 20/02/2015 17:30
Ce topic fait partie de la série de topics du fxSDK.
En plus des options de programmation intégrée comme le Basic Casio ou Python, la plupart des calculatrices Casio supportent des
add-ins, des programmes natifs très polyvalents avec d'excellentes performances. Les add-ins sont généralement programmés en C/C++ avec l'aide d'un ensemble d'outils appelé SDK.
Plusieurs SDK ont été utilisés par la communauté avec le temps. D'abord le
fx-9860G SDK de Casio avec fxlib pour Graph monochromes (plus maintenu depuis longtemps). Puis le
PrizmSDK avec libfxcg pour Prizm et Graph 90+E (encore un peu actif sur Cemetech). Et plus récemment celui que je maintiens, le
fxSDK, dont gint est le composant principal.
gint est un unikernel, ce qui veut dire qu'il embarque essentiellement un OS indépendant dans les add-ins au lieu d'utiliser les fonctions de l'OS de Casio. Ça lui permet beaucoup de finesse sur le contrôle du matériel, notamment la mémoire, le clavier, l'écran et les horloges ; mais aussi de meilleures performances sur le dessin, les drivers et la gestion des interruptions, plus des choses entièrement nouvelles comme le moteur de gris sur Graph monochromes.
Les sources de gint sont sur la forge de Planète Casio :
dépôt Gitea Lephenixnoir/gint
Aperçu des fonctionnalités
Les fonctionnalités phares de gint (avec le fxSDK) incluent :
- Toutes vos images et polices converties automatiquement depuis le PNG, sans code à copier (via fxconv)
- Un contrôle détaillé du clavier, avec un GetKey() personnalisable et un système d'événements à la SDL
- Une bibliothèque standard C plus fournie que celle de Casio (voir fxlibc), et la majorité de la bibliothèque C++
- Plein de raccourcis pratiques, comme pour afficher la valeur d'une variable : dprint(1,1,"x=%d",x)
- Des fonctions de dessin, d'images et de texte optimisées à la main et super rapides, surtout sur Graph 90+E
- Des timers très précis (60 ns / 30 µs selon les cas, au lieu des 25 ms de l'OS), indispensables pour les jeux
- Captures d'écran et capture vidéo des add-ins par USB, en temps réel (via fxlink)
Avec quelques mentions spéciales sur les Graph monochromes :
Un moteur de gris pour faire des jeux en 4 couleurs !
La compatibilité SH3, SH4 et Graph 35+E II, avec un seul fichier g1a
Une API Unix/POSIX et standard C pour accéder au système de fichiers (Graph 35+E II seulement)
Et quelques mentions spéciales sur les Graph 90+E :
Une nouvelle police de texte, plus lisible et économe en espace
Le dessin en plein écran, sans les bordures blanches et la barre de statut !
Un driver écran capable de triple-buffering
Une API Unix/POSIX et standard C pour accéder au système de fichiers
Galerie d'add-ins et de photos
Voici quelques photos et add-ins réalisés avec gint au cours des années !
Arena (2016) — Plague (2021)
Rogue Life (2021)
Momento (2021)
Communication avec le PC (cliquez pour agrandir)
Utiliser gint pour développer des add-ins
Les instructions pour installer et utiliser gint sont données dans les divers tutoriels recensés dans le
topic du fxSDK. Il y a différentes méthodes de la plus automatique (GiteaPC) à la plus manuelle (compilation/installation de chaque dépôt). Le fxSDK est compatible avec Linux, Mac OS, et marche aussi sous Windows avec l'aide de WSL, donc normalement tout le monde est couvert
Notez en particulier qu'il y a des
tutoriels de développement qui couvrent les bases ; tout le reste est expliqué dans les en-têtes (fichiers
.h) de la bibliothèque que vous pouvez
consulter en ligne, ou dans les ajouts aux changelogs ci-dessous.
Changelog et informations techniques
Pour tester les fonctionnalités et la compatibilité de gint, j'utilise un add-in de test appelé gintctl (
dépôt Gitea Lephenixnoir/gintctl). Il contient aussi une poignée d'utilitaires d'ordre général.
Ci-dessous se trouve la liste des posts indiquant les nouvelles versions de gint, et des liens vers des instructions/tutoriels supplémentaires qui accompagnent ces versions.
Anecdotes et bugs pétés
Ô amateurs de bas niveau, j'espère que vous ne tomberez pas dans les mêmes pièges que moi.
TODO list pour les prochaines versions (2023-04-03)
gint 2.11
- Changements de contextes CPU. À reprendre du prototype de threading de Yatis pour permettre l'implémentation d'un véritable ordonnanceur. Demandé par si pour faire du threading Java.
- Applications USB. Ajouter le support de descripteurs de fichiers USB. Potentiellement pousser jusqu'à avoir GDB pour debugger.
- Support de scanf() dans la fxlibc. Codé par SlyVTT, plus qu'à nettoyer et fusionner.
Non classé
- Regarder du côté serial (plus facile que l'USB) pour la communication inter-calculatrices (multijoueur) et ultimement l'audio (libsnd de TSWilliamson).
- Un système pour recompiler des add-ins mono sur la Graph 90+E avec une adaptation automatique.
- Support des fichiers en RAM pour pouvoir utiliser l'API haut-niveau sur tous les modèles et éviter la lenteur de BFile à l'écriture quand on a assez de RAM.
Citer : Posté le 06/05/2019 09:46 | #
On n'a pas migré les comptes, c'est pas le même Gitea, et migrer depuis Gitlab ne peut être fait automatiquement.
Il faut utiliser le pseudo que tu comptes utiliser pour la v5 (tu peux garder le même évidemment), puisqu'à terme les comptes seront liés.
Citer : Posté le 06/05/2019 09:53 | #
Tant que tu bosse dessus y'a moyen que tu finisses le makefile automatique ?
Oui je peux, désolé désolé ! >_<"
Peux-tu cross-poster ton issue du Gitlab sur le Gitea pendant que tu y es ?
Citer : Posté le 06/05/2019 14:47 | #
Ouaip c'est ce que je voulais faire, mais j'arrivais pas à me connecter .
Du coup je crée un compte avec mon pseudo Kirafi et je recrée l'issue Lephe .
Pourras-tu survivre plus de 20 secondes dans ce fameux tunnel appelé Graviton
Rebondis entre les murs en évitant les piques dans SpikeBird
Pourras-tu éviter de te faire écraser dans FallBlocs (élu Jeu Du Mois)
La version 2048 tactile amélioré au plus haut point : 2048 Delux !
Pars à la recherche des morceaux d'étoile dans Lumyce (élu Jeu Du Mois)
Citer : Posté le 17/05/2019 08:24 | #
Je serais curieux de savoir comment tu as fait pour détecter la graph 35+E II, car le MPU est le même que l'ancien, à savoir le SH7724 ? (on en a déjà parlé sur la shout mais je préfère que ce sois disponible au plus grand nombre).
As-tu rencontré des problèmes avec les adresses des different modules (RTC, TMU, etc...) (normalement non car tout est à la même place).
Le clavier est différent ? ou fonctionne-t-il toujours aussi bizarrement ?
As-tu changer là où gint s'installais en RAM ? Comment peux-tu être sûr du rien n'est écrasé, car tu as dit que Casio a conscience de la nouvelle taille de la RAM ?
À quand une release de gint ? (ce n'est pas que j'adore me perdre dans le code de gint, mais un peu quand même )
Citer : Posté le 17/05/2019 12:29 | #
Eh bien, c'est facile, je ne l'ai pas fait : j'ai détecté la version d'OS 03.x. C'est suffisamment "correct" car on sait que l'OS utilise le nouveau driver de l'écran si et seulement si il est en version 3. Donc gint utilise toujours le même driver que l'OS... qui est normalement le bon. Mais ça ne marchera pas si on fait des changements d'OS avec d'autres machines (qui ne marchent déjà pas car le driver système n'est pas bon !).
TMU et clavier marchent, RTC je n'ai pas encore testé mais je suis persuadé que c'est bon. Tout ça c'est sur le MPU. En tous cas tout gint marche pareil depuis que j'ai changé l'écran.
Je n'ai pas changé la zone où gint s'installe en RAM, qui est dans la première moitité (date de l'époque de Kristaba tout ça). Je n'ai pas de garantie que ça doit marcher, mais ça marche.
Je suis en train de faire les fonctions de rendu de texte pour la Graph 90. C'est un peu compliqué parce qu'il faut l'optimiser correctement sinon tu perds des précieux FPS dans les applications... et c'est plus crucial que sur les Graphs mono. Tu peux déjà utiliser la version sur la branch compat sur Gitea comme l'ancienne, mais toutes les fonctions ne sont pas là.
Je fais au plus vite, dès que je serai plus coincé dans les problèmes au Canada.
Citer : Posté le 22/06/2019 21:34 | # | Fichier joint
Un mois plus tard, voici la version de rendu de texte pour la Graph 90+E. J'ai débuggé au passages les polices proportionnelles, qui sont beaucoup plus agréables sur cet écran. Vous noterez qu'il y a aussi des lettres qui descendent sous la ligne de base (g, j, la virgule...).
J'ai fait 5 polices prototypes avant d'arriver à un rendu qui me convienne et équilibre un bon confort visuel avec une taille raisonnable. Je suis content du résultat !
Reste encore le dessin d'images sur Graph 90+E, qui sera une horreur à implémenter mais qu'il faut faire vraiment bien sinon les performances poseront des problèmes. Je vous tiens au courant !
Citer : Posté le 22/06/2019 23:23 | #
Wow ça rend super bien !!
Comment tu as géré les fonts ?
C'est une image bitmap que tu lis ? ou à la compilation tu génères les données en brut dans un tableau ?
Il te reste seulement le dessin pour prizm ?
Gint pour fx9860g est entièrement fini actuellement ?
En tout cas, merci beaucoup pour ce projet qui m'est très inspirant <3
Citer : Posté le 22/06/2019 23:29 | # | Fichier joint
Les polices sont converties par fxconv à partir d'une image et de quelques métadonnées que je passe actuellement sur la ligne de commande.
Voilà l'image d'origine (x2) :
À la compilation, je génère des données (une structure essentiellement) contenant un certain encodage de la police fait pour que le rendu soit rapide. Bon là sur Graph 90 c'est très décent mais c'est pas fulgurant comme sur Graph 75. Je pourrais les générer dans un tableau mais je trouve ça très moche donc je génère à la place un fichier object avec une section .data déclarant un unique symbole (variable) dont le nom est choisi à la conversion.
Pour la Graph 90, il ne me reste que le dessin et je peux reprendre le tronc commun. Gint pour Graph 75 n'est pas tout à fait fini car dans mon procédé de réécriture/portage, je me suis arrêté pour faire le dessin sur Graph 90 avant de finir le clavier et quelques autres éléments. Mais il n'y a rien de nouveau à faire pour atteindre la version 2 sur Graph 75, juste récupérer et bouger un peu du code existant.
Content que ça te plaise !
Citer : Posté le 22/06/2019 23:46 | #
Jolie police. Si je peux me permettre, différencier un poil plus le zéro du O (avec un point, une barre, whatever) est pas plus mal niveau lisibilité
Citer : Posté le 22/06/2019 23:56 | #
C'était fait sur la photo... mais je trouve ça pas terrible. La forme est déjà différente (contrairement au 5x7) et la barre transervsale est plus épaisse que les contours, ça se voit sur la photo. Franchement je me fie au contexte...
Merci du reste, ça fait plaisir
Ajouté le 23/06/2019 à 16:32 :
J'ai fini de corriger le clipping, ce qui signifie que le texte peut dépasser de l'écran sans problème quand vous dessinez.
Citer : Posté le 24/06/2019 02:08 | # | Fichier joint
Voici une petite photo d'une exception du processeur (aka System ERROR) pour la Graph 90+E. Pour l'instant c'est intégré avec les mains mais ça vous ne le verrez jamais.
On retrouve essentiellement les mêmes infos que pour une SysERROR, mais j'ai la place d'en rajouter pas mal.
Ajouté le 28/06/2019 à 21:27 :
Et soudain je réalise que même quand je supprime des headers dans les sources, je peux toujours compiler car il va chercher les headers dans le dossier où j'ai installé la version précédente. Diantre, c'était un coup à se faire bien avoir. '-'
Citer : Posté le 28/06/2019 22:59 | #
Y a pas moyen pour l'affichage des exceptions de récupérer TEA et décoder l'exception pour tenter de voir si c'est un souci d'alignement ? J'ai un draft de ce genre plus ou moins dans mes brouillons :
uint32_t *TEA = (void*)0xFF00000C; /* exception address */
void handle_exc(void)
{
uint32_t spc = get_spc();
uint32_t code = *EXPEVT & 0x7FF;
switch (spc & 0xF000) {
case 0x0000:
switch (spc & 0x000F) {
case 0x0003:
/* `bsrf rm`, `braf rm`, `pref @rm`: jump. */
type = INST;
break;
case 0x0004: /* FALLTHRU */
case 0x0005: /* FALLTHRU */
case 0x0006:
/* `mov.<size> rm, @(r0, rn)` */
type = DATA;
break;
}
}
}
Mon blog ⋅ Mes autres projets
Citer : Posté le 29/06/2019 05:08 | #
Si, on peut faire ça, j'y ai pensé il y a pas longtemps. Mais j'ai pas forcément envie d'embarquer un désassembleur dans le gestionnaire d'exceptions...
Citer : Posté le 29/06/2019 11:51 | #
Pas besoin d'embarquer un assembleur complet, il n'y a pas tant d'instructions que ça qui interagissent avec la mémoire.
Mon blog ⋅ Mes autres projets
Citer : Posté le 29/06/2019 15:23 | #
Ben 65 quand même, après je dis pas que les opcodes sont difficiles à sélectionner (enfin c'est "non trivial").
En plus il faut récupérer les opérandes et la taille de l'opération sinon tu peux pas vérifier que c'est effectivement mal aligné.
Du reste j'ai mis "probably" parce que je prends des précautions mais c'est nécessairement un problème d'alignement, parce que la seule autre possibilité c'est taper en-dehors de P0 en user mode, et on n'est pas en user mode.
Citer : Posté le 02/07/2019 14:06 | #
J'ai dû faire une fausse-manip' lors de l'installation :
Cela n'est pas le cas…
Citer : Posté le 02/07/2019 15:00 | #
Non en effet, il sont désormais dans le dossier du compilateur. Comme tu le vois, soit je travaille sur gint et le fxSDK, soit je travaille sur les tutoriels, mais dès que je fais l'un l'autre se retrouve en retard... >_>
Voilà comment trouver le dossier. Demande au compilateur où est le binaire de gint :
/home/el/opt/sh3eb-elf-2.31.1-8.2.0/lib/gcc/sh3eb-elf/8.2.0/libgint-fx.a
Ensuite déplace-toi dans le dossier indiqué puis dans include/gint :
% cd include/gint
Et voilà, tu y es.
defs mpu display-cg.h display.h drivers.h hardware.h keycodes.h syscalls.h
drivers clock.h display-fx.h dma.h gint.h keyboard.h rtc.h timer.h
Citer : Posté le 02/07/2019 15:03 | #
Il ne veut pas, j'ai des erreurs de syntaxe :
/Users/antoine/gcc/sh3eb-elf-2.32-8.3.0/lib/gcc/sh3eb-elf/8.3.0/libgint-fx.a: line 1: syntax error near unexpected token `newline'
/Users/antoine/gcc/sh3eb-elf-2.32-8.3.0/lib/gcc/sh3eb-elf/8.3.0/libgint-fx.a: line 1: `!<arch>'
Citer : Posté le 02/07/2019 15:05 | #
Mais... mais enfin, la ligne de commande... x)
Est-ce que tu comprends ce que tu as tapé ? Tu as indiqué le nom d'un fichier, libgint-fx.a, tout seul. Tu as tenté d'exécuter un fichier de gint qui... n'est pas là pour ça.
Relis mes exemples, tu verras que tu as oublié plusieurs choses.
Citer : Posté le 02/07/2019 15:07 | #
Ah oui tiens… le plus drôle c'est que la suite marche très bien…
Citer : Posté le 05/07/2019 02:16 | #
Je découvre que même créer un fichier n'est pas trivial sur la Graph 35+E II et peut causer des crashs... le système de fichiers c'est vraiment pas gagné.