1146 lines
25 KiB
ArmAsm
1146 lines
25 KiB
ArmAsm
|
|
__NO_SAVE_SYMBOLS_IMPORT = 1
|
|
.include "loader.inc"
|
|
|
|
.include "drives/drivecode-common.inc"
|
|
.include "hal/hal.inc"
|
|
|
|
.include "cpu.inc"
|
|
.include "kernal.inc"
|
|
|
|
.segment "DISKIO_PLUGIN_ZP" : zeropage
|
|
|
|
PARAMSPTR: .res 2
|
|
SAVEPTR: .res 2
|
|
LENGTH: .res 2
|
|
BLOCKCNT: .res 1
|
|
BYTECOUNT: .res 1
|
|
|
|
MAXBLOCKS = 64
|
|
|
|
.segment "DISKIO_PLUGIN"
|
|
|
|
.ifdef TRNSADDR
|
|
.org TRNSADDR - 2
|
|
.word * + 2; load address
|
|
.endif
|
|
|
|
.exportzp status_FILE_TOO_LARGE = diskio::status::FILE_TOO_LARGE
|
|
.exportzp status_FILE_ON_DISK_TOO_SMALL = diskio::status::FILE_ON_DISK_TOO_SMALL
|
|
.exportzp status_FILE_ON_DISK_TOO_LARGE = diskio::status::FILE_ON_DISK_TOO_LARGE
|
|
.exportzp status_WRITE_PROTECT_ON = diskio::status::WRITE_PROTECT_ON
|
|
|
|
WRITE_PROTECTED = $fe
|
|
|
|
SAVE_FROM_RAM_UNDER_IO = LOAD_UNDER_D000_DFFF & (PLATFORM <> diskio::platform::COMMODORE_16)
|
|
|
|
.if LOAD_VIA_KERNAL_FALLBACK
|
|
.import KERNLCLOSE
|
|
.endif; LOAD_VIA_KERNAL_FALLBACK
|
|
|
|
.import sendbyte
|
|
.import receivbyte
|
|
|
|
.export save
|
|
|
|
save: stx PARAMSPTR
|
|
sty PARAMSPTR + 1
|
|
|
|
ldy #saveparams::buffer
|
|
lda (PARAMSPTR),y
|
|
sta swapparams
|
|
iny
|
|
lda (PARAMSPTR),y
|
|
sta swapparams + 1
|
|
|
|
ldy #saveparams::filename
|
|
lda (PARAMSPTR),y
|
|
sta SAVEPTR
|
|
iny
|
|
lda (PARAMSPTR),y
|
|
sta SAVEPTR + 1
|
|
dey
|
|
;ldy #0
|
|
: lda (SAVEPTR),y
|
|
beq :+
|
|
sta savename41 - drvsaver41 + saver41,y
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
sta savename71 - drvsaver71 + saver71,y
|
|
sta savename81 - drvsaver81 + saver81,y
|
|
.endif; ONLY_1541_AND_COMPATIBLE
|
|
|
|
iny
|
|
cpy #FILENAME_MAXLENGTH
|
|
bcc :-
|
|
: cpy #0
|
|
bne :+
|
|
lda #diskio::status::FILE_NOT_FOUND
|
|
sec
|
|
rts
|
|
|
|
: ldy #saveparams::length
|
|
clc
|
|
lda #2
|
|
adc (PARAMSPTR),y
|
|
sta LENGTH
|
|
tax
|
|
iny
|
|
lda #0
|
|
adc (PARAMSPTR),y
|
|
sta LENGTH + 1
|
|
tay
|
|
|
|
lda #0
|
|
sta BLOCKCNT
|
|
clc
|
|
: inc BLOCKCNT
|
|
bne :+
|
|
dec BLOCKCNT
|
|
: txa
|
|
sbc #$fe
|
|
tax
|
|
tya
|
|
sbc #0
|
|
tay
|
|
bcs :--
|
|
|
|
lda BLOCKCNT
|
|
cmp #MAXBLOCKS + 1
|
|
bcc :+
|
|
lda #diskio::status::FILE_TOO_LARGE
|
|
rts
|
|
|
|
: ldx #.lobyte(swapparams)
|
|
ldy #.hibyte(swapparams)
|
|
jsr swapdrvcod
|
|
bcc saverinstd
|
|
|
|
.if LOAD_VIA_KERNAL_FALLBACK
|
|
|
|
cmp #diskio::status::DEVICE_INCOMPATIBLE
|
|
beq :+
|
|
sec
|
|
rts
|
|
:
|
|
ldx SAVEPTR
|
|
ldy SAVEPTR + 1
|
|
BUFFER_MEMCONFIG
|
|
ENABLE_KERNAL_SERIAL_ROUTINES
|
|
jsr kernalsave
|
|
RESTORE_MEMCONFIG_Y
|
|
.endif; !LOAD_VIA_KERNAL_FALLBACK
|
|
rts
|
|
|
|
saverinstd: SET_FLAGS_N_DATA_V_CLK
|
|
bmi saverinstd
|
|
SYNC
|
|
: SET_FLAGS_N_DATA_V_CLK
|
|
bpl :-
|
|
CLEAR
|
|
: SET_FLAGS_N_DATA_V_CLK
|
|
bvs :-
|
|
|
|
waitready: SET_FLAGS_N_DATA_V_CLK
|
|
bvc waitready
|
|
|
|
ldy #saveparams::from
|
|
lda (PARAMSPTR),y
|
|
sta SAVEPTR
|
|
iny
|
|
lda (PARAMSPTR),y
|
|
sta SAVEPTR + 1
|
|
|
|
; get status/number of file blocks
|
|
jsr receivbyte
|
|
beq devnotpres
|
|
cmp #WRITE_PROTECTED
|
|
beq writeprot
|
|
cmp #diskio::status::FILE_NOT_FOUND; = $ff
|
|
beq savereturn
|
|
|
|
cmp BLOCKCNT
|
|
beq :+
|
|
|
|
php
|
|
lda #0
|
|
jsr sendbyte
|
|
plp
|
|
lda #diskio::status::FILE_ON_DISK_TOO_SMALL
|
|
bcc savereturn
|
|
lda #diskio::status::FILE_ON_DISK_TOO_LARGE
|
|
bcs savereturn; jmp
|
|
|
|
: jsr sendcount
|
|
|
|
ldy #saveparams::loadaddress
|
|
lda (PARAMSPTR),y
|
|
jsr sendbyte
|
|
dec BYTECOUNT
|
|
iny
|
|
lda (PARAMSPTR),y
|
|
jsr sendbyte
|
|
dec BYTECOUNT
|
|
|
|
.if SAVE_FROM_RAM_UNDER_IO
|
|
BUFFER_MEMCONFIG
|
|
.endif
|
|
jsr sendloop
|
|
beq savedone
|
|
|
|
: jsr sendblock
|
|
bne :-
|
|
savedone:
|
|
.if SAVE_FROM_RAM_UNDER_IO
|
|
RESTORE_MEMCONFIG_Y
|
|
.endif
|
|
lda #diskio::status::OK
|
|
SKIPWORD
|
|
writeprot: lda #diskio::status::WRITE_PROTECT_ON
|
|
SKIPWORD
|
|
devnotpres: lda #diskio::status::DEVICE_NOT_PRESENT
|
|
savereturn:
|
|
pha
|
|
jsr restoreldr
|
|
pla
|
|
cmp #diskio::status::OK + 1
|
|
rts
|
|
|
|
sendblock: SET_FLAGS_N_DATA_V_CLK
|
|
bvc sendblock
|
|
|
|
jsr sendcount
|
|
|
|
sendloop: ldy #0
|
|
:
|
|
.if SAVE_FROM_RAM_UNDER_IO
|
|
ENABLE_ALL_RAM_X
|
|
lda (SAVEPTR),y
|
|
ENABLE_IO_SPACE_X
|
|
.else
|
|
lda (SAVEPTR),y
|
|
.endif
|
|
jsr sendbyte
|
|
iny
|
|
dec BYTECOUNT
|
|
bne :-
|
|
|
|
clc
|
|
tya
|
|
adc SAVEPTR
|
|
sta SAVEPTR
|
|
bcc :+
|
|
inc SAVEPTR + 1
|
|
:
|
|
CLEAR
|
|
|
|
dec BLOCKCNT
|
|
rts
|
|
|
|
sendcount: lda #$fe
|
|
ldx LENGTH + 1
|
|
bne :+
|
|
ldx LENGTH
|
|
cpx #$fe
|
|
bcs :+
|
|
txa
|
|
: sta BYTECOUNT
|
|
|
|
sec
|
|
lda LENGTH
|
|
sbc BYTECOUNT
|
|
sta LENGTH
|
|
bcs :+
|
|
dec LENGTH + 1
|
|
|
|
: lda BYTECOUNT
|
|
jmp sendbyte
|
|
|
|
saver41:
|
|
.org $05ba; loadfile41
|
|
|
|
.assert * <= loadfile41, error, "***** 1541 save code above loadfile41 position. *****"
|
|
.assert * >= loadfile41, error, "***** 1541 save code below loadfile41 position. *****"
|
|
|
|
drvsaver41: .scope cbm1541
|
|
|
|
.include "via.inc"
|
|
|
|
.assert (filesectors + MAXBLOCKS + 1) <= wdogentr41, error, "***** 1541 track/sector buffer too small. *****"
|
|
|
|
filetracks = idxloop41
|
|
filesectors = idxloop41 + MAXBLOCKS + 1
|
|
writeblock = $0510
|
|
rawblock = $0700
|
|
|
|
CURRBLOCK = $06
|
|
SENDVALUE = $09
|
|
TRKSEC = SENDVALUE
|
|
BLOCKSIZE = $0e
|
|
NUMBLOCKS = $74
|
|
|
|
DSKID = $12
|
|
BUFPNT = $30
|
|
HDRPNT = $32
|
|
HBID = $39
|
|
DRIVE = $3d
|
|
DBID = $47
|
|
|
|
SRCH = $f510
|
|
SRCH20 = $f538
|
|
SRCH30 = $f54e
|
|
ERR = $f553
|
|
WRT05 = $f575
|
|
WRT10 = $f586
|
|
CHKBLK = $f5e9
|
|
WRITEBLOCKLEN = CHKBLK - $10 - SRCH; $c9
|
|
|
|
TIMER = VIA2_T1C_H
|
|
|
|
bmi filenotfnd
|
|
|
|
lda #BUSY_LED | MOTOR
|
|
jsr setbv2b41
|
|
;ldy FILETRACK
|
|
lda FILESECTOR41
|
|
bcs filefound; jmp
|
|
|
|
RESTORELOOP41 = $d9
|
|
RESTOREMAIN41 = RESTORELOOP41 + 1
|
|
|
|
; FILENAMEHASHVALSLO and NUMBLOCKS, will possibly be overwritten
|
|
saveentry: lda #ATNA_OUT | DATA_OUT
|
|
ldx #RESTOREMAIN41
|
|
sta (.lobyte($03 - RESTOREMAIN41),x); VIA1_PRB
|
|
|
|
: lda $00,x
|
|
sta .lobyte($0100 - RESTOREMAIN41),x
|
|
cpx #$0100 - 21
|
|
bcc :+
|
|
lda SECTORLINKTABLE41 + 21,x
|
|
sta RESTORELOOP41 + 21,x
|
|
: inx
|
|
bne :--
|
|
|
|
jsr initlink41
|
|
|
|
;ldy #0
|
|
: lda #CLK_IN
|
|
and (V1B41),y; VIA1_PRB
|
|
beq :-
|
|
lda #ATNA_OUT | CLK_OUT
|
|
sta (V1B41),y; VIA1_PRB
|
|
: lda (V1B41),y; VIA1_PRB
|
|
lsr
|
|
bcs :-
|
|
ldx #$ff
|
|
: inx
|
|
saveinit: lda savename41,x
|
|
sta FILENAME41,x
|
|
bne :-
|
|
sta NUMBLOCKS
|
|
|
|
lda (V2B41),y; VIA2_PRB
|
|
ldy #WRITE_PROTECTED
|
|
and #WRITE_PROTECT
|
|
beq writeprot
|
|
|
|
jsr findfile41; SP = $08 -> $06
|
|
|
|
enumblocks: ldx NUMBLOCKS
|
|
lda filesectors,x
|
|
ldy filetracks,x
|
|
jsr getblock41
|
|
bcc enumblocks
|
|
|
|
inc NUMBLOCKS
|
|
lda LINKSECTOR41
|
|
ldy LINKTRACK41
|
|
filefound: ldx NUMBLOCKS
|
|
cpx #MAXBLOCKS + 1
|
|
bcs :+
|
|
sta filesectors,x
|
|
tya
|
|
sta filetracks,x
|
|
bne enumblocks
|
|
:
|
|
ldy NUMBLOCKS
|
|
|
|
filenotfnd: ; y = diskio::status::FILE_NOT_FOUND = $ff
|
|
writeprot: ; y = WRITE_PROTECTED = $fe
|
|
|
|
.assert getbyterts41 < writeblock, error, "***** getbyte runs into writeblock *****"
|
|
|
|
ldx #WRITEBLOCKLEN + 1
|
|
lda #OPC_RTS
|
|
: sta writeblock - 1,x
|
|
lda SRCH - 2,x
|
|
dex
|
|
bne :-
|
|
inc writeblock + WRT10 - 3 - SRCH; OPC_JMP_ABS -> OPC_EOR_ABS, no write protect check
|
|
lda #OPC_TXA
|
|
sta writeblock + SRCH30 - SRCH
|
|
inc writeblock + ERR - SRCH; OPC_JMP_ABS -> OPC_EOR_ABS, no sync timeout check
|
|
stx BUFPNT
|
|
stx HDRPNT + 1
|
|
stx DRIVE
|
|
inx
|
|
: lda ID041,x
|
|
jsr sertoraw41
|
|
sta DSKID,x
|
|
dex
|
|
bpl :-
|
|
stx TIMER
|
|
ldx #.hibyte(writeblock)
|
|
stx writeblock + SRCH20 + 2 - SRCH
|
|
stx writeblock + WRT10 + 5 - SRCH
|
|
|
|
pla
|
|
|
|
tya
|
|
ENABLE_WATCHDOG
|
|
DRIVESENDBYTE 1541, SENDVALUE
|
|
|
|
;ldy #0
|
|
beq saveloopin; jmp
|
|
|
|
saveloop: jsr rdygetbyte
|
|
beq saverexit; branch if file on disk too small/large
|
|
|
|
sta BLOCKSIZE
|
|
|
|
;ldx #0
|
|
: jsr getbytewdog41
|
|
sta rawblock + 2,x
|
|
inx
|
|
cpx BLOCKSIZE
|
|
bcc :-
|
|
|
|
lda #ATNA_OUT | CLK_OUT | DATA_OUT
|
|
sta VIA1_PRB
|
|
sei
|
|
|
|
lda #0
|
|
: sta rawblock + 2,x
|
|
inx
|
|
bne :-
|
|
|
|
ldx CURRBLOCK
|
|
ldy filesectors + 1,x
|
|
lda filetracks + 1,x
|
|
sta rawblock
|
|
bne :+
|
|
ldy BLOCKSIZE
|
|
iny
|
|
: sty rawblock + 1
|
|
ldy filetracks,x
|
|
sty TRKSEC
|
|
lda filesectors,x
|
|
sta TRKSEC + 1
|
|
jsr trkseek41
|
|
ldx #.lobyte(TRKSEC)
|
|
stx HDRPNT
|
|
dex
|
|
stx HBID; 8
|
|
dex
|
|
stx DBID; 7
|
|
;ldx #.hibyte(rawblock)
|
|
stx BUFPNT + 1
|
|
jsr writeblock + WRT05 - SRCH
|
|
ldy CURRBLOCK
|
|
iny
|
|
saveloopin: sty CURRBLOCK
|
|
cpy NUMBLOCKS
|
|
bcc saveloop
|
|
|
|
saverexit: lda #OPC_JSR_ABS
|
|
sta restore
|
|
lda CURRTRACK41
|
|
pha
|
|
|
|
rdygetbyte: ldx #0
|
|
lda #ATNA_OUT
|
|
sta (V1B41,x); VIA1_PRB
|
|
:
|
|
restore: jmp getbytewdog41
|
|
sta $00,x
|
|
inx
|
|
bne :-
|
|
sei
|
|
|
|
pla
|
|
sta CURRTRACK41
|
|
|
|
jmp RESTOREMAIN41
|
|
|
|
.endscope
|
|
|
|
savename41: .res FILENAME_MAXLENGTH
|
|
.byte 0
|
|
|
|
.assert * <= $0700, error, "***** 1541 save code too large. *****"
|
|
|
|
.reloc
|
|
saver41end:
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
saver71:
|
|
.org $04e1; loadfile71
|
|
|
|
.assert * <= loadfile71, error, "***** 1571 save code above loadfile71 position. *****"
|
|
.assert * >= loadfile71, error, "***** 1571 save code below loadfile71 position. *****"
|
|
|
|
drvsaver71: .scope cbm1571
|
|
|
|
.include "via.inc"
|
|
|
|
.assert (filesectors + MAXBLOCKS + 1) <= rawblock, error, "***** 1571 track/sector buffer too small. *****"
|
|
|
|
writeblock = $0310
|
|
rawblock = $0700
|
|
|
|
NUMBLOCKS = $1b
|
|
CURRBLOCK = $1c
|
|
BLOCKSIZE = $1d
|
|
SENDVALUE = $1e
|
|
TRKSEC = SENDVALUE
|
|
|
|
BUFPNT = $30
|
|
HDRPNT = $32
|
|
HBID = $39
|
|
DRIVE = $3d
|
|
DBID = $47
|
|
|
|
SRCH = $f510
|
|
SRCH20 = $f538
|
|
SRCH30 = $f54e
|
|
ERR = $f553
|
|
WRT05 = $f575
|
|
WRT10 = $f586
|
|
CHKBLK = $f5e9
|
|
WRITEBLOCKLEN = CHKBLK - $10 - SRCH
|
|
|
|
TIMER = VIA2_T1C_H
|
|
|
|
bcc aftfindfil
|
|
;lda #diskio::status::FILE_NOT_FOUND; $ff
|
|
jmp filenotfnd
|
|
|
|
.import CUSTOMZPBUFFSIZE71
|
|
|
|
lda #ATNA_OUT | DATA_OUT
|
|
sta VIA1_PRB
|
|
|
|
ldx #0
|
|
: lda CUSTOMZPBUFFER71,x
|
|
sta $00,x
|
|
inx
|
|
cpx #.lobyte(CUSTOMZPBUFFSIZE71)
|
|
bne :-
|
|
|
|
ldx #0
|
|
stx NUMBLOCKS
|
|
|
|
: lda #CLK_IN
|
|
and VIA1_PRB
|
|
beq :-
|
|
lda #ATNA_OUT | CLK_OUT
|
|
sta VIA1_PRB
|
|
: lda VIA1_PRB
|
|
lsr
|
|
bcs :-
|
|
|
|
lda #WRITE_PROTECT
|
|
and VIA2_PRB
|
|
beq writeprot
|
|
|
|
;ldx #0
|
|
dosave: lda savename71,x
|
|
beq :+
|
|
sta FILENAME71,x
|
|
inx
|
|
bne dosave
|
|
:
|
|
sec
|
|
jmp findfile71
|
|
|
|
aftfindfil: lda #BUSY_LED | MOTOR
|
|
jsr bsetv2b71
|
|
lda DIRSECTORS71,x
|
|
bcc :+; jmp
|
|
|
|
enumblocks: ldx NUMBLOCKS
|
|
lda filesectors,x
|
|
ldy filetracks,x
|
|
jsr getblock71
|
|
bcs enumblocks
|
|
|
|
lda LINKSECTOR71
|
|
ldy LINKTRACK71
|
|
inc NUMBLOCKS
|
|
: ldx NUMBLOCKS
|
|
cpx #MAXBLOCKS + 1
|
|
bcs :+
|
|
sta filesectors,x
|
|
tya
|
|
sta filetracks,x
|
|
bne enumblocks
|
|
:
|
|
ldx #WRITEBLOCKLEN
|
|
: lda SRCH - 1,x
|
|
sta writeblock - 1,x
|
|
dex
|
|
bne :-
|
|
inc writeblock + WRT10 - 3 - SRCH; OPC_JMP_ABS -> OPC_EOR_ABS, no write protect check
|
|
lda #.hibyte(writeblock)
|
|
sta writeblock + SRCH20 + 2 - SRCH
|
|
sta writeblock + WRT10 + 5 - SRCH
|
|
lda #OPC_TXA
|
|
sta writeblock + SRCH30 - SRCH
|
|
inc writeblock + ERR - SRCH; OPC_JMP_ABS -> OPC_EOR_ABS, no sync timeout check
|
|
lda #OPC_RTS
|
|
sta writeblock + WRITEBLOCKLEN
|
|
stx BUFPNT
|
|
stx HDRPNT + 1
|
|
stx DRIVE
|
|
lda #.lobyte(TRKSEC)
|
|
sta HDRPNT
|
|
ldx #$08
|
|
stx HBID
|
|
dex
|
|
stx DBID
|
|
;ldy #.hibyte(rawblock)
|
|
stx BUFPNT + 1
|
|
|
|
lda NUMBLOCKS
|
|
SKIPWORD
|
|
writeprot: lda #WRITE_PROTECTED
|
|
filenotfnd:
|
|
ldx #.lobyte(trkseek71) - 1
|
|
txs
|
|
|
|
ldy #$ff
|
|
sty TIMER
|
|
ENABLE_WATCHDOG
|
|
DRIVESENDBYTE 1571, SENDVALUE
|
|
|
|
lda NUMBLOCKS
|
|
beq saverexit
|
|
|
|
;ldy #0
|
|
saveloop: sty CURRBLOCK
|
|
|
|
jsr rdygetbyte
|
|
beq saverexit; branch if file on disk too small/large
|
|
sta BLOCKSIZE
|
|
|
|
;ldx #0
|
|
: jsr getbyte
|
|
sta rawblock + 2,x
|
|
inx
|
|
cpx BLOCKSIZE
|
|
bcc :-
|
|
|
|
lda #ATNA_OUT | CLK_OUT | DATA_OUT
|
|
sta VIA1_PRB
|
|
sei
|
|
|
|
lda #0
|
|
beq :++; jmp
|
|
: sta rawblock + 2,x
|
|
inx
|
|
: cpx #$fe
|
|
bcc :--
|
|
|
|
ldx CURRBLOCK
|
|
ldy filesectors + 1,x
|
|
lda filetracks + 1,x
|
|
sta rawblock
|
|
bne :+
|
|
ldy BLOCKSIZE
|
|
iny
|
|
: sty rawblock + 1
|
|
ldy filetracks,x
|
|
sty TRKSEC
|
|
lda filesectors,x
|
|
sta TRKSEC + 1
|
|
sta CLEARSECTORLINKTABLE71
|
|
jsr trkseek71
|
|
jsr onemhz71
|
|
jsr writeblock + WRT05 - SRCH
|
|
|
|
ldy CURRBLOCK
|
|
iny
|
|
cpy NUMBLOCKS
|
|
bcc saveloop
|
|
|
|
saverexit: lda #ATNA_OUT | CLK_OUT | DATA_OUT
|
|
sta VIA1_PRB
|
|
|
|
sei
|
|
ldx CURRTRACK71
|
|
txs
|
|
|
|
.macro HOOK71
|
|
tsx
|
|
stx CURRTRACK71
|
|
ldx #0
|
|
.endmacro
|
|
RETURNTOLOADER71 HOOK71
|
|
|
|
rdygetbyte: ldx #0
|
|
lda #ATNA_OUT
|
|
sta VIA1_PRB
|
|
|
|
getbyte: lda #$ff
|
|
sta TIMER
|
|
ENABLE_WATCHDOG
|
|
DRIVEGETBYTE 1571, getbytecmp
|
|
rts
|
|
|
|
filetracks = idleloop71
|
|
filesectors = *
|
|
|
|
.endscope
|
|
|
|
savename71: .res FILENAME_MAXLENGTH
|
|
.byte 0
|
|
|
|
.reloc
|
|
saver71end:
|
|
|
|
saver81:
|
|
.org $0594; loadfile81
|
|
|
|
.assert * <= loadfile81, error, "***** 1581 save code above loadfile81 position. *****"
|
|
.assert * >= loadfile81, error, "***** 1581 save code below loadfile81 position. *****"
|
|
|
|
drvsaver81: .scope cbm1581
|
|
|
|
.include "cia.inc"
|
|
|
|
filetracks = $0900
|
|
filesectors = $0a00
|
|
rawblock = $0b00
|
|
|
|
NUMBLOCKS = $18
|
|
CURRBLOCK = $19
|
|
BLOCKSIZE = $1a
|
|
SENDVALUE = $1b
|
|
|
|
STROBE_CONTROLLER = $ff54
|
|
|
|
OK_DV = $00
|
|
WRTSD_DV = $90
|
|
TRKWRT_DV = $a2
|
|
|
|
FD2K4K_F = $fea4
|
|
|
|
BUFFER0 = $0300
|
|
BUFFERSIZE = $0100
|
|
|
|
BUFFERINDEX = (rawblock - BUFFER0) / BUFFERSIZE
|
|
|
|
JOBCODESTABLE = $02
|
|
JOBTRKSCTTABLE = $0b
|
|
|
|
TRACKOFFSET = 0
|
|
SECTOROFFSET = 1
|
|
|
|
BUFFERTRACK = JOBTRKSCTTABLE + (2 * BUFFERINDEX) + TRACKOFFSET
|
|
BUFFERSECTOR = JOBTRKSCTTABLE + (2 * BUFFERINDEX) + SECTOROFFSET
|
|
|
|
bcc aftfindfil
|
|
bcs filenotfnd; jmp
|
|
|
|
lda #DATA_OUT
|
|
sta CIA_PRB
|
|
|
|
jsr swapzp81; restore loader zeropage
|
|
|
|
lda FD2K4K_F
|
|
cmp #'f'
|
|
bne notonfd
|
|
ldx #fdwatchdge - fdwatchdog - 1
|
|
: lda fdwatchdog,x
|
|
sta getbyte,x
|
|
dex
|
|
bpl :-
|
|
notonfd:
|
|
ldx #0
|
|
stx NUMBLOCKS
|
|
|
|
: lda #CLK_IN
|
|
and CIA_PRB
|
|
beq :-
|
|
lda #CLK_OUT
|
|
sta CIA_PRB
|
|
: lda CIA_PRB
|
|
lsr
|
|
bcs :-
|
|
|
|
lda #WRITE_PROTECT
|
|
and CIA_PRB
|
|
beq writeprot
|
|
|
|
dosave: lda savename81,x
|
|
beq :+
|
|
sta filename81,x
|
|
inx
|
|
bne dosave
|
|
:
|
|
sec
|
|
jmp findfile81
|
|
|
|
aftfindfil: tya
|
|
pha
|
|
jsr bsyledon81
|
|
pla
|
|
tay
|
|
lda DIRTRACKS81,x
|
|
bne :+; jmp
|
|
|
|
enumblocks: ldx NUMBLOCKS
|
|
lda filetracks,x
|
|
ldy filesectors,x
|
|
jsr getblock81
|
|
bcs enumblocks
|
|
|
|
;lda LINKTRACK
|
|
;ldy LINKSECTOR
|
|
inc NUMBLOCKS
|
|
: ldx NUMBLOCKS
|
|
|
|
cpx #MAXBLOCKS + 1
|
|
bcs :+
|
|
pha
|
|
tya
|
|
sta filesectors,x
|
|
pla
|
|
sta filetracks,x
|
|
bne enumblocks
|
|
:
|
|
txa
|
|
SKIPWORD
|
|
writeprot: lda #WRITE_PROTECTED
|
|
SKIPWORD
|
|
filenotfnd: lda #diskio::status::FILE_NOT_FOUND; $ff
|
|
pha
|
|
|
|
jsr initwdog81
|
|
jsr enablwdg81
|
|
|
|
pla
|
|
|
|
DRIVESENDBYTE 1581, SENDVALUE
|
|
|
|
lda NUMBLOCKS
|
|
beq saverexit
|
|
|
|
;ldy #0
|
|
saveloop: sty CURRBLOCK
|
|
|
|
jsr enablwdg81
|
|
|
|
jsr rdygetbyte
|
|
beq saverexit; branch if file on disk too small/large
|
|
sta BLOCKSIZE
|
|
|
|
;ldx #0
|
|
: jsr getbyte
|
|
sta rawblock + 2,x
|
|
inx
|
|
cpx BLOCKSIZE
|
|
bcc :-
|
|
|
|
lda #CLK_OUT | DATA_OUT
|
|
sta CIA_PRB
|
|
sei
|
|
|
|
lda #0
|
|
beq :++; jmp
|
|
: sta rawblock + 2,x
|
|
inx
|
|
: cpx #$fe
|
|
bcc :--
|
|
|
|
retry: ldx CURRBLOCK
|
|
ldy filesectors + 1,x
|
|
lda filetracks + 1,x
|
|
sta rawblock
|
|
bne :+
|
|
ldy BLOCKSIZE
|
|
iny
|
|
: sty rawblock + 1
|
|
|
|
lda filetracks,x
|
|
sta BUFFERTRACK
|
|
lda filesectors,x
|
|
sta BUFFERSECTOR
|
|
jsr initcntr81
|
|
lda #WRTSD_DV
|
|
ldx #BUFFERINDEX
|
|
jsr STROBE_CONTROLLER
|
|
|
|
lda JOBCODESTABLE + BUFFERINDEX; FD does not return the error status in the accu
|
|
cmp #OK_DV + 1
|
|
bcs retry
|
|
|
|
ldy CURRBLOCK
|
|
iny
|
|
cpy NUMBLOCKS
|
|
bcc saveloop
|
|
|
|
: lda #TRKWRT_DV
|
|
ldx #BUFFERINDEX
|
|
jsr STROBE_CONTROLLER
|
|
|
|
lda JOBCODESTABLE + BUFFERINDEX; FD does not return the error status in the accu
|
|
cmp #OK_DV + 1
|
|
bcs :-
|
|
|
|
saverexit: lda #CLK_OUT | DATA_OUT
|
|
sta CIA_PRB
|
|
sei
|
|
|
|
zpbuffer = returnrun + returnend - return
|
|
|
|
ldx #returnend - return - 1
|
|
: lda return,x
|
|
sta returnrun,x
|
|
lda $00,x
|
|
sta zpbuffer,x; buffer zeropage, as it will be overwritten with pre-loader system zeropage
|
|
dex
|
|
bpl :-
|
|
|
|
jmp returnrun
|
|
return:
|
|
.org rawblock
|
|
|
|
.macro HOOK81
|
|
ldx #returnend - return - 1
|
|
: lda zpbuffer,x
|
|
sta $00,x; restore zeropage
|
|
dex
|
|
bpl :-
|
|
|
|
jsr swapzp81
|
|
.endmacro
|
|
|
|
returnrun: RETURNTOLOADER81 HOOK81
|
|
|
|
.org * - returnrun + return
|
|
returnend:
|
|
|
|
rdygetbyte: ldx #0
|
|
stx CIA_PRB
|
|
|
|
getbyte: lda #COUNT_PHI2 | FORCE_LOAD | ONE_SHOT | TIMER_START
|
|
sta CIA_CRB; reset watchdog time-out
|
|
|
|
DRIVEGETBYTE 1581
|
|
rts
|
|
|
|
fdwatchdog: lda #$ff
|
|
sta $4005; VIA_T1C_H
|
|
fdwatchdge:
|
|
.endscope
|
|
|
|
savename81: .res FILENAME_MAXLENGTH
|
|
.byte 0
|
|
|
|
.assert * <= DRVCODEND81, error, "***** 1581 save code too large. *****"
|
|
|
|
.reloc
|
|
saver81end:
|
|
|
|
.endif; ONLY_1541_AND_COMPATIBLE
|
|
|
|
.if LOAD_VIA_KERNAL_FALLBACK
|
|
|
|
kernalsave: stx namestrpos
|
|
sty namestrpos + 1
|
|
ldx #0
|
|
namestrpos = * + 1
|
|
: lda $ffff,x
|
|
beq :+
|
|
sta savename + 2,x
|
|
inx
|
|
cpx #FILENAME_MAXLENGTH
|
|
bcc :-
|
|
: stx FNLEN
|
|
|
|
lda #KERNALFILENO
|
|
ldx FA
|
|
ldy #$00
|
|
jsr SETLFS
|
|
lda FNLEN
|
|
ldx #.lobyte(savename + 2)
|
|
ldy #.hibyte(savename + 2)
|
|
jsr SETNAM
|
|
jsr OPEN
|
|
bcs jmpsaveerr
|
|
|
|
ldx LA
|
|
jsr CHKIN
|
|
|
|
ldx #0
|
|
ldy #0
|
|
kernalenum: lda STATUS
|
|
bne kernlenumd
|
|
|
|
.if KERNAL_FALLBACK_SEI_WORKAROUNDS
|
|
BRANCH_IF_DRIVE_PARALLEL :++
|
|
: BRANCH_IF_BLOCK_NOT_READY :-
|
|
:
|
|
.endif; KERNAL_FALLBACK_SEI_WORKAROUNDS
|
|
jsr BASIN
|
|
lda STATUS
|
|
bne kernlenumd
|
|
inx
|
|
bne kernalenum
|
|
iny
|
|
bne kernalenum
|
|
kernlenumd: cmp #KERNAL_STATUS_EOF
|
|
bne jmpsaveerr
|
|
|
|
lda #diskio::status::FILE_NOT_FOUND
|
|
cpx #0
|
|
bne :+
|
|
cpy #0
|
|
bne :+
|
|
jmpsaveerr: jmp saveerror
|
|
: lda #0
|
|
sta BYTECOUNT
|
|
clc
|
|
: inc BYTECOUNT
|
|
bne :+
|
|
dec BYTECOUNT
|
|
: txa
|
|
sbc #$fe
|
|
tax
|
|
tya
|
|
sbc #0
|
|
tay
|
|
bcs :--
|
|
|
|
lda BYTECOUNT
|
|
cmp BLOCKCNT
|
|
beq :+
|
|
|
|
lda #diskio::status::FILE_ON_DISK_TOO_SMALL
|
|
bcc jmpsaveerr
|
|
lda #diskio::status::FILE_ON_DISK_TOO_LARGE
|
|
bcs jmpsaveerr; jmp
|
|
:
|
|
jsr KERNLCLOSE
|
|
|
|
lda #KERNALFILENO
|
|
ldx FA
|
|
ldy #$01
|
|
jsr SETLFS
|
|
clc
|
|
lda #2
|
|
adc FNLEN
|
|
ldx #.lobyte(savename)
|
|
ldy #.hibyte(savename)
|
|
jsr SETNAM
|
|
jsr OPEN
|
|
bcs saveerror
|
|
|
|
ldx LA
|
|
jsr CKOUT
|
|
lda #diskio::status::GENERIC_KERNAL_ERROR
|
|
ldx STATUS
|
|
bne saveerror
|
|
|
|
ldy #saveparams::loadaddress
|
|
lda (PARAMSPTR),y
|
|
jsr BSOUT
|
|
iny
|
|
lda (PARAMSPTR),y
|
|
jsr BSOUT
|
|
|
|
lda #diskio::status::WRITE_PROTECT_ON
|
|
ldx STATUS
|
|
bne saveerror
|
|
|
|
sec
|
|
lda LENGTH
|
|
sbc #2
|
|
sta LENGTH
|
|
bcs :+
|
|
dec LENGTH + 1
|
|
:
|
|
ldy #saveparams::from
|
|
lda (PARAMSPTR),y
|
|
sta SAVEPTR
|
|
iny
|
|
lda (PARAMSPTR),y
|
|
sta SAVEPTR + 1
|
|
|
|
krnlsavelp: lda #diskio::status::GENERIC_KERNAL_ERROR
|
|
ldx STATUS
|
|
bne saveerror
|
|
|
|
ldy #0
|
|
.if SAVE_FROM_RAM_UNDER_IO
|
|
ENABLE_ALL_RAM_X
|
|
lda (SAVEPTR),y
|
|
ENABLE_KERNAL_SERIAL_ROUTINES_Y
|
|
.else
|
|
lda (SAVEPTR),y
|
|
.endif
|
|
jsr BSOUT
|
|
inc SAVEPTR
|
|
bne :+
|
|
inc SAVEPTR + 1
|
|
: sec
|
|
lda LENGTH
|
|
sbc #1
|
|
sta LENGTH
|
|
lda LENGTH + 1
|
|
sbc #0
|
|
bcc :+
|
|
sta LENGTH + 1
|
|
ora LENGTH
|
|
bne krnlsavelp
|
|
:
|
|
lda #diskio::status::OK
|
|
|
|
saveerror: pha
|
|
txa
|
|
pha
|
|
jsr KERNLCLOSE
|
|
pla
|
|
tax
|
|
pla
|
|
cmp #diskio::status::OK + 1
|
|
rts
|
|
|
|
savename: .byte "@:"
|
|
.res FILENAME_MAXLENGTH
|
|
|
|
.endif; LOAD_VIA_KERNAL_FALLBACK
|
|
|
|
swapparams: .word 0; buffer
|
|
|
|
.word cbm1541::saveentry; entry
|
|
.word drvsaver41; to
|
|
.word saver41end - saver41; length
|
|
.word saver41; from
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
.word drvsaver71 + 5; entry
|
|
.word drvsaver71; to
|
|
.word saver71end - saver71; length
|
|
.word saver71; from
|
|
|
|
.word drvsaver81 + 4; entry
|
|
.word drvsaver81; to
|
|
.word saver81end - saver81; length
|
|
.word saver81; from
|
|
|
|
.endif; ONLY_1541_AND_COMPATIBLE
|