This is my first tutorial so bear with me. I’d suggest reading up on MFM protections a little on some of the other tutorials before jumping into this one.
wait for title page to appear
start AR
faq dff024 0 80000

578, 44140 and 441c2 look promising
After breakpointing each, 441c2 was triggered.
Scrolling back, looks like the routine starts at 4406a.

breakpoint 4406a
Looking at this routine it appears that the data at $439fa is a load
table of some kind and it appears to be repetitions of
disk address (in bytes), file length (bytes).
Routine is called with file number in D0 and load address in A0.
Looking at this routine further it appears to use a sector size of 1024
and each track has 6 sectors.
Scrolling through the file table, the last file is at $E3491 and is $20d4,
this could pose us with a few problems then as this amounts to over 900k of data.
Anyway, lets hardwire some values into the loader and rip off all the mfm data.
breakpoint $4408e, at this point the values have been read from the file table and
the load address is in A2, the end address in A3, the disk offset in d4.
Lets try
d4 = 3000 (disk offset)
a2 = 100000 (assuming you have 2mb of chip ram to spare)
a3 = 1e2565 ($e3491+$20d4-$3000+$100000)
ok and breakpoint $440da
ok now we have all the data and you can save it off to disk (in two halves since theres too much for 1 disk)
SM part1, 100000 180000
sm part2, 180000 1e2565
Now we either need to split this game over 2 disks or we can consider packing down some of the files to try and get it down to less than 880k for a standard disk.
Considering we only need to gain back probably 30-40k, in this instance we can probably try packing down some of the data.
Looking through the file table, there is an ideal candidate,
disk offset 84546, length 1017e.
If this file isnt already packed and we can cut it down to around 50% then theres a good chance we can get the rest of the data to fit on the disk.
This is one of the files that is loaded in the initial loading sequence just after the title page appears, so either by breakingpointing the load routine or using the disk data you have already extracted, you should be able to save off the data for this file.
Using rob northens pro pack, I was able to shrink this from 65918 bytes to 32525.
This should give us the saving we need. I called my newly packed file GA84546.RNC
(catchy eh?)
Now disassemble the bootblock (either by reading it into memory using RT command) or by rebooting and stopping execution as soon as the screen changes colour.
You will see in the bootblock a similar load routine which reads in data from track 2 to 43400 and starts execution from there.

put a breakpoint at the jmp $43400 and then dump the memory area $439FA again (the load table). You will see it is more or less blank at this stage with just 1 entry.
If you breakpoint $4408e again and continue execution, you will see that the first thing that happens is that the loader is called with $efc00 and $198 and the load address is $439fa.

This is reading the main load table from the very end of the disk over this initial load table. So there is just one more area of the disk that we need to dump.
Simpy breakpoint $440da again and then
SM loadtable, 439fa 43b92
now we have all the mfm data, we need to prepare the data in memory and then write the tracks to a blank disk.
lets do the following
lM part1, 100000
lm part2, 180000
trans 1946c4 1e2565 1846c4
lm ga84546.rnc, 1d2565
lm loadtable, 1da472
What I have done is removed the old unpacked file at $84546 and appended the packed one onto the end and the load table too.
Notice that I only moved the data by $10000 bytes and not the whole $1017e bytes of the file, this makes it much simpler to modify the load table entries

This is the next job, for each of the load table entries above $84546 you need to subtract $10000 from the disc offset.
Then finally the load table for $84546 needs adjusting to $D5565 and the length to
now you are ready to insert a blank disk and
WT 1 !159 100000
right now lets patch the original load table to pick up our load table that is
now at $DD472 ($da472+$3000)
RT 1 2 43400
M 439FA
right now lets modify the $EFC00 to $DD472 and
WT 1 2 43400 to resave.

Now that we have all the data in memory we can write a little routine
and call it instead of the loader and see how the game copes.
something along the lines of
A F0000
F0000 SUB.L #$3000, d4
F0006 ADD.L #$100000,d4
F000C move.l d4,a0
F000E move.b (a0)+,(a2)+
F0010 cmp.l a2,a3
F0012 bne F000E
F0014 rts
wire this into the load routine
A 4408e
4408e JSR F0000
44094 BRA 440DA
then G43400
Hopefully the game should "load" for a while and then when the probe title page appears after the main title it will crash.
If you put a breakpoint at $4383e and then dump the memory at $800 you will
see our RNC packed data, so its not suprising that the game crashes at this point.
So no we look for some free memory to store our load routine.
I normally fill the memory with a known value (say $55) and then boot up the game and after some time playing the game, use F 55 55 55 55 to search for an area of memory which has not been overwritten.
In this case its possible to use the area of memory $180-$800. This is enough to fit a load routine and the pro-pack decruncher.
I assemble the loader using devpac (my loader sourcecode is attached) and then save out the binary data to a blank disk using monam.
I then insert my crack disk and
RT 0 1 40000
I then insert the disk containing the loader and
LM loader, 40400
then insert the crack disk again and
WT 0 1 40000
I now take another look at the load routine (from $4408e) and look where it puts
its raw mfm buffer.
at $44118 we find this code:

My loader expects the mfm buffer in a1, so I ensure this is the case before jumping to my loader at $180. So I
RT 1 2 43400
and place this code at $4408e..

04408e move.l $4466e(pc),a1
044092 add.l #$3400,a1
044098 jsr $180
a4409e bra $440da
before I
WT 1 2 43400
In addition to this if you run the game from the original disks and stop the game at the title page, you will find another load routine more or less identical to the one above, at address $e48a. If you scroll down to $e514 you will see this one gets its mfm buffer from $ea68 and adds $3400 as above.
So we need to patch this one in a similar way to the above.
Fortunately address $e48a is part of the file we previously packed above, and it is a simple case of modifying the original file at offet $e48a-$800 (since it is loaded to address $800). You can LM this file to $800 assemble the following:

00e48a movea.l $ea68(pc),a1
00e48e lea $3400(a1),a1
00e492 jsr $180
00e498 bra $e4d6
then SM it back out again. You will then need to repack it and re-insert it into the disk data at the correct point (this is explained above, and I will not go into detail here). You may need to modify the load table again too but when i repacked the file it came out a few bytes smaller, so i didnt bother.
Finally we need a bootblock that will load the original loader to $43400 and the new loader to $180.
I used the following code:
I did an RT 0 1 40000
assembled the bootblock code to $4000c, used the M command to put in the $444f5300
(DOS) and $0000370 values into $40000 and $40008 and then used bootchk 40000. I then did a WT 0 1 40000 to write it back to the disk.

Once this is all done, the crack should boot up and load right the way upto the main title page.
A couple of things you do have to be aware of if you are using your own load routine.

1. The propack depacker is quite stack hungry and this game doesnt allow for this.
What I did was save the stack pointer and repoint it to the mfm buffer area while the depacking was going on and then reset it back to what it was afterwards.

2. The second loader at $e48a works exactly like the first one and gets called initially with another dummy load table that loads in the real table. You either need to patch the 2nd load table (at $ddf6) the same way as before – or you can do what I did and code this into the loader to check for $EFC00 and change it to $DD472.

Finally to get this game past the title screen, there is one last routine that needs patching (again its inside the code that we packed that gets loaded to $800 – so we need to unpack, patch, repack and reinsert the disk data again).
There is a simple routine at $ea6c that reads track 1 and checks the length of the data read and returns 1 if the track length is less than $1a2c.
This routine can be patched to always return 0 (in d0 and at $eb3c just in case).

Loader sourcecode..
Once all this is done you should have a 100% working game.
I havent playtested this much, but i dont forsee any problems.


Publication author

Users not found

Notify of

Inline Feedbacks
View all comments
19 years ago

Hope to see more great stuff from you :yes

19 years ago

welcome dude, great tut for a great game

19 years ago

Yep, I second that, nice one 🙂

19 years ago

welcome phantasm! 🙂


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