Hacking the ST rom


Hey guys, hope im not breaking too many rules by posting this here (but the other rom hacking threads look a bit dead).

Thanks Jed for the pointers, they really helped!

Here is what I have done so far, now all I have to learn is to get into an encrypted rom, manipulate the crc checks and then it should be good to play on GGPO (I think).

P.S. Sorry the quality is so bad of the videos, my laptop just isnt strong enough to record at a better setting :frowning:


Don’t worry about it I posted a lot of Vsav stuff in this thread all the time and now working on porting a cps1 game to cps2.

Also, feel free to use my A3 hacks which the notes are posted in this thread for removing the counter hit flash and adding the hidden characters to the select screen.

FF86AD aka Player Address + 0x2AD - Status Timer
FF86AE aka Player Address + 0x2AE - Status

Flags for Status
0E - Pure white / air tech
10 - Lighten / throw tech
12 - Red / Priority
14 - Pink / Damage Reduction
16 - Light Blue / Just Defend


Sweeeet! Thanks Jed, I really wanted to add the flash after you mentioned it but after many wasted hours I gave up, just couldn’t find the byte that dictated this. :smiley:


Here is my notes for the changes so far.

Currently im putting my code in the test menu text location, since I figured it was safe to use that location as im not aware of anyone confirming a3 has an intact debug still flaggable.

Also not in the videos I also check for X-Dhalsim and give him a smaller push block strength.

jump instruction for guard cancel: 034820
value max guard: 00FF864C

alpha counter removal - 2EE78 : 042E 0010 024C
replace with (jump to next instruction!): 4EF9 0002 EE7E

Data needed for pushblock during subroutine: 0291BE bsr 2920C

do b@FF8502 = c ; Character is Dan
do b@FF8532 = 1 ; Char is Vism
do b@FF8771 = 03
do D0=7

29278 = the call to do push block animation
Flash screen : do w@80410A=9280

Override who can do PB (all X ism chars)
replacing 2920C: 0C2E 001F 0102
with: jmp 016300 : 4EF9 0001 6300
016300 : cmpi.b 1f, (102,A6) : 0C2E 001F 0102
016306 : beq 01631E : 6716
016308 : cmpi.b ff, (132, a6) : 0C2E 00FF 0132
01630E : bne 016324 : 6614
016310 : move.b (24d, a6), d0 : 102E 024D
016314 : addi.b 1C, d0 : 0600 001C
016318 : cmp.b d0, (24c, a6) : B02E 024C
01631C : bgt 016324 : 6E06
01631E : jmp 029224 : 4EF9 0002 9224
016324 : jmp 029212 : 4EF9 0002 9212
01632A : 

Modifying how much push block is given:
replacing 29258: (move.b 1f, A4) 197C 001F 02C2
with: jmp 01631C : 4EF9 0001 632A
01632A : move.b 1f, (2C2, a4) : 197C 001F 02C2
016330 : cmpi.b 1f, (102,a6) : 0C2E 001F 0102
016336 : beq 016372 : 673A
016338 : cmpi.b ff, (132, a6) : 0C2E 00FF 0132
01633E : bne 016372 : 6632
016340 : move.b ff, (24b, a6) : 1D7C 00FF 024B
016346 : move.b 1C, (29a, a6) : 1D7C 001C 029A
01634C : addi.b 1C, (24d, a6) : 062E 001C 024D
016352 : addi.b 1C, (24f, a6) : 062E 001C 024F
016358 : cmpi.b 0f, (102,a6) : 0C2E 000F 0102
01635E : bne 016366 : 6606
016360 : move.b 15, (2C2, a4) : 197C 0015 02C2
016366 : moveq 0, d0 : 7000
016368 : moveq 3a, d3 : 763A
01636A : moveq 2f, d4 : 782F
01636C : jmp 02927C : 4EF9 0002 927C
016372 : jmp 02925E : 4EF9 0002 925E

return to 2925E for regular anim, jump to 2927C to skip anim so remain in block.

do b@FF864B = Timer to initiate gauge recharge
do b@FF869A = :FF869A = v: 1343 029A
do b@FF864D = 24:FF864D = v+(FF864D): D729 024D
do b@FF864F = 24:FF864F = v+(FF864F): D729 024F


I had an idea for the right side all day. And it seemed likely it would work I didn’t do it at first. I just wanted to figure out how to get past the 0x1000 hurdle more.

Unmodified Palette


CPS1 Palette with some liberty


The the idea was to use 4 as the base interleave it with 3 for the left side graphics.


Huh, I thought it was only 2 days of silence.



Need to get rid of the doubling that lasts from 0x2000 to 0x3FFF and etc


Dude, if you or anyone ports cps1 audio into ST a reality, I will donate an arcade cab.


Jed is already making room for your cab.


Not going to happen, unless some one wants to do a hack job of wiring the Kabuki on to your cps2 board. I’ll be using the q-sound still. Probably going to just reuse ST sound programming and samples. Then maybe, switch to HSF2 at a later for the CPS1 character voice samples. But this is way down the line I still need to fix the graphics, get past the ram checks, rewrite memory locations, fix inputs, fix any bugs, then either settings rewrite or sound.


Dah, I forgot about the Kabuki chip. Isn’t that just a custom Z80? I wonder if anyone’s ever sussed out the differences between it and a vanilla Z80.

I figured there would be a lot of nagging manipulation like that. Once you have a game fairly well ported (as a proof of concept), it would be awesome to get some other people on board working on the whole CPS1 library. Especially with Darksoft’s CPS2 flash cart coming soon (I was shocked to discover how far along he is). That would be amazing to have the CPS1 & CPS2 libraries running on the same hardware. And since it will be easily updatable, people will be contributing bug reports & fixes (similar to what we see in the MAME community). Also all sorts of hacks and homebrew will likely pop up. For those of you not following, here’s the interest thread on neo-geo: http://www.neo-geo.com/forums/showthread.php?254247-CPS2-Multi-Game-Cartridge


Here’s the differences sound hardware wise.
There is more than just the Z80 that is different. Kabuki custom Z80 with encryption, YM-2151 and OKIM6295 for the sound processing. Cps2 uses Z80 with a q-sound chip. CPS1 dash forgoes the Z80 and uses the main 68k and q-sound for sound as well reading q-sound data and ram for protection.


So any idea how I would go about getting my changes into the sfa3.zip (encrypted) romset?

I figured I could just play the decrypted rom on ggpo via the unsupported room but sfa3ud.zip rom isnt supported by ggpofba.


@wazeem: use XCopy to decrypt & re-encrypt the roms - https://www.mediafire.com/folder/tsu2b5ndrl0ut/ST_hacking


@pof‌ I have tried already but no version seems to work.

Does it have to be a specific version or something?


SFA3 I believe is one of those games that got a redump of atleast the encryption key between ggpofba and current version of mame.

So you have to use the custom option for it.
from cps2crpt.c

	// name                 key               upper                  watchdog
	{ "sfa3",     { 0x6abfc8e0,0x2780ddc1 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfa3u",    { 0xe7bbf0e5,0x67943248 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfa3ur1",  { 0xe7bbf0e5,0x67943248 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfa3h",    { 0x8422df8c,0x7b17a361 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfa3hr1",  { 0x8422df8c,0x7b17a361 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfa3b",    { 0xd421c0b2,0x8116d296 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfz3j",    { 0x7d49f803,0x0cbe2d79 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfz3jr1",  { 0x7d49f803,0x0cbe2d79 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfz3jr2",  { 0x7d49f803,0x0cbe2d79 }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfz3a",    { 0x990b9301,0xa4e42c7e }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0
	{ "sfz3ar1",  { 0x990b9301,0xa4e42c7e }, 0x100000 },    // 0C80 1C62 F5A8  cmpi.l  #$1C62F5A8,D0


SF2HF CPS2 roadmap
Get graphics ported correctly
Pass the ram checks
Fix Inputs
Add a Settings Menu

I’m still stuck on step 1
So imagine if capcom still used cps1 fonts.




Break from Hyper Fighting

ST Title screen code a lot of jumps to use of to make a main menu with.

00AA12: btst    #$6, ($7e,A5); Start button is pressed or not
00AA18: bne     $aa5c; branch to jmp $2b1c if not pressed.
00AA1A: tst.b   ($2e3,A5); Service switch
00AA1E: beq     $aa28; if not pressed

00AA28: move.w  ($0,A5), D0
00AA2C: move.w  ($32,PC,D0.w), D1

00AA30: jsr     ($2e,PC,D1.w)
00ABA2: move.b  ($7f,A5), D1
00ABA6: not.b   D1
00ABA8: and.b   ($7e,A5), D1
00ABAC: andi.w  #$30, D1
00ABB0: beq     $abf8; goes to an rts
00ABB4: lea     ($2e9,A5), A1
00ABB8: tst.b   ($344,A5)
00ABBC: bne     $abdc
00ABBE: btst    #$5, D1
00ABC2: beq     $abcc
00ABCC: btst    #$4, D1
00ABD0: beq     $abf8; goes to an rts
00ABD2: moveq   #$1, D2
00ABD4: moveq   #$1, D0
00ABD6: bsr     $ab7e
00AB7E: tst.b   ($2df,A5)
00AB82: bne     $ab9a
00AB84: move.b  (A1), D4
00AB86: moveq   #$0, D3
00AB88: move.b  ($2e0,A5), D3
00AB8C: addq.w  #1, D3
00AB8E: mulu.w  D0, D3
00AB90: andi    #$ef, CCR
00AB94: sbcd    D3, D4
00AB96: bcs     $ab9e
00AB98: move.b  D4, (A1)
00AB9A: moveq   #$0, D3
00AB9C: rts

00ABD8: beq     $abfa
00ABFA: move.b  D2, ($2f0,A5)
00ABFE: move.w  #$a0, D0

00AC02: jsr     $9a8.w
0009A8: trap    #$2
0009AC: lea     (-$8000,A5), A4
0009B0: tst.b   (A4,D0.w)
0009B4: beq     $9ce
0009CE: rte
0009AA: rts

00AC06: jsr     $2c86.w
002C86: moveq   #$0, D0
002C88: move.w  D0, ($20,A5)
002C8C: move.w  D0, ($1e,A5)
002C90: lea     ($aa,A5), A0
002C94: move.w  #$1f, D0
002C98: moveq   #-$1, D1
002C9A: move.l  D1, (A0)+
002C9C: move.l  D1, (A0)+
002C9E: dbra    D0, $2c9a
002C9A: move.l  D1, (A0)+
002C9C: move.l  D1, (A0)+
002C9E: dbra    D0, $2c9a

   (loops for 90 instructions)

002CA2: rts

00AC0A: jsr     $b2a.w
000B2A: trap    #$b
000B2E: lea     (-$7f00,A5), A4
000B32: move.w  #$7, D7
000B36: tst.b   ($0,A4)
000B3A: beq     $b62
000B62: lea     ($20,A4), A4
000B66: dbra    D7, $b36
000B36: tst.b   ($0,A4)
000B3A: beq     $b62
000B62: lea     ($20,A4), A4
000B66: dbra    D7, $b36

   (loops for 24 instructions)

000B6A: rte
000B2C: rts

Then off to clear a bunch of data and go to character select.


Some input hacks i did… all of them were pretty simple, minus the Rh crazy kick which actually demanded some work…

-Zangief’s Green Hand: DP + punch;
-Ken’s Crazy Kicks: QCF + kicks, like in HDR;
-Cammy’s Backfist: QCB, like in HDR (forgot to show it);
-Cammy’s Hooligan “HCF”, or to be more precise, i changed the last direction from up-forward to just forward;
-Fei’s Chicken Wing: same as cammy’s hooligan;


This morning decided to not work on graphics and do preliminary work on program roms.
B950E addi.w #$4000,D1

Get rid of the 4000 and you can use the ssf2 font.


Now it branches to itself with this bit of code.
B9178 tst.b ($2d2,A5)
B917C bne $B9178

So switch it to a beq it quickly passes the warning and ascii title screens it boots into this garbled screen and reading the memory it’s the Dev menu and it’s upside down.


And since the inputs don’t work I can’t do anything.

Now with Video


Inputs only Directions and Punches

ADR   Change
1D2BC 804001
1D2C8 804000