💾 Archived View for mirrors.apple2.org.za › active › 4am › images › games › action › Crumb%20Eater%2… captured on 2023-07-10 at 19:14:39.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

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

--------------Crumb Eater--------------
A 4am crack                  2014-09-24
---------------------------------------

"Crumb Eater" is a 1983 religiously
themed arcade game by Mike Levine and
distributed by Davka Corporation.

Along with information about how to
play and what keys to use, the game
displays these instructions:

                 --v--

IF YOU THINK THAT YOU NEED MORE TIME
TO FINISH A MAZE, PRESS THE ESC
KEY. YOU WILL HAVE TO ANSWER A
A QUESTION ABOUT PASSOVER. YOU WILL
RECEIVE 5 EXTRA SECONDS FOR EVERY
CORRECT ANSWER.

                 --^--

So, there's that.

COPYA fails miserably and immediately.
Locksmith Fast Disk Backup fares no
better. EDD 4 bit copy gives no read
errors, but the copy it creates just
hangs on boot with the drive motor on.

Turning to my trusty Disk Fixer sector
editor, I go to "Input/Output Control"
(press "O") and set CHECKSUM ENABLED =
NO. 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, with one
exception: T00,S0A.

Given that the original disk boots
correctly, I'm going to guess that this
sector is either unused (in which case,
I have a damaged original disk but
caught a lucky break) or part of a copy
protection scheme (in which case I
don't care).

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. So no more COPYA+B942:18
patch. From now on, it's Super Demuffin
or Advanced Demuffin to convert disks
to a standard format. Let's see if
AUTOTRACE can capture the RWTS from the
original disk. If not, I'll have to
resort to manual investigation.

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

]PR#5
...
CAPTURING BOOT0
...reboots slot 6...
...reboots slot 5...
SAVING BOOT0
/!\ BOOT0 JUMPS TO ($BBFE)
CAPTURING BOOT1
...reboots slot 6...
...reboots slot 5...
SAVING BOOT1
SAVING RWTS

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, this
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"), there's a good
chance I'll be able to use a tool
called Advanced Demuffin (written in
1983 by The Stack) to convert the disk
from whatever weird format it uses to
store its sector data into a standard
disk readable by unprotected DOS 3.3
disks or any other third-party tools.
In this case, 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".

If anything looks fishy or non-
standard, AUTOTRACE just stops, and I
have to check the files it saved so far
to determine why. But in this case, it
ran all the way through, automatically
capturing BOOT0, BOOT1, and RWTS files.

There was one warning along the way,
though: boot0 is not jumping to boot1
in the usual way. Let's see what that's
about.

]BLOAD BOOT0,A$800
]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-   6C FE BB    JMP   ($BBFE)

Highly suspect. I definitely want to
see what evil lurks at whatever address
$BBFE is pointing to. That area of
memory is normally reserved for the
denibblizing process when reading data
from a sector. It's scratch space,
essentially. It's overwritten every
time the RWTS reads a sector from the
disk (after boot1 is loaded).









BBFE- 00 BB



BB00-   A9 00       LDA   #$00
BB02-   85 D6       STA   $D6
BB04-   BD 8D C0    LDA   $C08D,X
BB07-   A9 FF       LDA   #$FF
BB09-   EA          NOP
BB0A-   30 05       BMI   $BB11
BB0C-   A2 B1       LDX   #$B1
BB0E-   4C F0 BB    JMP   $BBF0
BB11-   AD FD FF    LDA   $FFFD
BB14-   A9 00       LDA   #$00
BB16-   F0 05       BEQ   $BB1D
BB18-   A2 B2       LDX   #$B2
BB1A-   4C F0 BB    JMP   $BBF0

; search for a nibble sequence
BB1D-   BD 8C C0    LDA   $C08C,X
BB20-   A9 00       LDA   #$00
BB22-   8D 00 02    STA   $0200
BB25-   BD 8C C0    LDA   $C08C,X
BB28-   10 FB       BPL   $BB25
BB2A-   C9 EB       CMP   #$EB
BB2C-   D0 F7       BNE   $BB25
BB2E-   BD 8C C0    LDA   $C08C,X
BB31-   10 FB       BPL   $BB2E
BB33-   C9 D5       CMP   #$D5
BB35-   D0 EE       BNE   $BB25
BB37-   BD 8C C0    LDA   $C08C,X
BB3A-   10 FB       BPL   $BB37
BB3C-   C9 AA       CMP   #$AA
BB3E-   D0 E5       BNE   $BB25

; wipe most of memory ($0800..$95FF)
; although, ironically, not the part
; I'm using for boot tracing
BB40-   A9 4C       LDA   #$4C
BB42-   A0 00       LDY   #$00
BB44-   99 00 95    STA   $9500,Y
BB47-   88          DEY
BB48-   D0 FA       BNE   $BB44
BB4A-   CE 46 BB    DEC   $BB46
BB4D-   AD 46 BB    LDA   $BB46
BB50-   C9 07       CMP   #$07
BB52-   D0 EC       BNE   $BB40

; fiddle with RWTS to ignore epilogue
; bytes (WTF)
BB54-   A9 18       LDA   #$18
BB56-   8D 42 B9    STA   $B942
BB59-   A9 0A       LDA   #$0A

; read T00,S0A into $4000 (hey, this
; means that unreadable sector was part
; of the copy protection after all)
BB5B-   8D ED B7    STA   $B7ED
BB5E-   D0 05       BNE   $BB65
...
BB65-   A9 00       LDA   #$00
BB67-   8D EC B7    STA   $B7EC
BB6A-   8D F0 B7    STA   $B7F0
BB6D-   A9 40       LDA   #$40
BB6F-   8D F1 B7    STA   $B7F1
BB72-   A9 01       LDA   #$01
BB74-   8D F4 B7    STA   $B7F4
BB77-   8D F8 B7    STA   $B7F8
BB7A-   8D EA B7    STA   $B7EA
BB7D-   8E E9 B7    STX   $B7E9
BB80-   8E F7 B7    STX   $B7F7

; more RWTS fiddling, so sector reads
; save raw nibble data in $6C00 range
BB83-   A0 6C       LDY   #$6C
BB85-   8C 10 B9    STY   $B910
BB88-   8C CE B8    STY   $B8CE
BB8B-   8C D2 B8    STY   $B8D2
BB8E-   88          DEY
BB8F-   8C 21 B9    STY   $B921

; another sector read, with modified
; RWTS 
BB92-   20 E7 BB    JSR   $BBE7

; copy the raw nibble data elsewhere
BB95-   A0 55       LDY   #$55
BB97-   B9 00 6C    LDA   $6C00,Y
BB9A-   99 00 5C    STA   $5C00,Y
BB9D-   88          DEY
BB9E-   10 F7       BPL   $BB97
BBA0-   AD 02 6B    LDA   $6B02
BBA3-   85 06       STA   $06

; another sector read
BBA5-   20 E7 BB    JSR   $BBE7
BBA8-   AD 02 6B    LDA   $6B02
BBAB-   85 07       STA   $07
BBAD-   20 E7 BB    JSR   $BBE7
BBB0-   AD 02 6B    LDA   $6B02
BBB3-   85 08       STA   $08

; compare this read's nibble data to
; the previous read's nibble data
BBB5-   A0 55       LDY   #$55
BBB7-   B9 00 6C    LDA   $6C00,Y
BBBA-   D9 00 5C    CMP   $5C00,Y
BBBD-   D0 2F       BNE   $BBEE
BBBF-   88          DEY
BBC0-   10 F5       BPL   $BBB7

; some more comparisons, just because
BBC2-   A5 06       LDA   $06
BBC4-   C5 07       CMP   $07
BBC6-   D0 04       BNE   $BBCC
BBC8-   C5 08       CMP   $08
BBCA-   F0 17       BEQ   $BBE3

; success path is here --
; first, restore the RWTS code
BBCC-   A9 38       LDA   #$38
BBCE-   8D 42 B9    STA   $B942
BBD1-   A0 BC       LDY   #$BC
BBD3-   8C 10 B9    STY   $B910
BBD6-   8C CE B8    STY   $B8CE
BBD9-   8C D2 B8    STY   $B8D2
BBDC-   88          DEY
BBDD-   8C 21 B9    STY   $B921

; then continue with boot1 as normal
BBE0-   4C 00 B7    JMP   $B700
BBE3-   4C 54 BB    JMP   $BB54
...
BBE7-   A9 B7       LDA   #$B7
BBE9-   A0 E8       LDY   #$E8
BBEB-   4C B5 B7    JMP   $B7B5

; failure path is here
BBEE-   A2 B3       LDX   #$B3
BBF0-   20 58 FC    JSR   $FC58
BBF3-   20 2D FF    JSR   $FF2D
BBF6-   8E 03 04    STX   $0403
BBF9-   4C 5B B7    JMP   $B75B

The important takeaway here is that
there don't appear to be any long-term
side effects of this copy protection.
If it succeeds, it restores everything
that it modified (in the RWTS code),
then it just jumps to $B700 to start
the boot1 phase. But that's it; nothing
else seems to rely on some magic number
that it pulls from the raw nibbles or
anything. It doesn't decrypt anything.
It doesn't even clear the carry flag.

With that knowledge, I can safely
ignore it and focus on getting the disk
into a standard format, using Advanced
Demuffin and the "RWTS" file that my
AUTOTRACE program saved.

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

]PR#5
...

]BRUN ADVANCED DEMUFFIN 1.5

[press "5" to switch to slot 5]

[press "R" to load a new RWTS module]
  --> At $B8, load "RWTS" from drive 1

[press "6" to switch to slot 6]

[press "C" to 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 unless something goes
horribly wrong.

                 --v--

ADVANCED DEMUFFIN 1.5    (C) 1983, 2014
ORIGINAL BY THE STACK    UPDATES BY 4AM
=======PRESS ANY KEY TO CONTINUE=======
TRK:R..................................
+.5:
    0123456789ABCDEF0123456789ABCDEF012
SC0:...................................
SC1:...................................
SC2:...................................
SC3:...................................
SC4:...................................
SC5:...................................
SC6:...................................
SC7:...................................
SC8:...................................
SC9:...................................
SCA:R..................................
SCB:...................................
SCC:...................................
SCD:...................................
SCE:...................................
SCF:...................................
=======================================
16SC $00,$00-$22,$0F BY1.0 S6,D1->S6,D2

                 --^--

The disk's own RWTS gave a read error
on T00,S0A, but that's OK. I already
know that that's part of the copy
protection, so I don't care about it.
The rest of the disk reads just fine.
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, my 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, because it's executing a copy
   protection routine during boot to
   check if the disk is original.
   (Hint: it's not.)

I already have enough information to
fix problem #2. The copy protection is
located at $BB00, and it is executed
immediately after boot0 (T00,S00) loads
boot1 (T00,S01-09). This line of code:

084A-   6C FE BB    JMP   ($BBFE)

...needs to look like this:

084A-   6C FD 08    JMP   ($08FD)

T00,S00,$4B change "FE BB" to "FD 08"

Now the disk boots far enough to start
grinding, because it can't read itself.
The RWTS still expects the rest of the
disk to be in a non-standard format,
but that's no longer true -- Advanced
Demuffin wrote out each sector in a
standard format. So I need to patch the
RWTS on my copy so it can read itself.

The original disk uses a modified
version of DOS 3.3. (It's so close,
that I was able to capture it with my
automated tools.) So I'm really just
reverting the modifications they made
30 years ago. Better late than never.

For future reference (mostly mine),
here's a nice chart of the memory
locations for all the prologues and
epilogues in a DOS 3.3-shaped RWTS. If
the RWTS stores $B700 in T00,S01 (most
do), then $B8xx will be in T00,S02;
$B9xx in T00,S03; and so on.


                0x |  read | write
    ---------------+-------+-------
                D5 | $B955 | $BC7A
      prologue  AA | $B95F | $BC7F
     /          96 | $B96A | $BC84
    ADDRESS -------+-------+-------
     \          DE | $B991 | $BCAE
      epilogue  AA | $B99B | $BCB3
                EB |       | $BCB8
    ---------------+-------+-------
                D5 | $B8E7 | $B853
      prologue  AA | $B8F1 | $B858
     /          AD | $B8FC | $B85D
    DATA ----------+-------+-------
     \          DE | $B935 | $B89E
      epilogue  AA | $B93F | $B8A3
                EB |       | $B8A8
    ---------------+-------+-------


(Note to self: write an RWTS comparison
tool.)

Using my trusty Disk Fixer sector
editor, I found 7 bytes that differ
from the standard DOS 3.3 RWTS:

T00,S02,$9E change "FF" to "DE"
T00,S02,$A3 change "FF" to "AA"
T00,S02,$A8 change "FF" to "EB"
T00,S03,$35 change "FF" to "DE"
T00,S03,$3F change "FF" to "AA"
T00,S03,$91 change "FF" to "DE"
T00,S03,$9B change "FF" to "AA"

With these patches in place, my copy
can now boot and read itself. It loads
and runs without complaint. There
doesn't appear to be any further copy
protection.

Quod erat liberandum.

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