From 8b58e3b94f3e512b34d75eb94d4290e8c74c292a Mon Sep 17 00:00:00 2001 From: Peter Ferrie Date: Fri, 28 Dec 2018 11:46:36 -0800 Subject: [PATCH 1/2] verify Infocom 18-sector format --- src/apicode.a | 5 +++ src/apidefs.a | 5 ++- src/id/inspect0.a | 97 ++++++++++++++++++++++++++++++++++++++++++++++ src/passport.a | 19 ++++++--- src/strings/en.a | 5 ++- src/strings/enid.a | 3 +- 6 files changed, 126 insertions(+), 8 deletions(-) diff --git a/src/apicode.a b/src/apicode.a index c65b9e0..75550d4 100644 --- a/src/apicode.a +++ b/src/apicode.a @@ -53,6 +53,11 @@ ; reset before each operation ; set in IDBootloader() after reading T00,S00 +;gIsInfocom18 + !byte FALSE ; 0=true, 1=false + ; reset before each operation + ; set in IDBootFailure() after reading T00 + FIRSTFILTER ;gIsRDOS !byte FALSE ; 0=true, 1=false diff --git a/src/apidefs.a b/src/apidefs.a index 09da977..9546487 100644 --- a/src/apidefs.a +++ b/src/apidefs.a @@ -99,8 +99,10 @@ gIsPanglosDOS = gIsAdvent-$01 ; byte gIsDavidson = gIsPanglosDOS-$01 ; byte gIsRDOS13 = gIsDavidson-$01 ; byte ;LASTFILTER ; add new gIs* above this line +;gIsInfocom18 is a special case whose ID is not in the regular inspection path +gIsInfocom18 = gIsRDOS13-$01 ; byte ;gMECCFastloadType is a special case integer whose default value cannot be #FALSE -gMECCFastloadType = gIsRDOS13-$01 ; byte +gMECCFastloadType = gIsInfocom18-$01 ; byte gOnAClearDayYouCanReadForever = gMECCFastloadType-$01 ; byte gUsingRAMDisk = gOnAClearDayYouCanReadForever-$01 ; byte @@ -168,6 +170,7 @@ ConstructStandardDelivery = jConstructStandardDelivery !warn "gIsPanglosDOS=",gIsPanglosDOS !warn "gIsDavidson=",gIsDavidson !warn "gIsRDOS13=",gIsRDOS13 +!warn "gIsInfocom18=",gIsInfocom18 !warn "gOnAClearDayYouCanReadForever=",gOnAClearDayYouCanReadForever !warn "gUsingRAMDisk=",gUsingRAMDisk !warn "gRAMDiskRef=",gRAMDiskRef diff --git a/src/id/inspect0.a b/src/id/inspect0.a index fd0cb2d..95dd7fb 100755 --- a/src/id/inspect0.a +++ b/src/id/inspect0.a @@ -18,6 +18,14 @@ IDBootloader bne - stx gMECCFastloadType stx gLastTrack + + lda gIsInfocom18 + bne .sanity + lda #s_infocom18 + jsr PrintByID + jmp UseUniversal + +.sanity ; ; Quick sanity check -- only recognized values for $0800 ; are 1 or 2 for regular disks, and 5 for possible Electronic Arts. @@ -288,3 +296,92 @@ PrereadT00Partial .exit rts } + +;------------------------------- +; IDBootFailure +; main entry point to identify the bootloader +; when the initial read failed +; identifies Infocom 18-sector side B disks +; doubles as verification routine after ID +; written by qkumba +; +; in: nothing +; out: carry set if we can't ID it +;------------------------------- +!zone { +IDBootFailure + lda #FALSE + sta gIsInfocom18 + bit gMode ; only in verify-mode + bmi .branchno + +VerifyInfocom18 + lda $C0E9 + lda #$1A ; the length of a track + sta tmp ; keep X register free + ldy #0 + +- iny + bne + + dec tmp + beq .branchno ++ lda $C0EC + bpl - +-- cmp #$D5 + bne - +- lda $C0EC + bpl - + cmp #$AA + bne -- +- lda $C0EC + bpl - + cmp #$AD + beq .tryinfocom + ldx gIsInfocom18 + beq -- ; resume if already in Infocom mode + ;;other things here in future +.branchno + jmp .no + +.tryinfocom +- lda $C0EC + bpl - + nop + nop ; ignore half of 4x4 track number +- lda $C0EC + bpl - ; ignore half of 4x4 track number + + lda #$12 ; all 18 sectors when in verify mode + ldx gIsInfocom18 + beq .setcount + lda #$01 ; only one sector when in ID mode +.setcount + sta tmp ; sector counter + + lda #$00 +-- ldy #$56 +- ldx $C0EC + bpl - + eor $BA00,x ; from universal RWTS + dey + bne - +- ldx $C0EC + bpl - + eor $BA00,x ; from universal RWTS + iny + bne - +- ldx $C0EC + bpl - + eor $BA00,x ; from universal RWTS + bne .no + dec tmp + bne -- + sta gIsInfocom18 + clc ; all clear + !byte $24 +.no + sec + lda $C0E8 + rts + +} diff --git a/src/passport.a b/src/passport.a index d170add..ac690d2 100755 --- a/src/passport.a +++ b/src/passport.a @@ -274,6 +274,8 @@ Reaction jsr IgnoreAddressChecksum jsr ReadSector bcc + + jsr IDBootFailure ; /src/id/inspect0 + bcc + lda #s_fail jsr PrintByID lda #s_fatal0000 @@ -375,11 +377,20 @@ ReadWithRWTS sta checksector+2 .read lda KEY - bpl checksector + bpl .checkinfocom bit STROBE cmp #$e0 ;ignore backtick (MAME debug break) - beq checksector + beq .checkinfocom jmp Cancel +.checkinfocom + lda gIsInfocom18 + bne checksector + jsr VerifyInfocom18 + bcc .passtrack + jmp FatalError +.passtrack + jmp .prevtrack + checksector lda $FFFF ; status of current sector in sector map (modified above) pha @@ -387,10 +398,8 @@ checksector bcc + cmp #kSectorCustomLast bcs + - jsr PreReadSector - tax pla - txa + jsr PreReadSector pha ; replace status (on stack) with new status returned from PreReadSector + cmp #kSectorIgnore ; skip this sector? beq nextsector diff --git a/src/strings/en.a b/src/strings/en.a index 78e3bb4..93edb74 100755 --- a/src/strings/en.a +++ b/src/strings/en.a @@ -123,6 +123,7 @@ StringTable !word .rdos13 !word .ssi !word .aacount + !word .infocom18 ; ; Text can contain substitution strings, which ; are replaced by current values at runtime. Each @@ -148,7 +149,7 @@ StringTable ; can be set directly before calling PrintByID. ; .header - !text "Passport by 4am 2018-10-14",$00 + !text "Passport by 4am 2018-12-28",$00 .mainmenu !text "________________________________________",$8D,$8D,$8D,$8D,$8D,$8D,$8D !text " " @@ -456,4 +457,6 @@ StringTable !text "T%t,S%0 Found SSI protection check",$8D,$00 .aacount !text "T%t,S%0 Found AA nibble count",$8D,$00 +.infocom18 + !text "T00,S00 Found Infocom 18-sector format",$8D,$00 } diff --git a/src/strings/enid.a b/src/strings/enid.a index b1f75ed..e7ef4d7 100644 --- a/src/strings/enid.a +++ b/src/strings/enid.a @@ -109,4 +109,5 @@ s_davidson = $67 s_rdos13 = $68 s_ssi = $69 s_aacount = $6A -STRINGCOUNT = $6B +s_infocom18 = $6B +STRINGCOUNT = $6C From 617a2020b685f341a9d824c1313fcff5168e4939 Mon Sep 17 00:00:00 2001 From: Peter Ferrie Date: Fri, 28 Dec 2018 22:20:48 -0800 Subject: [PATCH 2/2] verify 13-sector disks, too --- src/apicode.a | 11 +++- src/apidefs.a | 5 +- src/id/inspect0.a | 160 ++++++++++++++++++++++++++++++++++++++------- src/passport.a | 26 +++++++- src/strings/en.a | 8 ++- src/strings/enid.a | 4 +- 6 files changed, 181 insertions(+), 33 deletions(-) diff --git a/src/apicode.a b/src/apicode.a index 75550d4..09cc254 100644 --- a/src/apicode.a +++ b/src/apicode.a @@ -48,16 +48,21 @@ ; instead of falling back to built-in RWTS ; compile-time flag, no way to change at runtime -;gMECCFastloadType - !byte 00 ; int +;gIs13Sector + !byte FALSE ; 0=true, 1=false ; reset before each operation - ; set in IDBootloader() after reading T00,S00 + ; set in IDBootFailure() after reading T00 ;gIsInfocom18 !byte FALSE ; 0=true, 1=false ; reset before each operation ; set in IDBootFailure() after reading T00 +;gMECCFastloadType + !byte 00 ; int + ; reset before each operation + ; set in IDBootloader() after reading T00,S00 + FIRSTFILTER ;gIsRDOS !byte FALSE ; 0=true, 1=false diff --git a/src/apidefs.a b/src/apidefs.a index 9546487..faee4d7 100644 --- a/src/apidefs.a +++ b/src/apidefs.a @@ -101,8 +101,10 @@ gIsRDOS13 = gIsDavidson-$01 ; byte ;LASTFILTER ; add new gIs* above this line ;gIsInfocom18 is a special case whose ID is not in the regular inspection path gIsInfocom18 = gIsRDOS13-$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 -gMECCFastloadType = gIsInfocom18-$01 ; byte +gMECCFastloadType = gIs13Sector-$01 ; byte gOnAClearDayYouCanReadForever = gMECCFastloadType-$01 ; byte gUsingRAMDisk = gOnAClearDayYouCanReadForever-$01 ; byte @@ -171,6 +173,7 @@ ConstructStandardDelivery = jConstructStandardDelivery !warn "gIsDavidson=",gIsDavidson !warn "gIsRDOS13=",gIsRDOS13 !warn "gIsInfocom18=",gIsInfocom18 +!warn "gIs13Sector=",gIs13Sector !warn "gOnAClearDayYouCanReadForever=",gOnAClearDayYouCanReadForever !warn "gUsingRAMDisk=",gUsingRAMDisk !warn "gRAMDiskRef=",gRAMDiskRef diff --git a/src/id/inspect0.a b/src/id/inspect0.a index 95dd7fb..480d98e 100755 --- a/src/id/inspect0.a +++ b/src/id/inspect0.a @@ -20,11 +20,18 @@ IDBootloader stx gLastTrack lda gIsInfocom18 - bne .sanity + bne .check13 lda #s_infocom18 jsr PrintByID jmp UseUniversal +.check13 + lda gIs13Sector + bne .sanity + lda #s_13sector + jsr PrintByID + jmp UseUniversal + .sanity ; ; Quick sanity check -- only recognized values for $0800 @@ -302,7 +309,8 @@ PrereadT00Partial ; main entry point to identify the bootloader ; when the initial read failed ; identifies Infocom 18-sector side B disks -; doubles as verification routine after ID +; and pure 13-sector disks +; doubles as Infocom verification routine after ID ; written by qkumba ; ; in: nothing @@ -310,40 +318,44 @@ PrereadT00Partial ;------------------------------- !zone { IDBootFailure - lda #FALSE - sta gIsInfocom18 - bit gMode ; only in verify-mode - bmi .branchno VerifyInfocom18 lda $C0E9 - lda #$1A ; the length of a track - sta tmp ; keep X register free +.retry13 + ldx #$1A ; the length of a track ldy #0 -- iny +--- iny bne + - dec tmp - beq .branchno -+ lda $C0EC + dex + bne + + +.no sec + lda $C0E8 + rts + +.badsect + lda gIsInfocom18 + beq .no ; if in Infocom mode already then we have a true failure + bne .retry13 ; otherwise, try to identify 13-sector instead + ; the issue being that both have a D5 AA AD sequence + ++ +- lda $C0EC bpl - -- cmp #$D5 - bne - + bne --- - lda $C0EC bpl - cmp #$AA bne -- - lda $C0EC bpl - + cmp #$B5 ; 13-sector only + beq .build13 cmp #$AD - beq .tryinfocom - ldx gIsInfocom18 - beq -- ; resume if already in Infocom mode - ;;other things here in future -.branchno - jmp .no + bne -- -.tryinfocom - lda $C0EC bpl - nop @@ -373,15 +385,113 @@ VerifyInfocom18 - ldx $C0EC bpl - eor $BA00,x ; from universal RWTS - bne .no + bne .badsect dec tmp bne -- sta gIsInfocom18 - clc ; all clear - !byte $24 -.no - sec + +.checkmode + bit gMode ; verify-mode already? + bpl + ; yes, continue + + lda #%00000000 ; + sta gMode ; no, switch to verify-mode + lda #s_toverify + jsr PrintByID ; and say so + ++ clc ; all clear lda $C0E8 rts + ;build 5-and-3 decoding table + ;for 13-sector support + +.build13 + ldx #$00 + ldy #$AB +- tya + sta tmp + lsr + ora tmp + cmp #$FF + bne + + cpy #$D5 + beq + + txa + sta $800,y + inx ++ iny + bne - + sty gIs13Sector + beq .checkmode ; always taken + +read13 + lda $C0E9 + lda #$1C ; retry count + sta tmp + +.readaddr + dec tmp + bmi .badread + clc + ldx #$02 ; 512 nibbles + ldy #0 + +.readdata + php +--- iny + bne + + dex + beq .badread ++ +- lda $C0EC + bpl - +-- cmp #$D5 + bne --- +- lda $C0EC + bpl - + cmp #$AA + bne -- +- lda $C0EC + bpl - + cmp #$B5 + bne + + ldy #$03 +-- lda $C0EC + bpl -- + rol + sta $3C +- lda $C0EC + bpl - + and $3C + dey + bne -- + plp + cmp gSector + bne .readaddr + bcs .readdata ++ plp + bcc .readaddr + eor #$AD + bne read13 +-- ldy #$9A +- ldx $C0EC + bpl - + eor $800,x + dey + bne - +- ldx $C0EC + bpl - + eor $800,x + iny + bne - +- ldx $C0EC + bpl - + eor $800,x + cmp #$01 ; set carry if non-zero + !byte $24 +.badread + sec + lda $C0E8 + rts } diff --git a/src/passport.a b/src/passport.a index ac690d2..a448199 100755 --- a/src/passport.a +++ b/src/passport.a @@ -254,6 +254,8 @@ Reaction sta gTriedUniv sta gSaidWriting sta gIsProtDOS + sta gIsInfocom18 + sta gIs13Sector lda #$00 sta gTrack sta gSector @@ -341,6 +343,17 @@ UseUniversal jsr PatchUniversalRWTSForOrigin bmi ReadWithRWTS ; always branches ; +; On pure 13-sector disks, we just hijack the read routine to perform a +; verification instead. +; ++ lda gIs13Sector + bne + + lda #read13 + sta jCallRWTS+2 + bne ReadWithRWTS ; always branches +; ; On other disks that use the universal RWTS for the entire disk, we use ; an adaptive RWTS that accepts any epilogue on the first sector but then ; enforces all other sectors to have the same epilogue. @@ -370,7 +383,10 @@ ReadWithRWTS lda #$22 jsr ChangeTrackNW lda #$0F - jsr ChangeSector + ldx gIs13Sector + bne + + lda #$0C ++ jsr ChangeSector lda #T22S0F @@ -415,8 +431,11 @@ checksector ; If we just got to this track, check for whole-track protections. ; ldx #$0F ;16-sector + lda gIs13Sector + beq .expect13 lda gIsDOS32 bne + +.expect13 ldx #$0C ;13-sector + cpx gSector bne .checkoptional @@ -493,7 +512,10 @@ nextsector jmp .read .prevtrack lda #$0F - jsr ChangeSector + ldx gIs13Sector + bne + + lda #$0C ++ jsr ChangeSector lda gTrack sec sbc #$01 diff --git a/src/strings/en.a b/src/strings/en.a index 93edb74..58e4448 100755 --- a/src/strings/en.a +++ b/src/strings/en.a @@ -124,6 +124,8 @@ StringTable !word .ssi !word .aacount !word .infocom18 + !word .toverify + !word .sector13 ; ; Text can contain substitution strings, which ; are replaced by current values at runtime. Each @@ -149,7 +151,7 @@ StringTable ; can be set directly before calling PrintByID. ; .header - !text "Passport by 4am 2018-12-28",$00 + !text "Passport by 4am 2018-12-29",$00 .mainmenu !text "________________________________________",$8D,$8D,$8D,$8D,$8D,$8D,$8D !text " " @@ -459,4 +461,8 @@ StringTable !text "T%t,S%0 Found AA nibble count",$8D,$00 .infocom18 !text "T00,S00 Found Infocom 18-sector format",$8D,$00 +.toverify + !text "Switching to verify-only mode",$8D,$00 +.sector13 + !text "T00,S00 Found 13-sector format",$8D,$00 } diff --git a/src/strings/enid.a b/src/strings/enid.a index e7ef4d7..d3121ac 100644 --- a/src/strings/enid.a +++ b/src/strings/enid.a @@ -110,4 +110,6 @@ s_rdos13 = $68 s_ssi = $69 s_aacount = $6A s_infocom18 = $6B -STRINGCOUNT = $6C +s_toverify = $6C +s_13sector = $6D +STRINGCOUNT = $6E