Date: 2007-07-09 00:27
"Beyond the Ice Palace" (c)1988 Elite
Things you will need:
- 1. The original of "Beyond the Ice Palace" (c)1988 Elite. The CAPS (SPS) version (numbered 1541) is the one I've used here.
- 2. An Amiga or a copy of UAE.
- 3. Resource, or another suitable disassembler.
- 4. Asm-One, or your personal favourite assembler.
So, here we go again - for a change, we'll do this one all in our assembler instead of using Action Replay or any 'freezer' carts. For those of you crying "o noes! no magic button!", don't worry it won't hurt a bit...
The game comes on a custom-format disk, but as we will see there's not much data on the disk for us to rip. Let's get started at the only place to begin - the bootblock. So since we're doing our work in Asm-One, lets reserve room for the bootblock and read it in:
buff: blk.b 512*2,0
Assemble this amazing piece of code with 'A', put your orig in df0: and read the first 2 sectors in:
>>> RS >>> RAM PTR> buff >>> DISK PTR> 0 >>> LENGTH> 2
By now you should all know that the bootblock starts with 12 bytes we don't need to worry about ("DOS"+disktype-flag, checksum & rootblock value), so we start disassembling after this using "D buff+12".
Of course, the addresses you see if you're following along at home probably won't match, it's unimportant since we'll access everything by offsets from the buffer base. Quick examination shows that it does the usual (a0=custom reg base, DMA off, executes code in supervisor mode by setting PRIV exception vector), then copies some code (from buff+$6e) to $78000 and jumps to it, so we need to check this code out with "D buff+$6e". (in my setup, the code copies from $2508a to $78000, buff is at $2501c therefore $2508a-$2501c = $6e).
We see it has a little loop that fades the screen to black, not important for us! We're only interested in what it loads, and where... keep looking. Well, the code at buff+$90 sets A1 and A2 to point to two registers important for disk access (CIAAPRA and CIABPRA) so this looks promising. Some disk setup occurs, and then we see what look suspiciously like parameters for the loader, starting with "LEA $31900,A5" (the load address) and the filesize "MOVE $90A0,D5". Scroll further down and it's easy to spot the loader itself (buff+$24c), we see it sets the DSKSYNC ($DFF07E) to $A245 and the MFM buffer address for DMA ($DFF020) to $70000. It's clear that we need to rip the loader and write a little program that loads the data from disk into a buffer so that we can access it, so let's close Asm-One for now and turn to another essential tool of the trade... Resource.
Fire up Resource, and use the "Disassemble Bootsector" option found in the "Macros 3" menu. Scroll down to the first "LEA" line, and then use the "Labels->Create multiple->All" option to give all the subroutines individual names. You'll need to scroll down to the "JMP $100" line and place the cursor after this, and do the "Labels->Create multiple->All" a couple more times to make the disassembly complete, I guess Resource gets a bit confused about the program flow. Once everything looks labelled (no "START+$xx" branches etc.) then we can safely save it out to our workdisk using the "Save all" option. Now we're ready to get back into Asm-One and start ripping!
At this stage we need to make a note of the things we need to modify the program to do:
- 1. load the files to a buffer we specify, not an absolute address.
- 2. set the MFM buffer to point to our own, not an absolute address.
- 3. not execute the title-pic display code + copperlist setup.
The program "icerip01.s" in the archive attached to this tutorial is the sourcecode that accomplishes this task, everything is commented so I won't repeat myself here. Unlike the "magic button" AR approach, you need to understand (most of) the program flow, so you know which pieces of code to patch and which to skip over...there's no question it takes longer, but think of it as good practice! If you are too lazy to look at it, just take my word for it that it does the 3 steps listed above :)
So we "A"ssemble our code, and "J"ump to it after putting the original disk in the drive, and after some loading we should return to Asm-One where we can save the loaded data out to our workdisk:
At this point we have "icepic.bin" which is the title picture + palette + copperlist for displaying it, and we have "icegame.bin" which is the game proper. There is no further loading in the game (play it and/or search through the game code for disk-loaders if you don't trust me), so we can dispense with the games horrible $1400 bytes/track (4 sectors/track, each $500 in length) custom disk format, and stick all this data together with some simple startup code to create a single-file executable for the game.
Again, we should probably make a note of the things we need to do in our code (not really necessary for this game, but good practice for the future when you crack something a bit more challenging):
- 1. disable OS and go into supervisor mode.
- 2. setup the palette/copperlist to display the titlepic.
- 3. pause for LMB/fire button.
- 4. jump to the game.
One thing worth noting here, is that the game code goes to $100. Also worth noting, is that the game code directly precedes the picture in memory... that is, the game code occupies $100-$318ff, and the picture occupies $31900-3a9cc. This doesn't leave us any room before the gamecode for our little 'stub' of code, so what we'll do is place our code after the 2 binaries in consecutive memory (so it will execute from $3a9cc) before packing the whole lot. The code for the palette/copperlist setup can be ripped directly from the game bootblock, just like we did with the loader, and in fact our stub only contains a few lines of code. The file "icecrack01.s" in the attached archive is the one you should be looking at...
After assembling this, and writing the binary to disk ("WB", start = maingame, end = theend) you should have a 239988 byte long file (I called mine "icecrack01.bin"), this contains everything we need...now it's Stonecracker time!
We use the professional mode, it's an absolute file. The load address is $100, we want to jump to $3a9cc where our little setup code is stuck onto the end of the ripped gamefiles, and we set the decruncher out of the way in spare memory at $7f000. Set the super/user stack pointers to the top of 512k ram, and we're ready to pack! Stonecracker produces a 100k file at the end of all this, not bad for an entire game :)
Save your new exe to disk, and reboot to test...
Enjoy the great David Whittaker music, and the pretty horrible graphics/gameplay!
Greetings to all the #flashtro regulars (Come join us on IRC channel #flashtro (EFNET)), and thanks to Stingray for setting me straight on a n00b mistake I made in my file-ripping code :)
That's all for this one, back to idling!
Filesize: 0KB, downloaded 58 times