passport/src/id/bootfailure.a

430 lines
8.3 KiB
Plaintext

;-------------------------------
; IDBootFailure
; main entry point to identify the bootloader
; when the initial read failed
; identifies Infocom 18-sector side B disks
; and pure 13-sector disks
; and Broderbund RW18 disks
; doubles as Infocom verification routine after ID
; triples as RW18 verification routine after ID
; written by qkumba
;
; in: nothing
; out: carry set if we can't ID it
;-------------------------------
!zone {
IDBootFailure
VerifyInfocom18
lda $C0E9
lda #2
sta modsrc
.retry13
ldx #$1A ; the length of a track
ldy #0
--- iny
bne +
dex
bne +
.no sec
lda $C0E8
rts
.badsect
dec modsrc
beq .no
lda gIsInfocom18
and gIsRW18
beq .no ; if in Infocom/RW18 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
+
jsr ReadNib
-- cmp #$D5
bne ---
jsr ReadNib
cmp #$9D
beq .RW18
cmp #$AA
bne --
jsr ReadNib
cmp #$B5 ; 13-sector only
beq .build13
cmp #$AD
bne --
jsr Read4x4
lda #$12 ; all 18 sectors when in verify mode
ldx gIsInfocom18
beq .setcount ; passport-test-suite/Trinity - Side B.woz [Z=1] here
lda #$02 ; passport-test-suite/Time Lord.woz [Z=0] here
; only two sectors when in ID mode
.setcount
sta tmp ; sector counter
lda #$00
-- ldy #$56
.x1
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x1 != >* {
!serious "branch crosses a page"
}
}
eor $BA00,x ; from universal RWTS
dey
bne -
.x2
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x2 != >* {
!serious "branch crosses a page"
}
}
eor $BA00,x ; from universal RWTS
iny
bne -
.x3
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x3 != >* {
!serious "branch crosses a page"
}
}
eor $BA00,x ; from universal RWTS
bne .badsect
dec tmp
bne --
sta gIsInfocom18
.checkmode
bit gMode ; verify-mode already?
bpl + ; yes, continue
lda #%00000000
sta gMode ; no, switch to verify-mode
jsr PrintByID ; and say so
!byte s_toverify
+ clc ; all clear
lda $C0E8
rts
.RW18
jsr .rw18pro
bne .badsect
ldx gIsRW18
beq .verifyrw18
sta gIsRW18
bne .checkmode ; always taken
;build 5-and-3 decoding table
;for 13-sector support
.no13
jmp ---
.build13
lda gTrack
bne .no13 ; skip if not boot phase
ldx #0
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
.verifyrw18
ldx #$06 ; six sectors, three times the usual size
stx tmp ; sector counter
stx $40
stx $41
stx $42
stx $43
stx $44
stx $45
.retryrw18
jsr ReadNib
-- cmp #$D5
bne .retryrw18
jsr ReadNib
cmp #$9D
bne --
jsr .rw18pro
bne .badrw18
ldx $2D
cmp $40,x
beq .badrw18
sta $40,x
ldy #4
- dey
beq .badrw18
.x4
-- ldx $C0EC
bpl --
!if RELBASE != $2000 {
!if >.x4 != >* {
!serious "branch crosses a page"
}
}
lda $BA00,x
eor #$A5
bne -
sta $3A
tay
.x5
-- ldx $C0EC
bpl --
!if RELBASE != $2000 {
!if >.x5 != >* {
!serious "branch crosses a page"
}
}
eor $3A
eor $BA00,x
sta $2F
lda $BA00,x
asl
asl
sta $30
.x6
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x6 != >* {
!serious "branch crosses a page"
}
}
and #$C0
ora $BA00,x
sta $3A
lda $30
asl
asl
.x7
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x7 != >* {
!serious "branch crosses a page"
}
}
sta $30
and #$C0
ora $BA00,x
sta $3B
lda $30
asl
.x8
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x8 != >* {
!serious "branch crosses a page"
}
}
asl
ora $BA00,x
eor $3B
eor $2F
iny
bne --
.x9
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x9 != >* {
!serious "branch crosses a page"
}
}
eor $BA00,x
eor $3A
and #$3F
bne .badrw18
jsr ReadNib
cmp #$D4
bne .badrw18
dec tmp
bne .jmpretryrw18
jmp .checkmode
.jmpretryrw18
jmp .retryrw18
.badrw18
jmp .badsect
.rw18pro
.x10
-- ldx $C0EC
bpl --
!if RELBASE != $2000 {
!if >.x10 != >* {
!serious "branch crosses a page"
}
}
lda $BA00,x ; region (half)
sta $2C
.x11
-- ldx $C0EC
bpl --
!if RELBASE != $2000 {
!if >.x11 != >* {
!serious "branch crosses a page"
}
}
lda $BA00,x ; region (half)
sta $2D
.x12
-- ldx $C0EC
bpl --
!if RELBASE != $2000 {
!if >.x12 != >* {
!serious "branch crosses a page"
}
}
lda $BA00,x ; checksum
eor $2C
eor $2D
bne +
.x13
-- ldx $C0EC
bpl --
!if RELBASE != $2000 {
!if >.x13 != >* {
!serious "branch crosses a page"
}
}
lda $BA00,x ; epilogue
eor #$AA
+ rts
seekread13
dec gCommand
jsr $BD00 ; seek
inc gCommand
read13
lda $C0E9
lda #$1C ; retry count
sta tmp
.readaddr
dec tmp
bmi .badread2
clc
ldx #$03 ; 768 nibbles
ldy #0
.readdata
php
--- iny
bne +
dex
beq .badread1
+
jsr ReadNib
-- cmp #$D5
bne ---
jsr ReadNib
cmp #$AA
bne --
jsr ReadNib
cmp #$B5
bne +
ldy #$03
.x14
-- lda $C0EC
bpl --
!if RELBASE != $2000 {
!if >.x14 != >* {
!serious "branch crosses a page"
}
}
rol
sta $3C
.x15
- lda $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x15 != >* {
!serious "branch crosses a page"
}
}
and $3C
dey
bne --
plp
cmp gSector
bne .readaddr
bcs .readdata
+ plp
bcc .readaddr
eor #$AD
bne .readaddr
-- ldy #$9A
.x16
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x16 != >* {
!serious "branch crosses a page"
}
}
eor $800,x
dey
bne -
.x17
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x17 != >* {
!serious "branch crosses a page"
}
}
eor $800,x
iny
bne -
.x18
- ldx $C0EC
bpl -
!if RELBASE != $2000 {
!if >.x18 != >* {
!serious "branch crosses a page"
}
}
eor $800,x
cmp #$01 ; set carry if non-zero
!byte $2c
.badread1
plp
.badread2
sec
lda $C0E8
rts
}
; this prevents branches in this file from crossing a page
; (adjust as necessary)
filler !fill 9