gRWTSParams !byte $01,$60,$01,$00 _track !byte $00 _sector !byte $00 !word dct gAddress !word $1F00 !byte $00,$00 gCommand !byte $01 gError !byte $00,$FE,$60,$01,$00,$00 dct !byte $00,$01,$EF,$D8,$00 ;------------------------------- ; ReadSector ; high-level function to read a single sector. ; in: gIsProtDOS is TRUE or FALSE ; if gProtDOS is FALSE, jCallRWTS has been set to ; the RWTS entry point (e.g. $BDxx or $3Dxx) ; out: all registers clobbered ; C clear if read was successful ; C set if read failed ;------------------------------- ReadSectorXY stx gTrack sty gSector ReadSector ; ; Lots of custom RWTS routines need these zero page locations ; set to magic values. Always the same values though! ; lda #$AA sta $31 lda #$AD sta $4E ; ; Copy requested track and sector into RWTS parameter table. ; These are maintained outside the table because some disks ; alter the values from inside the RWTS. (MUSE) ; lda gTrack sta _track lda gSector sta _sector lda gIsProtDOS beq _protread @go ldy #gRWTSParams jsr jCallRWTS bcc + lda gOnAClearDayYouCanReadForever beq @go + rts ; ; "Protected.DOS" has enough differences that we just ; split everything out here. The hi/lo RWTS parameter ; table address is set in A/Y instead of Y/A. The ; RWTS entry point is $BA00. The third data prologue ; nibble is stored in zp$4E and varies based on track ; and sector. ; _protread lda gTrack ; T02,S05+ use "protected" mode cmp #$03 ; (altered data prologue and bcs @protected ; nibble translate table) cmp #$02 ; T00,S00 - T02,S04 use bcc @standard ; "standard" mode lda gSector cmp #$05 bcs @protected @standard lda #$9B sta $BF2C bne @go ; unconditional branch @protected lda #$B5 sta $4E lda #$D5 sta $BF2C ; execution falls through here @go lda #gRWTSParams jsr $BA00 ; note non-standard entry point bcc + lda gOnAClearDayYouCanReadForever beq @go + rts ;------------------------------- ; PreReadSector ; in: A contains sector map code that specifies what to do ; out: A contains (possibly new) sector map code ; assume all other things clobbered ;------------------------------- PreReadSector cmp #kSectorResetAdaptiveRWTS beq @reset cmp #kSectorIgnoreAddressChecksum beq IgnoreAddressChecksum cmp #kSectorCustomDOS32B4BB beq @b4bb cmp #kSectorCustomEarthware beq @earthware rts @reset jsr CopyUniversal lda #kSectorRequired rts @b4bb ldx jCallRWTS+2 dex dex dex dex stx @a+2 stx @b+2 ldx #$D5 @a stx $FF76 ldx #$ED @b stx $FFB2 rts @earthware ldx #$4C stx $B8F6 ldx #$89 stx $B8F7 ldx #$B6 stx $B8F8 rts IgnoreAddressChecksum ; out: A,Y preserved ; X clobbered ldx #$00 stx $B98A rts ;------------------------------- ; ChangeTrack ; in: A = new track ;------------------------------- ChangeTrack sta @new+1 jsr WriteTrack @new lda #$d1 ; modified at runtime ; note: execution falls through here ChangeTrackNW ; "N"o "W"rite sta gTrack jsr ClearTSBuffer rts ;------------------------------- ; ChangeSector ; in: A = new sector ;------------------------------- ChangeSector sta gSector clc adc #BASEPAGE sta gAddress+1 rts ;------------------------------- ; WriteTrack ; in: none ;------------------------------- WriteTrack jsr AnalyzeTrack WriteTrackNA ; entry point used by Special Delivery tracer ; to write track with 'N'o 'A'nalysis bit gMode bpl @exit ; don't write anything in verify mode lda gSaidWriting beq @doTheWriteThing ; only print 'writing to' message once ; we haven't yet printed any 'writing to...' message in the log, so ; figure out what that should look like and do it now jsr PrintByID !byte s_writingto lda gHardDiskRef beq @maybeWritingToRAMDisk ; we are writing to a file on a hard disk, so print the ; full pathname of that file jsr PrintHardDiskImagePath bvc @doneSaidWriting ; always branches @maybeWritingToRAMDisk lda gRAMDiskRef beq @notWritingToRAMDisk lda #s_ramdisk ; writing to (a file on) a RAM disk !byte $2C @notWritingToRAMDisk lda #s_slotanddrive ; writing to a slot and drive sta + jsr PrintByID + !byte $FD ; SMC @doneSaidWriting lda #TRUE sta gSaidWriting @doTheWriteThing jsr SwapProDOS ; ProDOS out -> in jsr WriteTrackFirstPass jsr SwapProDOS ; ProDOS in -> out bcs FatalWriteError @exit rts ;------------------------------- ; FatalWriteError ; in: A has MLI error code ; out: does not return, exits via TheEnd ;------------------------------- FatalWriteError sta gDisplayBytes tax lda #s_writeioerr cpx #MLI_IOERR beq @print lda #s_writenodev cpx #MLI_NODEV beq @print lda #s_writeprot cpx #MLI_WRITEPROT beq @print lda #s_othermli @print sta + jsr PrintByID !byte s_writeerr jsr PrintByID + !byte $FD ; SMC jmp TheEnd