Kick Off 2
© Anco
What you need:

1.      Original game or SPS #2191
2.      A little asm experience
3.      AR3 cart.



In this tutorial we’ll have a look at Kick Off 2, v1.6e, which is protected with:

1.      encryption
2.      two disk checks
3.      6 checksum routines


Start by making a copy of original game. You’ll notice an error on track 2 & 3. 
Then we have a disk based protection.
A good start is always the bootblock, load it into memory; RT 0,70000. And disassemble; D 7000C

Here is some very useful infos. Boot is loading $ 1ae00 amount of data into memory starting at address
$ 30000, from offset $ 1600 on disk. Disassemble a bit more:

Part of the bootblock is copied into memory, starting at address $ 4adb0 and then executed. This part in
memory, then copies data from address $ 30000 to $ 5300. Interesting, as boot loaded data to $ 30000.
Reboot with original disk, and enter AR when it starts loading. Search for a jump to $ 4adb0 and set a
Breakpoint there:

When this breakpoint raises, the other copy routine is now in memory. Disassemble it and find the next
jump & set a breakpoint, see above picture.

Now, first part of the decrypter is in memory, starting at $ 1ed66. It is moving data to address $ 0 and 
the fun starts. This stops of from using breakpoints now. 
We by now know, game was loading data to $ 30000 and then copies it to $ 5300. If we disassemble 
data at $ 30000 or $ 5300 its all nonsense, cause its encrypted. (try yourself). So, its most likely
to decrypt data at $ 5300 and then execute it. Exit AR wait a few secs and enter again. Look for jumps
around address $ 1e000;

If none found, exit AR and re-enter again. At some point, you should have a jmp $ 5300 at $ 1ff84.
This will start game, after it has been decrypted. Assemble and change the jump $ 5300 a jmp $ 1ff84 
and exit AR. This will make game loop when decrypted. Enter AR after 10 secs. 

Game was loading $ 1ae00 amount of data into memory. Decrypted file starts at $ 5300 + $ 1ae00 = $ 20100.
It must end at $ 20100 then. Insert a blank disk and save memory; SM a,5300 20100.
This is the file we will work on, and then at last write back to copy of game. Before we do this, we will
Locate the disk checks and checksums.
Lets starts with the disk checks. Boot original game. When loading stops and the sound is playing in 
Background, remove original disk and insert copy of game and continue loading. (press fire).
After a while, screen turns black and game hangs. This is the disk check failing.

Enter AR, see above picture. At $ 55ce we have a routine checking d6 for a value, if it fails address $ 55be
is called. This repeats at $ 55d4 and a check if d1 is # 0 at $ 55dc. If these fails, game just loops.
If these are NOP’ed out, loading can continue.. We need something to search for, so we can find
this routine in our decrypted file. Use opcodes for $ 55cc, see above pic.
Insert disk with saved file on, and load it to address $ 20000: LM a,20000.

Search for the opcodes: F 9c 45,20000. AR returns two addresses, this means we have two disk checks.
On above pic, you can see the checks, and where to kill them. Assemble and NOP them out.
Next up is the checksums. In Tip Off, one type included “ cmp.l #xxxxxxxx,d1”, Try search for this; 
F b2 bc,20000.

There is a hit at $ 24ad2. If the checked value is not matching, regs. are not restored, causing a crash.
To kill this, change the BEQ at $ 24ad8 to a BRA, see above. Also notice $ 24abe, putting value # 10af6
in a0. If you disassemble $ 10af6, soon after one of the disk checks will appear…
I tried searching for more cmp.l instructions, but no luck. But for cmp.w instructions, more luck!
Try search for cmp.w #xxxx,d3; F b6 7c,20000. There is bonus at $ 23814.

Again, its checking for a value, if it fails, some crap code is called (JMP (A2)). If it passes, regs are restored
And game continues. Again, kill it by changing the BEQ to a BRA, see above.
I got no luck with reg. D4, but D5..
Do the search; F ba 7c,20000. AR returns 7 addresses.

First 5 is just nonsense, but last 2 are interesting. $ 28ddc checks d5 for a value if it fails, stack is messed
up by $ 28de2. If it passes, this code is skipped. Kill it, by NOP’ing out $ 28de2. 
The same applies for routine at $ 2f232, kill it by NOP’ing out $ 2f238.
I noticed most of the checksums use some kind of a dbf loop. I tried searching for those;

Lots of hits. After disassembling all of them, $ 234e2 stood out. If routine fails, $ 234ea calls $ 25ee4,
which just RTS, without restoring regs. Kill this one, by NOP’ing out the BNE at $ 234ea, see above.
I continued searching for dbf loops and found one more, based on reg. D2:

Kill this last one, by NOP’ing out the BNE at $ 2e7fe. Save memory back to disk; SM A,20000 3ae00.
Its time to write the decrypted & cracked file back to copy of game. Insert copy of game and read out
a part of disk; RT 0 20 10000. From boot, we knew file started at offset $ 1600, so this must equal
to address $11600 in memory. Insert disk with saved file and load in; LM a,11600.

Remember the JMP $ 1ed66 on boot, calling the decrypter ? This is not needed anymore (of course)
and must be replaced to a JMP $ 5300, calling the file directly. Assemble and fix this, see above.
Remember to fix bootblock checksum. Insert copy of game and write memory back, see above.



Publication author

offline 2 hours


Comments: 1160Publics: 2778Registration: 06-03-2017

Notify of

Inline Feedbacks
View all comments
6 years ago

Fascinating stuff! Thanks for enlightening us :]

14 years ago

Yes cool job Rob 😉 Well done again on that one ^^

14 years ago

I never understood tyhe loaders 🙁

14 years ago

Another decent tutorial Rob – I think it’s time you moved onto custom MFM games now 🙂


This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Password generation

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Would love your thoughts, please comment.x