xvortex / VTXCart

Reverse engineering Neo Geo 161 in 1 cartridge to change Rom games
68 stars 14 forks source link

CPLD: Detect Reset and remap menu #16

Closed ArcadeTV closed 11 months ago

ArcadeTV commented 11 months ago

Dear Vortex,

I'd like to implement a "back-to-menu" function upon soft- or hard-reset into the CPLD. Do you have any information about how to detect a reset from the cartslot?

Thank you very much!

jwestfall69 commented 11 months ago

The reset signal will go low if the motherboard does a hard reset (watchdog), but using that as a reason for going back to the menu is problematic. There are a couple games that force a watchdog as part of their copy protection.

Rolel commented 11 months ago

We could list games that does this, and maybe keep reset work on the others ? A first step that covers >90% of game library.

ArcadeTV commented 11 months ago

We were thinking about different approaches to make this work. My research involved comparing the behaviour of different bioses upon reset. As far as I can tell there's a difference in hard- and soft-reset but I can't tell for sure that the locations that the bios jumps to is always identical. We were thinking about detecting the location of the program counter to trigger reloading the menu and a reset afterwards. Of course it would have been nice if this would have worked with a bios patch, but since the unibios has its own protection against altering the binary (not just a simple checksum) this seems to be a dead end. What we are looking for is some kind of state, signal, pc location or anything like that making both hard- and soft-reset detectable. Another idea was to feed the CPLD with a button that can be installed onto the cart, but I dunno how convenient this would be inside a cabinet. Thanks for your responses so far!

Rolel commented 11 months ago

Why not simply counting time ?

For the first 30sec, the soft reset won't go to menu. Then you let soft reset switch to menu. This is pure cpld code but only work as long as games with security measures only triggers reset in the startup sequence.

jwestfall69 commented 11 months ago

Re the crash, it maybe unrelated to unibios as it looks like there is a bug in the CPLD code for PROG CP1. When you go back to the menu then pick another game there is nothing that is resetting P2_BANK back to 3'd0. This could cause the wrong 1MB from the flash chip to be mapped to the PORT memory region for the game. This could then lead to a crash when the game jumped to that region to execute code.

You could try changing

if (M68K_ADDR[19:1] == 19'b1100000011111110111) GSEL <= M68K_DATA[7:0]; // 0x2C0FEE

to

if (M68K_ADDR[19:1] == 19'b1100000011111110111) // 0x2C0FEE
begin
    GSEL <= M68K_DATA[7:0]; 
    P2_BANK <= 3'd0;
end

and see if that magically fixes the crashing

ArcadeTV commented 11 months ago

@jwestfall69 That is some really neat input, thank you very much! I'm afraid those freezes also happen with regular games, tested on real hardware and MiSTer.

I'd love to know if there was a "universal location for reset". I can't verify this entry in the neogeodev wiki:

Is $C00426 an universal BIOS call for a complete reset ?

https://wiki.neogeodev.org/index.php?title=68k_vector_table

jwestfall69 commented 11 months ago

I'm not sure on that, but even if that was the universal location seems like there are still a few issues?

ArcadeTV commented 11 months ago

I asked around and Furrtek was kind to give this answer:

It appears like so. Several BIOS addresses jump to the same init code, but C00426 seems to be the one games use. Without the A[23:20] lines on the cart slot, the only way that comes to mind would be using a state machine to detect a "jmp $C00426" instruction. Idle state: Read with D=4EF9 ? If so, store address and goto state 1. State 1: Read with D=00C0 at address+2 ? If so, goto state 2. If any other access, go back to idle. State 2: Read with D=0426 at address+4 ? If so, reset detected. If any other access, go back to idle.

We will try to implement this and see how far we can get.

Thanks again!!

jwestfall69 commented 11 months ago

It will be interesting to see if that works.

One thing to consider is not all mvs motherboards have the cart directly on the cpu's data bus. So if the bios is the one doing the jmp instruction the cart/cpld likely wont be able to see the it.

leonkiriliuk commented 11 months ago

Reset handling has to be handled in the CPLD code. Everything else (e.g. CPU) is either halted or in reset thanks to the NEO-B1/Watchdog. PRG CP1 is the only FPGA that gets the real reset signal from B1. On MVS, it ignores it. On AES, Vortex added code to set GSEL back to 0. So physical reset button works correctly already on AES. Stock Unibios reset only resets the CPU, so CPLD never gets the reset signal and never resets its internal GSEL reg correctly.

@jwestfall69 you're correct about some games having a problem. If I add code to set GSEL to 0 when reset goes low (i.e. we are in reset) these games never run; the game menu comes back. BUT.. this copyright protection only exists in MVS/Arcade mode code of the game! :)

If you switch Unibios to AES mode, then MVS reset works correctly. But most MVS PCBs don't have a reset button. If you compare MVS schematics to AES schematics, you'll see that all you need is a push button and 2 wires to add reset functionality.

Modifying PRG CP1, adding reset physical button, and running MVS in AES BIOS mode restores proper reset back to menu with no issues. But this is a limitation since the MVS will now never run in arcade mode correctly. Not unless you don't mind doing physical power cycling every time to change the game and skip the new code. Which is a big no-no for me, given I don't like power cycling the arcade CRT monitor so many times.