Hard Hat Mack / no fastloader edition
by Raven / The C700 Club / August 2011
Introduction
------------
FASTLOADER was a revolutionary piece
of hacking in the original Apple ][
era. Using an intentionally corrupted
DOS 3.3 file, it loaded just enough
of itself to bootstrap its own RWTS
and load the rest of itself into
memory. This had several advantages:
- fast to load, even under standard
DOS 3.3
- could use all of memory, even the
portion above $9600 normally reserved
for DOS
Unfortunately for those of us in the
modern era, the mini-RWTS embedded in
the FASTLOADER-enabled file assumes
it is loading itself from a real DOS
3.3 floppy disk. Programs like the
excellent DOS 3.3 Launcher allow you
to run many old DOS 3.3 games directly
from a ProDOS hard drive. This is
great when it works, but it doesn't
work with FASTLOADER-enabled files.
DOS 3.3 Launcher works by patching
the RWTS of a standard DOS 3.3 disk,
but it isn't sophisticated enough to
patch the embedded RWTS within a
FASTLOADER-enabled file.
There are dozens of great DOS 3.3
games that are only available in
FASTLOADER-enabled files. Original
disks are copy-protected or lost in
the mists of time, and no other
cracked copies exist.
The goal of this exercise is to
reauthor an already-cracked game
that uses a FASTLOADER, so that it
is stored and loaded as standard files
on a standard DOS 3.3 disk. This disk
can then be imaged, virtualized, and
launched directly from a ProDOS hard
drive using DOS 3.3 Launcher.
Getting Started
---------------
To begin with, we downloaded a disk
image of a cracked copy of HARD HAT
MACK from ftp.apple.asimov.net, the
ultimate source for all your
Apple ][ needs. Then we used ADT Pro
to transfer the disk image to a real
floppy disk on a real Apple //e. (This
step requires a serial card or an
Uthernet card in your Apple //e to
perform the transfer. Learn more at
http://adtpro.sourceforge.net/
If you do not have a real Apple //e,
or if you do not have the add-on card
necessary to transfer disk images to
it, you can open the disk image in
your favorite emulator.) No other
special hardware is required -- no
hacked ROMs, no special F8 ROMs, no
WildCard-like add-on cards.
Booting the HARD HAT MACK disk brings
up a silly menu program, which we can
safely ignore. We break to a BASIC
prompt and try to load the game.
]BLOAD HARD HAT MACK
This returns suspiciously quickly,
and with good reason. It's not loading
the entire 166-sector file; it's only
loading the 1019-byte FASTLOADER
routine.
We could spend hours explaining how
FASTLOADER works, but Deckard has
already done an excellent job of that.
Read the full explanation here:
http://boutillon.free.fr/Underground/
Outils/Beautiful_Boot/
Beautiful_Boot.html
Here are the things you absolutely
need to know about FASTLOADER:
- It relocates itself from $0800 to
$0400 (text page 1) and JMPs there.
If you're looking at a monitor listing
of, say, $08A9, remember that this
code will be at $04A9 by the time it
is executed.
- It starts loading the rest of the
game at $0800 and stores the last
loaded page in $FB/$FC. At the end of
the loading, this address will tell us
how much of memory is used by the game
and how much is unused.
- After it finishes loading the rest
of the game into memory, it JMPs to
$04A9 to perform some final memory
relocation and then start the game.
Remember, $04A9 was originally $08A9
before FASTLOADER relocated itself.
First Steps
-----------
We want FASTLOADER to load the game
for us, then we want to save it into
a standard file. That's the end goal:
a file that loads normally, without
relying on its own RWTS. This will
allow us to virtualize the disk into
an image file and launch it under
ProDOS, via DOS 3.3 Launcher.
The obvious place to start is after
FASTLOADER has loaded the game for us.
According to the disassembly provided
by Deckard, this occurs at $04A9,
a.k.a. $08A9. Let's JMP to the
monitor at that point at poke around.
*8A9:4C 59 FF
*7FDG
The screen immediately fills with
garbage characters, as FASTLOADER
relocates itself to $0400 and runs,
then returns to a monitor prompt.
Checking the zero-page location $FB
tells us where FASTLOADER stopped
loading the game into memory.
*FB.FC
00FB- 00 C0
Whoa! This game goes all the way to
the edge of ROM-space at $C000.
Normal DOS 3.3 occupies $9600-$BFFF,
and everything above that is un-
writeable. This game literally
couldn't be any bigger without
relying on auxiliary memory.
Unfortunately, the fact that
FASTLOADER executes within text page 1
($0400-$07FF) makes it difficult to
debug. Just by JMPing into the
monitor when we did, we've shifted the
"text" on screen and destroyed what
remains of the FASTLOADER code. But
it's not done yet! There are still
three memory relocation loops at $04A9
before it JMPs to the start of the
game. This final routine no longer
exists at $08A9 (that's long since
been overwritten with game code) --
it ONLY exists on the text page, which
we just corrupted.
Time to reboot and start over...
Patching the FASTLOADER
-----------------------
]PR#6
]BLOAD HARD HAT MACK
]CALL -151
*8A9L
08A9- B9 DA 04 LDA $04DA,Y
08AC- 8D B6 04 STA $04B6
08AF- 8C B9 04 STY $04B9
08B2- A2 00 LDX #$00
08B4- BD 00 00 LDA $0000,X
08B7- 9D 00 00 STA $0000,X
08BA- E8 INX
08BB- D0 F7 BNE $08B4
08BD- C8 INY
08BE- C0 08 CPY #$08
08C0- 90 E7 BCC $08A9
08C2- BD 00 04 LDA $0400,X
08C5- 9D 00 25 STA $2500,X
08C8- E8 INX
08C9- D0 F7 BNE $08C2
08CB- 4C CE 25 JMP $25CE
08CE- BD 00 23 LDA $2300,X
08D1- 9D 00 04 STA $0400,X
08D4- E8 INX
08D5- D0 F7 BNE $08CE
08D7- 4C 2D 08 JMP $082D
The purpose of this routine is to set
up the first 8 pages of memory
($0000-$07FF) before JMPing to the
start of the game. HARD HAT MACK
actually uses the code that will end
up in the first eight pages, so this
final routine is not optional.
The routine is split into three
phases:
1. $08A9-$08C1 sets up everything
except page 4 ($0400-$04FF)
2. $08C2-$08CD moves page 4 to $2500
and JMPs to it
3. $08CE-$08D9 sets up page 4
Phase one uses a lookup table at $04DA
(currently $08DA, right?) to determine
the source of each page to copy into
the first eight pages.
*8DA.8E1
08DA- 20 21 22 03 04 24
08E0- 25 26
So $2000-$20FF ends up at $00-$FF,
$2100-$21FF ends up at $0100-$01FF,
$2200-$22FF ends up at $0200-$02FF,
$2400-$24FF ends up at $0500-$05FF,
$2500-$25FF ends up at $0600-$06FF,
$2600-$26FF ends up at $0700-$07FF.
Pages 3 and 4 remain untouched.
(Technically, they are copied onto
themselves, which does nothing.)
Phase two copies $0400-$04FF to
$2500-$25FF and JMPs to $25CE, which
is the relocated address of the "next"
instruction, the start of phase three.
Phase three copies $2300-$23FF to
$0400-$04FF, then JMPs to $082D, which
is the start of the actual game.
That's how it works. But how do we
patch it so we can save it into a
new file? There's no way we can save
it all at once. JMPing into the
monitor at the end of this routine
would corrupt page 1 (stack), page 2
(keyboard buffer), and pages 4-7
(text page). There is no longer any
active DOS, since the game code
extends all the way to $BFFF. And
even a warm reboot would destroy
page 8 (during boot) and everything
above $9600 (once DOS is loaded).
We need to save it in pieces.
First, we'll save the upper range,
from $9600-$BFFF. We patch FASTLOADER
to break into the monitor immediately
after it finishes loading the game,
then move $9600-$BFFF down to a place
that won't get overwritten by DOS when
we reboot.
*8A9:4C 59 FF
*7FDG
*2000<9600.BFFFM
We insert a blank DOS 3.3 disk with no
HELLO program, and type 6<ctrl-P>
at the monitor prompt to perform a
warm reboot. (We do NOT hit
OA-Ctrl-Reset as this would corrupt
part of the memory we're trying to
save.) Once we get to the BASIC prompt
(ignoring the FILE NOT FOUND error
because we don't have a HELLO
program), we save the data that used
to start at $9600 (but now starts
at $2000).
]BSAVE HARD HAT MACK DATA,A$2000,
L$2A00
Re-insert the original HARD HAT MACK
disk and reboot. This time we will
save page 8.
]PR#6
...
]BLOAD HARD HAT MACK
]CALL -151
*8A9:4C 59 FF
*7FDG
*2000<800.8FFM
Re-insert the other disk where you
saved HARD HAT MACK DATA, and do
another warm reboot.
*6<ctrl-P>
...
]BSAVE HARD HAT MACK PAGE 8,A$2000,
L$100
Re-insert the original HARD HAT MACK
disk and reboot. This (last) time, we
will save $0900-$95FF and combine it
with page 8 that we just saved.
Before we can proceed, we have to
solve a small problem. "Phase two"
copies page 4 onto page 25, but we
can't afford to overwrite page 25
because "phase one" tries to copy it
into page 6. If we can relocate page 4
to an unused page, we can NOP out
phase two and patch up phases one and
three to run from that unused page
before JMPing to the start of the
game.
Inspection and a little bit of
experimentation reveals that page 27
($2700-$27FF) is unused. We can patch
the FASTLOADER so that it loads the
game, copies page 4 to $2700 instead
of $2500, and then breaks into the
monitor.
*8C7:27
*8CD:27
*8D7:4C 59 FF
*7FDG
Time to warm reboot...
*6<ctrl-P>
...restore page 8...
]BLOAD HARD HAT MACK PAGE 8,A$800
...and save the combined file...
]BSAVE HARD HAT MACK,A$7FD,L$8E03
RANGE ERROR
Damn, DOS 3.3 prevents us from saving
a file larger than $7FFF. We need to
hack DOS to remove that restriction:
]CALL -151
*A964:FF
*<ctrl-C>
]BSAVE HARD HAT MACK,A$7FD,L$8E03
A Crazy Plan
------------
Now we have the entire game split
into two files, but no way to load
them into the right places in memory.
If we try to load the DATA file over
the active copy of DOS at $9600, bad
things happen. If we try to load the
DATA file somewhere else and then move
it to $9600, we'll overwrite DOS and
be unable to load the main file. If
we load the main file first, we'll
have nowhere to load the DATA file...
right?
Not quite. In an Apple ][ with an
extended 80-column card or a RAM card,
there's a perfectly good place to
store the DATA file: auxiliary memory.
That means changing the requirements
of the game loader from 64K to 128K.
But remember the ultimate goal here:
to get HARD HAT MACK to load under
ProDOS, via DOS 3.3 Launcher.
According to its documentation,
DOS 3.3 Launcher already requires
128K. So we can safely assume that
auxiliary memory is available.
Here, then, is The Crazy Plan:
1. Load the DATA file ($9600-$BFFF)
into main memory at a safe location,
like $2000.
2. Move the DATA to a location in
auxiliary memory that would not be
used by DOS 3.3 Launcher or ProDOS.
According to the DOS 3.3 Launcher
documentation, AUX$2000-$5FFF is
unused. That will be more than enough
space; we only need AUX$2000-$49FF.
3. Load the main game file into main
memory ($07FD-$95FF).
4. Now that we no longer need DOS, it
is safe to overwrite $9600-$BFFF in
main memory with the DATA stored at
AUX$2000-$49FF.
5. JMP to the relocated FASTLOADER
routine in page 27 to set up the lower
eight pages, then JMP to the start of
the game.
It's foolproof!
Adventures in Aux
-----------------
There are two parts to using auxiliary
memory: copying data to, and copying
data from. Information is hard to come
by, but here is an old Apple tech note
about double hires graphics mode that
covers the basics of reading and
writing from auxiliary memory:
http://apple2.boldt.ca/?page=til/
tn.aiie.003
Access to auxiliary memory is
controlled by writing to soft switches
in the $C0xx range.
$C000 - turn off 80 column mode or
nothing else works
$C002 - read from main memory
$C003 - write to main memory
$C004 - read from auxiliary memory
$C005 - write to auxiliary memory
There are separate switches for
reading and writing, which makes it
easy to move large chunks of memory
from main to auxiliary, or vice versa.
Here is a small program to copy the
HARD HAT MACK DATA file (loaded at
$2000-$49FF) into auxiliary memory.
We store this at $0300 because that
page is unused by HARD HAT MACK. It
looks like the program is just copying
data onto itself, but because it
writes to the soft switch at $C005,
it is actually reading from main
memory and writing to auxiliary
memory.
]CALL -151
*300L
0300- 8D 00 C0 STA $C000
0303- 8D 02 C0 STA $C002
0306- 8D 05 C0 STA $C005
0309- A0 00 LDY #$00
030B- A2 00 LDX #$00
030D- BD 00 20 LDA $2000,X
0310- 9D 00 20 STA $2000,X
0313- E8 INX
0314- D0 F7 BNE $030D
0316- 8D 04 C0 STA $C004
0319- EE 0F 03 INC $030F
031C- EE 12 03 INC $0312
031F- 8D 05 C0 STA $C005
0322- C8 INY
0323- C0 2A CPY #$2A
0325- 90 E4 BCC $030B
0327- 8D 04 C0 STA $C004
032A- 60 RTS
And here is the program to do the
opposite, copy the data from AUX$2000
to $9600 in main memory. This is made
slightly more complicated by the fact
that, once you turn on the switch to
read from auxiliary memory, the
Apple ][ will read the next assembly
instruction from auxiliary memory too.
That means we need to move part of
our program to auxiliary memory first
($032B-$0340) before we can continue
with moving the HARD HAT MACK DATA
($0341-$0368).
*32BL
032B- 8D 00 C0 STA $C000
032E- 8D 02 C0 STA $C002
0331- 8D 05 C0 STA $C005
0334- A2 44 LDX #$44
0336- BD 00 03 LDA $0300,X
0339- 9D 00 03 STA $0300,X
033C- E8 INX
033D- E0 69 CPX #$69
033F- 90 F5 BCC $0336
0341- 8D 04 C0 STA $C004
0344- 8D 03 C0 STA $C003
0347- A0 00 LDY #$00
0349- A2 00 LDX #$00
034B- BD 00 20 LDA $2000,X
034E- 9D 00 96 STA $9600,X
0351- E8 INX
0352- D0 F7 BNE $034B
0354- 8D 05 C0 STA $C005
0357- EE 4D 03 INC $034D
035A- EE 50 03 INC $0350
035D- 8D 04 C0 STA $C004
0360- C8 INY
0361- C0 2A CPY #$2A
0363- 90 E4 BCC $0349
0365- 8D 02 C0 STA $C002
0368- 60 RTS
We save this program to disk, then we
can return our attention to patching
HARD HAT MACK.
*<ctrl-C>
]BSAVE AUXMOVE,A$300,L$69
]BLOAD HARD HAT MACK
]CALL -151
If we look at page 27, we see the
last remnants of the FASTLOADER
routine at $27A9. But the code still
assumes that it's being run from
$04A9. We need to patch it up so it
will run properly from page 27.
*27A7:A0 00
*27AB:27
*27AE:27
*27B1:27
If we also patch the lookup table
used by "phase one," we can eliminate
phases two and three altogether. The
only reason phase three exists is
because FASTLOADER couldn't overwrite
page 4 in phase one. But now that this
code is no longer executing from page
4, we can do everything in one phase.
*27DA.27E1
27DA- 20 21 22 03 04 24
27E0- 25 26
*27DE:23
After the newly-patched phase one is
complete, we need to call the AUX-
to-main relocation routine we wrote
at $032B. This will put the HARD HAT
MACK DATA in its rightful place at
$9600-$BFFF. This overwrites DOS, but
that's fine because by the time this
is called we won't need DOS anymore.
*27C2:20 2B 03
Now we can JMP to the game.
*27C5:4C 2D 08
Finally, we need to put a JMP to $27A7
at the beginning of the HARD HAT MACK
file so we can just BRUN it and have
everything work as expected.
*7FD:4C A7 27
*<ctrl-C>
]BSAVE HARD HAT MACK,A$7FD,L$8E03
HELLO, Is It Me You're Looking For?
-----------------------------------
Here is the HELLO program that auto-
runs HARD HAT MACK on boot.
10 TEXT : HOME
20 D$ = CHR$ (4)
30 PRINT D$;"BLOAD HARD HAT MAC
K DATA"
40 PRINT D$;"BRUN AUXMOVE"
50 PRINT D$;"BRUN HARD HAT MACK
"
]SAVE HELLO
]PR#6
That's All, Folks
-----------------
We won't bother with instructions on
creating a disk image and launching
through DOS 3.3 Launcher, because its
documentation does a thorough job of
explaining how to use the included
DOS 3.3 Copier program and then
launching the disk image from ProSel.
http://apple2.org.za/gswv/a2zine/Docs/
Dos33Launcher_Docs.txt
Enjoy this arcade classic directly
from your hard drive, courtesy of
The C700 Club!
[Download HARD HAT MACK]