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 » NESizm and Prizoop — Now on fx-CG100/Graph Math+!
Calcloverhk Hors ligne Membre Points: 444 Défis: 10 Message

NESizm and Prizoop — Now on fx-CG100/Graph Math+!

Posté le 14/01/2026 15:05

The day has finally come: NESizm and Prizoop are now available on the latest Classwiz calculators fx-CG100 and Graph Math+, with the same features and ROM support as in fx-CG50/Graph 90+E!


ROMs used: MANTLE.NES, Pokémon Red Version

A few years back, Thomas Williamson released NESizm and Prizoop that allow users to load their favorite NES and Gameboy (Color) ROMs into a Prizm fx-CG calculator. They unfortunately do not work on the latest calculators as Casio removed the ability to run add-ins natively.

As a remedy, Planète Casio released MPM to restore the add-ins, but at the current stage it only supports add-ins that are either compiled under fxSDK/gint, or adapted by directly mapping Graph Math+ address to each corresponding fx-CG50 syscall.

The MPM version of both NESizm and Prizoop released today use the one-to-one mapping approach, and thus only supports fx-CG100/Graph Math+ with OS 02.00.0202/02.00.2202. Any other OS version will lead to a system error as the addresses are different for each version.

I may update both emulator add-ins if MPM is updated with latest OS support, but finding correct addresses takes quite a lot of repetitive searches and I have to do so again every time the OS/MPM updates. I was able to quickly determine them thanks to Parisse's (developer of KhiCAS) syscall script and Lephe's fxos tools. Ultimately, they need to be ported to fxSDK/gint with rewrite that removes dependencies to legacy syscalls, but the effort is much larger due to API differences between fxSDK/gint and PrizmSDK.

Both emulators are attached to this thread. Have fun!

Fichier joint


Lephenixnoir En ligne Administrateur Points: 25912 Défis: 174 Message

Citer : Posté le 14/01/2026 15:20 | #


Incredible work! Can you list all the syscalls you had to replace? Ultimately MPM's loader mpm.bin will take care of intercepting syscalls which will work around the need to rebuild the applications all the time.
Mon graphe (28 Juin): (MPM ; v5 ; Azur ; passe gint 3 ; ...) || Rogue Life
Calcloverhk Hors ligne Membre Points: 444 Défis: 10 Message

Citer : Posté le 14/01/2026 15:54 | #


Lephenixnoir a écrit :
Incredible work! Can you list all the syscalls you had to replace? Ultimately MPM's loader mpm.bin will take care of intercepting syscalls which will work around the need to rebuild the applications all the time.

Bdisp_DDRegisterSelect        // 0x01A2, 0x80074268
Bdisp_DefineDMARange          // 0x01A3, 0x800742a0
Bdisp_WriteDDRegister3_bit7   // 0x01A6, 0x800743de
Bdisp_PutDisp_DD_stripe       // 0x0260, 0x8007a2da
Bdisp_AreaClr                 // 0x02B2, 0x8007bbcc
Bdisp_Fill_VRAM               // 0x0275, 0x8007a6ca
Bdisp_EnableColor             // 0x0921, 0x80115d50
Bfile_GetBlockAddress         // 0x1DAA, 0x80333cf2
SaveVRAM_1                    // 0x1E62, 0x80251824
LoadVRAM_1                    // 0x1E63, 0x80251838
CMT_Delay_micros              // 0x11D6, 0x80230b4e
MCS_WriteItem                 // 0x151A, 0x80259388
MCS_CreateDirectory           // 0x154B, 0x8025b166
MCSGetDlen2                   // 0x1562, 0x8025c392
MCSGetData1                   // 0x1563, 0x8025c3f8
RTC_GetTime                   // 0x02C0, 0x8007cbbc
Serial_IsOpen                 // 0x1BC6, 0x8030a89e
Serial_Open                   // 0x1BB7, 0x8030a358
Serial_Close                  // 0x1BB8, 0x8030a3f6
Serial_PollTX                 // 0x1BC0, 0x8030a6ea
Serial_PollRX                 // 0x1BBF, 0x8030a6d6
Serial_Read                   // 0x1BBA, 0x8030a4ee
Serial_Write                  // 0x1BBE, 0x8030a678

C.Basic Wiki Project progress as of 2024/2/12
   30%
Ptune4 (Submit SDRAM test result) | C.Basic developer
The reptile will say "Planète" and then "Casio".

Slyvtt Hors ligne Maître du Puzzle Points: 3083 Défis: 17 Message

Citer : Posté le 14/01/2026 18:58 | #


How do you manage the interception of the syscalls by mpm.bin ?

For SquishIt, I had to call the GetKeyWait syscall and then used a direct call to the address


uintptr_t GetKeyWaitOS_Address = 0x802382fe;
typedef int (*GetKeyWaitOS_func_t)(int* column, int* row, int type_of_waiting, int timeout_period, int menu, unsigned short* keycode);

int SquishIt_GetKeyWait( unsigned int keycode_to_check ) {
    GetKeyWaitOS_func_t GetKeyWaitOS = (GetKeyWaitOS_func_t) GetKeyWaitOS_Address;
    int retour;
    int column, row;
    int target_column, target_row;
    unsigned short keycode_returned;

    if      (keycode_to_check==KEY_EXIT)    {   target_column = 0x06;    target_row = 0x09; }
    else return 0;

    retour = GetKeyWaitOS( &column, &row, 1, 0, 0, &keycode_returned );
    if (retour == 1 && target_column==column && target_row==row) return 1;
    else return 0;

}


It works great but is a kind of pain in the a__ to code such trick.

(Had to do this cause this is called when already in a World Switch and hence the keyboard driver of gint is Off. So I needed to call directly the OS).

Maybe is there a better and simpler way to handle this.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Calcloverhk Hors ligne Membre Points: 444 Défis: 10 Message

Citer : Posté le 14/01/2026 19:42 | #


I adopt this kind of function cast from KhiCAS syscalls.c:

int GetKeyWait_OS(int*column, int*row, int type_of_waiting, int timeout_period, int menu, unsigned short*keycode) {
  int (*ptr)(int*column, int*row, int type_of_waiting, int timeout_period, int menu, unsigned short*keycode) = 0x802382fe;
  return ptr(column,row,type_of_waiting,timeout_period,menu,keycode);
}

You can omit the parameter names for ptr declaration (i.e. int (*ptr)(int*, int*, int, int, int, unsigned short*)) but simply copying the whole set is faster.
C.Basic Wiki Project progress as of 2024/2/12
   30%
Ptune4 (Submit SDRAM test result) | C.Basic developer
The reptile will say "Planète" and then "Casio".

Slyvtt Hors ligne Maître du Puzzle Points: 3083 Défis: 17 Message

Citer : Posté le 14/01/2026 20:56 | #


Ok so you are basically doing like me, your are directly striking the function address.
Thanks
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Calcloverhk Hors ligne Membre Points: 444 Défis: 10 Message

Citer : Posté le 16/01/2026 06:23 | #


I tried to define a global macro that cast address into a syscall name:
#define CAST(address, type, name, proto) \
  typedef type (*name##_func_t) proto; \
  name##_func_t name = (name##_func_t) (uintptr_t) address;

This condenses the definition into:
CAST(0x8007a6ca, void, Bdisp_Fill_VRAM, (int, int))
CAST(0x8007a2da, void, Bdisp_PutDisp_DD_stripe, (int, int))
CAST(0x80251824, void, SaveVRAM_1, (void))
...

However this causes System ERROR and I'm not sure what exactly went wrong. I do notice the size of libfxcg.a is reduced by adopting this casting, so something must be missing here.

I also have another macro that basically replicates the KhiCAS way of casting, but that requires an extra parameter for names in function call and prototype.
C.Basic Wiki Project progress as of 2024/2/12
   30%
Ptune4 (Submit SDRAM test result) | C.Basic developer
The reptile will say "Planète" and then "Casio".

Lephenixnoir En ligne Administrateur Points: 25912 Défis: 174 Message

Citer : Posté le 16/01/2026 10:47 | #


Probably because you're defining the symbols as function pointers instead of functions (this makes a difference at the call site).
Mon graphe (28 Juin): (MPM ; v5 ; Azur ; passe gint 3 ; ...) || Rogue Life
Calcloverhk Hors ligne Membre Points: 444 Défis: 10 Message

Citer : Posté le 16/01/2026 15:44 | #


In fact, this macro can even be simplified into a straightforward one for my use case:
#define CAST(address, name) \
  void name() { \
    void (*ptr)() = address; \
    return ptr(); \
  }

CAST(0x8030a89e, Serial_IsOpen)
CAST(0x8030a358, Serial_Open)
CAST(0x8030a3f6, Serial_Close)
...

I guess this still works because at the end of the day we call these syscalls as intended within the source files, whereas this is compiled in an entirely independent environment.
C.Basic Wiki Project progress as of 2024/2/12
   30%
Ptune4 (Submit SDRAM test result) | C.Basic developer
The reptile will say "Planète" and then "Casio".

Lephenixnoir En ligne Administrateur Points: 25912 Défis: 174 Message

Citer : Posté le 16/01/2026 16:11 | #


Technically in C if you construct a function (or function pointer) which has empty arguments then it accepts anything. This is unlike having void as arguments in which case it accepts no arguments. The difference between using "any arguments" vs. having a prototype is that no conversions can be applied, so e.g. if the function expects an uint64_t and you provide an uint32_t, the call will go very wrong, whereas if you give a prototype the compiler will insert a type conversion.

Anyway if you have a prototype at the call site you can do whatever you want when defining the syscall itself. Not having a prototype at the call site is a bit risky but will work in most cases because syscalls take parameters of reasonable types (basically all integers and pointers).
Mon graphe (28 Juin): (MPM ; v5 ; Azur ; passe gint 3 ; ...) || Rogue Life
Sansxd69wtf Hors ligne Membre Points: 6 Défis: 0 Message

Citer : Posté le 05/08/2026 07:05 | #


Really love your efforts for porting Prizoop and NESizm for the fx-CG100 . It opened up millions of games for my college calc. But 2 problems I face on my fx-CG100:

1. Saves and .gbc: I play zelda (Zelda Ages & Seasons). It works fine when I run the .gbc and it saves also correctly but when I close prizoop and open the .gbc again in prizoop, the save loads, but the gamescreen is stuck in a white background. this problem is not there when I run the .gbz with the save instead. (But I dont want the .gbz cause of lesser speed, performance and visual glitches)

2. Audio-Visual Speed Mismatch: Audio is 2x slower than the visuals. Faced it with zelda, MGS, super mario bros, pokemon, etc. I tried tweaking the clamp speed and frameskip settings but no matter what I do, the audio is always 2x slower than the visuals. It's very evident especially in the Undertale GBC and it ruins the gameplay

Can you get these issues checked?
Also would be so helpful if you could make a repo and post the updated CG100 prizoop project files.

----
[fx-CG100; OS ver. 02.00.0202; C876A2C005521BF_40]
-----

EDIT:
I dug out my CG50 yesterday and ran the original prizoop.g3a but it also has the same '2x slower audio' problem.
So it's not a bug in the port, it's a fault in the original prizoop's code.
@CalcLoverHK, could you post the ported prizoop project files? Would be very helpful.
Sansxd69wtf Hors ligne Membre Points: 6 Défis: 0 Message

Citer : Posté le 06/08/2026 08:50 | #


Okay so I think I have a explanation as to why this problem is there on my CG50 and CG100:

Older calcs like CG10/CG20 (which prizoop was primarily made for) ran at 58 MHz and the new CG50/CG100 runs at 118MHz which is nearly twice the speed of the older calcs.
Now prizoop uses asynchronous audio rendering to prevent the audio from stuttering and causing problems if im not wrong. So I think tswilliamson hardcoded a specific clock divider and sample rate for the serial port's code (whose values are for CG10/CG20).
On the faster fx-CG50/100, the graphics engine easily reaches a full 60 frames per second but as the internal audio timing is set to the same old values, the sound buffer still gets processed at half the speed of the visual frames generated....

I think since tswilliamson added CG50 compatibility near the end of prizoop's dev lifecycle, it mightve slipped his mind to change the values for the clock divider and sample rate to the new CG50.

Please let me know your opinions on my theory and would be VERY helpful if I could inspect the ported prizoop project files T-T
Calcloverhk Hors ligne Membre Points: 444 Défis: 10 Message

Citer : Posté le 10/08/2026 04:57 | #


Hi, sorry for the late reply. I saw your messages a couple days ago but couldn't take time to reply because I was working on other things. I also haven't digged into NESizm/Prizoop for a while, as I planned to port both of them to fxSDK and update with my current libsyscall work that has the infrastructure for multiple OS versions support, so bear with me if I make mistakes below.

About your Zelda GBC, I apologize that I might not be to fix this issue due to not knowing much about the inner working of Prizoop at the moment. I will try to see what exactly happens though.

The 2x audio speed difference indeed can happen, but it's not because of CPU speed, but rather the PFC (peripheral) clock. For reference, the PFC frequency in fx-CG10/20 and fx-CG50/100 is 14.74 MHz and 29.49 MHz respectively. However, that means if not treated properly, the audio pitch should be 2x faster, and you mentioned that it is slower instead. Hmm, this sounds weird to me.

(Edit: Actually doubling the CPU speed does affect the audio pitch and speed, but the final outcome should be tied to your clamp speed setting.)

Both NESizm and Prizoop are available on GitHub, and I did not change them that much rather than syscall mapping and UI adjustment. I will upload my changes on my fork later today, however.
C.Basic Wiki Project progress as of 2024/2/12
   30%
Ptune4 (Submit SDRAM test result) | C.Basic developer
The reptile will say "Planète" and then "Casio".


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:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
captcha
Rafraîchissez la page si vous souhaitez obtenir un nouveau CAPTCHA.

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