💾 Archived View for mirrors.apple2.org.za › active › 4am › images › games › action › Pitstop%20II%20… captured on 2023-01-29 at 06:57:52.

View Raw

More Information

-=-=-=-=-=-=-

---------------Pitstop II--------------
A 4am crack                  2014-08-13
---------------------------------------

"Pitstop II" is a 1984 racing game
developed by Synergistic Software and
distributed by Epyx. The title screen
credits three people by name: Ivan
Manley, R. Clardy, and D. Stinnett.

[The copy protection is identical to
several other titles I've seen before,
including

- "Gertrude's Secrets, "Bumble Games,"
  "Juggles' Rainbow, "Moptown Parade,"
  "Reader Rabbit," and "Wizard of
  Words" by The Learning Company

- "Xevious" by Mindscape

- "The Notable Phantom" by DesignWare

- "Animal Kingdom" and "Race Car
  'Rithmetic" by Unicorn Software

Which is an interesting discovery in
and of itself.

Anyway, this write-up is quite similar
to those, with a few updates and
corrections.]

Booting the disk looks and sounds like
a normal DOS 3.3 boot, complete with
the drive seeking to track 2, then 1,
then 0, then swinging to the middle of
the disk to read the catalog track. It
even displays a BASIC prompt during
boot, as if it's loading a HELLO
program.

However, the disk is uncopyable by any
automated method. COPYA fails miserably
and immediately. EDD 4 bit copy gives
no read errors, but the copy it creates
only gets as far as loading DOS and
displaying the BASIC prompt before
filling the screen with garbage and
rebooting.

In my experience, disks do not
spontaneously reboot unless someone
tells them to.

Turning to my trusty Copy ][+ sector
editor, I press "P" to get to the
Sector Editor Patcher, and select "DOS
3.3 PATCHED". This option ignores
checksum bytes and epilogue sequences
-- as long as the address and data
prologue are standard ("D5 AA 96" and
"D5 AA AD", respectively), this will
allow me to read each sector. And lo
and behold, it works! I can read the
data from every sector on every track.
Track $11 does appear to contain a disk
catalog, which strongly suggests this
program is file-based.

Based on my limited experience cracking
other disks, I would guess that this
disk has

- Standard prologue bytes before the
  address and data fields [otherwise
  Copy ][+ sector editor would give
  read errors, even with the "DOS 3.3
  PATCHED" option]

- Non-standard epilogue bytes after the
  address and data fields [otherwise
  COPYA would work]

- Some secondary protection [otherwise
  the bit copy created with EDD 4 would
  work]

Given the (relatively) weak structural
protection, I used to turn to the DOS
3.3 master disk, patch the RWTS to
ignore checksums and epilogue bytes
(changing $B942 from "SEC" to "CLC"),
and run COPYA. Then, one fine day, and
completely by accident, I came across
an original disk with a bad sector. I
suppose this shouldn't surprise me.
These floppies are decades old by now;
it's amazing any of them work at all.

The point is, I shouldn't be using
tools that ignore potentially serious
read errors. There are other tools,
like Super Demuffin, that can convert a
disk like this (with non-standard
epilogue bytes) into a standard format.
It requires figuring out what the
actual epilogue bytes are, but it has
the advantage of surfacing a read error
if the original disk actually has a
read error.

So... no more COPYA+B942:18 patch. From
now on, it's Super Demuffin or Advanced
Demuffin to convert disks to a standard
format. Just by looking at the first
few sectors, it appears that this disk
uses a DOS 3.3-derived RWTS, which
means that my AUTOTRACE program should
be able to extract the RWTS from the
original disk.

[S6,D1=original disk]
[S5,D1=my work disk]

]PR#5
...
CAPTURING BOOT0
...reboots slot 6...
...reboots slot 5...
SAVING BOOT0

For those of you just tuning in, my
work disk uses a custom program that I
affectionately call "AUTOTRACE" to
automate the process of boot tracing as
far as possible. For some disks (like
this one, apparently), it just captures
track 0, sector 0 (saved in a file
called "BOOT0") and stops. For other
disks that load in the same way that an
unprotected DOS 3.3 disk loads, it
captures the next stage of the boot
process as well (in a file called
"BOOT1"). BOOT1 contains sectors 0-9 on
track 0, which are loaded into memory
at $B600..$BFFF. This generally
contains the RWTS routines which the
program uses to read the rest of the
disk.

If the RWTS is fairly normal as well
(and my AUTOTRACE program just spot-
checks a few memory locations to guess
at its "normalcy"), AUTOTRACE extracts
the RWTS routines (generally loaded
from track 0, sectors 2-9 into $B800..
$BFFF) and saves *that* into a third
file called "RWTS". There's a good
chance I'll be able to load that "RWTS"
file into a tool called Advanced
Demuffin (written in 1983 by The Stack)
to convert the disk into a standard
disk readable by unprotected DOS 3.3
disks or any other third-party tools.

If anything looks fishy or non-
standard, AUTOTRACE just stops, and I
have to check the files it saved so far
to determine why. In this case, it
stopped after capturing T00,S00. So I
need to look at that sector and figure
out why.

]CALL -151




...

Everything here looks pretty normal
(i.e. just like an unprotected DOS 3.3
disk), until it goes to jump to the
boot1 code. Usually that happens with
an indirect JMP ($08FD), which, in a
normal boot0, will end up continuing
execution at $B700 which is stored in
track 0, sector 1. But in this case, I
see:

084A-   4C C0 08    JMP   $08C0



08C0-   8E E9 B7    STX   $B7E9
08C3-   6C FD 08    JMP   ($08FD)

OK, that's harmless (as far as copy
protection goes). This boot0 code is
close enough to normal that I should
be able to run my AUTOTRACE1 script
to patch the boot0 code and interrupt
the boot before it jumps to boot1.


...reboots slot 6...
...reboots slot 5...
SAVING BOOT1
SAVING RWTS

Excellent! I have the RWTS and can load
it into Advanced Demuffin.

Advanced Demuffin will only load RWTS
files from a drive in slot 6, which is
annoying since mine is in slot 5. Note
to self: patch that someday. In the
meantime, I'm swapping floppy disks
like some kind of 20th century peasant.

[S6,D1=my work disk]

]PR#6
]BRUN ADVANCED DEMUFFIN 1.1

--> LOAD NEW RWTS MODULE
    At $B8, load "RWTS"
    from drive 1

[S6,D1=original disk]
[S6,D2=blank disk]

--> FORMAT TARGET DISK

...grind grind grind...

--> CONVERT DISK

This disk is 16 sectors, and the
default options (copy the entire disk,
all tracks, all sectors) don't need to
be changed.

ADVANCED DEMUFFIN 1.1  - COPYRIGHT 1983
WRITTEN BY THE STACK -CORRUPT COMPUTING
=======PRESS ANY KEY TO CONTINUE=======
TRK:...................................
+.5:
    0123456789ABCDEF0123456789ABCDEF012
SC0:...................................
SC1:...................................
SC2:...................................
SC3:...................................
SC4:...................................
SC5:...................................
SC6:...................................
SC7:...................................
SC8:...................................
SC9:...................................
SCA:...................................
SCB:...................................
SCC:...................................
SCD:...................................
SCE:...................................
SCF:...................................
=======================================
16 SC $00,$00 TO $22,$0F BY $01 TO DRV2

The disk's own RWTS gave no read errors
on any track. This is the power and the
genius of Advanced Demuffin. Every disk
must be able to read itself. So, let it
read itself, then capture the data and
write it out in a standard format.

There are two problems with this copy:

1. Depending on how the original disk
   was written, this copy may or may
   not be able to read itself. I may
   need to patch the disk's RWTS to
   deal with the fact that the disk is
   now in a standard format.

2. Even if it can read itself, it won't
   run. The copies I tried to make --
   even the bit copies -- just rebooted
   endlessly, which means there is some
   code being executed during boot to
   check if the disk is original.
   (Hint: it's not.)

Just by booting my copy, I can rule out
problem #1. The disk seems to read
itself just fine. It makes it exactly
as far as my failed bit copy -- far
enough to figure out that it's not an
original disk, fill the screen with
garbage, and reboot.

But wait...

[S6,D1=my work disk]
[S6,D2=non-working copy]

]PR#6
...
]CATALOG,S6,D2

C1983 DSR^C#254
493 FREE

 B 003 BOOT

OK, this disk has a "catalog," but it's
obviously just a stub for a disk-based
loader. (I attempted "BRUN BOOT" and it
crashed.) It's either tightly bound to
the custom DOS on the disk, or it
doesn't like the 64K DOS on my work
disk, or maybe it's not even used.

Let's back up.

]PR#5            ; reboot work disk
...
]BLOAD BOOT1,A$2600
]CALL -151







B700-   20 00 BB    JSR   $BB00

I've learned from previous cracks (and
from actually reading "Beneath Apple
DOS" instead of, you know, just staring
at it on my bookshelf) that, in a
standard DOS-3.3-derived RWTS, the area
from $BB00 to $BC55 is overwritten
during every disk read. (It's used as
scratch space during denibblization,
which is totally a real word that I
just made up.)

So why is there executable code there?
Let's find out.



BB00-   A0 00       LDY   #$00
BB02-   B9 00 BB    LDA   $BB00,Y
BB05-   99 00 02    STA   $0200,Y
BB08-   88          DEY
BB09-   D0 F7       BNE   $2B02
BB0B-   60          RTS

Well that's definitely suspicious.
Relocating yourself into the input
buffer at $0200? Seriously, who does
that?

I'm guessing that the first instruction
after this is the entry point, so after
relocation, that would be $020C.





; this subroutine seeks to track $11
; and sets the reset vector to
; something unfriendly
020C-   20 CF 02    JSR   $02CF
020F-   A9 0A       LDA   #$0A
0211-   85 2A       STA   $2A

; initialize disk motor
; (highly suspicious)
0213-   AE E9 B7    LDX   $B7E9
0216-   BD 89 C0    LDA   $C089,X
0219-   BD 8E C0    LDA   $C08E,X

; set some counters
021C-   A9 C7       LDA   #$C7
021E-   85 48       STA   $48
0220-   A9 02       LDA   #$02
0222-   85 49       STA   $49
0224-   A9 80       LDA   #$80
0226-   85 29       STA   $29
0228-   C6 29       DEC   $29

; reboots (bad)
022A-   F0 67       BEQ   $0293

; position the drive head to where the
; nibble check needs it
022C-   20 44 B9    JSR   $B944
022F-   B0 62       BCS   $0293
0231-   A5 2D       LDA   $2D
0233-   C9 0D       CMP   #$0D
0235-   D0 F1       BNE   $0228
0237-   A0 00       LDY   #$00
0239-   BD 8C C0    LDA   $C08C,X
023C-   10 FB       BPL   $0239
023E-   88          DEY

; reboots (bad)
023F-   F0 52       BEQ   $0293

; Search for a specific sequence of
; nibbles in the "dead zone" between
; the address field and data field.
; This area is normally not important,
; so COPYA didn't copy it precisely
; because normal disks don't care.
; (Actually, it's even more evil than
; that, because the original disk is
; written with timing bits in specific
; non-standard places between the
; nibbles in the dead zone. This code
; not only requires the right nibbles
; in the right order, it reads them
; just slightly slower than normal. So
; the timing bits need to be in the
; right places too, or else this code
; will read the wrong nibble values
; while it's out of sync. This will
; trip up even the best bit copiers.
; And you can forget about making a
; disk image for emulators -- those
; don't store timing bits at all.)
0241-   C9 D5       CMP   #$D5
0243-   D0 F4       BNE   $0239
0245-   A0 00       LDY   #$00
0247-   BD 8C C0    LDA   $C08C,X
024A-   10 FB       BPL   $0247
024C-   88          DEY

; reboots (bad)
024D-   F0 44       BEQ   $0293
024F-   C9 E7       CMP   #$E7
0251-   D0 F4       BNE   $0247
0253-   BD 8C C0    LDA   $C08C,X
0256-   10 FB       BPL   $0253
0258-   C9 E7       CMP   #$E7

; reboots (bad)
025A-   D0 37       BNE   $0293
025C-   BD 8C C0    LDA   $C08C,X
025F-   10 FB       BPL   $025C
0261-   C9 E7       CMP   #$E7

; reboots (bad)
0263-   D0 2E       BNE   $0293

; kill some time to get out of sync
; with the "proper" start of nibbles)
0265-   BD 8D C0    LDA   $C08D,X
0268-   A0 10       LDY   #$10
026A-   24 06       BIT   $06

; now start looking for nibbles that
; don't really exist (except they do,
; because we're out of sync and reading
; timing bits as data)
026C-   BD 8C C0    LDA   $C08C,X
026F-   10 FB       BPL   $026C
0271-   88          DEY

; reboots (bad)
0272-   F0 1F       BEQ   $0293
0274-   C9 EE       CMP   #$EE
0276-   D0 F4       BNE   $026C

; check for nibble sequence stored
; in reverse order at $2C7
0278-   A0 07       LDY   #$07
027A-   BD 8C C0    LDA   $C08C,X
027D-   10 FB       BPL   $027A
027F-   D1 48       CMP   ($48),Y
0281-   D0 10       BNE   $0293
0283-   88          DEY
0284-   10 F4       BPL   $027A

; if we made it this far, the nibble
; check passed
0286-   A9 80       LDA   #$80
0288-   8D 4E 9E    STA   $9E4E
028B-   A9 A1       LDA   #$A1
028D-   8D 4F 9E    STA   $9E4F
0290-   4C 4D 9E    JMP   $9E4D

That last section at $0286..$0290 is
interesting. After the nibble check
passes, it replaces two bytes at $9E4E
and $9E4F, then immediately jumps to
$9E4D. That implies that this nibble
check is called via an unconditional
jump, not a JSR. With my trusty Copy
][+ sector editor, I searched the disk
for "4C 0C 02" and found one reference
on track 00, sector 0B, byte $4D. I
wonder if I can just change those two
bytes to bypass the nibble check
altogether and turn this into a working
copy:

T00,S0B,$4E change "0C 02" to "80 A1"

Success! The game boots and runs with
no complaint. There doesn't appear to
be any further protection.

Quod erat liberandum.

---------------------------------------
A 4am crack                     No. 106
------------------EOF------------------