From 23b5538d66fd777ea4627b39004736f444d7c73a Mon Sep 17 00:00:00 2001 From: 4am Date: Wed, 22 Jul 2020 19:01:07 -0400 Subject: [PATCH] add support for TSR protection --- src/apicode.a | 4 ++++ src/apidefs.a | 4 +++- src/id/inspect0.a | 25 ++++++++++++------------- src/id/tsr.a | 32 ++++++++++++++++++++++++++++++++ src/passport.a | 18 ++++++++++++++---- src/patchers/tsr.a | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/rwts.a | 31 +++++++++++++++++++++++++++---- src/strings/en.a | 4 ++++ src/strings/enid.a | 3 ++- 9 files changed, 142 insertions(+), 23 deletions(-) create mode 100644 src/id/tsr.a create mode 100644 src/patchers/tsr.a diff --git a/src/apicode.a b/src/apicode.a index 0155e08..a4aa51f 100644 --- a/src/apicode.a +++ b/src/apicode.a @@ -64,6 +64,10 @@ ; set in IDBootloader() after reading T00,S00 FIRSTFILTER +;gIsTSR + !byte FALSE ; 0=true, 1=false + ; reset before each operation + ; set in IDBootloader() after reading T00,S00 ;gIsDiversi !byte FALSE ; 0=true, 1=false ; reset before each operation diff --git a/src/apidefs.a b/src/apidefs.a index deee067..552db35 100644 --- a/src/apidefs.a +++ b/src/apidefs.a @@ -102,9 +102,10 @@ gIsMUSERWTS = gIsRDOS13-$01 ; byte gIsHolle = gIsMUSERWTS-$01 ; byte gIsPhoenix = gIsHolle-$01 ; byte gIsDiversi = gIsPhoenix-$01 ; byte +gIsTSR = gIsDiversi-$01 ; byte ;LASTFILTER ; add new gIs* above this line ;gIsInfocom18 is a special case whose ID is not in the regular inspection path -gIsInfocom18 = gIsDiversi-$01 ; byte +gIsInfocom18 = gIsTSR-$01 ; byte ;gIs13Sector is a special case whose ID is not in the regular inspection path gIs13Sector = gIsInfocom18-$01 ; byte ;gMECCFastloadType is a special case integer whose default value cannot be #FALSE @@ -179,6 +180,7 @@ ConstructStandardDelivery = jConstructStandardDelivery !warn "gIsHolle=",gIsHolle !warn "gIsPhoenix=",gIsPhoenix !warn "gIsDiversi=",gIsDiversi +!warn "gIsTSR=",gIsTSR !warn "gIsRDOS13=",gIsRDOS13 !warn "gIsInfocom18=",gIsInfocom18 !warn "gIs13Sector=",gIs13Sector diff --git a/src/id/inspect0.a b/src/id/inspect0.a index eb25a90..5c89866 100755 --- a/src/id/inspect0.a +++ b/src/id/inspect0.a @@ -215,20 +215,18 @@ IDBootloader lda #TRUE sta gIsProDOS jsr IDVolumeName - bcs .useuniv ; ; Dinkey-DOS (ProDOS file structure with DOS 3.3-ish RWTS in language card) ; detectable now because IDVolumeName just read the first sector of the ; volume directory into memory so we can look for a unique filename ; - jsr IDDinkeyDOS - bcs .useuniv ++ jsr IDDinkeyDOS + bcs + lda #s_dinkeydos jsr PrintByID lda #TRUE sta gIsDinkeyDOS - beq .useuniv ; always branches ; ; Apple Pascal (all versions) ; @@ -239,7 +237,6 @@ IDBootloader lda #TRUE sta gIsPascal jsr IDVolumeName - bvc .useuniv ; always branches ; ; David-DOS II ; @@ -249,7 +246,6 @@ IDBootloader jsr PrintByID lda #TRUE sta gIsDavidDOS - beq .useuniv ; always branches ; ; Encrypted Datasoft bootloader ; @@ -259,7 +255,15 @@ IDBootloader jsr PrintByID lda #TRUE sta gIsDatasoft - beq .useuniv ; always branches +; +; TSR bootloader +; ++ jsr IDTSR + bcs + + lda #s_tsr + jsr PrintByID + lda #TRUE + sta gIsTSR ; ; Micrograms bootloader ; (just for display) @@ -268,7 +272,6 @@ IDBootloader bcs + lda #s_micrograms jsr PrintByID - bcc .useuniv ; always branches ; ; Quick-DOS ; (just for display) @@ -277,7 +280,6 @@ IDBootloader bcs + lda #s_quickdos jsr PrintByID - bcc .useuniv ; always branches ; ; RDOS ; (just for display) @@ -286,7 +288,6 @@ IDBootloader bcs + lda #s_rdos jsr PrintByID - bcc .useuniv ; always branches ; ; Dav Holle encrypted bootloader @@ -299,9 +300,7 @@ IDBootloader lda #TRUE sta gIsHolle -+ -.useuniv - jmp UseUniversal ++ jmp UseUniversal } !zone { diff --git a/src/id/tsr.a b/src/id/tsr.a new file mode 100644 index 0000000..35a462c --- /dev/null +++ b/src/id/tsr.a @@ -0,0 +1,32 @@ +;------------------------------- +; IDTSR +; identify TSR bootloader +; +; in: track buffer contains T00,S00 +; out: C clear if TSR bootloader found +; C set otherwise +; all registers clobbered +; all other flags clobbered +; +; tested with +; - Dawn Patrol +; - Dungeon +; - Theseus and the Minotaur +;------------------------------- +IDTSR + lda #$00 + ldx #$FE + ldy #$02 + jsr compare + !byte $B0,$0F + bcs + + ldx #$1C + ldy #$03 + jsr compare + !byte $20,$B3,$08 + bcs + + ldx #$01 + ldy #$04 + jsr compare + !byte $A5,$27,$C9,$09 ++ rts ; passport-test-suite/Dawn Patrol.woz [C=0] matches diff --git a/src/passport.a b/src/passport.a index 1648043..d9aa473 100755 --- a/src/passport.a +++ b/src/passport.a @@ -126,6 +126,7 @@ FirstMover !source "id/jsr8b3.a" !source "id/mecc.a" !source "id/datasoft.a" + !source "id/tsr.a" !source "id/protecteddos.a" !source "id/encode44.a" !source "id/encode53.a" @@ -320,8 +321,6 @@ ADStyle UseUniversal jsr IncProgress jsr StartWithUniv - lda gIsDinkeyDOS - bne + ; ; On Dinkey-DOS disks (e.g. Ultima V, Times of Lore), we start with the ; universal RWTS then apply a patch in memory. @@ -331,9 +330,19 @@ UseUniversal ; read unprotected disks. A separate patcher finds the actual code that ; alters the sector number to print it to the log. ; + lda gIsDinkeyDOS + bne + jsr PatchUniversalRWTSForOrigin bmi ReadWithRWTS ; always branches ; +; On TSR disks (e.g. Dawn Patrol, Dungeon), we start with the universal +; RWTS then apply a patch in memory. +; ++ lda gIsTSR + bne + + jsr PatchUniversalRWTSForTSR + TODO +; ; On pure 13-sector disks, we just hijack the read routine to perform a ; verification instead. ; @@ -793,7 +802,7 @@ _applyToAll !source "patchers/polarware.a" ; gIsProDOS only !source "patchers/sierra.a" ; gIsBoot0 only !source "patchers/corrupter.a" ; T13 only - !source "patchers/ea.a" ; (gIsEA || gIsBoot0) only + !source "patchers/ea.a" ; gIsEA || gIsBoot0 only !source "patchers/gamco.a" ; gPossibleGamco only !source "patchers/optimum.a" ; gIsOptimum only !source "patchers/bootcounter.a" ; T01 only @@ -804,7 +813,7 @@ _applyToAll !source "patchers/jsr8635.a" ; gIsRWTS only !source "patchers/jmpb4bb.a" ; T02 only !source "patchers/dos32muse.a" ; T01 && gIsDOS32 only - !source "patchers/sra.a" ; gIsDOS32 or gIsRWTS only + !source "patchers/sra.a" ; gIsDOS32 || gIsRWTS only !source "patchers/sierra13.a" ; gIsDOS32 only !source "patchers/ssprot.a" ; gIsF7F6 only !source "patchers/f7f6.a" ; gIsF7F6 only @@ -823,6 +832,7 @@ _applyToAll !source "patchers/choplifter.a" ; gIsChoplifter only !source "patchers/pdi.a" ; gIsDiversi only !source "patchers/harvey.a" ; T01 only + !source "patchers/tsr.a" ; T04 && gIsTSR only lda gPatchCount beq .nopatches diff --git a/src/patchers/tsr.a b/src/patchers/tsr.a new file mode 100644 index 0000000..7dda86c --- /dev/null +++ b/src/patchers/tsr.a @@ -0,0 +1,44 @@ +;------------------------------- +; #TSR +; RWTS changes per track based on +; contents of F8 ROM (no, really) +; +; tested on +; - Dawn Patrol +; - Dungeon +; - Theseus and the Minotaur +;------------------------------- +!zone { + bit gMode ; nothing to do here in verify-only mode + bpl .exit + lda gIsTSR + bne .exit + ldx gTrack + cpx #$04 + bne .exit + + lda #$0B + ldx #$A0 + ldy #$0A + jsr compare ; if T04,S0B,$A0 == + !byte $A9,$C8 + !byte $8D,$8C,$BE + !byte $A9,$BF + !byte $8D,$8D,$BE + bcs .exit ; passport-test-suite/Dawn Patrol.woz [C=0] here + + sta gDisplayBytes + lda #s_bytrack + jsr PrintByID + + lda #$0B + ldx #$A2 + ldy #$01 + jsr modify ; then set T04,S0B,$A2 = + !byte $2C + ldx #$A7 + ldy #$01 + jsr modify ; and set T04,S0B,$A7 = + !byte $2C +.exit +} diff --git a/src/rwts.a b/src/rwts.a index 51ff023..01caea6 100755 --- a/src/rwts.a +++ b/src/rwts.a @@ -89,7 +89,7 @@ PreReadSector cmp #kSectorResetAdaptiveRWTS beq .reset cmp #kSectorIgnoreAddressChecksum - beq .ignore + beq IgnoreAddressChecksum cmp #kSectorCustomDOS32B4BB beq .b4bb rts @@ -97,8 +97,6 @@ PreReadSector jsr CopyUniversal lda #kSectorRequired rts -.ignore - jmp IgnoreAddressChecksum .b4bb ldx jCallRWTS+2 dex @@ -158,7 +156,7 @@ PatchUniversalRWTSForAdaptive !zone { PatchUniversalRWTSForOrigin -; out: N flag set +; out: N=1 ldy #$0F - lda .addressepilogue, y sta $B990, y @@ -190,6 +188,31 @@ PatchUniversalRWTSForOrigin !byte $60 } +!zone { +PatchUniversalRWTSForTSR +; out: Z=0 + lda #tsr_callback + sta $BE8D + rts +tsr_callback + pha + ldy gTrack + cpy #$05 + bcc .normal + lda $F800, y + and #$42 + bne + + lda #$42 ++ ora #$B5 + !byte $2C +.normal lda #$AD + sta $B8FC + pla + jmp $B9A0 +} + gTrack !byte $00 gSector !byte $00 diff --git a/src/strings/en.a b/src/strings/en.a index ae12e2e..0c0e437 100755 --- a/src/strings/en.a +++ b/src/strings/en.a @@ -135,6 +135,7 @@ StringTableLow !byte <.pdi !byte <.sve !byte <.cmpnopnop + !byte <.tsr StringTableHigh !byte >.header @@ -256,6 +257,7 @@ StringTableHigh !byte >.pdi !byte >.sve !byte >.cmpnopnop + !byte >.tsr ; ; Text can contain substitution strings, which @@ -610,4 +612,6 @@ StringTableHigh !text "T%t,S%0 Found PDI protection check",$8D,$00 .sve !text "T%t,S%0 Found SVE protection check",$8D,$00 +.tsr + !text "T00,S00 Found TSR bootloader",$8D,$00 } diff --git a/src/strings/enid.a b/src/strings/enid.a index e1b523f..fa1b028 100644 --- a/src/strings/enid.a +++ b/src/strings/enid.a @@ -121,4 +121,5 @@ s_choplifter = $73 s_pdi = $74 s_sve = $75 s_cmpnopnop = $76 -STRINGCOUNT = $77 +s_tsr = $77 +STRINGCOUNT = $78