What's new
Here's how to setup the environment. The mame rom is garou.zip. The file below has the modified mame called 'neogeod.exe' which has the bank switching disabled.
https://drive.google.com/file/d/1tWs52SX_xovwqFQ3w7BvnqMxs0ARRKvz/view?usp=sharing

There are also 2 ips patches that you can apply to the garou roms from the Neo Ragex 5.2a set on archive dot org. If you wish to have the current patches applied to Mame copy the first 0x0 - 0x1FFFF of the ips patched '253d-s1.rom' to the mame debug memory windows in the Region ':csolt1:fixed' starting at 0x0 using the drop down selection.

Then do the same to the 253d-p1.rom, but you will have to byte swap the data beforehand. I'm using gq-4x rom programmer windows app to byte swap and then save the new bin. Copy the modified and now byte swapped region 0x1C000 - 1EFFF, and paste it into the same starting address in Region ':csolt1:maincpu.'

Fixed layer memory is in 'Neo-Geo Sprites (optimized)/:spritesgen/0/m_videoram' starting at address 0x0e000.
Used YYCHR.exe to edit the srom tile layout. This website app below can be used to load the Srom, and it will show the last 3 nibbles for the tile you have selected. First nibble I believe is the palette.
https://neospriteviewer.mattgreer.dev/

When I mess with data in the Region ':csolt1:maincpu.' in the '1d710' area I can get the win icons to disappear. If the wrong data is altered though it will trigger the watchdog. Not sure what's goin on in this area yet.

Edit:
Win icon data is in 0x1d7e0-0x1d840
Power bar S/P is in 0x1e260-0x1e2c0

The tiles can be edited changing data around in here. Trying to make sense of it.
 
Last edited:
If you've got decrypted graphics somewhere you're ahead of the game. I forget if you can let mame decrypt them and then dump them from there, I don't think I made that happen last time I ran into it though.

I am looking at a "P power" in my un-patched game. But I did use the exe you supplied to boot it.

1704510866928.png


In my game, in the fix data you pointed out ('Neo-Geo Sprites (optimized)/:spritesgen/0/m_videoram' starting at address 0x0e000), the value in memory for P/S started '2421' and was sometimes '3421' presumably 2/3 being palettes toggling. So the location is 421... somewhere. That would be the top left tile of the P. The next tile is 422.

Anyway I'm just poking around a little bit. Neo Geo sends stuff to the vram by moving a location into $3c0000 and then sending the data to $3c0002. You can see the garou code doing this, seemingly just for the fix layer, at 0x1fea, where it hits $3c0000 with a location and then does any given number of sequential sends to 3c0002 from there. Set a breakpoint at 001FEA and then you can watch the action happen one location at a time by f5-ing each time. The d3 register holds the vram location it's targeting, and then the data is streaming out of the location at A3.

The data seems staged in/around 1041e8 (which is where my data 2421 comes from).
"find 100000,ffff,w.2421" in debugger found it

The last byte (21) data is set in program code when it sets address A0 and then pulls the data from it a short time later.

01C7B0: lea ($1b24,PC) ; ($1e2d6), A0 (sets A0=$1e2d6)
and the first byte of data at 1e2d6 is "21"

and the next line of code sets the first part of the word

01C7B0: lea ($1b24,PC) ; ($1e2d6), A0
01C7B4: move.w #$2400, D0

so D0 is 2400, and A0 is 1e2d6, and then shortly thereafter the byte at (A0) is moved into D0
...
01C7D2: jsr $18e0.l
...
001A44: move.b (A0)+, D0

D0 then gets moved into 1041e8 (the staging location) which had been set to A1 through a couple of previous steps.
001A46: move.w D0, (A1)+ (so, move 2421 into 1041e8 )

That's about all I can do tonight, maybe it jumpstarts you a bit. I would expect that, if you can see the sprites, the "P" is hanging out at block 421. Probably 421 times 16 bytes or 32 bytes or whatever a tile is, I forget lol. Then I'm not sure how you want to attack it. Maybe its NOT there and that's where it needs to be moved. I can tool around a little more later but I don't necessarily want to steal your fun.
 
Last edited:
Thank you ekorz. Going to be getting at the P/S Icons next. Your post is perfect timing. I'll have to site down and digest all what you said. Still not sure what a 'word' is, need to google that.

Think the win icons are figured out. The first byte is a prefix for the the first nibble of the tile location. Then it has 8 bits, which are the the last two bits of the tile address. Thought these were going to be a headache with the tiles swapped around from the original in places where they would fit, but so far not so bad.
GAROU.png


If everything else goes well, will upload a patch that people can hopefully test the game to make sure there are no more bugs before burning to a 161. Have a feeling there is going to be stuff that was missed.
 
Last edited:
I should mention that if those patches you're running actually patch the program code at any of those memory locations, then things may be working differently. I was booting the non-patched game. But you should be able to open a disassembly window (Ctrl+D) and type in those addresses, and see. Or set a breakpoint.
 
Here it is. You can test this in neoragex 5.0 or 5.2a. Grab it from archive dot org and apply the ips patch to the p1 and s1. Let me know if you find any glitches.

https://drive.google.com/file/d/1GYdUTipF8YyrYWiI8O_pGh4P0jmUCjP7/view?usp=sharing

Asked fgto79 to test this new set on his darksoft cart. I'm not betting on it working, but it's if it does, it will most likely work the same on the 161 in 1. Even if it doesn't it may still work as is on a 161 in 1.

You will have to cut out the first 128kb of the srom, and use that for the 161 in 1. I'm guessing the way neoragex handles the 128kb srom, it just doesn't work right unless it's 512kb mirrored. Like said before, it's working fine in mame with the bank switching disabled, which basically only can address the first 128kb of srom.

Thanks to ekorz for their research. The first bit of the word for the P/S icons wasn't apparent at first, and his findings helped me out.
 
Last edited:
Guess KOF2000 is next to fix for the 161. Most tiles looks good with the neoragex patch posted in the main 161 thread. The character names on the select screen are the main problem, they take too much tile space. The original font for this will have to go to make it fit. The left facing assist character portraits for player 2 need to be redone. The mode select screen in AES mode too.
The Neo Geo splash screen has to be overwritten to make it all fit, so it's going be be corrupted. Might be able to call the fix layer in the bios to replace it during the splash screen, not sure if that's possible.

kof.png

This one is going to take a while with the big roster.
 
The Neo Geo splash screen
Couple links to get you going on that, if it's what I think you mean. I don't know what KOF does, but if it was done in-cart then you can switch to done-by-system-rom:
It's called "Eyecatcher" https://wiki.neogeodev.org/index.php?title=Eyecatcher
Couple of flags for it on the 68k program header: https://wiki.neogeodev.org/index.php?title=68k_program_header ($114 is the choice above)
https://nicole.express/2021/high-speed-coding-neo-geo.html fun write-up and some good repos/links
 
@ekorz most of what you wrote makes sense. How were you able to come up with the address 0x1fea as handling the tile data?

 
@ekorz most of what you wrote makes sense. How were you able to come up with the address 0x1fea as handling the tile data?

Can't remember exactly but it was probably a watchpoint on the VRAM registers. If you set up watchpoints on 3c0000 and 3c0002 you'll see a stream of commands that follow a pattern of setting a vram address and then sending data to it (https://wiki.neogeodev.org/index.php?title=VRAM)

1705000575132.png


Those watchpoints will hit and you'll see the PC that's doing the writing. For all the hits where the VRAM Address was in target, it was that PC doing the writes.

e.g. this will show you just the times SOMETHING is setting a vram address in the Fix area. Looks like 2F56 also hits there sometimes

wpset 3c0000,2,w,wpdata>7000&&wpdata<7500

1705000912209.png
 

Attachments

  • 1705000700136.png
    1705000700136.png
    6.9 KB · Views: 15
Patch doesn't work on the 161 in 1. Came up with the same error that Fgto79 had on his darksoft cart. Dagnabbit.
 
Came up with the same error that Fgto79 had on his darksoft cart. Dagnabbit.
The address error at 7C0153?

1705432727834.png


It's weird that I don't really see 7C0XXX as part of this: https://wiki.neogeodev.org/index.php?title=Fix_bankswitching which is the link that shows the region as "extension"
1705432938284.png


Anyway, you can set a breakpoint at 391B4 to see what it does, or a watchpoint at 7C0153, or an address register point on it. Maybe even though you've adjusted all the graphics, something in the program code is still doing some shit in the extension region. Even just trying to checksum it, or something.
 
The 68k ram 200000-2fffff wasn't bank switching in mame, that's one of the reasons why it's crashing there. The program rom makes writes to 0x2FFFC0 that tell it what program bank to swap to. Mame was saying 'unmapped memory address' when it calls for these in the error log. I have no idea why but assume this is an instruction the SMA chip would handle or something. On the 161 it is bank switching, so there is a different error from mame's, which is odd. I compared samsh5pf bank switching and it uses 0x2FFFF0 writes to switch the bank. I replaced all calls of 0x2FFFC0 with the samsho5pf one of 2FFFF0. This got mame bank switching garou exactly like the 161 in 1 is doing because now I get the same error, and when checking memory viewer it shows the same bank the 161 is on.

Here is the next problem. Samsh5pf bank switches in 1MB chunks writing bytes like 0001 or 0002 for the bank selection. Garou is using bytes like 011A or 8313, and many more, to select the bank. Here is the source of mame's prot_sma.cpp.


Code:
uint32_t sma_prot_device::garou_bank_base(uint16_t sel)
{
    static const int bankoffset[64] =
    {
        0x000000, 0x100000, 0x200000, 0x300000, // 00
        0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04
        0x2f0000, 0x3f0000, 0x400000, 0x500000, // 08
        0x420000, 0x520000, 0x440000, 0x540000, // 12
        0x498000, 0x598000, 0x4a0000, 0x5a0000, // 16
        0x4a8000, 0x5a8000, 0x4b0000, 0x5b0000, // 20
        0x4b8000, 0x5b8000, 0x4c0000, 0x5c0000, // 24
        0x4c8000, 0x5c8000, 0x4d0000, 0x5d0000, // 28
        0x458000, 0x558000, 0x460000, 0x560000, // 32
        0x468000, 0x568000, 0x470000, 0x570000, // 36
        0x478000, 0x578000, 0x480000, 0x580000, // 40
        0x488000, 0x588000, 0x490000, 0x590000, // 44
        0x5d0000, 0x5d8000, 0x5e0000, 0x5e8000, // 48
        0x5f0000, 0x5f8000, 0x600000, // rest not used?
  };

    // unscramble bank number
    int data = bitswap<6>(sel, 12, 14, 6, 7, 9, 5);

    int bankaddress = 0x100000 + bankoffset[data];
    return bankaddress;
}

I'm not yet sure if the bank switch at 0x2ffff0 can address to the areas that don't start in increments of 0x100000. Right now with the bytes garou is calling, the bank switching is just jumping to different sections in 1MB increments like 0x200000 or 0x500000. Like normal bank switching does on non SMA games. It's not looking too good right now.
 
@ekorz can you enlighten me on how this sub routine and dword are loading the 1MB sections into 68k 200000 ram?
Code:
Offset 58EEC

sub_58EEC:
move.w  (word_2FFFF0).l,d0
andi.w  #$FF,d0
rts
; End of function sub_58EEC

-=-=-=-

Offset 2FFFF0

ROM:002FFFF0 word_2FFFF0:    dc.w $8000              ; DATA XREF: sub_58EEC↑r
ROM:002FFFF2                 dc.w $81
ROM:002FFFF4                 align 8
ROM:002FFFF8                 dc.l $FFBFFFBF, $FFFFFFFF

So it moves the bank word into DO, then I'm not sure what andi.w is doing with the #$FF. This routine is setting up the bank word before being loaded into the bank write at 2ffff0?

And then the word at 2FFFF0 handles the loading of the data into the 68k ram? Does the dc.w $8000 tell it that it's a 1MB section of data? And then the dc.w $81 tells it that there are 8 sections of the prom that can be loaded? Then finally dc.l $FFBFFFBF, $FFFFFFFF is how it knows to load in 100000 offset increments?
 
Last edited:
So it moves the bank word into DO, then I'm not sure what andi.w is doing with the #$FF
Honestly I haven't dealt with any neo geo bank-switching before so I'm catching up myself. This is sort of rambling and not fully formed at this point.

The andi.w is 'masking' the value that was loaded into D0. Why? I dunno! But the 00FF mask is stripping off the first two digits and you're left with a value between 00 and FF. Presumably wherever the code is RTSing to, it is expecting D0 to have two digits in it, and it does something with it.


1705794446604.png


When I load it up in mame, and set a breakpoint for 58EEC, the value it pulls into D0 is not necessarily the value that I actually see at 2ffff0. Every time I type in "2ffff0" and hit enter, that value changes. It's some crazy shit!

So it's protection or something? "SMA random number"

https://github.com/mamedev/mame/blo...6899d59485b8/src/mame/neogeo/neogeo.cpp#L1454

case NEOGEO_GAROU:
// addon_r here gives SMA random number
space.install_write_handler(0x2fffc0, 0x2fffc1, write16smo_delegate(*this, FUNC(neogeo_base_state::write_bankprot)));
space.install_read_handler(0x2fe446, 0x2fe447, read16m_delegate(*m_slots[m_curr_slot], FUNC(neogeo_cart_slot_device::protection_r)));
space.install_read_handler(0x2fffcc, 0x2fffcd, read16sm_delegate(*m_slots[m_curr_slot], FUNC(neogeo_cart_slot_device::addon_r)));
space.install_read_handler(0x2ffff0, 0x2ffff1, read16sm_delegate(*m_slots[m_curr_slot], FUNC(neogeo_cart_slot_device::addon_r)));
break;

Anyway if I could keep going I'd say follow the code after it RTSs at 58EF6. It seems to hit that 58EEC from more than one spot, so it will return to more than one spot. And those branches do other masking and checking and then run more code. I'm looking at one right now where it drop D0 into the stack real quick, then does something resembling loading with it:

0125DA move.l D0, -(A7) 2F00
0125DC move.w #$812a, $2fffc0.l 33FC
0125E4 move.l (A7)+, D0 201F
0125E6 lea $200000.l, A1 43F9
0125EC add.w D0, D0 D040
0125EE add.w D0, D0 D040
0125F0 adda.l ($2,A1,D0.w), A1 D3F1
0125F4 addq.l #2, A1 5489
0125F6 lsl.w #4, D1 E949
0125F8 lea (A1,D1.w), A1 43F1
0125FC rts 4E75

The whole operation manipulated A1 to be:
A1 002069C8

Which seems at least in the neighborhood of a banking address.

Then the LongWord at that address is read back into D0, and... more stuff I haven't stepped through to understand yet.

039EB8 move.l (A1), D0 2011
039EBA addi.l #$200000, D0 0680
039EC0 move.l D0, ($b4,A4) 2940
039EC4 moveq #$0, D0 7000
039EC6 move.b ($5c,A4), D0 102C
039ECA addq.w #1, D0 5240
039ECC lsl.w #3, D0 E748
039ECE move.w D0, ($54,A4) 3940
039ED2 moveq #$0, D0 7000
039ED4 move.b ($5d,A4), D0 102C
039ED8 addq.w #1, D0 5240
039EDA lsl.w #4, D0 E948
039EDC neg.w D0 4440
039EDE move.w D0, ($56,A4) 3940
039EE2 movea.l ($76,A4), A0 206C
039EE6 moveq #$0, D0 7000
039EE8 move.w #$5f, D7 3E3C
039EEC move.l D0, (A0)+ 20C0
039EEE dbra D7, $39eec 51CF
039EF2 move.l #$39ef8, (A4) 28BC
039EF8 tst.b ($b9,A4) 4A2C
039EFC bgt $39f02 6E04
039EFE rts 4E75
 
Just a thought. Run a trace and have it break at that 58EEC address. Maybe there’s a WRITE action somewhere, to something else, before it jumps to that routine.
 
Seems like an old problem. Here is a new boot being sold on Aliexpress.
And is still using the proto rom.
 

Attachments

  • variant-image-cor-garou-8.jpeg
    variant-image-cor-garou-8.jpeg
    165.4 KB · Views: 41
It was taking up too much of my life. Had to cut if loose. Would be too much work trying to rewrite the bank switching for me, and not knowing if that's all it would need.
 
Back
Top