passport/src/id/trace32.a
2022-08-04 19:10:53 -07:00

347 lines
8.3 KiB
Plaintext

; DOS 3.2 boot tracer
; for DOS 3.2 disks with a 3.2/3.3 hybrid bootloader
; that boots automatically on 16-sector drives
; e.g. many early disks from Edu-Ware, Hartley, DLM, Milliken
;-------------------------------
; TraceDOS32/TraceDOS32LO
; set up boot trace to capture 13-sector RWTS
;-------------------------------
!zone {
TraceDOS32
lda #<.TraceDOS32b
ldx #>.TraceDOS32b
bne .linktrace ; always branches
TraceDOS32LO
lda #<.TraceDOS32LOb
ldx #>.TraceDOS32LOb
.linktrace
jmp Trace
.TraceDOS32b
lda #<.TraceDOS32c
sta $0846
lda #>.TraceDOS32c
sta $0847
bne .linkjmp
.TraceDOS32LOb
ldy #$00
lda $0837
cmp #$4C
beq +
ldy #$0A
+ lda #<.TraceDOS32c
sta $0838,y
lda #>.TraceDOS32c
sta $0839,y
.linkjmp
jmp $0801
.TraceDOS32c
lda #$03
ldx #$0D
ldy #$36
jsr CompareMemory
!byte $A6,$2B
!byte $A9,$09
!byte $85,$27
!byte $AD,$CC,$03
!byte $85,$41
!byte $84,$40
!byte $8A
!byte $4A
!byte $4A
!byte $4A
!byte $4A
!byte $A9,$02
!byte $85,$3F
!byte $A9,$5D
!byte $85,$3E
!byte $20,$43,$03
!byte $20,$46,$03
!byte $A5,$3D
!byte $4D,$FF,$03
!byte $F0,$06
!byte $E6,$41
!byte $E6,$3D
!byte $D0,$ED
!byte $85,$3E
!byte $AD,$CC,$03
!byte $85,$3F
!byte $E6,$3F
bcs .tryChoplifter
lda $03CC
cmp #$B2 ; RDOS
clc
beq ++ ; passport-test-suite/Epidemic.woz [Z=1] matches
cmp #$B6 ; DOS 3.2 loaded high
beq +
cmp #$36 ; DOS 3.2 loaded low
bne .fail
pha
jsr MoveT00PakHigh ; move our packed T00 modules out of the way first
pla
+ sec
++ php ; pulled later to distinguish RDOS from DOS 3.2
;
; set up RWTS entry point and other self-modified vectors
; that depend on where the RWTS is in memory
;
clc
adc #$03 ; $B9 or $39
sta b4bbmodify+2
sta b4bbmodify2+2
adc #$04 ; $BD or $3D
sta jCallRWTS+2
adc #$02 ; $BF or $3F
sta b4bbcompare+1
lda #$00
sta jCallRWTS+1
;don't let The Game Show print
lda $343
eor #$4C
bne +
sta $345
lda #$6C
sta $343
lda #$3E
sta $344
+
; set up final trace
lda #$4C
sta $033A
lda #<TraceDOS32d
sta $033B
lda #>TraceDOS32d
sta $033C
ldy $0300
jmp $0301
.tryChoplifter
lda #$03
ldx #$01
ldy #$10
jsr CompareMemory
!byte $A2,$2E ;LDX #$2E
!byte $9A ;TXS
!byte $84,$48 ;STY $48
!byte $A2,$00 ;LDX #$00
!byte $BC,$00,$03 ;LDY $0300,X
!byte $88 ;DEY
!byte $A9,$EA ;LDA #$EA
!byte $20,$26,$03 ;JSR $0326
bcs .fail ; passport-test-suite/Eggs-It.woz [C=0] matches
jsr PrintByID
!byte s_choplifter
jsr PrintByID
!byte s_diskrwts
jmp Choplifter
; something did not match, not comfortable tracing,
; but we know enough to know that the universal RWTS won't work,
; so we're done
.fail jmp FatalError
.RDOSPatch
lda #$B3
ldx #$00 ; check for "JMP $B9xx;LDY #$00"
ldy #$05 ; at RWTS entry point
jsr CompareMemory ; (i.e. $B300)
!byte $4C,WILDCARD,$B9,$A0,$00
bcs .fail
lda #TRUE
sta gIsRDOS13
sta gDisplayBytes
jsr PrintByID
!byte s_rdos13
lda #<.RDOS13Hook
sta jCallRWTS+1
lda #>.RDOS13Hook
sta jCallRWTS+2
lda #<.RDOS13Seek
sta $BAC7
lda #>.RDOS13Seek
sta $BAC8
lda $BC76
cmp #$D5
beq .patchmap
lda #$C9 ; override address prologue to avoid reliance on $48
sta $BC75
lda #$D4
sta $BC76
bne .patchmap
TraceDOS32d
plp
bcc .RDOSPatch
lda jCallRWTS+2
ldx #$00 ; check for "STY $48;STA $49"
ldy #$04 ; at RWTS entry point
jsr CompareMemory ; (e.g. $BD00 or $3D00)
!byte $84,$48,$85,$49
bcs .fail
lda #$FA
sta modsrc
lda jCallRWTS+2
sec
sbc #$05
sta modsrc+1
ldy #$00
lda #$4C ; set up JMP at $B8FA to our routine that will
sta (modsrc),y ; check whether the data field is missing
iny
lda #<FFer
sta (modsrc),y
iny
lda #>FFer
sta (modsrc),y
ldy #$07
lda #$F8 ; change BEQ at $B900 to branch to that JMP at $B8FA
; if data prologue is not found
sta (modsrc),y
.patchmap
; skip sectors $0D, $0E, and $0F on all tracks
; since this is a 13-sector disk
lda #<sectormap
sta .C+1
lda #>sectormap
sta .C+2
lda #kSectorIgnore
ldx #$22
.A ldy #$0F
.B cpy #$03
bcs .D
.C sta $FFFF
.D inc .C+1
bne +
inc .C+2
+ dey
bpl .B
dex
bpl .A
; set flag for patcher
lda #TRUE
sta gIsDOS32
;retain track 00 for RDOS because we can
ldy gIsRDOS13
beq +
; skip T00,S00-S0A
; since we're going to construct our own bootloader later
ldy #$0A
- sta T00,y
dey
bpl -
; check for MUSE sector doubling RWTS
lda jCallRWTS+2
ldx #$09
ldy #$02
jsr CompareMemory
!byte $20,$DD
bcs + ; passport-test-suite/Robotwar.woz [C=0] matches
lda #$08
sta gDisplayBytes
jsr PrintByID
!byte s_muse
; read the rest of the disk with the original RWTS
+
jmp ADStyle
; callback to check if the data field is missing
; and if so, fill the RWTS data buffer with zeros
; and tell the caller that nibblizing was successful
FFer
ldy #$00
- lda $C08C,x
bpl -
cmp #$FF
bne +
iny
bne -
tya
ldy jCallRWTS+2
dey
sty .G+2
dey
sty .F+2
tay
.F sta $FF00,y
iny
bne .F
.G sta $FF00,y
iny
cpy #$9A
bne .G
- clc
rts
+ sec
rts
.RDOS13Hook
ldx _sector
stx $BAF6
lda _track
sta $BAF5
bne +
cpx #$0C
beq - ;lie that T00S0C exists
;standard 13-sector prologue on T00
;because we can't decode the 16-sector version
lda $BC76
pha
lda $BC8B
pha
lda #$D5
sta $BC76
lda #$B5
sta $BC8B
jsr +
pla
sta $BC8B
pla
sta $BC76
rts
+ lda gAddress
sta $BAF7
lda gAddress+1
sta $BAF8
ldx #1
stx $B718 ;count of sectors (low part)
dex
stx $B719 ;count of sectors (high part)
jmp $BA00
.RDOS13Seek
jsr $BC65 ;read address
lda $2E
cmp $BAF5
bne +
jmp $BAC9
+ sec ;fail on the tracks that don't exist
rts
}