; /!\ 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 ;------------------------------- ReadWithRWTS 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+2 .read lda KEY bpl .checkinfocom bit STROBE cmp #$e0 ;ignore backtick (MAME debug break) beq .checkinfocom jmp Cancel .checkinfocom lda gIsInfocom18 and gIsRW18 bne checksector dec gCommand jsr ReadSector ; seek inc gCommand jsr VerifyInfocom18 bcc .passtrack jmp FatalError .passtrack jmp .prevtrack checksector 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 + .expect13 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 sec .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 .checkoptional pla pha ; ; 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.) ; .tryuniversal 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 .maybedavidson jsr IDDavidson bcc .optional .fatal pla ; if we get to here, we've jmp FatalError ; decided the read error is fatal .optional jsr PrintByID ; say we're skipping this optional sector !byte s_optbad ; /!\ execution falls through here nextsector pla lda checksector+1 bne .nodec dec checksector+2 .nodec dec checksector+1 ldy gSector dey tya jsr ChangeSector lda gSector bmi .prevtrack .linkread jmp .read .prevtrack lda #$0F ldx gIs13Sector bne + lda #$0C + jsr ChangeSector ldy gTrack dey tya 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 Pass 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 @printFinalMessage lda gPatchCount beq @passWithZeroPatches lda #s_passcrack ; 'crack complete' !byte $2C @passWithZeroPatches lda #s_passcrack0 ; 'crack complete but no patches' !byte $2C @passVerify lda #s_pass ; 'verification complete' sta + jsr PrintByID + !byte $FD ; SMC bvc .TheEnd ; always branches Cancel 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. ;------------------------------- PreCheckT00 ldy #$00 sty gTrack - lda precheck_sectors, y bmi + sta gSector jsr IgnoreAddressChecksum tya pha jsr ReadSector pla tay bcs FatalError + iny cpy #$10 bne - rts FatalError 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 @failont22s0f jsr PrintByID !byte s_fatal220f .TheEnd jmp TheEnd precheck_sectors ; 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