Hi all.

I've been scouring the internet for a while now trying to find a method on actually finding/getting syscalls.

I've found a few places where they are found e.g. WikiPrizm (looks outdated) and fxdoc by Lephenixnoir but even that is 2 years old.

I'm looking to get them for the latest OS version 3.60.
If you just want a list of syscalls the most comprehensive is SimLo's original. I created the fxdoc repository to share notes with Yatis, but we didn't do as much reverse-engineering as I imagined so unfortunately there's little to be found there. We spend more time on device drivers than syscalls because we both run our own kernels on the fx-CG and don't use OS-provided functionality anymore.

If you want to study them for yourself, the method is fairly simple; if you disassemble at 0x80020070, you get this syscall execution code:

Code:
 80020070:  d202   mov.l   0x80673c90, r2
 80020072:  4008   shll2   r0
 80020074:  002e   mov.l   @(r0,r2), r0
 80020076:  402b   jmp     @r0
 80020078:  0009   nop

This gives you the address of the syscall table, which here is 0x80673c90 (Graph 90+E OS 3.40).

Every entry is a pointer; here are the first 16 ones :

Code:
  0x80673c90:   8002c548  8002c550  8002c55e  8002c5a2   ...H ...P ...^ ....
  0x80673ca0:   8002c64a  8002c7b0  8002c7c0  8002c7fa   ...J .... .... ....
  0x80673cb0:   8002c834  8002c84c  8002c8a4  8002c8e6   ...4 ...L .... ....
  0x80673cc0:   8002c918  8002c98a  8002c992  8002c99a   .... .... .... ....

You can disassemble them; a few point to data. Once you find addresses that don't point to valid memory you can conclude that you've found the end of the table. This is the info that my tool gives:

Code:
Syscall information:
  Syscall table address                      (0x8002007c)  :  0x80673c90
  Entries that point to valid memory                       :  0x1f68
  First seemingly invalid entry                            :  0x01010000
  Syscall entries outside ROM:
    (none)

WikiPrizm is fairly up-to-date, not because it's very active but rather because the OS almost never changes. When I tried to make a collection of all hardware-related resources I ended up only finding a couple of pages that I believe are not up-to-date, and none of them are about syscalls.

Everything that you can find documented as far back as 2011 you can pretty safely trust still works. If there's one thing that never changes, it's the syscall tables; on the black-and-white models they date back about 15 years with no major change...

Disassembling is pretty easy, unwinding the technical stack is probably more challenging. Device drivers are not very difficult to work with all things considered, because they only go a few function calls deep before touching hardware registers, which exposes the role of the routines. However, working with functions well hidden inside the OS can be horrendous ; GetKey() for instance is a practical nightmare IMO.
Lephe wrote:
If you just want a list of syscalls the most comprehensive is SimLo's original. I created the fxdoc repository to share notes with Yatis, but we didn't do as much reverse-engineering as I imagined so unfortunately there's little to be found there. We spend more time on device drivers than syscalls because we both run our own kernels on the fx-CG and don't use OS-provided functionality anymore.

If you want to study them for yourself, the method is fairly simple; if you disassemble at 0x80020070, you get this syscall execution code:

Code:
 80020070:  d202   mov.l   0x80673c90, r2
 80020072:  4008   shll2   r0
 80020074:  002e   mov.l   @(r0,r2), r0
 80020076:  402b   jmp     @r0
 80020078:  0009   nop

This gives you the address of the syscall table, which here is 0x80673c90 (Graph 90+E OS 3.40).

Every entry is a pointer; here are the first 16 ones :

Code:
  0x80673c90:   8002c548  8002c550  8002c55e  8002c5a2   ...H ...P ...^ ....
  0x80673ca0:   8002c64a  8002c7b0  8002c7c0  8002c7fa   ...J .... .... ....
  0x80673cb0:   8002c834  8002c84c  8002c8a4  8002c8e6   ...4 ...L .... ....
  0x80673cc0:   8002c918  8002c98a  8002c992  8002c99a   .... .... .... ....

You can disassemble them; a few point to data. Once you find addresses that don't point to valid memory you can conclude that you've found the end of the table. This is the info that my tool gives:

Code:
Syscall information:
  Syscall table address                      (0x8002007c)  :  0x80673c90
  Entries that point to valid memory                       :  0x1f68
  First seemingly invalid entry                            :  0x01010000
  Syscall entries outside ROM:
    (none)

WikiPrizm is fairly up-to-date, not because it's very active but rather because the OS almost never changes. When I tried to make a collection of all hardware-related resources I ended up only finding a couple of pages that I believe are not up-to-date, and none of them are about syscalls.

Everything that you can find documented as far back as 2011 you can pretty safely trust still works. If there's one thing that never changes, it's the syscall tables; on the black-and-white models they date back about 15 years with no major change...

Disassembling is pretty easy, unwinding the technical stack is probably more challenging. Device drivers are not very difficult to work with all things considered, because they only go a few function calls deep before touching hardware registers, which exposes the role of the routines. However, working with functions well hidden inside the OS can be horrendous ; GetKey() for instance is a practical nightmare IMO.


Really insightful, thanks for responding! I have extracted the firmware from the OS Update tool but currently having issues loading it into IDA. Have you got any tips for this?
You're welcome! I don't use IDA so I can't guide you directly; a screenshot of your problem might help. For it to work you need to load the flat binary at 0x80000000 and preferably also at 0xa0000000 if possible. Architecture is SH4AL-DSP but SH-4A might be good too, or even SH-3 is a sane default.

Make sure you have fixed and decompressed the OS image obviously.
Lephe wrote:
You're welcome! I don't use IDA so I can't guide you directly; a screenshot of your problem might help. For it to work you need to load the flat binary at 0x80000000 and preferably also at 0xa0000000 if possible. Architecture is SH4AL-DSP but SH-4A might be good too, or even SH-3 is a sane default.

Make sure you have fixed and decompressed the OS image obviously.


Yup it's decompressed (I can tell as there are CASIOABS strings and other OS related strings, and it sucessfully decompressed).

Currently I'm using IDA's "Renesas SH-4 (big endian) [SH4B]" (since I assumed it was big endian, using the little endian version has no change). Furthermore I'm creating a RAM section at 0x8C000000 (from this forum post) with a size of 0x10000 (64kb after referencing the datasheet of the CG-50's M12L64164A) and creating the ROM section at what you said 0x80000000, with the size being just the size of the file I'm loading (0xB60000 in this case). Then for IDA's loading address that is again 0x80000000. I chose the device specific setting as a SH7055, which shouldn't matter as it only changes where IDA puts the labels for the Model Specific Registers.

But now I'm stuck since it's asking me to mark an entry point and I have no clue where that is. Apologies for the wall of text!

EDIT: An afterthought but I'd thought I'd edit to ask; what do you use to disassemble the OS image?

EDIT 2: Yet another edit for clarification! I am loading the 3070 resource as I assume that is the one I need as it's the largest and 3069 and 3071 are probably bootloader, and well you don't want to mess with them!

Also on my firmware dumping endeavours I found that the MacOS versions of Casio's software actually have debug symbols included including the OS Updater and the emulator, you just need to extract the files from the .pkg for which there are tools out there to do so.
You're almost there! The entry point is where does the program start? In this case since it's the full OS+kernel, the question is where does it boot? And the answer is 0x80000000, just at the start. Smile

I use a custom disassembler with extra features, but I don't recommend using it because it's very rough/experimental, and surely not as good as IDA.

Yes loading 3070 is correct. 3069 IIRC is the installer; 3071 would be fine too, 3070 and 3071 are likely the fx-CG 50 and Graph 90+E (French equivalent) versions of the same OS.
Lephe wrote:
You're almost there! The entry point is where does the program start? In this case since it's the full OS+kernel, the question is where does it boot? And the answer is 0x80000000, just at the start. Smile

I use a custom disassembler with extra features, but I don't recommend using it because it's very rough/experimental, and surely not as good as IDA.

Yes loading 3070 is correct. 3069 IIRC is the installer; 3071 would be fine too, 3070 and 3071 are likely the fx-CG 50 and Graph 90+E (French equivalent) versions of the same OS.


I knew what an entry point was just didn't know if it was different and I even tried marking the start but it only gives any meaningful dissasembly up to 0x800000B0. Probably because after that it's a big block of 0x00 until you reach 0x300. But marking it at 0x340 gives some function (but not many).

I might give your disassembler a go and see where I get with that. Any insight on my issue would be much appreciated!
That's normal, the main "function" ends very quickly. There are series of subcalls and jumps leading all around the kernel. Here you can find a similar disassembly on the G-III OS, maybe it can give you an idea of what to look for.

You should configure IDA to explore functions recursively but I'm pretty sure this kind of thing is the default.

I know people have done it before in both IDA and Ghidra so you should be able too. ^^
Yep got it working now. Had to tweak a few kernel options and confirmed the syscall disassembly you sent in your first reply.

I do have a few more questions:

1. I see some strings here that are used during normal use of the CG-50 but have no xrefs. I assume this is because it's in a "Langdata" pack. Do we know how these strings are referenced?

2. Your fxdoc syscalls have different offsets than what libfxcg uses making it hard to confirm certain ones, what's up with that?

3. Again about your fxdoc repository; I see some syscalls are missing while they were known e.g. FrameColor. Was this intentional or was it because they are missing, or some other reason entirely?
Excellent! Good luck with your exploration.

For question 1, I don't actually know. There may simply be tables of strings that are not accessed directly.

For questions 2 and 3, that's because Yatis and me almost exclusively disassembled the fx series, which has a different syscall table. Some of the syscalls are identical, and the MPU is definitely the same, but the numbering is different (and the fx-CG has way more). For reference here is SimLo's syscall table for the fx series.
Thank you for the speedy reply! That makes sense. Although I do think there are more syscalls that just aren't documented yet because of certain things that the OS does that I can see to directly replicate with syscalls we have (e.g. showing a glyph on the screen at all times, or adding keybinds that can do something without our addin being the main process). IDA has very nicely identified all the syscalls in the table as subroutines that I can rename, jump to etc.

Upon further research I see how these strings are referenced now. In TestMode you can display a list of strings and their index. There are syscalls to get these strings as you can see here here and here.

Have you loaded modified versions of the OS onto the calculator before? And a tag on question can you load custom versions onto the emulator?

Also is the CPU actually Big Endian or is it little?

Thank you for all your help on this! You have been an invaluable source!
Loading modified OS images onto the calculator is a very sensitive idea because it could be used to bypass the exam mode. As many unfortunate events have proven before, this is the kind of topic that leads to manufacturers completely blocking third-party programs, forcing OS updates, signing code, etc. It's my personal conviction that such topics should not be exposed in public. You can do it yes, but if you must I humbly request you discuss it privately.

I haven't tried loading modified OS files on the emulator. I believe this can be done fairly easily because the emulator just has a ROM file that you could edit directly by just pasting your modified OS file over the start of it. If you test it, I'd be happy to know!

The CPU is big-endian. Actually it is bi-endian, it can work in both modes; there is a pin that selects the byte order. On CASIO calculators that pin is always hard-wired to big-endian.

I'm happy to help! If you find stuff or just disassemble and annotate code we would be honored to host links or information about it on https://bible.planet-casio.com/ as we try to maintain a comprehensive low-level resource there.
I completely understand the risk of Casio implementing more security and I see why this isn't really a publicly discussed topic (which is unfortunate if you ask me) and I have saw this before in various game modding communities I have been apart of.

I have actually viewed some resources and forum posts on planet-casio through my addin development. The latter weren't as useful to me as they probably were (mostly because I don't speak anything above a UK high-school level of French from a number of years ago now and some things got lost in Google translate). But it does seem like the most active place for Casio (probably because of their prevalence in France, and I assume a requirement? but not too sure there).

Anyway, thank you again for all your help. And if you do use Discord, a friend request would be very welcome: setmetatable#7259
Yes the state of information regarding OS updates is a bit ambiguous. To be honest, we're just all trying to enjoy ourselves making tools and games while not compromising the situation that makes it possible.

Planète Casio is indeed the community with the most activity right now; you're welcome to cross-post your work there if you want to reach out (as, unfortunately, few people have dual accounts on other communities such as Cemetech, and vice-versa). We're used to posts in English and translating when useful.

Even though I say that, you won't find more advice on using fx-CG syscalls than here, because a different SDK/API is most commonly used. ^^
  
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