The fxSDK is a development kit for CASIO calculators of the fx-9860G and fx-CG series. It is based on gint, a unikernel that provides a free-standing runtime for add-ins with new APIs, custom drivers and advanced performance tricks. This has been my main project since about 2015 so I'm excited to introduce it! 馃榿

The SDK works on Linux, Mac OS with some tweaks, and WSL on Windows. It is based on the latest gcc for SH3/SH4, using a custom (slightly incomplete) C99 libc with a ported math library, and the latest libstdc++ supporting C++20. The canonical build system for libs and add-ins is CMake, with a normal-enough setup that dual-targeting calculators and PCs is reasonably easy. All of this is tied with a package-manager-like tool for automating installs.

The unikernel, gint, provides the runtime for add-ins (like libfxcg). It has its own drivers which it runs by taking control of the hardware from the OS, which means it gives add-ins full access to the display, timers, DMA, DSP, and interrupts in general. Add-ins can still programmatically switch between gint and the normal OS runtime, commonly to invoke the main menu or to access the file system, for which there is a Unix/libc interface (open/fopen/opendir).

gint's focal point (and the most exciting part for me) is performance. It comes with a profiling library that can measure instruction sequences down to the cycle, very efficient image rendering, and it uses many assembler optimization techniques that I believe I am the first to use. I've had some impressive results, such as games running at 100 FPS full-screen on simple frames on the fx-CG 50 with no overclock (* when using a pretty crazy rendering pipeline).

Some random highlights of using gint include a streamlined system for converting images, fonts and other assets at compile-time; a USB driver that allows you to take screenshots and video capture of add-ins in real-time (with some slowdown); and access to a ton more memory, both through extra heap arenas in gint's memory allocator and through custom linker sections for on-chip memory.

The main downsides of using it stem from lost interactions with the OS, so it works best for applications that don't try to integrate with the OS' UI or look-and-feel, like games. You also have to carry the library and kernel code in add-ins, making G3A files larger (usually by 50-100 kiB).

-

The fxSDK has long been the system of choice for writing add-ins on Plan猫te Casio. Initially I was hesitant to advertise it here because I didn't want to "compete" with the PrizmSDK, but seeing as there is little activity I'm hoping I can help and inspire some of you to pick up your fx-CG again. 馃檪

Since I've been at it actively for 7 years I have a ton of cool stories and ideas I want to share, but that would never fit on a single post. 馃槃 I'll stop here for now, let me know if you want to learn more about any of the things I briefly touched upon!

If you want to try out the SDK, start at the fxSDK repository's README which will walk through the install process through all of the relevant repositories.
Lephe wrote:

gint's focal point (and the most exciting part for me) is performance. It comes with a profiling library that can measure instruction sequences down to the cycle, very efficient image rendering, and it uses many assembler optimization techniques that I believe I am the first to use. I've had some impressive results, such as games running at 100 FPS full-screen on simple frames on the fx-CG 50 with no overclock (* when using a pretty crazy rendering pipeline).


Are there any performance benefits other than assembly optimisation?
And, could these optimisations be implemented in something like libfxcg, or do they only work with the specific gint way of running things?
For the availability in libfxcg, I'd say it's about 50/50! Many small things depend on controlling the hardware, eg. the TMU for the profiling, the DSP for rendering, or the DMA for memory copies. You can access the hardware in libfxcg, but you don't have interrupts and you can mess up the OS. Some tools only work in gint, like async USB or higher-precision timers. But in the end, most of the assembly/low-level programming techniques like using on-chip memory would easily transpose to libfxcg, and they already carry a lot of power.

There are some performance benefits outside of assembly optimization; examples include the DMA-based dclear() function (Bdisp_AllClr_VRAM) which is about 2.5x faster then using the CPU, a fully asynchronous dupdate() (Bdisp_PutDisp_DD) method, or general benefits of using hardware interrupts in terms of latency.

In my experience, the most useful part is actually having easy/automatic access to these features, so that for example the SDK automatically converts images to a format that has a variety of fast rendering functions and users don't need to worry about it.

As a side note, getting the optimized assembly right is surprisingly hard! I think I spent 20-30 hours on the image renderers for example. There are many things to consider: local superscalar parallelism obviously, but also stalls and delays in the pipeline, branching loops vs. DSP loops, branchless tricks, DSP register abuses, and of course on a higher level memory speed (both read/write), caching, bus structure, etc. I'm sure some of you will have new ideas/insights to improve the performance even further.
is there any short documentation for gint ?
And how i can use gint and fxSDK with C++ ? and use any of cppp libraries like <vector> , <map> ?
Basically the documentation is coming with the header files, but you can also find some interesting stuff in the tutorial here (sorry that's in french) : https://www.planet-casio.com/Fr/forums/topic14914-1-tutoriels-dutilisation-de-gint.html

Feel free to ask questions on Planete Casio forum or shoutbox, or also here in case of need if you have questions, Lephe will be happy to help or myself if I can.

Basically to use C++ with gint, you need to respect several steps:
- specify that you are using C++ language with the directive : project(addin VERSION 1.0.0 LANGUAGES CXX) in CMakeList.txt
- add reference to the langage C++ with the -std option in target compile option : target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -std=c++20) in CMakeList.txt (in that case I target to use C++ 20 specification)
- if you plan to use C++ stuff (STL), dont forget to add the stdc++ library at linking stage : target_link_libraries(myaddin Gint::Gint -lstdc++)


An example is given here : https://gitea.planet-casio.com/Slyvtt/cBox2D_App/src/branch/main/CMakeLists.txt

Then for code you can use <vector>, <list>, <deque> ... as usual
Thanks Sly. Yes the headers are the main source of documentation. I realize it's a bit unappealing but they're written in a documentation style so they should still be relatively clear. For C++ make sure to add -lstdc++ at the end of the list of libraries (more specifically after gint and any other high-level library, before libc and libgcc if they are listed).
I had this issue for a while now that many of the add-ins found on Plan猫te Casio, which are built with fxSDK and gint, do not start on my Casio fx-CG50.
The add-ins are showing up in the main menu but when trying to launch some of them nothing happens. There's not even a loading indicator.

The issue seems to be related to the internal add-in name. If I build it without a name it always starts on my calc:
Code:
if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
  generate_g3a(TARGET HelloWorld OUTPUT "HelloWorld.g3a"
    NAME "" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)

I could also fix other add-ins by removing the name and rebuilding the G3A:
1. Copy the binary starting from 0x7000 in the G3A and save it to addin.bin for example.
2. Then dump the icons with

Code:
g3a-icondump addin.g3a

3. Finally create the G3A again without a name and with the dumped icons/binary:

Code:
mkg3a -i sel:sel.bmp -i uns:uns.bmp -n "" addin.bin

This python script automates the entire process.

I tested many add-ins all with internal names from Plan猫te Casio. The date is the modified date and shows which version I tested. Interestingly some add-ins start even though they have an internal name so I'm not sure what triggers this issue:

Working:
- 2026-04-18 18:42 https://www.planet-casio.com/Fr/programmes/programme4566-last-boson-x-yatis-lephe-jeux-add-ins.html
- 2025-07-07 02:47 https://www.planet-casio.com/Fr/programmes/programme4568-last-raycasting-farhi-jeux-bric-a-brac.html
- 2024-10-27 23:55 https://www.planet-casio.com/Fr/programmes/programme4470-last-wonder-aces-massena-jeux-actionsport.html
- 2024-08-12 16:35 https://www.planet-casio.com/Fr/programmes/programme4445-last-racer3d-cg-mb88-jeux-add-ins.html
- 2024-02-09 15:22 https://www.planet-casio.com/Fr/programmes/programme4385-last-sudosolver-jhb-jeux-reflexion.html
- 2023-12-21 12:03 https://www.planet-casio.com/Fr/programmes/programme4377-last-geetetris-jhb-jeux-reflexion.html
- 2023-05-23 01:13 https://www.planet-casio.com/Fr/programmes/programme4346-last-lecteur-de-texte-lephenixnoir-utilitaires-add-ins.html
- 2023-04-30 03:25 https://www.planet-casio.com/Fr/programmes/programme4341-last-chaos-drop-lephenixnoir-jeux-add-ins.html
- 2023-04-10 12:49 https://www.planet-casio.com/Fr/programmes/programme4336-last-the-limg-image-editor-mb88-utilitaires-add-ins.html
- 2023-02-09 17:05 https://www.planet-casio.com/Fr/programmes/programme4268-last-maverick-bird-lephenixnoir-jeux-add-ins.html
- 2023-02-05 21:41 https://www.planet-casio.com/Fr/programmes/programme4312-last-shmup-slyvtt-jeux-directiontir.html
- 2022-10-06 21:31 https://www.planet-casio.com/Fr/programmes/programme4297-last-zyperzetron-2000-massena-jeux-actionsport.html
- 2022-04-12 02:03 https://www.planet-casio.com/Fr/programmes/programme4240-last-teh-moon-show-massena-jeux-add-ins.html
- 2022-04-10 16:37 https://www.planet-casio.com/Fr/programmes/programme4236-last-3d-pong-alice-jeux-directiontir.html
- 2021-08-08 23:16 https://www.planet-casio.com/Fr/programmes/programme4154-last-momento-kikoodx-jeux-actionsport.html
- 2022-06-24 22:13 https://www.planet-casio.com/Fr/programmes/programme4267-last-editeur-hexadecimal-lephenixnoir-utilitaires-add-ins.html

Not working:
- 2026-08-02 18:06 https://www.planet-casio.com/Fr/programmes/programme4657-last-droppy-slyvtt-jeux-actionsport.html
- 2026-08-02 18:03 https://www.planet-casio.com/Fr/programmes/programme4659-last-icicle-alice-jeux-strategie.html
- 2026-08-02 17:58 https://www.planet-casio.com/Fr/programmes/programme4655-last-dam-that-river-fcalva-jeux-strategie.html
- 2026-08-02 17:19 https://www.planet-casio.com/Fr/programmes/programme4656-last-laquarelle-lephenixnoir-jeux-add-ins.html
- 2025-08-26 23:19 https://www.planet-casio.com/Fr/programmes/programme1905-last-bust-a-move-eiyeron-jeux-add-ins.html
- 2025-03-27 21:31 https://www.planet-casio.com/Fr/programmes/programme4485-last-calibrate-calamari-utilitaires-graphisme.html
- 2023-05-31 13:33 https://www.planet-casio.com/Fr/programmes/programme4225-4-outrun-for-graph-90e-slyvtt-jeux-actionsport.html
- 2022-11-19 17:43 https://www.planet-casio.com/Fr/programmes/programme4238-last-after-burner-lephenixnoir-jeux-add-ins.html
- 2022-08-15 19:19 https://www.planet-casio.com/Fr/programmes/programme4173-last-duet-yatis-lephe-jeux-add-ins.html
- 2022-02-14 05:56 https://www.planet-casio.com/Fr/programmes/programme4210-last-magic-light-10-finally-slyvtt-jeux-reflexion.html
- 2022-01-09 11:16 https://www.planet-casio.com/Fr/programmes/programme4208-last-minesweeper-gladosse-jeux-reflexion.html
- 2021-11-13 16:35 https://www.planet-casio.com/Fr/programmes/programme4192-last-frozen-frenzy-massena-jeux-add-ins.html
- 2021-08-23 20:52 https://www.planet-casio.com/Fr/programmes/programme4100-last-ast3-c-tituya-jeux-add-ins.html
- 2020-08-26 19:00 https://www.planet-casio.com/Fr/programmes/programme4027-last-justtoomanymechanics-kikoodx-jeux-add-ins.html


Has anyone else seen this problem before?
This has been reported just these last few days on Plan猫te Casio as well.

It is a known fact that an add-in with a wrong internal name will not load. What I remember is that the internal name must be @NAME where "NAME" must consist of at most 7 letters.

The internal names for the add-ins you identified as working were:

@BOSONX (6)
@RAYCASTING (10)
@WNDRACE (7)
@RACERD (6)
@SUDOSOLVER (10)
@GEETETRIS (9)
@TEXTVIEWER (10)
@CHAOSDROP (9)
@LIMGEDITOR (10)
@MAVERICK (8 )
@MYSHMUP (7)
@ZZ (2)
@MOON SHOW (9, including a space!)
@3D PONG (7, including a space!)
@MOMENTO (7)
@HEXEDITOR (9)

And the internal names that are not working were:

@DROPPY (6)
@MYADDIN (7) (this is Icicle by Alice)
@DAMTHATRIV (10)
@LAQUARELLE (10)
@BAM (3)
@CALIBRATE (9)
@OUTRUN (6)
@AFTERBURNE (10)
@DUET (4)
@MAGICLIGH (9)
@MINESWEEP (9)
@FROZEN FR (9, including a space!)
@AST3 (4)
@JTMM (4)

I checked and what fxgxa does is:

- g1a header is documented as having an 8-byte internal name at 0x020, followed by 3 unknown bytes (so could go up to 11 in theory); fxgxa limits to 8 bytes.
- g3a header is documented as having an 11-byte internal name at 0x060; fxgxa limits to 11 bytes.

Note that the CMake command never specifies --internal, only -n, and therefore fxgxa should use its default, which shouldn't contain spaces, so there's at least something not quite right.

Anyway, to the most important point, I see no obvious criterion that separates these two groups. The code that loads add-in in the OS is known so I can look into that to figure out the exact criterion.

Removing internal names is not really satisfactory as some data (e.g. main memory files) are tracked based on it, and I'm not sure duplicate internal names are intended.

Finally, a few people tested l'Aquarelle lately as it was an entry in a contest, and:
- Mb88, who has 3.60.xx0x said @LAQUARELLE failed, @CPC worked, @LAQUARE failed
- Alice, who has 3.60.xx0x, said @LAQUARELLE worked (!!)

The non-determinism is a bit scary. >_<"
@DMASTER also failed on my calculator, as well as @DESAL if I recall correctly. I tried those when I had issues when changing the name of my CPC#33 game (I'm improving it further but the original version is in the first file for the juges and has the tag "alpha" in the repo.). I have 03.60.2202. It would be interesting to see if Alice has the exact same version by comparing dumps. You said the OS can be dumped with gintctl, right?

If others also have issues with internal names, they can use the little tool I coded yesterday. It allows one to patch the internal name: https://git.planet-casio.com/mibi88/internal_fix.

I hope we can figure out what causes the issue 馃榿.
It might be a good idea to check how the OS actually loads add-ins. I wonder if there are differences between OS versions and maybe even the CG50 and Graph90+E.

I tested all these add-ins on OS 03.70.0202.
I used mibi88's tool to check what internal names work in L'Aquarelle:
@LAQUARELLE, @CPC and @LAQUARE all failed for me.

Also updated my script so it no longer removes the addin name and only clears the internal name to @. I know this is not a great solution but with this name every add-in always starts successfully for me. But I added the option to specify a custom internal name too.
I've been checking the code and I have a first theory. When you open an add-in a folder is created in the MCS (main memory) with the add-in's internal name as folder name. If this fails, the add-in does not start and we don't reach the point where any filesystems ops are done so you wouldn't get the hourglass/spinning symbol.

Now, the main known reason why MCS_CreateDirectory() can fail is if the MCS runs out of directory entries. This holds up decently as a theory:
* This would explain why there is bizarre state and the same OS sometimes accepts, sometimes refuses the app
* This would explain why using "@" works, as this would share a single folder
* However this would imply that once the MCS is out of directory entries, no new add-ins could work, which doesn't seem to match reality. I don't know if there is a mechanism to recycle entries automatically or not.

We could test that theory by calling MCS_CreateDirectory() manually with different names on calculators that encounter the failures. For that:
* Documentation of the function on the old models: https://bible.planet-casio.com/simlo/chm/v20/fx_legacy_MCS.htm
* Syscall numbers on the CG-50: https://bible.planet-casio.com/simlo/chm/v20/fx_fxCG20_syscalls.htm (MCS_CreateDirectory is 0x1515)

The test would look like this:

Code:
int dirno;
int rc = MCS_CreateDirectory("@LAQUARE", &dirno);
// rc = 0: Success
// rc = 0x42: Already exists (also counts as success)
// Anything else: failure (notably 0x43, directly listing full)


The contents of the MCS can also be browsed in the secret menu: power off, OPTN + x10^ + AC/ON, then on the popup, sequence 5, 9, 6, 3. Counting the number of entries should us with clues as to whether that might be the issue. I can't check right now so I'll come back to it later, but you might find more data before I get a chance.
I made an addin that allows you to input a name and see the return code for MCS_CreateDirectory: https://app.filen.io/#/d/28c07e43-c5c3-44ca-ad29-e550a8525d32%23584d39536163424862437433445f6e47776765323872444834556d5259346b31

I always get 0x40 and it seems that I cannot create any directory regardless of what name I try. So I guess it's full. The list is also very long in the secret menu.
But in the emulator I could create them and it gives 0 as a result. But once they are created you can't create them again and it's back to 0x40. I never saw 0x42 or 0x43 in my testing.

Edit:
Added the 0x43 error code to the addin and fixed some bugs.
Also why is there a second parameter in your example and the docs? All headers in the current PrizmSDK only declare:
Code:
int MCS_CreateDirectory(unsigned char *dir);

I checked the list in the secret menu and there are 107 entries (if I didn't miscount).
5 of them have no @ in front of them (system, library, Prizoop, Nesizm, main)

I feel like there might be limit of around 100 MCS directories.

Edit 2:
Im planning to make a MCSUtil add-in, that allows browsing the dir list and delete individual or all dirs.
I could already get a missing syscall (

Code:
int MCS_GetDirectoryEntryByNumber( char dirno, TMainMemoryDirectoryEntry*pdir )
) that's not in the PrizmSDK working because you can define them yourself.
I included now the correct syscall that has

Code:
int MCS_CreateDirectory(unsigned char *dir, char* dirno);
and with that I get 0x42 for existing dirs and 0x43 for everything else.
Also maybe it could show the current amount of dir entries out of the max in the main menu.
You can find the current progress here: https://github.com/Computer-Freak-2004/MCSUtil
Thanks. LDA told me he cleared his main memory and the problem went away. This seems like a good sign that we have the correct explanation.

An add-in to clear extra entries is a great idea, assuming of course you set its internal name to "@", otherwise it might not work when most needed ;p

Have you confirmed whether entries existing in the MCS is correlated with add-ins starting or not?
Quote:
An add-in to clear extra entries is a great idea, assuming of course you set its internal name to "@", otherwise it might not work when most needed ;p

Yes I already thought about that xD:

Code:
MKG3AFLAGS := -n basic:"MCS Util" -n internal:"" -i uns:../unselected.bmp -i sel:../selected.bmp

Quote:
Have you confirmed whether entries existing in the MCS is correlated with add-ins starting or not?

Yes, once I fill up all MCS dirs and try to start an add-in with a new internal name it doesn't work. It can't create a new dir and fails with 0x43. But after I just delete one dir it works again and I can see the new entry in the list.
Great! Empty string as internal name will fail with error 0xf0; I checked this in the code. You most likely need the "@". Maybe mkg3a adds it automatically...
No, I don't need to add an extra "@". You can see in the hexdump of my G3A that there is an @:

Code:
陋卢陆炉聬藛拧聧脫每镁每镁每镁每每__搂            I!聫          0艙              MCS Test                      聽聽@          MCS Test                MCS Test           
Yeah so mkg3a adds it for you, same thing anyway.
The add-in is finished: https://github.com/Computer-Freak-2004/MCSUtil
It would be great if you could test it. After that I will upload it to the Cemetech Archives.

This add-in uses 2 syscalls (0x1515 and 0x1533) that are not defined in the latest PrizmSDK 0.6. So does that mean I would need another version with the older addresses (0x0363 and 0x037D) for the CG10?
Also do the rest of the already defined syscalls in PrizmSDK work on all fx-CG calc models (CG10/20/50)?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement