💾 Archived View for mirrors.apple2.org.za › active › 4am › images › games › action › Commando%20(4am… captured on 2023-05-24 at 23:01:57.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

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

----------------Commando---------------
A 4am crack                  2015-03-19
---------------------------------------

Name: Commando
Genre: arcade
Year: 1987
Authors: Quicksilver Software, Inc.
Publisher: Data East USA, Inc.
Media: single-sided 5.25-inch floppy
OS: Quick-DOS
Other versions:
  - The Shiek / Digital Gang
  - The Blade

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  immediate disk read error

Locksmith Fast Disk Backup
  unable to read any track

EDD 4 bit copy (no sync, no count)
  no errors, but copy displays the
    Quick-DOS title screen then hangs

Copy ][+ nibble editor
  all tracks use standard prologues
  (address: D5 AA 96, data: D5 AA AD)
  but modified epilogues
  (address: FF FF EB, data: FF FF EB)

Disk Fixer
  ["O" -> "Input/Output Control"]
    set Address Epilogue to "FF FF EB"
    set Data Epilogue to "FF FF EB"
  Success! All tracks readable!
  T00 -> Quick-DOS bootloader (loads in
    language card)
  T11 -> DOS 3.3 disk catalog

Why didn't COPYA work?
  modified epilogue bytes (every track)

Why didn't Locksmith FDB work?
  modified epilogue bytes (every track)

Why didn't my EDD copy work?
  probably a nibble check during boot

Next steps:

  1. Super Demuffin
  2. Patch RWTS
  3. Find nibble check and bypass it

                   ~

               Chapter 1
          In Which We Choose
      The Right Tool For The Job


                 --v--

      SUPER-DEMUFFIN AND FAST COPY
Modified by: The Saltine/Coast to Coast


   Address prologue: D5 AA 96

   Address epilogue: FF FF EB    DISK
                     ^^^^^     ORIGINAL
change from DE AA ---+++++

      Data prologue: D5 AA AD

      Data epilogue: FF FF EB
                     ^^^^^
change from DE AA ---+++++


 Ignore write errors while demuffining!


  D - Edit parameters
      <SPACE> - Advance to next parm
      <RETURN> - Exit edit mode
  R - Restore DOS 3.3 parameters
  O - Edit Original disk's parameters
  C - Edit Copy disk's parameters
  G - Begin demuffin process

                 --^--

Pressing "G" switches to the Locksmith
Fast Disk Copy UI. It assumes that both
disks are in slot 6, and that drive 1
is the original and drive 2 is the
copy.

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

                 --v--

     LOCKSMITH 7.0  FAST DISK BACKUP


   R...................................
   W***********************************
HEX 00000000000000001111111111111111222
TRK 0123456789ABCDEF0123456789ABCDEF012
   0...................................
   1...................................
   2...................................
   3...................................
   4...................................
   5...................................
   6...................................
   7...................................
   8...................................
   9...................................
   A...................................
   B...................................
   C...................................
   D...................................
12 E...................................
   F...................................
[               ] PRESS [RESET] TO EXIT

                 --^--

]PR#6
...displays Quick-DOS title screen
   then hangs...

                   ~

               Chapter 2
        In Which We Learn That
     Hard Work Pays Off Over Time,
    But Laziness Pays Off Right Now


My EDD bit copy didn't work. Now my
demuffin'd copy doesn't work either.
Where's that nibble check?

[Disk Fixer]
  --> "F"ind
    --> "H"ex
      --> "BD 89 C0"

One thing that virtually all nibble
checks have in common is turning on the
drive motor by accessing a specific
address in the $C0xx range. For slot 6,
it's $C0E9, but to allow disks to boot
from any slot, developers usually use
code like this:

  LDX <slot number x 16>
  LDA $C089,X

There's nothing that says where the
slot number has to be, although the
disk controller ROM routine uses zero
page $2B and lots of disks just reuse
that. There's also nothing that says
you have to use the X-register as the
index, or that you must use the
accumulator as the load register. But
most RWTS code does, out of convention
I suppose (or possibly fear of messing
up such low-level code in subtle ways).

Here's the irony: depending on when the
nibble check is invoked, turning on the
drive motor is completely superfluous,
because it's already guaranteed to be
on. So you've provided a lazy way for
me to find the very code that you don't
want me to find.

Always search for "BD 89 C0". Always
always always.

Anyway, I found it on T00,S06. It looks
like this in Disk Fixer's disassembler:

T00,S06
----------- DISASSEMBLY MODE ----------
; save zero page
0000:A0 00          LDY   #$00
0002:B9 00 00       LDA   $0000,Y
0005:91 36          STA   ($36),Y
0007:88             DEY
0008:D0 F8          BNE   $0002

; initialize death counter
000A:A9 0A          LDA   #$0A
000C:85 50          STA   $50

; turn on drive motor manually
000E:A6 2B          LDX   $2B
0010:BD 89 C0       LDA   $C089,X
0013:BD 8E C0       LDA   $C08E,X

; an address (assuming this page is
; loaded at $D800)
0016:A9 9F          LDA   #$9F
0018:85 48          STA   $48
001A:A9 D8          LDA   #$D8
001C:85 49          STA   $49
001E:A9 80          LDA   #$80
0020:85 51          STA   $51
0022:C6 51          DEC   $51

; if death counter hits 0, give up
0024:F0 66          BEQ   $008C

; find next address field
0026:20 A7 D8       JSR   $D8A7

; if that failed, give up
0029:B0 61          BCS   $008C

; check if sector is $0D
002B:A5 2E          LDA   $2E
002D:C9 0D          CMP   #$0D

; if not, loop back until we find it
002F:D0 F1          BNE   $0022

; look for $D5 nibble
0031:A0 00          LDY   #$00
0033:BD 8C C0       LDA   $C08C,X
0036:10 FB          BPL   $0033
0038:88             DEY
0039:F0 51          BEQ   $008C
003B:C9 D5          CMP   #$D5
003D:D0 F4          BNE   $0033

; 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.)
003F:A0 00          LDY   #$00
0041:BD 8C C0       LDA   $C08C,X
0044:10 FB          BPL   $0041
0046:88             DEY
0047:F0 43          BEQ   $008C
0049:C9 E7          CMP   #$E7
004B:D0 F4          BNE   $0041
004D:BD 8C C0       LDA   $C08C,X
0050:10 FB          BPL   $004D
0052:C9 E7          CMP   #$E7
0054:D0 36          BNE   $008C  ; fail
0056:BD 8C C0       LDA   $C08C,X
0059:10 FB          BPL   $0056
005B:C9 E7          CMP   #$E7
005D:D0 2D          BNE   $008C  ; fail

; kill some time to get out of sync
; with the "proper" start of nibbles)
005F:BD 8D C0       LDA   $C08D,X
0062:A0 10          LDY   #$10
0064: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)
0066:BD 8C C0       LDA   $C08C,X
0069:10 FB          BPL   $0066
006B:88             DEY
006C:F0 1E          BEQ   $008C  ; fail
006E:C9 EE          CMP   #$EE
0070:D0 F4          BNE   $0066

; check for nibble sequence stored
; in reverse order at $D89F
0072:A0 07          LDY   #$07
0074:BD 8C C0       LDA   $C08C,X
0077:10 FB          BPL   $0074
0079:D1 48          CMP   ($48),Y
007B:D0 0F          BNE   $008C
007D:88             DEY
007E:10 F4          BPL   $0074

; (nibble check passed)
; restore zero page
0080:A0 00          LDY   #$00
0082:B1 36          LDA   ($36),Y
0084:99 00 00       STA   $0000,Y
0087:88             DEY
0088:D0 F8          BNE   $0082

; clear carry and exit
008A:18             CLC
008B:60             RTS

; all failures end up here -- try a few
; more times then give up completely
008C:C6 50          DEC   $50
008E:F0 03          BEQ   $0093
0090:4C 1E D8       JMP   $D81E

; (nibble check failed)
; restore zero page
0093:A0 00          LDY   #$00
0095:B1 36          LDA   ($36),Y
0097:99 00 00       STA   $0000,Y
009A:88             DEY
009B:D0 F8          BNE   $0095

; set carry and exit
009D:38             SEC
009E:60             RTS

So it's a nibble check that clears the
carry on success and sets it on
failure. There are no other side
effects. The quickest way to bypass it
is to change the start of the routine
to clear the carry unconditionally and
exit.

T00,S06,$00 change "A0 00" to "18 60"

(The RWTS appears to be flexible enough
to read the demuffin'd disk, so no RWTS
patches are required.)

Quod erat liberandum.

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