diff --git a/src/analyze.a b/src/analyze.a index 0e1823b..93accbc 100755 --- a/src/analyze.a +++ b/src/analyze.a @@ -302,3 +302,22 @@ xB660 .no rts } + +;------------------------------- +; IsEATrack6 +; check if track 6 even exists +; in the case of EA, track 6 reads as track 5 +; +; in slot 6, drive 1 is on track to test +; out C clear if read track does not match expected track +; C set otherwise +;------------------------------- +IsEATrack6 + lda gTrack + cmp #6 + sec + bne + + lda $2E ;DOS read track number + sbc #5 + cmp #1 ++ rts diff --git a/src/id/ea.a b/src/id/ea.a new file mode 100644 index 0000000..679fe1f --- /dev/null +++ b/src/id/ea.a @@ -0,0 +1,107 @@ +;------------------------------- +; IDEA +; identify Electronic Arts custom bootloader +; +; in: track buffer contains T00,S00 +; out: C clear if EA bootloader was found +; C set if not found +; all other flags clobbered +; all registers clobbered +; +; module by qkumba +;------------------------------- +IDEA + lda #$00 + tax + ldy #36 + jsr compare + !byte $05,$4C,$04,$08,$A9,$00,$8D,$F2 + !byte $03,$A9,$C6,$8D,$F3,$03,$49,$A5 + !byte $8D,$F4,$03,$A9,$00,$8D,$C7,$09 + !byte $AD,$E9,$C0,$A9,$B0,$85,$3E,$A9 + !byte $02,$20,$00,$0C + bcc + + lda #$00 + tax + ldy #39 + jsr compare + !byte $05,$4C,$04,$08,$A9,$00,$8D,$F2 + !byte $03,$A9,$C6,$8D,$F3,$03,$49,$A5 + !byte $8D,$F4,$03,$A9,$00,$8D,$C7,$09 + !byte $AD,$E9,$C0,$A9,$B7,$48,$A9,$B0 + !byte $85,$3E,$A9,$00,$20,$00,$0C ++ rts + +foundea +; +; We found an EA bootloader. Now we create +; an RWTS that can read the rest of the disk. +; Starting with our built-in RWTS, we modify address +; and data prologues based on the parameters of the +; original disk. +; +!zone { + lda #s_eab0 + jsr PrintByID + jsr CopyUniversal + +; mark track 6 as "skip" in sector map + + ldy #$0F + lda #$00 +.skipsectors + sta T06,y + dey + bpl .skipsectors + +; mark track $22 as "optional" in sector map + + ldy #$0F + lda #$80 +.ignoresectors + sta T22,y + dey + bpl .ignoresectors + +;hook read data prologue + lda #<.checktrk + sta $BE36 + lda #>.checktrk + sta $BE37 + +; +; this RWTS alters the data prologue in a routine +; on a non-zero track, so we need to set a flag so +; we know to search for it later +; + lda #TRUE + sta gIsEA + jmp ADStyle + +.prologtbl + !byte $AA, $BB, $AD, $CF + + ;try regular values first + +.checktrk + ldy #0 + lda .prologtbl, y + sta $B8F1 + lda .prologtbl+2, y + sta $B8FC + jsr $B8DC + bcc + + + ;on failure, switch to alternative values + ;we keep using the last successful values until we fail + ;and then we switch again + + lda .checktrk + 1 + eor #1 + sta .checktrk + 1 + + ;and allow DOS to retry + ;if DOS runs out of retries, then Passport will report it + ++ rts +} diff --git a/src/id/inspect0.a b/src/id/inspect0.a index 35206a4..a323d18 100755 --- a/src/id/inspect0.a +++ b/src/id/inspect0.a @@ -18,14 +18,17 @@ CheckT00S00 sta gLastTrack ; Quick sanity check -- only recognized values for $0800 -; are 1 or 2. +; are 1 or 2 for regular disks, and 5 for possible Electronic Arts. lda $0800 beq + cmp #$03 bcc ++ + cmp #$05 + beq ++ + - jmp UseUniversal +- jmp UseUniversal + ++ ; ; Copy the boot sector from $0800 to the track/sector buffer @@ -139,6 +142,15 @@ CheckT00S00 jmp TheEnd .notencoded53 +; +; Try to identify Electronic Arts bootloader. +; +.tryea + jsr IDEA + bcs .notea + jmp foundea + +.notea .useuniv ; ; We didn't recognize the boot sector, so use the universal diff --git a/src/passport.a b/src/passport.a index cd5d04f..f8b0c0b 100755 --- a/src/passport.a +++ b/src/passport.a @@ -73,6 +73,8 @@ PR0 = $FE89 IN0 = $FE93 ; Zero-page addresses we use for variables +!ifdef PASS2 { +} else { nibsrcindex = $EC ; byte nibdestindex = $ED ; byte prbuf = $EE ; word @@ -89,8 +91,11 @@ tmpa = $FC ; byte tmpx = $FD ; byte tmpy = $FE ; byte flag = $FF ; byte +} ; Application constants (not zero addresses) +RELBASE = $6B00 ; address to move Passport code + ; so that it's out of the way BASEPAGE = $10 ; Special Delivery tracer assumes ; this is $10, so don't change it! TRUE = $00 ; Lots of code assumes this is $00 @@ -98,21 +103,20 @@ TRUE = $00 ; Lots of code assumes this is $00 ; don't change it either! FALSE = $01 -FirstMover - ldy #>LastMover-FirstMover ldx #$00 -FM lda $2000,x - sta $6800,x +FM lda FirstMover + ((255 + LastMover - FirstMover) & $FF00),x + sta $B500,x inx bne FM - inc FM+2 - inc FM+5 - dey - cpy #$48 + dec FM+2 + dec FM+5 + lda FM+2 + cmp #$1F bne FM jmp OneTimeSetup - !pseudopc *+$4800 { +FirstMover + !pseudopc RELBASE { !zone ; use localized strings based on current language @@ -143,6 +147,7 @@ FM lda $2000,x !source "id/specdelivery.a" !source "id/encode44.a" !source "id/encode53.a" + !source "id/ea.a" !source "print.a" !source "compare.a" !source "modify.a" @@ -408,10 +413,19 @@ checksector ; .checksync jsr IsSyncBytes - bcs .tryuniversal + bcs .checktrack6 lda #s_sync jsr PrintByID +; +; 4) track simply does not exist (Electronic Arts in particular) +; +.checktrack6 + jsr IsEATrack6 + bcs .tryuniversal + lda #s_eatrk6 + jsr PrintByID + ; note: execution falls through here .skiptrack @@ -711,6 +725,7 @@ _applyToAll !source "patchers/fbff.a" !source "patchers/sierra.a" !source "patchers/corrupter.a" + !source "patchers/ea.a" lda gPatchCount beq .nopatches @@ -767,11 +782,19 @@ gIsProtDOS !byte FALSE ; 0=true, 1=false ; set after reading T00 +gIsEA + !byte FALSE ; 0=true, 1=false + ; set after reading T00 + gOnAClearDayYouCanReadForever !byte FALSE ; 0=true, 1=false ; compile-time flag, no way to change at runtime !source "applyglobals.a" !source "universalrwts.a" -LastMover } +LastMover + +!if ($B500 - ((255 + LastMover - FirstMover) & $FF00)) != RELBASE { + !serious "RELBASE requires adjustment to ", ($B500 - ((255 + LastMover - FirstMover) & $FF00)) +} diff --git a/src/patchers/corrupter.a b/src/patchers/corrupter.a index 6b21fea..4ed060a 100644 --- a/src/patchers/corrupter.a +++ b/src/patchers/corrupter.a @@ -1,40 +1,40 @@ -;------------------------------- -; #CORRUPTER -; intentionally destroys T00,S00 -; if protection check fails -;------------------------------- -!zone { -corrupter - lda #$0F - sta .sector+1 -.sector lda #$FF ; modified at runtime - ldx #$2C - ldy #$07 - jsr compare - !byte $20,$E3,$03,$84,$00,$85,$01 - bcs .nextsector - ldx #$D4 - ldy #$0F - jsr compare - !byte $A9,$00,$8D,$00,$A0,$EE,$D3,$40 - !byte $AD,$D3,$40,$C9,$FF,$D0,$F1 - bcs .nextsector - ldx #$A4 - ldy #$0F - jsr compare - !byte $A9,$23,$85,$02,$A9,$00,$85,$03 - !byte $A9,$01,$85,$04,$20,$28,$40 - bcs .nextsector - sta gDisplayBytes - pha - lda #s_corrupter - jsr PrintByID - pla - ldy #$01 - jsr modify - !byte $60 -.nextsector - dec .sector+1 - bpl .sector -.exit -} +;------------------------------- +; #CORRUPTER +; intentionally destroys T00,S00 +; if protection check fails +;------------------------------- +!zone { +corrupter + lda #$0F + sta .sector+1 +.sector lda #$FF ; modified at runtime + ldx #$2C + ldy #$07 + jsr compare + !byte $20,$E3,$03,$84,$00,$85,$01 + bcs .nextsector + ldx #$D4 + ldy #$0F + jsr compare + !byte $A9,$00,$8D,$00,$A0,$EE,$D3,$40 + !byte $AD,$D3,$40,$C9,$FF,$D0,$F1 + bcs .nextsector + ldx #$A4 + ldy #$0F + jsr compare + !byte $A9,$23,$85,$02,$A9,$00,$85,$03 + !byte $A9,$01,$85,$04,$20,$28,$40 + bcs .nextsector + sta gDisplayBytes + pha + lda #s_corrupter + jsr PrintByID + pla + ldy #$01 + jsr modify + !byte $60 +.nextsector + dec .sector+1 + bpl .sector +.exit +} diff --git a/src/patchers/ea.a b/src/patchers/ea.a new file mode 100644 index 0000000..4fe25ef --- /dev/null +++ b/src/patchers/ea.a @@ -0,0 +1,205 @@ +;------------------------------- +; #EA +; patched RWTS and p-code madness +; +; module by qkumba +;------------------------------- +!zone { +_ea + lda gIsEA ; only ever seen this protection + beq + ; on Electronic Arts titles + jmp .dostitles + ++ ldy #40 + jsr SearchTrack + !byte $8D,$6F,$BC,$8C,$70,$BC,$A0,$20 + !byte $88,$F0,$D7,$AD,$EC,$C0,$10,$FB + !byte $49,$D5,$D0,$F4,$EA,$AD,$EC,$C0 + !byte $10,$FB,$C9,$BB,$D0,$F2,$EA,$AD + !byte $EC,$C0,$10,$FB,$C9,$CF,$D0,$E8 + bcs + + pha + txa + clc + adc #27 + tax + adc #10 + sta .patch2+1 + pla + pha + ldy #1 + jsr modify + !byte $AA +.patch2 + ldx #$D1 + pla + ldy #1 + jsr modify + !byte $AD + ++ ldy #13 + jsr SearchTrack + !byte $03, $49 ;ldi #$05 + !byte $01, $03, $65 ;jsra $bc00 + !byte $01, $03, $79 ;jsra $a000 + !byte $03, $4C ;ldi #$00 + !byte $04, $EB, $19 ;lda $c0e8 + bcs + + inx + inx + inx + inx + inx + ldy #1 + jsr modify + !byte $04 ++ ldy #15 + jsr SearchTrack + !byte $BF,$9F,$BE,$F6,$04,$2E,$9B,$DA + !byte $5A,$16,$DA,$30,$06,$45,$C2 + bcs + + inx + ldy #1 + jsr modify + !byte $EE + ++ ldy #8 + jsr SearchTrack + !byte $20,$10,$07,$A5,$56,$D0,$A7,$4C + bcs + + inx + inx + inx + inx + inx + inx + ldy #1 + jsr modify + !byte $00 + ++ ldy #15 + jsr SearchTrack + !byte $03, $49 ;ldi #$05 + !byte $01, $03, $65 ;jsra $bc00 + !byte $03, $4C ;ldi #$00 + !byte $01, $03, $79 ;jsra $a000 + !byte $07, $01 ;sub #$4d + !byte $0F, $F5, $70 ;bne $a9f6 + bcs + + pha + txa + adc #7 + tax + adc #4 + sta .patch3 + 1 + pla + pha + ldy #1 + jsr modify + !byte $04 + pla +.patch3 + ldx #$D1 + ldy #1 + jsr modify + !byte $00 + ++ ldy #13 + jsr SearchTrack + !byte $4C,$E7,$B2,$4C,$74,$B3,$00,$00 + !byte $C9,$CB,$D0,$7C,$60 + bcs + + pha + txa + adc #11 + tax + pla + ldy #1 + jsr modify + !byte $00 + ++ ldy #15 + jsr SearchTrack + !byte $03,$49 ;ldi #$05 + !byte $01,$03,$65 ;jsr $BC00 + !byte $03,$4C ;ldi #$00 + !byte $01,$03,$6C ;jsr $B500 + !byte $07,$1C ;sub #$50 + !byte $0F,$78,$60 ;bne $B97B + bcs + + pha + txa + adc #11 + tax + pla + ldy #1 + jsr modify + !byte $4C + ++ ldy #14 + jsr SearchTrack + !byte $78,$20,$00,$D7,$C9,$4D,$F0,$06 + !byte $20,$67,$67,$20,$AA,$BF + bcs + + inx + inx + inx + inx + inx + ldy #1 + jsr modify + !byte $00 + ++ ldy #12 + jsr SearchTrack + !byte $20,$3E,$91,$20,$F3,$76,$20,$00 + !byte $61,$4C,$94,$69 + bcs + + inx + inx + inx + inx + inx + inx + ldy #1 + jsr modify + !byte $2C + +.dostitles + ldy #23 + jsr SearchTrack + !byte $09, $7A ;ldi #$00 + !byte $06, $7E, $A3 ;sta $0ee2 + !byte $08, $4D, $A1 ;jsra $0cd1 + !byte $08, $4D, $A1 ;jsra $0cd1 + !byte $08, $4D, $A1 ;jsra $0cd1 + !byte $08, $4D, $A1 ;jsra $0cd1 + !byte $07, $74, $6D ;lda $c0e8 + !byte $07, $7E, $A3 ;lda $0ee2 + bcs + + pha + txa + adc #21 + tax + pla + ldy #1 + jsr modify + !byte $7F + ++ ldy #13 + jsr SearchTrack + !byte $A2,$04,$20,$4F,$1E,$20,$00,$A6 + !byte $A5,$48,$D0,$01,$60 + bcs + + pha + txa + adc #11 + tax + pla + ldy #1 + jsr modify + !byte $00 + ++ +.exit +} diff --git a/src/strings/en.a b/src/strings/en.a index cbc570b..49ab216 100755 --- a/src/strings/en.a +++ b/src/strings/en.a @@ -84,8 +84,10 @@ s_specdel = $41 s_bytrack = $42 s_a5count = $43 s_restart = $44 -s_corrupter = $45 -STRINGCOUNT = $46 +s_corrupter= $45 +s_eab0 = $46 +s_eatrk6 = $47 +STRINGCOUNT = $48 !zone { StringTable @@ -159,6 +161,8 @@ StringTable !word .a5count !word .restart !word .corrupter + !word .eaboot0 + !word .eatrk6 ; ; Text can contain substitution strings, which ; are replaced by current values at runtime. Each @@ -407,7 +411,11 @@ StringTable !text "T%t,S%0 Found A5 nibble count",$8D,$00 .restart !text "Restarting scan",$8D,$00 -.corrupter - !text "T%t,S%0 Protection check intentionally",$8D - !text "destroys unauthorized copies",$8D,$00 +.corrupter + !text "T%t,S%0 Protection check intentionally",$8D + !text "destroys unauthorized copies",$8D,$00 +.eaboot0 + !text "T00 Found Electronic Arts bootloader",$8D,00 +.eatrk6 + !text "T06 Found EA protection track",$8D,00 }