mirror of
https://github.com/a2-4am/passport.git
synced 2024-09-07 23:54:47 +00:00
315 lines
8.2 KiB
Plaintext
Executable File
315 lines
8.2 KiB
Plaintext
Executable File
;-------------------------------
|
|
; Identification routines for various whole-track
|
|
; protections and other frivolities.
|
|
;
|
|
; The main entry point is SkipTrack, which is
|
|
; called when the last sector ($0F or $0C) of a
|
|
; newly-seeked track is unexpectedly unreadable.
|
|
; (All the words in that sentence are important.)
|
|
;
|
|
; This file also contains low-level subroutines
|
|
; that require precise timing. There are
|
|
; assemble-time guards around the timing-sensitive
|
|
; instructions, which means that changes to this
|
|
; file may result in fatal assembler build errors
|
|
; because you moved code that can't cross a page
|
|
; boundary and now it crosses a page boundary.
|
|
;-------------------------------
|
|
|
|
;-------------------------------
|
|
; SkipTrack
|
|
; out: C clear if we should skip this track
|
|
; C set if we should not skip this track
|
|
;-------------------------------
|
|
SkipTrack
|
|
; don't look for whole-track protections on track 0, that's silly
|
|
lda gTrack
|
|
sec
|
|
beq @linknoskip
|
|
;
|
|
; Electronic Arts protection track?
|
|
;
|
|
jsr IsWideTrack
|
|
lda #s_widetrack
|
|
bcc @print
|
|
;
|
|
; Nibble count track?
|
|
;
|
|
jsr JustTheSameDamnThingOverAndOver
|
|
lda #s_sync
|
|
bcc @print
|
|
;
|
|
; RW18-format track?
|
|
;
|
|
jsr VerifyInfocom18
|
|
lda #s_rw18
|
|
bcc @print
|
|
;
|
|
; Unformatted track?
|
|
;
|
|
jsr IsUnformatted
|
|
@linknoskip
|
|
bcs @donotskip
|
|
;
|
|
; $F7F6EFEAAB protection track?
|
|
; (initially presents as unformatted, needs separate test because it
|
|
; triggers special handling)
|
|
;
|
|
jsr IsF7F6
|
|
lda #s_unformat
|
|
bcs @print
|
|
lda #s_f7
|
|
bit gMode
|
|
bpl @print
|
|
bvc @print
|
|
; if we're in 'crack' mode, restart the scan to find the protection code
|
|
bvs SetupF7F6SecondRound ; always branches
|
|
|
|
@print sta +
|
|
jsr PrintByID
|
|
+ !byte $FD ; SMC
|
|
;
|
|
; Skipping T22 on a ProDOS disk might indicate the presence of a
|
|
; Gamco Industries protection elsewhere on the disk. Different
|
|
; Gamco disks present as different types of weirdness on T22 --
|
|
; EEEF, sync, or even unformatted. (The actual protection is just
|
|
; a bad block check, so putting the code here will catch all
|
|
; possible cases.)
|
|
;
|
|
lda gTrack
|
|
cmp #$22
|
|
clc
|
|
bne @donotskip
|
|
lda gIsProDOS
|
|
bne @donotskip
|
|
sta gPossibleGamco
|
|
@donotskip
|
|
rts
|
|
|
|
;-------------------------------
|
|
; IsF7F6
|
|
; check for a specific nibble sequence
|
|
; ("F7 F6 EF EE AB") that is used by a
|
|
; whole-track protection scheme
|
|
;
|
|
; in slot 6, drive 1 is on track to test
|
|
; out C clear if sequence was found
|
|
; C set if sequence was not found
|
|
;-------------------------------
|
|
IsF7F6
|
|
lda $C0E9
|
|
lda #$00
|
|
jsr WAIT
|
|
tay
|
|
lda #$19
|
|
sta nibcount
|
|
- jsr ReadNib
|
|
cmp #$F7
|
|
beq +
|
|
@restart iny
|
|
bne -
|
|
dec nibcount
|
|
bne -
|
|
sec
|
|
beq @driveoff
|
|
+ ldx #3
|
|
- jsr ReadNib
|
|
cmp @f7f6_sequence,x
|
|
bne @restart
|
|
dex
|
|
bpl -
|
|
clc
|
|
@driveoff
|
|
lda $C0E8
|
|
rts
|
|
|
|
@f7f6_sequence
|
|
!byte $AB,$EE,$EF,$F6
|
|
;-------------------------------
|
|
; SetupF7F6SecondRound
|
|
;
|
|
; Print that we found the F7F6 protection track,
|
|
; then restart the scan so we can search every sector
|
|
; for the protection code.
|
|
; Never returns.
|
|
; Exits via RestartScan.
|
|
;-------------------------------
|
|
SetupF7F6SecondRound
|
|
; Mark in the sector map that we should ignore
|
|
; this protection track the second time around.
|
|
lda checksector+1
|
|
sta @a+1
|
|
lda checksector+2
|
|
sta @a+2
|
|
ldy gSector
|
|
lda #kSectorIgnore
|
|
@a sta $D1D1 ; modifed at runtime
|
|
ldx @a+1
|
|
bne +
|
|
dec @a+2
|
|
+ dec @a+1
|
|
dey
|
|
bpl @a
|
|
jsr PrintByID ; print that we found the protection track
|
|
!byte s_f7
|
|
lda #TRUE
|
|
sta gIsF7F6 ; set global to activate expensive patcher
|
|
jmp RestartScan
|
|
|
|
;-------------------------------
|
|
; JustTheSameDamnThingOverAndOver
|
|
; check if track has 512 repeated nibbles
|
|
;
|
|
; in slot 6, drive 1 is on track to test
|
|
; out C clear if found
|
|
; C set otherwise
|
|
;-------------------------------
|
|
JustTheSameDamnThingOverAndOver
|
|
lda $C0E9 ; turn on drive motor, but we assume it's already spun up from previous reads so no waiting
|
|
lda #$60
|
|
sta tmp
|
|
lda #$19
|
|
sta unform+1
|
|
ldx #$00
|
|
;
|
|
; Timing-sensitive code! Cycle counts in margin for worst case path
|
|
;
|
|
@reset clv ; 2
|
|
ldy #$00 ; 2
|
|
sta @cmp+1 ; 4
|
|
@loop lda $C0EC ; 4
|
|
bpl @loop ; 2 when not taken
|
|
!if RELBASE != $2000 {
|
|
!if >@loop != >* {
|
|
!serious "branch crosses a page"
|
|
}
|
|
}
|
|
dex ; 2
|
|
bne @cmp ; 2 when not taken
|
|
dec unform+1 ; 5
|
|
beq @notfound ; 2 when not taken
|
|
@cmp cmp #$d1 ; 2
|
|
bne @reset ; 2 when not taken
|
|
iny ; 2
|
|
bne @loop ; 2 when not taken (3 when taken)
|
|
bvs @found ; 2 when not taken
|
|
bit tmp ; 3 (sets overflow flag)
|
|
bvs @loop ; 3 (always taken)
|
|
@found
|
|
clc
|
|
!byte $24
|
|
@notfound
|
|
sec
|
|
lda $C0E8
|
|
rts
|
|
|
|
;-------------------------------
|
|
; IsUnformatted
|
|
; check if track is unformatted by counting
|
|
; the number of valid nibbles in a row
|
|
;
|
|
; in slot 6, drive 1 is on track to test
|
|
; out C clear if track is unformatted
|
|
; C set if track is formatted
|
|
;-------------------------------
|
|
IsUnformatted
|
|
lda $C0E9 ; turn on drive motor, but we assume it's already spun up from previous reads so no waiting
|
|
lda #$00
|
|
sta unform
|
|
lda #$19
|
|
sta unform+1
|
|
;
|
|
; Timing-sensitive code! Cycle counts in margin for worst case path
|
|
;
|
|
clc
|
|
@reset ldy #$00
|
|
@loop ldx $C0EC ; 4
|
|
bpl @loop ; 2 when not taken
|
|
!if RELBASE != $2000 {
|
|
!if >@loop != >* {
|
|
!serious "branch crosses a page"
|
|
}
|
|
}
|
|
dec unform ; 5
|
|
bne + ; 2 when not taken
|
|
dec unform+1 ; 5
|
|
beq @unformatted;2 when not taken
|
|
+ lda gNIBTable,x; 4
|
|
bmi @reset ; 2 when not taken
|
|
iny ; 2
|
|
bne @loop ; 3 when taken
|
|
sec
|
|
@unformatted
|
|
lda $C0E8
|
|
rts
|
|
|
|
;-------------------------------
|
|
; IsWideTrack
|
|
; check if this track claims to be the previous track
|
|
; in the case of EA, track 6 reads as track 5
|
|
; in the case of Accolade, track $22 reads as track $21
|
|
;
|
|
; in slot 6, drive 1 is on track to test
|
|
; out C clear if found wide track
|
|
; C set if not found
|
|
;-------------------------------
|
|
IsWideTrack
|
|
lda $2E
|
|
clc
|
|
adc #1
|
|
cmp gTrack
|
|
beq +
|
|
sec
|
|
rts
|
|
+ clc
|
|
rts
|
|
|
|
;-------------------------------
|
|
; ReadNib
|
|
; read a single nibble from S6,D1
|
|
;
|
|
; in: S6,D1 must be spun up and ready to read
|
|
; out: A contains nibble value
|
|
;-------------------------------
|
|
ReadNib
|
|
.x1
|
|
- lda $C0EC
|
|
bpl -
|
|
!if RELBASE != $2000 {
|
|
!if >.x1 != >* {
|
|
!serious "branch crosses a page"
|
|
}
|
|
}
|
|
rts
|
|
|
|
;-------------------------------
|
|
; Read4x4
|
|
; read a 4-4-encoded value from S6,D1
|
|
;
|
|
; in: S6,D1 must be spun up and ready to read
|
|
; out: A contains decoded value
|
|
; @tmp clobbered
|
|
;-------------------------------
|
|
Read4x4
|
|
.x2
|
|
- lda $C0EC
|
|
bpl -
|
|
!if RELBASE != $2000 {
|
|
!if >.x2 != >* {
|
|
!serious "branch crosses a page"
|
|
}
|
|
}
|
|
sec
|
|
rol
|
|
sta tmp
|
|
.x3
|
|
- lda $C0EC
|
|
bpl -
|
|
!if RELBASE != $2000 {
|
|
!if >.x3 != >* {
|
|
!serious "branch crosses a page"
|
|
}
|
|
}
|
|
and tmp
|
|
rts
|