---------Principal's Assistant---------
A 4am crack                  2015-03-07
---------------------------------------

Name: Principal's Assistant: The
  Personal Printing Program
Genre: productivity
Year: 1987
Publisher: Learning Well / Pelican
  Software
Media: double-sided 5.25-inch floppy
OS: DOS 3.3
Other versions: none (preserved here
  for the first time)
Similar cracks:
  Write It Right (no. 216)
  Understanding Maps and Globes
    (no. 215)
  Seasons (no. 214)
  In the Days of Knights and Castles
    (no. 213)
  Library Skills (no. 212)
  Fun with Verbs (no. 211)
  Cause and Effect (no. 207)
  Fraction Tutorial (no. 194)

                   ~

               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 grinds on boot

Copy ][+ nibble editor
  modified address epilogue "AF FF FF"
  odd-numbered tracks (1, 3, 5...) also
    have a modified address prologue
    ("D4 AA 96")
  
Disk Fixer
  ["O" -> "Input/Output Control"]
  set Address Epilogue to "AF FF FF"
  -> even-numbered tracks readable
  T00 looks like a DOS 3.3 RWTS
  set Address Prologue to "D4 AA 96"
  -> odd-numbered tracks also readable
  T01 readable. Also T03, T05, T07...
  T11 looks like a DOS 3.3 disk catalog
  T01,S09 -> startup program is "HI"

Why didn't COPYA work?
  modified prologue and epilogue

Why didn't Locksmith FDB work?
  modified prologue and epilogue

Why didn't my EDD copy work?
  I don't know. Maybe a nibble check
  during boot?

Next steps:

  1. capture RWTS with AUTOTRACE
  2. convert disk to standard format
     with Advanced Demuffin
  3. patch RWTS to read demuffin'd disk
  4. find the nibble check & bypass it

                   ~

               Chapter 1
In Which We Attempt To Use The Original
    Disk As A Weapon Against Itself


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

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

]BRUN ADVANCED DEMUFFIN 1.5

["5" to switch to slot 5]

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

["6" to switch to slot 6]

["C" to convert disk]

                 --v--

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

                 --^--

Let's back up.

]PR#5
]BLOAD BOOT1,A$2600
]CALL -151

*FE89G FE93G     ; disconnect DOS
*B600<2600.2FFFM ; move RWTS into place
*BB00L

; set reset vector
BB00-   A9 5D       LDA   #$5D
BB02-   8D F2 03    STA   $03F2
BB05-   A9 B7       LDA   #$B7
BB07-   EA          NOP
BB08-   8D F3 03    STA   $03F3
BB0B-   49 A5       EOR   #$A5
BB0D-   8D F4 03    STA   $03F4

; set mysterious zero page for no
; apparent reason
BB10-   A9 AA       LDA   #$AA
BB12-   85 31       STA   $31

; set up something from the slot x16
; (maybe a reboot in The Badlands?)
BB14-   AD E9 B7    LDA   $B7E9
BB17-   4A          LSR
BB18-   4A          LSR
BB19-   4A          LSR
BB1A-   4A          LSR
BB1B-   09 C0       ORA   #$C0
BB1D-   8D 95 BA    STA   $BA95

; continue the boot
BB20-   4C 00 B7    JMP   $B700

I've seen this before. The RWTS uses
zero page $31 to check the second byte
of the address (or data (or both))
prologue (or epilogue (or both)).

*B944L

; routine to read address prologue
B944-   A0 FC       LDY   #$FC
B946-   84 26       STY   $26
B948-   C8          INY
B949-   D0 04       BNE   $B94F
B94B-   E6 26       INC   $26
B94D-   F0 F3       BEQ   $B942
B94F-   BD 8C C0    LDA   $C08C,X
B952-   10 FB       BPL   $B94F

; find prologue nibble #1
B954-   4A          LSR
B955-   C9 6A       CMP   #$6A    <-- !
B957-   D0 EF       BNE   $B948
B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959

; find #2
B95E-   C5 31       CMP   $31     <-- !
B960-   D0 F2       BNE   $B954
B962-   A0 03       LDY   #$03
B964-   BD 8C C0    LDA   $C08C,X
B967-   10 FB       BPL   $B964

; find #3
B969-   C9 96       CMP   #$96
B96B-   D0 E7       BNE   $B954

The code to find prologue nibble #1
explains how this disk can read its
odd-numbered tracks (with non-standard
address prologue "D4 AA 96").

Normal address prologue byte 1 is $D5.
In binary: $D5 = 1101 0101
After LSR:       0110 1010 = $6A

Odd-numbered tracks use $D4 instead.
In binary: $D4 = 1101 0100
After LSR:       0110 1010 = $6A

So this code will match either prologue
and work on both odd and even tracks.

Furthermore, RWTS code is time-critical
between reading the last bit of one
nibble and reading the first bit of the
next. If it's too fast or too slow, it
will get out of phase (because the disk
spins independently of the CPU).

Compare DOS 3.3 (cycle count in margin)

B94F-   BD 8C C0    LDA   $C08C,X
B952-   10 FB       BPL   $B94F
B954-   C9 D5       CMP   #$D5    | 2
B956-   D0 F0       BNE   $B948   | 2 *
B958-   EA          NOP           | 2
B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959

(*) on the time-critical path, this
    branch is not taken, so always 2

...and this disk's RWTS:

B94F-   BD 8C C0    LDA   $C08C,X
B952-   10 FB       BPL   $B94F
B954-   4A          LSR           | 2
B955-   C9 6A       CMP   #$6A    | 2
B957-   D0 EF       BNE   $B948   | 2 *
B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959

Despite being more "flexible" (matching
$D5 or $D4), this disk's RWTS uses the
same number of bytes of code and runs
in the same number of cycles. Nice.

Now look at this code to match the
second nibble of the address prologue:

*B959L

B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959
B95E-   C5 31       CMP   $31
B960-   D0 F2       BNE   $B954

There's zero page $31, initialized at
$BB00 during boot.

Solution: an IOB module that Advanced
Demuffin calls before calling the
original disk's RWTS. (Read the docs on
my work disk.)

*C500G
...
]CALL -151
]BLOAD ADVANCED DEMUFFIN 1.5

; standard Advanced Demuffin setup
; (unchanged)
1400-   4A          LSR
1401-   8D 22 0F    STA   $0F22
1404-   8C 23 0F    STY   $0F23
1407-   8E 27 0F    STX   $0F27
140A-   A9 01       LDA   #$01
140C-   8D 20 0F    STA   $0F20
140F-   8D 2A 0F    STA   $0F2A

; initialize zero page
1412-   A9 AA       LDA   #$AA
1414-   85 31       STA   $31

; call RWTS
1416-   A9 0F       LDA   #$0F
1418-   A0 1E       LDY   #$1E
141A-   4C 00 BD    JMP   $BD00

*BSAVE IOB $31,A$1400,L$FB
*BRUN ADVANCED DEMUFFIN 1.5

["5" to switch to slot 5]

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

[press "I" to load a new IOB module]
  --> load "IOB $31" from drive 1

["6" to switch to slot 6]

["C" to convert disk]

                 --v--

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

                 --^--

]PR#5
]CATALOG,S6,D2

C1983 DSR^C#254
158 FREE

 A 004 HI
 B 009 PA.LIB
 B 022 PA2.LIB
 B 006 MENUS.LIB
 B 002 ZINFOZ
 B 013 TITLE.PAC
 A 014 MAIN
 B 002 OPEN.R.ASM
 B 021 TITLE.LIB
 B 013 DUMP
 B 028 PRINTERS
 B 015 CARDS
 A 005 PRINT
 B 003 PRINTER
 B 002 CARD
 B 002 PRINT.MENUS.LIB
 B 011 SET.MENUS.LIB
 B 002 SAMP.MENUS.LIB
 A 006 SETUP
 B 016 SAMP1.1.PAC
 B 018 SAMP1.3.PAC
 B 017 SAMP1.4.PAC
 B 017 SAMP1.5.PAC
 B 017 SAMP1.6.PAC
 B 017 SAMP1.7.PAC
 B 019 SAMP1.9.PAC
 B 017 SAMP1.10.PAC
 B 012 SAMP1.2.PAC
 B 008 SAMP1.8.PAC

]RUN HI
...works...

[S6,D1=demuffin'd copy]

]PR#6
...works...

Wait, what?

                   ~

               Chapter 2
  In Which We Angrily Investigate Why
    We Suddenly Have A Working Copy


[S6,D1=mysteriously working copy]
[S5,D1=my work disk]

]BLOAD RWTS,A$2800
]CALL -151
*FE89G FE93G
*B800<2800.2FFFM
*B944L
.
. all weirdness accounted for, until...
.
; find epilogue byte #1
B98B-   BD 8C C0    LDA   $C08C,X
B98E-   10 FB       BPL   $B98B
B990-   C9 DE       CMP   #$DE

; if found $DE, immediately exit with
; a "success" status (clear carry bit)
B992-   F0 0A       BEQ   $B99E

; if not $DE, do... this thing
B994-   48          PHA
B995-   68          PLA
B996-   BD 8C C0    LDA   $C08C,X

; Note: no BPL loop here! It only reads
; the data latch once.
B999-   C9 08       CMP   #$08
B99B-   B0 A5       BCS   $B942
B99D-   EA          NOP
B99E-   18          CLC
B99F-   60          RTS

It's looking for a timing bit after the
first epilogue byte. It doesn't even
care what the first epilogue byte was,
as long as it wasn't $DE.

This RWTS will accept two different
address prologues, "D5 AA 96" or "D4 AA
96". It will also accept two different
address epilogues, "DE" or anything-
other-than-DE-followed-by-a-timing-bit.

Why didn't the EDD copy work?
  EDD preserved the original prologue
  epilogue but not the timing bits.
  The prologue checker (at $B944) finds
  "D5 AA 96" (even-numbered tracks) or
  "D4 AA 96" (odd-numbered tracks). But
  the epilogue checker's first compare
  (at $B98B) didn't match because the
  first epilogue byte was still the
  original value ($AF), and its second
  compare (at $B999) didn't match
  because there was no timing bit after
  the first byte. There was never any
  separate nibble check; the structure
  of the disk itself is designed to
  foil nibble copiers.
  
Why did the demuffin'd copy work?
  Advanced Demuffin wrote out the data
  from each sector onto a standard disk
  that uses "D5 AA 96" prologue and "DE
  AA EB" epilogue. The RWTS always
  matches "D5 AA 96" and doesn't care
  that it never sees a "D4 AA 96" for a
  prologue. The epilogue checker always
  matches "DE" and never checks the
  timing bit. Thus, no RWTS patches are
  necessary.

I converted side B with the same RWTS.

Quod erat liberandum.

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