What's new
Okay so there's definitely more to the header "protection" than just a simple CRC/hash. It is running a hash over the first 0x500 bytes of the header, using a PRNG with the equation NewRNG = (OldRNG * 41C64E6D) + 3039. My google-fu failed me as I couldn't find any algorithms outside of people reverse-engineering pokemon (lol same PRNG there as here). However, simply bypassing the failure condition altogether causes the game to never load settings from the EEPROM at all, and when it freezes it is stuck in an infinite loop of reading the EEPROM. So I am not entirely sure they meant this to be protection so much as they used a hash of the header to see if they should read the settings, and then store a copy of that header and compare against that in the future for speed reasons. This is done as a rolling hash, calculating one position per loop as a background thread. The fix is to make the function that returns the current position always return 0. That way, it only ever hashes over the first byte of the header, but it notices that's different on the first iteration and does load the EEPROM. I've tested this bypass using the settings trojan on both Jambo Safari and Crazy Taxi and both are happy with the changed EEPROM as well as no longer freeze in the attract sequence.

This also explains why changing the free-play portion of the ROM header caused it to crash earlier in the attract than adding an EXE section for the trojan. Anyway, case closed, I don't have to add a compatibility mode to any of my tools, thank GOD. Instead I checked in a pair of patches for CT/JS that disables the "protection" properly so they still load settings but don't crash on header modifications. The only thing you can't modify is the initial "N" in the first byte, but you couldn't modify that anyway as it would then fail the NAOMI ROM check in the BIOS. Good call, @rtw you saved me a ton of time implementing unnecessary crap.

Anyway, if anyone else runs into games that freeze in the attract when applying settings, post them here. The patch should be relatively easy to locate for any game that uses this style of "protection". You just look for references to the constant "0x0C020000" in the code, find the section that compares an offset into that constant against another location, and gets that offset from some function. Then you patch the call to the location gathering function to instead set r0 to "0" and then nop the next instruction (branch delay register setup for the function call). Its as easy as that. But if people run into more games like this and they want settings working, I can probably jump in and fix the problem pretty fast.
 
good work :)
in general, Crazy Taxi and Jambo Safari protections works like that:
- read encrypted chunk of data from cart via decryption/protection chip
- at various game points compare ROM header C020000[RNG%0x500] with data read at prev step
if they do not match - do weird shit, like trashing game code/data in RAM at random locations, and sooner or later game will not function as it should :)

so, Sega hit two birds with one stone: protected game from simple copying, protected game header from changes by some c00lhax0rs
 
This is all super awesome! Thanks so much for all your hard work @DragonMinded . This code is all very high-quality.

I did have to make a couple of changes to the homebrew env setup Makefile to get it to work on MacOS and made a couple of small quality of life changes (adding a prefix var I can override on the commandline and ignore the patch if it's already been applied).
I tried these patches and the ignore the patch bit doesn't work on Linux. It prompts the user. I attempted to patch twice using the patch command and that worked fine (patch detected it was already patched and just saved rejects), although patch does return "1" in this case instead of "0". So it would crash the makefile. Unfortunately there's no way to ignore that and I assume that's what you were attempting.
 
I tried these patches and the ignore the patch bit doesn't work on Linux. It prompts the user. I attempted to patch twice using the patch command and that worked fine (patch detected it was already patched and just saved rejects), although patch does return "1" in this case instead of "0". So it would crash the makefile. Unfortunately there's no way to ignore that and I assume that's what you were attempting.
Sorry I should have tested more. Adding --force appears to suppress the prompt.
So that should make the full command
Code:
patch -R --dry-run --force -p0 -i newlib.patch || patch -N -p0 -i newlib.patch

And yeah, that return of 1 even when it ignores the patch is what I was trying to avoid. As I was iterating on the Makefile and trying to make it all work that bit was pretty annoying. Though realistically the only people who would hit this are people messing with the Makefile so it's not that big a deal.
 
A few updates.

- I finally got working sound in my toolchain. I don't actually remember what it was that I was tripping up on before, but I was copying both the AICA example programs out there and the basic setup of KallistiOS and it was not working. There was a lot of timer and interrupt-related stuff that all of the existing dreamcast examples assumed was setup by the BIOS which is not the case for Naomi. Anyway, the menu has some small sounds now. If you wish to disable them, hit the test button on the main menu to go to the config screen and disable menu sounds there.
- I have organized the config screen a little bit better. This is minor, but the options are now grouped together a little better and such.
- There is a bug currently with entering naomi system test mode. I am tracking it down, but it appears to be a bug in my threading library with respect to waiting for resources in the main thread. I don't know what's up yet, but that option will reboot the Naomi for now, sorry! I'm hoping to get it fixed soon.

EDIT: Menu bug has been fixed!
 
Last edited:
question / request:
so ... err... how to exit a game and recall the menu with joysticks and buttons to pick another game?
 
You'd probably have to hack each game to hook their inputs and listen.
 
I was briefly considering skipping the BIOS/reboot altogether after loading and just jumping to the game's entrypoint myself after performing the loads. It would be a bit of work (would need to set up the EEPROM myself but you know that'd be a benefit here, would need to make sure to put things back in memory, not sure on whether some games would be displeased) but if I did that it would mean that I could install hooks into the loaded BIOS that all games use, and add in a keypress detector with reboot to menu. It would be theoretically possible but it would be very difficult to get right with a really easy chance of going wrong with hard to debug crashes.

The menu was designed with the flow of rebooting the naomi to pick a new game. If you add "--persistent" to the command line you use to run the menu, then if you turn off the naomi for a few seconds it will detect that and then resend the menu on the next boot to pick a new game. That's probably the best you'll get for awhile.
 
Not much of anything to update but I've been working in the background to get accelerated video working properly with the goal of getting the menu to a full 60fps on all screens. That's not a super big deal, but animations will play slightly smoother and scrolling won't jitter if a frame drops anymore because there won't be any frame drops. I've got it mostly figured out except for when I went to enable 32-bit RGBA modes I'm getting lines through my textures. Funny enough, demul properly emulates the fault and displays it the same is the Naomi does. So I wonder if @MetalliC can think of anything off the top of his head that might cause this? Is there some hidden stride value in some register? I originally thought maybe its just setting the palette entries wrong, but it wouldn't be displaying the correct color in some areas with the correct texture alignment for the full face. I banged my head against it for awhile tonight and it doesn't make sense. If I am in 16-bit video modes, textures work fine regardless of if their palette entries are 16bit 1555 or 32bit 8888 color. But if I am in a 32-bit video mode, while software drawing works fine anything drawn by the PowerVR2 accelerated video gets lines in it, regardless of if the palette entries are 16bit or 32bit.

Here's the weird thing. Its definitely aligning on the texture, not the framebuffer, but I can't see anything I'm missing.

FEmuMieXsAcGYhr?format=png&name=900x900.png


And here's what it should look like (from 16bit modes that do work).

1637379127611.png
 
my blind suspicion was right - the texture used for rendering have that lines, so it seems the problem in tool/code you use to convert PNG to PVR
 
The same texture is used for both 16bit and 32bit, so I am confused. I also tried just setting every single entry in the texture to some value and it still has the lines in 32bit mode.

EDIT: I have just checked the converted textures and they do not appear to have those lines in them either. Perhaps it is the twiddling function that is wrong?

https://github.com/DragonMinded/netboot/blob/trunk/homebrew/libnaomi/ta.c#L712 <-- this here?
 
Hmmm, I think I am not calculating some memory positions right. If I move the texture memory arbitrarily forward in RAM by 2MB then the lines disappear. So you are right, the texture is getting corrupted somehow. However, the question is.....what shitty code did I write that is doing this?

EDIT: MAME does not support render config mode 5 (0888 mode) so I guess I will start with fixing that and then figure out what is messing with that memory.
 
yes, that routine probably wrong, for sure it wrong for paletted textures, where twiddling should be done in 4bit or 8bit units, and not 16bit words like in your code
 
MAME does not support render config mode 5 (0888 mode) so I guess I will start with fixing that and then figure out what is messing with that memory.
it doesnt matter. you may use 16bit frame buffer mode and use 24/32bit source textures
speaking in general, PVR2 internally always works in 32bit color mode, it converts to 32bit whatever source textures, and in the end store rendered result as per destination format, cutting bits count if needed
 
I couldn't figure out what was smashing over that memory. The problem does not appear in MAME so I could not trap memory and see what code was the problem. Given that it doesn't happen in MAME I am suspicious that it has to do with the TA/PVR writing over sections of memory. However, when I move the command buffer to 0xA5400000 instead of rounding the next megabyte up from the framebuffer the problem goes away. *shrug* oh well. At least it works.
 
have you read powervr2 docs ?
there is no any dedicated texture RAM and display list / frame buffer RAM, there is one unified RAM with 2 access modes (64bit for textures and 32bit for everything else), it will access same physical RAM, but just interleaved if compared one to another mode.
so, yes, you may trash some textures by FB or object lists/buffers, or vice versa, if not taking in account how it works.
 
in any case, your's "texture lines" problem caused by wrong texture conversion algo, as I see in the repo you still not fixed that.
 
Back
Top