2022-01-24 12:38:14 -08:00

279 lines
8.4 KiB

; /!\ execution falls though from ADStyle
; ReadWithRWTS
; This is the main loop. The caller has put an RWTS
; in place -- either by boot tracing or by starting
; with the built-in RWTS and patching -- and now it's
; time to do the thing. This routine reads the source
; disk, applies patches in memory, maybe writes out
; the result (depending on mode), and prints relevant
; log messages along the way.
; in: suitable RWTS is in place
; relevant globals from ID phase have been set
; out: all registers clobbered
; exits via TheEnd
ldx #0
ldy #0
dec gCommand
jsr ReadSectorXY ; clear DOS error
inc gCommand
jsr IncProgress
lda #$22
jsr ChangeTrackNW
lda #$0F
ldx gIs13Sector
bne +
lda #$0C
+ jsr ChangeSector
lda #<T22S0F
sta checksector+1
lda #>T22S0F
sta checksector+2
lda KEY
bpl .checkinfocom
cmp #$e0 ;ignore backtick (MAME debug break)
beq .checkinfocom
jmp Cancel
lda gIsInfocom18
and gIsRW18
bne checksector
dec gCommand
jsr ReadSector ; seek
inc gCommand
jsr VerifyInfocom18
bcc .passtrack
jmp FatalError
jmp .prevtrack
lda $FFFF ; status of current sector in sector map (modified above)
cmp #kSectorCustomFirst ; call a custom routine before deciding what to do with this sector?
bcc +
cmp #kSectorCustomLast
bcs +
jsr PreReadSector
+ pha ; replace status (on stack) with new status returned from PreReadSector
cmp #kSectorIgnore ; skip this sector?
beq nextsector
cmp #kSectorSwitchToBuiltinRWTS ; switch to built-in RWTS before reading this sector?
bne +
lda gTriedUniv
beq +
jsr SwitchToUniv
+ jsr ReadSector
bcc nextsector
; Uh oh, we got a read error. But do we care?
; If we just got to this track, check for whole-track protections.
ldx #$0F ;16-sector
lda gIs13Sector
beq .expect13
lda gIsDOS32
bne +
ldx #$0C ;13-sector
+ cpx gSector
bne .checkoptional
stx .sub+1
jsr SkipTrack
bcs .checkoptional
; Skip this track (we already printed the reason)
lda #$00
jsr ChangeSector
lda checksector+1
.sub sbc #$0F ;self-modified according to sectors per track
sta checksector+1
bcs +
dec checksector+2
+ jmp nextsector
; do this only *after* checking for track-skip
; to avoid fatal errors on unformatted tracks
; Maybe we marked this sector as optional based
; on markers in the bootloader.
cmp #kSectorOptional
beq .optional
; Otherwise we're in the middle of a track, so try switching to
; the universal RWTS and see if that helps. (Many disks contain
; an RWTS that can't read the early tracks or sectors that
; contain the RWTS code, since those are loaded by the
; disk controller firmware.)
lda gIsDOS32 ; is this a DOS 3.2 disk?
beq .fatal ; yes, so read error is fatal
lda gTriedUniv ; have we tried the universal RWTS?
beq .maybedavidson ; yes, but check one last thing
jsr SwitchToUniv ; no, switch it in now
jmp .read ; and re-read this sector
jsr IDDavidson
bcc .optional
.fatal pla ; if we get to here, we've
jmp FatalError ; decided the read error is fatal
jsr PrintByID ; say we're skipping this optional sector
!byte s_optbad
; /!\ execution falls through here
lda checksector+1
bne .nodec
dec checksector+2
dec checksector+1
ldy gSector
jsr ChangeSector
lda gSector
bmi .prevtrack
jmp .read
lda #$0F
ldx gIs13Sector
bne +
lda #$0C
+ jsr ChangeSector
ldy gTrack
jsr ChangeTrack ; in crack mode, this calls WriteTrack
; which calls AnalyzeTrack to apply patches,
; then (if we're not using a RAM disk)
; actually writes the track to the target
; disk or file
jsr IncProgress
lda gTrack
bmi Pass
cmp gLastTrack
bcs .linkread
bit gMode
bpl @passVerify
lda gRAMDiskRef
beq @printFinalMessage ; not using RAM disk, so we're done
; we've written the entire cracked disk as a file on the RAM disk,
; now a second pass to write that file out to the target disk drive
jsr PrintByID
!byte s_writingto
jsr PrintByID
!byte s_slotanddrive
jsr SwapProDOS ; ProDOS out -> in (preserves registers+flags)
jsr WriteRAMToDisk ; C=1 if error, and A=MLI error code
jsr SwapProDOS ; ProDOS in -> out (preserves registers+flags)
bit KEY ; preserves C
bmi Cancel
bcc @printFinalMessage
jmp FatalWriteError
lda gPatchCount
beq @passWithZeroPatches
lda #s_passcrack ; 'crack complete'
!byte $2C
lda #s_passcrack0 ; 'crack complete but no patches'
!byte $2C
lda #s_pass ; 'verification complete'
sta +
jsr PrintByID
+ !byte $FD ; SMC
bvc .TheEnd ; always branches
jsr PrintByID
!byte s_canceled
bvc .TheEnd ; always branches
; PreCheckT00
; Before we trace through the drive firmware (which --
; at least on some machines -- will loop forever looking
; for each sector), we do a pre-check to ensure that all
; the sectors we're about to trace are actually readable.
; Before calling this function, you need to set all 16
; bytes of the precheck_sectors array (see above for format).
; If all required sectors are readable by Passport's own
; sector read routine, this exits gracefully with all
; flags and registered clobbered.
; If any required sector fails to read, this exits via
; FatalError, which does not return.
ldy #$00
sty gTrack
- lda precheck_sectors, y
bmi +
sta gSector
jsr IgnoreAddressChecksum
jsr ReadSector
bcs FatalError
+ iny
cpy #$10
bne -
jsr PrintByID
!byte s_fail
lda gTrack
cmp #$22
bne .TheEnd
lda gSector
cmp #$0F
beq @failont22s0f
ldx gIsDOS32
bne .TheEnd
cmp #$0C
bne .TheEnd
jsr PrintByID
!byte s_fatal220f
.TheEnd jmp TheEnd
; This list is (re)initialized in IDBootloader,
; then potentially altered in IDDOS33 and elsewhere.
; Values are logical sector numbers.
; There are always 16 (0x10) values in this list.
; Negative values are ignored.
; Positive values are treated as logical
; sector numbers and read from track $00.
; Sectors are read in the order listed here.
!byte $09,$08,$07,$06,$05,$04,$03,$02,$01
!byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8