Bubble Bobble
? Taito Corp.

1987

?

You?ll need following:

1. Original game ? find on emunova.net
2. An Amiga or WINUAE
3. Action Replay or ROM image
4. Pencil and paper

Isn?t this just nostalgic?
Start by making a copy of original game. You?ll notice an error on track 0,
probably a good old copylock protection.
Boot copy of game to see how the protection behaves. Track counter moves to 0 at
the title screen (copylock check),
but game continues short after. You can actually play level one with no problems.
After level one, the game will start
to behave strangely. It might hang on level two, start over and over again at level
one, we can?t have that, can we?
Boot original game and enter AR when the track counter moves to 0 (at the title
pic). Copylock?s usually start with a
? PEA $$$$$ ?, search for the opcodes: F 48 7A. AR will only return
one address; 54B8C.

Disassemble address 54B8C and hit enter a few times. You?ll see typically
signs of a copylock, like the PEA and ILLEGAL
instruction. Continue disassembling until you reach end of copylock:

Copylock seems to end around address 5505A. Stick a breakpoint to this address and
exit AR. AR will then pop up,
when address 5505A are reached. BS 5505A.
When AR pops up, see registers with R. Looks like we have the key in D0. Elderly
copylocks often returned the key
at address 24, besides D0. See address 24 with M 24.
So, we have to return the key both in D0 + address 24.

The copylock is located in a file called ? snd ? ? tricky thing
to do . Insert copy of game and load it into memory,
starting at address 30000: LM SND,30000. File is located between 30000 305CC.

Disassemble address 30000 and hit enter a few times. Notice the BRA 300DC at address
30020, disassemble address
300DC and hit enter a few times. Bingo, 300DC is start of the copylock.
Assemble address 300DC and insert following code:

300DC; MOVE.L #2DAAB0BD,D0; wire correct key to D0
300E2; MOVE.L #D0,24.S; copy key from D0 to address 24
300E6; RTS; return

Save memory back as a file called ? snd?, overwriting the old one: SM
SND,30000 305CC.
To test your new crack, wouldn?t it be nice with unlimited life?
Let?s add a little trainer, giving player 1 & 2 unlimited life.
Assuming you are at start of level one, and still got all four lives, enter AR and
start trainer: TS 4. When it?s finished
searching, exit AR and loose ONE life.

Enter AR again and continue trainer: T 3. AR will return two addresses and game
stores count value in the first one.
Check what game does with this address: FA 1EBAE.

You?ll receive lot?s of references, but we are only interested in address
24B80. This address subtracts 1 from the life
count. Disassemble address 24B80 and hit enter a few times:

Besides address 24B80, also notice address 24B98. This instruction also subtracts
1 from an address. This is the
counter for player two. Notice that there are $18 between the two addresses ( 24B98-24B80=18),
as we shall use
this information later on. We?ll train the game, by simply NOP?ing out
these two instructions, and life count address will
newer decrease.
We want to patch the game, so it halts upon boot and gives us a visual information
about choosing trainer or not.
This will require a little trainer patch, which we?ll located at address 100.
Take note of the opcodes for the first instruction we?ll remove: M 24B80.
Take note of opcodes marked with red.
We?ll need them, to find the instruction later on.

Main loader is called ? BOOT ? and load a file into memory called ?
BUBBLE ?. This game does not use fixed address
for data, but relative. This means, that we have to use one of the registers as
an offset, to locate which part of memory
to patch.
Load file ? BOOT ? into memory, starting at address 30000: LM BOOT,30000.
File is located between address
30000 ? 300BC.
Disassemble address 30000 and hit enter a few times:

Loader ends at address 30072. Change the ? RTS ? to a loop routine and
save file back to disk, see picture above.
Reboot game and wait for it to hang. When it hangs, file ? bubble ?
has been loaded into memory, but isn?t executed, due
to due loop routine. Enter AR and press ? R ? to see registers. A3 points
to address 1D2D4, check contents of
address by typing N 1D2D4 and hit enter a few times. A3 seems to be pointing to
the main loader. We can then use
A3 as an offset, to calculate which addresses to patch.

Search for the opcodes for the ? SUBI.B ? instruction: F 04 39 00. AR
returns a punch of addresses, but we are only
interested in 24B80. We wish to alter address 24B80 and player two?s counter
was located $18 away, at address 24B98,
remember?
Use AR to calculate the number to add to A3, to make A3 point to the first address
we want to change:
? 24B80-1D2D4=78AC.

Read boot block into memory, starting at address 70000: RT 0 1 70000. Check for
spare bytes for our trainer:
N 70000. Seems like we have plenty of space here for our trainer. Before we code
the trainer, we
have to alter the main loader, so it calls our trainer, before executing the game.
Load file ? BOOT ? into memory,
starting at address 30000: LM BOOT,30000. Disassemble address 30020 and hit enter
a few times:

We have the loop routine at address 30072, and we want to alter it to a ?
JMP 100.S ?. But our changes is 2 bytes longer
than the original code, so we have to put the jump at address 3006E instead. This
will overwrite some of the game code,
so we have to replace it in our trainer patch. Take note of the opcodes for the
instruction at 3006E, see picture above.
Assemble 3006E and insert a ? JMP 100.S ?:

Save file back: SM BOOT,30000 300BC. Assemble offset $100 (70100) on boot block
and code the trainer:

You can?t assemble the first line using AR, so insert the opcodes instead,
see picture above.
Comments for the code:

70100; Restore code we removed in loader
70104; Set CLI colour to green
7010C; Check for left mouse
70114; If pressed, branch to 70122 and train game
70116; Check for right mouse
7011E; If pressed, branch to 7011E and start normal game
70120; loop routine, until mouse is pressed
70122; Add #78AC to A3, make it point to the first long word, in the first instruction
we want to NOP out (player 1)
70128; NOP out first long word
7012E; NOP out second long word
70136; Add #18 to A3, make it point to player two?s energy count down instruction
7013C; NOP out first long word (player 2)
70142; NOP out second long word (player 2)
7014A; Subtract #78C4 (78AC+18=78C4) from A3, restoring it to it?s original
value
70150; Return (start game)

When game boot?s, it load a while and CLI screen will flash green. If you
press Right mouse, normal game will start, if
Left mouse is pressed, the ? SUBI.B ? instructions will be NOP?ed
out and you?ll have unlimited life.

Next step, is getting the trainer into address 100. We do this, by adding a little
copy routine, moving the trainer from
offset $100 on boot block into address 100. Disassemble 7000C (start of boot code)
and hit enter a few times.
Take note of the line and change it to ? BSR 700C0 ?. We?ll the
put the copy routine at 700C0, and boot block will call
it upon game boot.

Assemble 700C0 and code the copy routine, see picture above.

Comments:

700C0; Dest. address 100 for trainer
700C6; Copy from offset $100 on disk
700CA; Copy $200, size to copy
700CE; Copy
700D0; Copy
700D4; Restore code we removed in start of boot block
700D8; Return to original boot code.

Correct boot block checksum: BOOTCHK 70000

Write boot block back: WT 0 1 70000.


Dedicated to the cutest girlie on earth, Victoria.

Rob

0

Publication author

offline 20 years

Rob

0
Comments: 103Publics: 79Registration: 20-07-2004

Subscribe
Notify of
guest

0 Comments
Newest
Oldest
Inline Feedbacks
View all comments
Foul
12 years ago

My all time favorite game !!! Excellent 🙂

0
Authorization
*
*

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

Registration
*
*
*

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.

0
Would love your thoughts, please comment.x
()
x