I’ve noticed a number of games available on this site for PRIZM calculators (space invaders, chess, senet, etc.) work fine on the CG10/20, but have broken graphics on the CG50. This has probably been asked before, but is there a workaround to fix these bugs without having to rewrite it all myself?
Yes so in general there isn't much to do. The #1 problem, which fixes almost all add-ins, is using a hardcoded VRAM address. Due to physical reasons the RAM on the fx-CG 50 starts at 0x8c000000, not 0x88000000, and so the VRAM moves as well.

Just use the GetVRAMAddress() syscall instead of the VRAM_ADDR macro (not sure how it's usually called), recompile, and most programs will work out of the box, and even on both platforms with the same g3a.

Additionally, many programs set some overclock on fx-CG 10/20 for a little added speed. The CPU of the fx-CG 50 natively runs faster than the fx-CG 10/20 (specifically twice as fast), and so this overclock step is no longer needed. It is even detrimental as the configuration it sets is slower than the default. This overclock step can thus be skipped. You can heuristically detect the fx-CG 50 with the stack address (if it's < 0x8c000000 -> fx-CG 10/20, if it's higher -> fx-CG 50).

I should also mention the icon style which has changed with the fx-CG 50 and has been backported to recent OS versions of the fx-CG 10/20. Old icons would benefit from a re-design.

Other than these simple considerations, I believe every program is different. Technical programs like emulators are extremely likely to have complicated memory layouts that would probably require the expertise of the author to port. I attempted to decipher CGDOOM once, but quickly gave up as there are so many memory-layout tricks, filesystem bypassing mechanisms, and generally an insane number of shenanigans that are hard to reverse-engineer and replicate on the CG-50.

As long as you don't get near these programs, and you have the source code, recompiling for the fx-CG 50 should be an easy and pleasant experience. ^^
Lephe wrote:
I attempted to decipher CGDOOM once, but quickly gave up as there are so many memory-layout tricks, filesystem bypassing mechanisms, and generally an insane number of shenanigans that are hard to reverse-engineer and replicate on the CG-50.

I will take it as a compliment Smile
CGDOOM is quite the tour the force indeed! My memories of dealing into it are admittedly quite painful, but this is mostly because of the complexity and the fact that I had no documentation (is there any by the way?). There is a reason why no similar program has appeared in years! ^^

If you ever want to port it, I would be glad to offer help. In France there is basically only the fx-CG 50, and it's a shame that CGDOOM cannot be played and advertised on this platform.
Lephe wrote:
...I would be glad to offer help.

I do not have fx-cg 50. Can you take current source code of CGDOOM, compile it and test on fx-cg 50?
If yes, we can try to fix it.
Yes I can! The most recent link I have for sources is https://martin.poupe.org/casio/cgdoom/cgdoom0.03src.zip , is that the correct one?

I no longer have my original port attempt, but I know the first few problems are about display and loading data from storage memory. Setting the VRAM addresses, disabling overclock etc. are the first obvious targets. Then IIRC, CGDOOM loads files by searching for for the first few bytes (or some kind of signature) on a 4k/page/sector/whatever-aligned address to find file fragments without querying the filesystem. This is probably what stopped me when I first wanted to port it.

If you have a chance, you can try to run the add-in on the fx-CG 50 emulator which is wonderfully close to actual hardware (I have run incredibly edgy programs on there with great success); the only major difference is that RAM is at the old fx-CG 10/20 address (0x88000000) and not the fx-CG 50 address (0x8c000000). Depending on how you want to tackle the port, this might save a lot of back-and-forth testing. ^^
Lephe wrote:
Yes I can! ...
Yes, it is my latest source, but there is an attempt to port cgdoom to fx cg-50 at https://github.com/ComputerNerd/cgdoom It contains the fix with GetVRAMAddress() and getSecondaryVramAddress(). You can try to merge these changes.
About the CreateFileMapping() function. As you probably already noticed, reading files from flash is very slow and there is a busy symbol. Moreover it takes RAM, when the data is already available in flash, which also can be read by pointer. So my idea is to find address of the file (wad) and read it directly. Unfortunately the file might be fragmented, so I have created file mapping, which is several records of pointer and size (of continuous data). I think I put some comments in the code. I think there is no need to change the code except to tune the addresses to match fx cg-50. The routine is pretty stupid, it reads the file per 4KB pieces and try to find each piece in flash. I think it can be optimised, the OS file read function seems to provide this address, but it is not important for porting.

Next thing is to tune RAM buffers. Do we have map of memory for fx cg50? There are rumors about 8MB of RAM in it. If this is true, cgdoom will work much better. fx cg20 has 2MB of RAM, but only about 1MB (in several pieces) was used for cgdoom

Sorry, but I did not develop anything for calculator for several years, so I forgot all the details. Please try to find the documentation from Simon Lothar (or anything more recent, if it exists)
Sorry for the delay. So I started from ComputerNerd's version, although there are some differences with the PrizmSDK: common/prizm.ld vs toolchain/prizm.x, -D_FXCG_MINICOMPAT (obviously) for compatibility ; and I also had to pull the platform.h header from your archive as ComputerNerd's version doesn't have one in CGDOOM-miniSDK/CGDOOM.

I still lack display_tools.h in my PrizmSDK, so I'm not confident I'm building it with the proper setup. Some update I made since my first attempt might have caused problems. Could you point me to the proper SDK source/version to use to compile CGDOOM? I'd rather solve one problem at a time and not mess around with the SDK as I'm not very familiar with it. ^^
Lephe wrote:
So I started from ComputerNerd's version

I noticed, that that project is incomplete, that is the reason I recommend you to ingegrate changes from it to cgdoom0.03. It should be compiled by Simon's mini SDK.
It's been quite some time but I do have some news.

I previously looked at the miniSDK setup instructions. It's not like it's unreasonable, but it's all from original fx-9860G SDK files and old versions of programs to build for which there seems to be no archive and no Git repository. While this might have made sense back in the day, digging up the old files would be quite painful and particularly error-prone, so I decided to let it rest and come back to it later.

When that specific later came about I proceeded with the PrizmSDK route but using the Jonimoose/libfxcg repository which is not customized by TSWilliamson. This one is much closer and I could get most the source files to build (with a tsunami of warnings) with minimal missing symbols at link time.

I just had to define calloc, getSecondaryVramAddress (for which I used syscall 0x1B0B), and remove the defines for Serial and BFile functions since the definitions want a specific version of the syscall calling code which I don't have; libfxcg provides theses syscalls anyway. I believe this is more or less how I went the first time, this should be good enough for a start, I see little room for bugs in these arrangements.

Right now I can get CGDOOM to link although RAM overflows by a health 429 kB. I'll dig into it and see if I can identify what's taking up all the space (hopefully something I included but shouldn't have).
Okay actually I pushed a little bit further. The linker script I used set the RAM size to 64 kiB, I just bumped that to the actual 512 kiB and it linked fine.

There are actually not any hardcoded RAM addresses apparently, my memory might have deceived me.

The add-in has no problem in accessing doom.wad; the "File Read" error disappears after transferring it. It now progresses up to a cryptic TLB miss error on a random address (TEA=6EA61CF4, PC=3), which is where the real fun begins. Time to comment out stuff and implement early exits until I narrow it down I guess.
So the problem above was because 6EA61CF4 (plus or minus some offset) made its way into the lump cache array even though it was supposed to be all-NULL at the start.

I tracked it down to CGDCalloc() not actually clearing the memory, which is extremely strange given that it does a simple call to memset(). All observations suggest that this call to memset() fails in some way; by contrast clearing byte-by-byte by hand with a loop (and a volatile pointer otherwise GCC turns the loop into a call to memset()) works.

The strange part about it is that the memset() function is obviously correct. It's provided by libfxcg because of the setup I have, but it's been in use for years and the assembler code (which I checked) shows nothing suspicious.

I replaced the call to memset() by a loop for now, but I am slightly worried since there are many others calls to memset() in the code.

(I have checked that neither the stack nor the data segment intersect the heap, but maybe other regions should be checked too.)

Anyway, now it boots up level 1 and I can move around! Some actions fail with a Z_Malloc error which is slightly annoying, I'll see if there are bugs (?) or if more heap can be obtained. So far it's still much easier than I remembered. ^^
The main difficulty was that the "system stack" was moved by ComputerNerd over to the user stack, likely because the old address of the system stack no longer works. This of course put restrictions on its size, namely 256 kB instead of CGDOOM's previously-set 422 kB.

Since I know where the system stack is now (just like before except that RAM starts at 0x0c000000), I set that setting back and now I can play pretty big portions of the level.

It seems that DOOM's built-in allocator (z_zone.c) supports only one zone, but we have two stacks to work with, plus possibly more memory, so there might be ways to increase the total (modifying z_zone.c to support two regions seems possible too).

There are graphical glitches on the HUD, I suppose I should be looking at that next. ^^
After discussion with other Planète Casio members, the success of my previous version is inconsistent. Basically it worked on my calc only. Two errors have been found on others; one during R_InitTextures, one for missing textures in R_TextureNumForName.

After filling the storage memory on my fx-CG 50 I was able to reproduce the second one, which I then tracked down to the loading of side definitions. A single glance at the relevant function shows me that this step has been a painful experience for previous ports too, I'll try and see what I can do. Surely it has something to do with the layout in storage memory, but the file mapping still appears successful even when the bug occurs.

Edit: I realize I did not explain the cause of the memset() bug. GCC was being very smart about CGDCalloc(), in which it had inline CGDMalloc(), and recognized the pattern for allocate-then-clear, replacing the whole function with a call to calloc() as an optimization.

Now that calloc() I had defined as libfxcg's sys_calloc(), which uses not memset() but a custom function called memsetZero() which doesn't work because it assumes 4-alignment of both pointer and size, and it's missing a delay slot instruction. (It seems to be written for x86 in some way.)

        mov r4,r0
        xor r1,r1
        mov.l r1,@(r0,r5)
        tst r5,r5
        bt/s Loop
        add #-4,r5

Anyway so I replaced that with an actual call to memset() and then it worked fine, so that's one mystery down, one more to go.
Incredible work on the DOOM-Port for the fx-CG50 so far! Smile (I know that you have a thread on Planet Casio but I don't have an account there, so I'm writing it here.)

I can play the game until E1M4 where it crashes. Also the secret level E1M9 crashes the game.

Here are some bugs I noticed while playing:
- Some areas have corrupted / strange textures (for example: the secret area that leads to the megaarmor and the pillars in E1M1)
- The game runs too fast when overclocking the calculator with Ptune2 to 213 MHz

Here is some stuff I would add:
- Difficulty setting (Ultraviolence is too hard and I don't want to cheat the whole time Very Happy)
- Run key
- FPS Counter
Thank you very much! I think it's time for an update. As you have found, there is this topic on Planète Casio and my version of CGDOOM is published on this Git repository, with the G3A file in the CGDOOM-minisdk/CGDOOM subfolder.

The bug with loading side definitions was tracked down to memcpy() not working in the Flash loading procedure (libfxcg uses the memcpy syscall, which I assume is either bugged or not designed as a fully-generic memcpy in the first place). I'm becoming paranoid due to not trusting standard functions!

Anyway I fixed that by using another version of memcpy, and CGDOOM has worked on every tested calculator since, which is 6 thanks to your test. Hurray! Smile

I then used the opportunity to implement so improvements and optimizations. The loading was already faster due to higher clock speeds on the fx-CG 50 (5.2 seconds for the shareware doom.wad), I added some heuristics and a binary index of the sectors where fragments are most likely to be located (~90% hit rate) and brought it down to 1.4s. (There's also some assembler black magic, which is less significant but I was inspired to write some. xD)

I also noticed that loads in-game were being made from uncached ROM addresses. While this is the proper choice for fragment search, actually copying data benefits greatly from the cache. I set it up to use P1 addresses during the game and this improved the game speed by about 35%.

As minor improvements, I also updated the icon style and rewrote input handling to use a direct KEYSC driver so as to support simultaneous key presses. I'm surprised that there aren't many (in my version of libfxcg, there aren't any) syscalls to do that directly.

Finally, I extended DOOM's internal allocator to support multiple pools of memory, so that I could supply it with both the system stack and every bit of user stack which is not used by the data/bss sections. This has allowed me to work on loading larger WADs like the Ultimate Doom one which Critor has recommended to me. (Critor is the one who worked on the Nspire CX port from which CGDOOM is derived, and the CX supports quite a lot of WADs).

Here are some bugs I noticed while playing:
- Some areas have corrupted / strange textures (for example: the secret area that leads to the megaarmor and the pillars in E1M1)
- The game runs too fast when overclocking the calculator with Ptune2 to 213 MHz

I don't know about the secret area (I'm both new to DOOM and bad at it!) but the pillars did have a texture problem in the Doom Ultimate WAD. If you use the shareware WAD linked on Planète Casio it should be fine. Then again this one has glitched textures in E1M2 anyway, so surely there's a bug left.

I'm not sure the game is rate-limited at all since the fx-CG 20 couldn't reach nominal speed, I'll look into it.

Here is some stuff I would add:
- Difficulty setting (Ultraviolence is too hard and I don't want to cheat the whole time)
- Run key
- FPS Counter

Ah so here's why I only finished Hangar once, it's locked on Ultraviolence... I figured 1% health boost was small. xD

Critor actually requested the difficulty screen too, this should be feasible. FPS counter same deal. The run key I don't know about, would you mind detailing a little bit?
The run key I don't know about, would you mind detailing a little bit?

Doom has normaly a button to run, but this version doesn't seem to have one. You can only walk. It is used to get away from enemies quickly and to get to secrets in time. I think the Shift-key could be a good key for the run-button.

If you use the shareware WAD linked on Planète Casio it should be fine.

I used that one but the texture glitch is still there. You can see this glitch not just on the pillars but also on some of the walls with these streched brown / gray lines. (I also tested the Ultimate Doom Wad and it has basically the same glitch just way more noticable)
I also started Doom with the shareware wad from my calc on my PC. The pillars and some walls render correctly without these brown / gray lines. But some textures actually seem to be corrupted in the wad, because they look exactly as corrupted on the PC and also on the calc. (for example: E1M2: the way over the slime with these white glitchy textures (this glitchy texture is not present in Ultimate Doom Wad, looks normal here))

So something still seems to be wrong with the game and also the shareware wad.

I also put the original Doom 1.9 shareware wad on my calc and it has a similar very noticable texture glitch like the Ultimate Doom Wad. But for some reason I could get into E1M8: Phobos Anomaly without crashing?? I even got the secret level E1M9 working.
I also edited all audio out of this wad and with that I got pretty similar results like the shareware wad from Planet Casio. It crashed at level 4.

So with a unmodified Doom 1.9 Shareware Wad you can play through the entire shareware version with some glitchy textures! Surprised
I used this one.
Here is something else I noticed: there's a CGDOOM-Version which does not have this texture glitch with the pillars and walls. It's the one on Cemetech here: http://ceme.tech/DL755
This version does not work on the CG-50 but you can run this one on the CG-50 Emulator that actually behaves more like an CG-20 Emulator with CG-50 firmware.

Maybe you can track down this issue more easily with the source code of this version of CGDOOM. Speaking of the source code - i don't know where it is because it's not included in the download on Cemetech. But it looks like an very early version of CGDOOM because many features that got added in a later version like changing the screen size or showing how much memory is still free are not there.

MPoupe also mentioned on Omnimaga ( https://www.omnimaga.org/casio-prizm-projects/cgdoom/30/) this in the changelog of the second version of CGDOOM on which your version is based on:

- support for composite textures was limited to 8KB to save RAM. It seems 8 KB is enough for switches (they use composite textures). Larger composite textures are cripled - see an image.

He also attached a screenshot which shows the same texture glitch. He also has an image of the first version of CGDOOM and it shows the pillars without the texture glitch. ( https://www.omnimaga.org/casio-prizm-projects/cgdoom/10/)

Maybe that's the reason for the texture glitch?
Thank you for your input, this is very valuable!

Since I clearly lacked experience with the game I downloaded GZDOOM and played around. Now I have a much clearer idea of what to aim for... there is quite a gap in experience right now.

I finally noticed that the pillar texture is indeed incorrect on Planète Casio's shareware WAD, which was invisible to me because I got a browny texture close enough to the original. I have confirmed by identifying the texture (WALL02_1) that the loading is correct, ie. the data read from the lump by the memory-map is correct (same when using Bfile), therefore the problem must be later on.

I could also confirm in GZDOOM the glitchy textures in the WAD itself, which I would not have suspected, thanks again there.

Thanks for testing the 1.9 WAD! It's really cool that it works. Things are moving a bit fast for me at the moment, but I'll definitely come back to it in time.

I've pushed some updates on the repository, which include some menu navigation ([X,θ,T] is ESCAPE, [log] is RETURN - this is temporary) and a main screen from which WADs can be selected, as well as some testing options.

This version does not work on the CG-50 but you can run this one on the CG-50 Emulator that actually behaves more like an CG-20 Emulator with CG-50 firmware.

As an aside, do you know more about this emulator? While working on my kernel I stumbled on some quirks I documented here including the CG-20 RAM address. If there is a more authoritative source on the program I'd be happy to hear more.

Anyway, this story about composite textures is very interesting. The armor stand is also corrupted in my version, this may be the reason. I'll investigate!
Really nice update! Good Idea The main screen is very useful if you have multiple wads on your calculator (which is probably not very often the case considering the low storage amount). Also I tested the option to not map the file to memory. With that I got in a few wads a bit further into the game and some crashed earlier. It works but is sometimes really slow even on an overclocked calculator.
The in-game menu is great but still a bit buggy:
- New Game: works great
- Options:
    - End Game: shows the text but I can't confirm
    - Message toggle: works
    - Graphic detail: doesn't work

- Load Game / Save Game: doesn't work, shows New Game menu (would be really cool if you can implement a save / load function)
- Read this!: works
- Quit game: doesn't work

As an aside, do you know more about this emulator?

No not really. I just saw that this fx-CG50 emulator had the same CPU speed as the CG20 and all the programs that didn't ran on the CG50 ran on this emulator and vice versa. So I think they just took their CG20 emulator put the CG50 firmware on it, changed a few graphics and called it a day.
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 4
» 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