;------------------------------- ; 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 bne + .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 }