home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CBM Funet Archive
/
cbm-funet-archive-2003.iso
/
cbm
/
c128
/
utilities
/
lrr270.sfx
/
lrr270.bin.s
< prev
next >
Wrap
Text File
|
1998-02-16
|
26KB
|
1,492 lines
; Little Red Reader/Writer utility package by Craig Bruce, 31-Jan-1992
; Written for C= Hacking Net-Magazine; for C-128, 1571, 1581
; Upgraded for FD-2000/4000 High Density MS-DOS disks, 08-Mar-1994
; Upgraded to clean up errors and add aborting, 16-May-1996
.org $5400
.obj "@0:lrr270.bin"
;====jump table and parameters interface ====
jmp initPackage ;()
jmp msDir ;( msDevice, msType ) : .AY=dirAddr, .X=direntCount
jmp msRead ;( msDevice, msType, startCluster, lenML,.A=trans,.X=cbmLfn )
jmp msWrite ;( msDevice, msType, writeDirent, .A=trans, .X=cbmLfn )
jmp msFlush ;( msDevice, msType )
jmp msDelete ;( writeDirent )
jmp msFormat ;( msDevice, msType, .A=low/highDensity )
jmp msBytesFree ;( ) : .AYX=bytesFree
jmp cbmCopy ;( .A=inLfn, .X=outLfn, .Y=tr )
jmp cbmDirent ;( .A=lfn )
.byte $cb,134 ;identification (location pk+30)
errno .buf 1 ;0=ok,1-15=msdos,16-19=internal,20-30=cbm
msDevice .buf 1
msType .buf 1 ;$00=1571, $ff=1581 or FD-2000/4000
startCluster .buf 2
lenML .buf 2 ;length medium and low bytes
writeDirent .buf 2 ;pointer to dirent
cdirBlocks .buf 2 ;cbm dirent blocks
cdirType .buf 1 ;cbm dirent filetype
cdirFlen .buf 1 ;cbm dirent filename length
cdirName .buf 16 ;cbm dirent filename
;====global declaraions====
kernelListen = $ffb1
kernelSecond = $ff93
kernelUnlsn = $ffae
kernelAcptr = $ffa2
kernelCiout = $ffa8
kernelSpinp = $ff47
kernelChkin = $ffc6
kernelChkout = $ffc9
kernelClrchn = $ffcc
kernelChrin = $ffcf
kernelChrout = $ffd2
kernelGetin = $ffe4
st = $90
ciaClock = $dd00
ciaFlags = $dc0d
ciaData = $dc0c
clusterBlockCount .buf 1 ;1 or 2
fatBlocks .buf 1 ;up to 9
rootDirBlocks .buf 1 ;up to 14
rootDirEntries .buf 1 ;up to 224
totalSectors .buf 2 ;up to 2880
firstFileBlock .buf 1
firstRootDirBlock .buf 1
fileClusterCount .buf 2
lastFatEntry .buf 2
bufCylinder .buf 1
bufSide .buf 1
fatDirty .buf 1
dirDirty .buf 14 ;flag for each directory block
formatParms .buf 1
sectorsPerTrack .byte 9 ;default, up to 18
.buf 4
sectorsPerCyl .byte 18 ;default, up to 36
;====test routines====
msFormat = *
lda #$0e
sta $ff00
jsr mountDisk
lda #0 ;cylinder
ldx #0 ;side
jsr readTrack
lda #<trackbuf
ldy #>trackbuf
sta 1024
sty 1025
rts
;====hardware level====
sendU0 = * ;( .A=burstCommandCode ) : .CS=err
pha
lda #0
sta st
lda msDevice
jsr kernelListen
lda #$6f
jsr kernelSecond
lda #"u"
jsr kernelCiout
bit st
bmi sendU0Error
lda #"0"
jsr kernelCiout
pla
jsr kernelCiout
bit st
bmi sendU0Error
clc
rts
sendU0Error = *
lda #25 ;device not present error
sta errno
sec
rts
toggleClock = *
lda ciaClock
eor #$10
sta ciaClock
rts
serialWait = *
lda #$08
- bit ciaFlags
beq -
rts
getBurstByte = *
jsr serialWait
ldx ciaData
jsr toggleClock
txa
rts
mountDisk = * ;() : .CS=err
lda #%00011010
jsr sendU0
bcc +
rts
+ jsr kernelUnlsn
bit st
bmi sendU0Error
clc
jsr kernelSpinp
bit ciaFlags
jsr toggleClock
jsr getBurstByte
and #$0f
sta errno
cmp #2
bcs mountExit
ldy #0
- jsr getBurstByte
sta formatParms,y
iny
cpy #6
bcc -
lda sectorsPerTrack
asl
sta sectorsPerCyl
;** set interleave to 4 if 1571, don't bother for other drives
bit msType
bmi mountExit
lda #%00001000
jsr sendU0
bcc +
rts
+ lda #4
jsr kernelCiout
jsr kernelUnlsn
clc
mountExit = *
rts
bufptr = 2
secnum = 4
readTrack = * ;( .A=cylinder, .X=side ) : trackbuf, .CS=err
pha
txa
and #$01
asl
asl
asl
asl
bit msType
bpl +
eor #$10
+ jsr sendU0
pla
bcc +
rts
+ jsr kernelCiout ;cylinder number
lda #1 ;start sector number
jsr kernelCiout
lda sectorsPerTrack ;sector count
jsr kernelCiout
jsr kernelUnlsn
sei
clc
jsr kernelSpinp
bit ciaFlags
jsr toggleClock
lda #<trackbuf
ldy #>trackbuf
sta bufptr+0
sty bufptr+1
lda #0
sta secnum
- bit msType
bmi +
jsr get1571BufPtr
+ jsr readSector
bcs trackExit
inc secnum
lda secnum
cmp sectorsPerTrack
bcc -
jsr toggleClock
clc
trackExit = *
cli
rts
get1571BufPtr = *
lda #<trackbuf
sta bufptr
ldx secnum
clc
lda #>trackbuf
adc bufptr1571,x
sta bufptr+1
rts
bufptr1571 = *
.byte 0,8,16,6,14,4,12,2,10
readSector = * ;( bufptr ) : .CS=err
jsr getBurstByte
and #$0f
sta errno
cmp #2
bcc +
rts
+ ldx #2
ldy #0
readByte = *
lda #$08
- bit ciaFlags
beq -
lda ciaClock
eor #$10
sta ciaClock
lda ciaData
sta (bufptr),y
iny
bne readByte
inc bufptr+1
dex
bne readByte
clc
rts
oldClock = 5
writeSector = * ;( bufptr, .A=cylinder, .X=side, .Y=sector ) : .CS=err
pha
sty secnum
txa
and #$01
asl
asl
asl
asl
ora #$02
bit msType
bpl +
eor #$10
+ jsr sendU0
pla
bcc +
rts
+ jsr kernelCiout ;track number
lda secnum ;sector number
jsr kernelCiout
lda #1 ;sector count
jsr kernelCiout
jsr kernelUnlsn
sei
lda #$40
sta oldClock
sec
jsr kernelSpinp ;set for burst output
sei
bit ciaFlags
ldx #2
ldy #0
writeByte = *
lda ciaClock
cmp ciaClock
bne writeByte
eor oldClock
and #$40
beq writeByte
lda (bufptr),y
sta ciaData
lda oldClock
eor #$40
sta oldClock
lda #8
- bit ciaFlags
beq -
iny
bne writeByte
inc bufptr+1
dex
bne writeByte
clc
jsr kernelSpinp
bit ciaFlags
jsr toggleClock
jsr serialWait
ldx ciaData
jsr toggleClock
txa
and #$0f
sta errno
cmp #2
cli
rts
;====logical-sector level====
initPackage = *
lda #$0e
sta $ff00
lda #$ff
sta bufCylinder
sta bufSide
ldx #13
- sta dirDirty,x
dex
bpl -
sta fatDirty
clc
rts
sectorSave = 5
readBlock = * ;( .A=cylinder,.X=side,.Y=sector ) : .AY=blkPtr,.CS=err
cmp bufCylinder
bne readBlockPhysical
cpx bufSide
bne readBlockPhysical
dey
tya
asl
clc
adc #>trackbuf
tay
lda #<trackbuf
clc
rts
readBlockPhysical = *
sta bufCylinder
stx bufSide
sty sectorSave
jsr readTrack
bcc readBlockPhysicalOk
lda errno
and #$0f
cmp #11 ;disk change
beq +
- lda #$ff
sta bufCylinder
stx bufSide
sec
rts
+ jsr mountDisk
lda bufCylinder
ldx bufSide
ldy sectorSave
bcc readBlockPhysical
jmp -
readBlockPhysicalOk = *
lda bufCylinder
ldx bufSide
ldy sectorSave
jmp readBlock
divideByCylSecs = * ;( .AY=number ) : .A=quotient, .Y=remainder
ldx #$ff
- inx
sec
sbc sectorsPerCyl
bcs -
dey
bpl -
clc
adc sectorsPerCyl
iny
tay
txa
rts
convertLogicalBlockNum = * ;( .AY=blockNum ) : .A=cyl, .X=side, .Y=sec
jsr divideByCylSecs
ldx #0
cpy sectorsPerTrack
bcc +
pha
tya
sbc sectorsPerTrack
tay
pla
ldx #1
+ iny
rts
destPtr = 6
curCylinder = 8
curSide = 9
curSector = 10
blockCountdown = 11
sourcePtr = 12
copyBlocks = * ;( .AY=startBlock, .X=blockCount, ($6)=dest ) : .CS=err
stx blockCountdown
jsr convertLogicalBlockNum
sta curCylinder
stx curSide
sty curSector
copyBlockLoop = *
lda curCylinder
ldx curSide
ldy curSector
jsr readBlock
bcc +
rts
+ sta sourcePtr+0
sty sourcePtr+1
ldx #2
ldy #0
- lda (sourcePtr),y
sta (destPtr),y
iny
lda (sourcePtr),y
sta (destPtr),y
iny
bne -
inc sourcePtr+1
inc destPtr+1
dex
bne -
inc curSector
lda curSector
cmp sectorsPerTrack
beq +
bcc +
lda #1
sta curSector
inc curSide
lda curSide
cmp #2
bcc +
lda #0
sta curSide
inc curCylinder
+ dec blockCountdown
bne copyBlockLoop
clc
rts
convertClusterNum = * ;( .AY=clusterNum ) : .AY=logicalBlockNum
sec
sbc #2
bcs +
dey
+ ldx clusterBlockCount
cpx #1
beq +
asl
sty 7
rol 7
ldy 7
+ clc
adc firstFileBlock
bcc +
iny
+ rts
readCluster = * ;( .AY=clusterNumber ) : clusterBuf, .CS=err
jsr convertClusterNum
;** read logical blocks comprising cluster
ldx #<clusterBuf
stx 6
ldx #>clusterBuf
stx 7
ldx clusterBlockCount
jmp copyBlocks
writeLogicalBlock = * ;( .AY=logicalBlockNumber, bufptr ) : .CS=err
jsr convertLogicalBlockNum
cmp bufCylinder
bne +
cpx bufSide
bne +
pha
lda #$ff
sta bufCylinder
sta bufSide
pla
+ jsr writeSector
rts
writeClusterSave .buf 2
writeCluster = * ;( .AY=clusterNumber, clusterBuf ) : .CS=err
jsr convertClusterNum
ldx #<clusterBuf
stx bufptr+0
ldx #>clusterBuf
stx bufptr+1
sta writeClusterSave+0
sty writeClusterSave+1
jsr writeLogicalBlock
bcc +
rts
+ lda clusterBlockCount
cmp #2
bcs +
rts
+ lda writeClusterSave+0
ldy writeClusterSave+1
clc
adc #1
bcc +
iny
+ jsr writeLogicalBlock
rts
;====MS-DOS format level====
bootBlock = 2
msDir = * ;( .A=forceMount ) : .AY=dirbuf, .X=dirEntries, .CS=err
ldx #$0e
stx $ff00
cmp #$d0
bne +
jsr mountDisk
bcc +
rts
;** get parameters from boot sector
+ lda #0
ldy #0
jsr convertLogicalBlockNum
jsr readBlock
bcc +
rts
+ sta bootBlock+0
sty bootBlock+1
ldy #13 ;get cluster size
lda (bootBlock),y
sta clusterBlockCount
cmp #3
bcc +
invalidParms = *
lda #17 ;invalid disk parms error
sta errno
sec
rts
+ ldy #16 ;check FAT replication count, must be 2
lda (bootBlock),y
cmp #2
bne invalidParms
ldy #22 ;get FAT size in sectors, max of 9
lda (bootBlock),y
sta fatBlocks
cmp #10
bcs invalidParms
ldy #17 ;get directory size
lda (bootBlock),y
sta rootDirEntries
cmp #225
bcs invalidParms
lsr
lsr
lsr
lsr
sta rootDirBlocks
ldy #19 ;get total sector count
lda (bootBlock),y
sta totalSectors+0
iny
lda (bootBlock),y
sta totalSectors+1
ldy #24 ;check sectors per track, must be 18 or fewer
lda (bootBlock),y
cmp #19
bcs invalidParms
ldy #26
lda (bootBlock),y
cmp #2 ;check number of sides, must be 2
bne invalidParms
ldy #14 ;check number of boot sectors, must be 1
lda (bootBlock),y
cmp #1
bne invalidParms
;** get derived parameters
lda fatBlocks ;first root directory sector
asl
clc
adc #1
sta firstRootDirBlock
clc ;first file sector
adc rootDirBlocks
sta firstFileBlock
lda totalSectors+0 ;number of file clusters
ldy totalSectors+1
sec
sbc firstFileBlock
bcs +
dey
+ sta fileClusterCount+0
sty fileClusterCount+1
lda clusterBlockCount
cmp #2
bne +
lsr fileClusterCount+1
ror fileClusterCount+0
+ clc
lda fileClusterCount+0
adc #2
sta lastFatEntry+0
lda fileClusterCount+1
adc #0
sta lastFatEntry+1
;** load FAT
lda #<fatbuf
ldy #>fatbuf
sta 6
sty 7
lda #1
ldy #0
ldx fatBlocks
jsr copyBlocks
bcc +
rts
;** load actual directory
+ lda #<dirbuf
ldy #>dirbuf
sta 6
sty 7
lda firstRootDirBlock
ldy #0
ldx rootDirBlocks
jsr copyBlocks
bcc +
rts
+ lda #<dirbuf
ldy #>dirbuf
ldx rootDirEntries
clc
rts
entryAddr = 2
entryWork = 4
entryBits = 5
entryData0 = 6
entryData1 = 7
entryData2 = 8
locateFatEntry = * ;( .AY=fatEntryNumber ) : entryAddr, entryBits1
sta entryBits
;** divide by two
sty entryAddr+1
lsr entryAddr+1
ror
;** times three
sta entryWork
ldx entryAddr+1
asl
rol entryAddr+1
clc
adc entryWork
sta entryAddr
txa
adc entryAddr+1
sta entryAddr+1
;** add base, get data
clc
lda entryAddr
adc #<fatbuf
sta entryAddr
lda entryAddr+1
adc #>fatbuf
sta entryAddr+1
ldy #2
- lda (entryAddr),y
sta entryData0,y
dey
bpl -
rts
getFatEntry = * ;( .AY=fatEntryNumber ) : .AY=fatEntryValue
jsr locateFatEntry
lda entryBits
and #1
bne +
;** case 1: first 12-bit cluster
lda entryData1
and #$0f
tay
lda entryData0
rts
;** case 2: second 12-bit cluster
+ lda entryData1
ldx #4
- lsr entryData2
ror
dex
bne -
ldy entryData2
rts
fatValue = 9
setFatEntry = * ;( .AY=fatEntryNumber, (fatValue) )
jsr locateFatEntry
lda fatValue+1
and #$0f
sta fatValue+1
lda entryBits
and #1
bne +
;** case 1: first 12-bit cluster
lda fatValue
sta entryData0
lda entryData1
and #$f0
ora fatValue+1
sta entryData1
jmp setFatExit
;** case 2: second 12-bit cluster
+ ldx #4
- asl fatValue
rol fatValue+1
dex
bne -
lda fatValue+1
sta entryData2
lda entryData1
and #$0f
ora fatValue
sta entryData1
setFatExit = *
ldy #2
- lda entryData0,y
sta (entryAddr),y
dey
bpl -
sty fatDirty
rts
dirtyDirent = * ;( writeDirent )
sec
lda writeDirent+0
sbc #<dirbuf
lda writeDirent+1
sbc #>dirbuf
lsr
and #$0f
tax
lda #$ff
sta dirDirty,x
rts
delCluster = 14
msDelete = * ;( writeDirent )
ldy #$0e
sty $ff00
lda writeDirent+0
ldy writeDirent+1
sta 2
sty 3
lda #$e5
ldy #0
sta (2),y
ldy #26
lda (2),y
sta delCluster+0
iny
lda (2),y
sta delCluster+1
- lda delCluster+1
cmp #12 ;cluster number high byte
bcc +
jmp dirtyDirent
+ tay
lda delCluster
jsr getFatEntry
pha
tya
pha
lda #0
sta fatValue+0
sta fatValue+1
lda delCluster+0
ldy delCluster+1
jsr setFatEntry
pla
sta delCluster+1
pla
sta delCluster
jmp -
flushBlock = 14
flushCountdown = $60
flushRepeats = $61
flushDirIndex = $61
msFlush = * ;( msDevice, msType ) : .CS=error
lda #$0e
sta $ff00
lda fatDirty
beq flushDirectory
lda #0
sta fatDirty
;** flush fat
lda #2
sta flushRepeats
lda #1
sta flushBlock
masterFlush = *
lda fatBlocks
sta flushCountdown
lda #<fatbuf
ldy #>fatbuf
sta bufptr
sty bufptr+1
- lda flushBlock
ldy #0
jsr writeLogicalBlock
bcc +
rts
+ inc flushBlock
dec flushCountdown
bne -
dec flushRepeats
bne masterFlush
;** flush directory
flushDirectory = *
lda firstRootDirBlock
sta flushBlock
lda rootDirBlocks
sta flushCountdown
lda #0
sta flushDirIndex
lda #<dirbuf
ldy #>dirbuf
sta bufptr+0
sty bufptr+1
- ldx flushDirIndex
lda dirDirty,x
beq +
lda #0
sta dirDirty,x
lda flushBlock
ldy #0
jsr writeLogicalBlock
dec bufptr+1
dec bufptr+1
+ inc flushBlock
inc flushDirIndex
inc bufptr+1
inc bufptr+1
dec flushCountdown
bne -
clc
rts
bfFatEntry = 14
bfBlocks = $60
msBytesFree = * ;( ) : .AYX=fileBytesFree
ldy #$0e
sty $ff00
lda #2
ldy #0
sta bfFatEntry+0
sty bfFatEntry+1
sty bfBlocks+0
sty bfBlocks+1
- lda bfFatEntry+0
ldy bfFatEntry+1
jsr getFatEntry
sty 2
ora 2
bne +
inc bfBlocks+0
bne +
inc bfBlocks+1
+ inc bfFatEntry
bne +
inc bfFatEntry+1
+ lda bfFatEntry+0
cmp lastFatEntry+0
lda bfFatEntry+1
sbc lastFatEntry+1
bcc -
ldx clusterBlockCount
- asl bfBlocks
rol bfBlocks+1
dex
bne -
lda #0
ldy bfBlocks+0
ldx bfBlocks+1
rts
;====file-copy level====
transMode = 14
lfn = 15
cbmDataPtr = $60
cbmDataLen = $62
cluster = $64
copyFileCluster = * ;( cluster, lfn, transMode ) : .CS=err
lda cluster+0
ldy cluster+1
jsr readCluster
bcc +
rts
+ lda #<clusterBuf
ldy #>clusterBuf
sta cbmDataPtr+0
sty cbmDataPtr+1
lda #0
sta cbmDataLen+0
lda clusterBlockCount
asl
sta cbmDataLen+1
;**get next cluster
lda cluster+0
ldy cluster+1
jsr getFatEntry
sta cluster+0
sty cluster+1
cpy #12 ;cluster number high byte
bcc copyFileClusterData
lda lenML
sta cbmDataLen
lda #$01
ldx clusterBlockCount
cpx #1
beq +
lda #$03
+ and lenML+1
bne +
ldx lenML
beq copyFileClusterData
+ sta cbmDataLen+1
copyFileClusterData = *
jsr commieOut
rts
cbmDataLimit = $66
commieOut = * ;( cbmDataPtr, cbmDataLen ) : .CS=err
ldx lfn
bne +
clc
rts
+ jsr kernelChkout
bcc commieOutMore
commieError = *
clc
adc #20
sec
sta errno
rts
commieOutMore = *
lda #255
ldx cbmDataLen+1
bne +
lda cbmDataLen
+ sta cbmDataLimit
ldy #0
- lda (cbmDataPtr),y
bit transMode
bpl +
tax
lda transBuf,x
beq commieNext
+ jsr kernelChrout
commieNext = *
iny
cpy cbmDataLimit
bne -
clc
lda cbmDataPtr
adc cbmDataLimit
sta cbmDataPtr
bcc +
inc cbmDataPtr+1
+ sec
lda cbmDataLen
sbc cbmDataLimit
sta cbmDataLen
bcs +
dec cbmDataLen+1
+ lda cbmDataLen
ora cbmDataLen+1
bne commieOutMore
jsr kernelClrchn
clc
rts
testAbort = *
jsr kernelGetin
bne +
clc
rts
+ cmp #"a"
bne testAbort
lda #16 ;abort error
sta errno
sec
rts
msRead = * ;( cluster, lenML, .A=transMode, .X=lfn ) : .CS=err
ldy #$0e
sty $ff00
sta transMode
stx lfn
lda startCluster+0
ldy startCluster+1
sta cluster+0
sty cluster+1
jmp +
- jsr testAbort
bcs ++
jsr copyFileCluster
bcc +
rts
+ lda cluster+1
cmp #12 ;cluster number high byte
bcc -
clc
+ rts
inLfn = $50
generateLf = $51
cbmDataMax = $52
reachedEof = $54
prevSt = $55
commieInInit = * ;( .A=transMode, .X=inLfn )
sta transMode
stx inLfn
lda #0
sta generateLf
sta reachedEof
sta prevSt
rts
commieIn = * ;( cbmDataPtr++, cbmDataMax ) : cbmDataLen, .CS=err, .Z=eof
lda #0
sta cbmDataLen
sta cbmDataLen+1
ldx reachedEof
beq +
lda #0
clc
rts
+ ldx inLfn
jsr kernelChkin
bcc commieInMore
jmp commieError
commieInMore = *
lda #255
ldx cbmDataMax+1
bne +
lda cbmDataMax
+ sta cbmDataLimit
ldy #0
- jsr commieInByte
bcc +
rts
+ beq +
sta (cbmDataPtr),y
iny
cpy cbmDataLimit
bne -
+ sty cbmDataLimit
clc
lda cbmDataPtr
adc cbmDataLimit
sta cbmDataPtr
bcc +
inc cbmDataPtr+1
+ clc
lda cbmDataLen
adc cbmDataLimit
sta cbmDataLen
bcc +
inc cbmDataLen+1
+ sec
lda cbmDataMax
sbc cbmDataLimit
sta cbmDataMax
bcs +
dec cbmDataMax+1
+ lda reachedEof
bne +
lda cbmDataMax
ora cbmDataMax+1
bne commieInMore
+ jsr kernelClrchn
lda cbmDataLen
ora cbmDataLen+1
clc
rts
commieInByte = * ;( ) : .A=char, .CS=err, .Z=eof, reachedEof
;** check for already past eof
lda reachedEof
beq +
brk
;** check for generated linefeed
+ lda generateLf
beq +
lda #0
sta generateLf
lda #$0a
clc
rts
;** check for eof
+ lda prevSt
and #$40
beq +
lda #$ff
sta reachedEof
lda #0
clc
rts
;** read actual character
+ jsr kernelChrin
ldx st
stx prevSt
bcc +
pha
jsr kernelClrchn
pla
jmp commieError
;** translate if necessary
+ bit transMode
bpl +
tax
lda transBufToAscii,x
beq commieInByte
cmp #$0d
bne +
sta generateLf
;** exit
+ ldx #$ff
clc
rts
firstFreeFatEntry = $5a
allocateFatEntry = * ;( ) : .AY=fatEntry, .CS=err
- lda firstFreeFatEntry
cmp lastFatEntry
lda firstFreeFatEntry+1
sbc lastFatEntry+1
bcc +
lda #19 ;disk full err
sta errno
rts
+ lda firstFreeFatEntry
ldy firstFreeFatEntry+1
jsr getFatEntry
sty 2
ora 2
bne +
lda firstFreeFatEntry
ldy firstFreeFatEntry+1
clc
rts
+ inc firstFreeFatEntry
bne -
inc firstFreeFatEntry+1
jmp -
msFileLength = $5c ;(3 bytes)
msWriteCluster = * ; (*) : .CS=err
;** get a new cluster
jsr allocateFatEntry
bcc +
rts
;** make previous fat entry point to new cluster
+ sta fatValue
sty fatValue+1
lda cluster
ora cluster+1
beq +
lda cluster
ldy cluster+1
ldx fatValue
stx cluster
ldx fatValue+1
stx cluster+1
jsr setFatEntry
jmp msClusterNew
+ lda writeDirent
ldy writeDirent+1
sta 2
sty 3
ldy #26
lda fatValue
sta (2),y
sta cluster
iny
lda fatValue+1
sta (2),y
sta cluster+1
;** make new fat entry point to null
msClusterNew = *
lda #$ff
ldy #$0f
sta fatValue
sty fatValue+1
lda cluster
ldy cluster+1
jsr setFatEntry
;** write new cluster data
+ lda cluster
ldy cluster+1
jsr writeCluster
bcc +
rts
;** add cluster length to file length
+ clc
lda msFileLength
adc cbmDataLen
sta msFileLength
lda msFileLength+1
adc cbmDataLen+1
sta msFileLength+1
bcc +
inc msFileLength+2
+ clc
rts
msWrite = * ;( msDevice, msType, writeDirent, .A=trans, .X=cbmLfn ) :.CS=err
ldy #$0e
sty $ff00
;** initialize
jsr commieInInit
lda #0
sta cluster
sta cluster+1
sta firstFreeFatEntry+1
sta msFileLength
sta msFileLength+1
sta msFileLength+2
lda #2
sta firstFreeFatEntry
;** copy cluster from cbm file
- jsr testAbort
bcc +
rts
+ lda #<clusterBuf
ldy #>clusterBuf
sta cbmDataPtr
sty cbmDataPtr+1
lda clusterBlockCount
asl
tay
lda #0
sta cbmDataMax
sty cbmDataMax+1
jsr commieIn
bcc +
rts
+ beq +
jsr msWriteCluster
bcc -
rts
;** wrap up after writing - set file length, dirty flag, exit.
+ lda writeDirent
ldy writeDirent+1
sta 2
sty 3
ldx #0
ldy #28
- lda msFileLength,x
sta (2),y
iny
inx
cpx #3
bcc -
jsr dirtyDirent
clc
rts
;===== commodore file level =====
cbmCopyTrans .buf 1
cbmCopy = * ;( .A=inLfn, .X=outLfn, .Y=outAscToCbmTranslationFlag )
sty cbmCopyTrans
ldy #$0e
sty $ff00
stx lfn
tax
lda #0
jsr commieInInit
- jsr testAbort
bcs +
lda #<clusterBuf
ldy #>clusterBuf
sta cbmDataPtr+0
sty cbmDataPtr+1
lda #<1024
ldy #>1024
sta cbmDataMax+0
sty cbmDataMax+1
jsr commieIn
bcs +
beq +
lda #<clusterBuf
ldy #>clusterBuf
sta cbmDataPtr+0
sty cbmDataPtr+1
lda cbmCopyTrans
sta transMode
jsr commieOut
lda #0
sta transMode
bcs +
jmp -
+ rts
cbmDirent = * ;( .A=lfn )
ldy #$0e
sty $ff00
tax
jsr kernelChkin
bcc ++
cdirErr = *
+ lda #0
sta cdirFlen
sta cdirBlocks
sta cdirBlocks+1
rts
;** get block count
+ jsr cdirGetch
jsr cdirGetch
jsr cdirGetch
sta cdirBlocks
jsr cdirGetch
sta cdirBlocks+1
;** look for filename
lda #0
sta cdirFlen
- jsr cdirGetch
cmp #34
beq +
cmp #"b"
bne -
jsr kernelClrchn
rts
;** get filename
+ ldy #0
- jsr cdirGetch
cmp #34
beq +
sta cdirName,y
iny
bne -
+ sty cdirFlen
- jsr cdirGetch
cmp #" "
beq -
sta cdirType
- jsr cdirGetch
cmp #0
bne -
jsr kernelClrchn
rts
cdirGetch = *
jsr kernelChrin
bcs +
bit st
bvs +
rts
+ pla
pla
jsr kernelClrchn
jmp cdirErr
;===== data =====
transBuf = *
;0 1 2 3 4 5 6 7 8 9 a b c d e f
.byte $00,$00,$00,$00,$00,$00,$00,$00,$14,$09,$0d,$00,$93,$00,$00,$00 ;0
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;1
.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ;2
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ;3
.byte $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf ;4
.byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$5f ;5
.byte $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ;6
.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$df ;7
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;8
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;9
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;a
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;b
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;c
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;d
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;e
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;f
transBufToAscii = *
;0 1 2 3 4 5 6 7 8 9 a b c d e f
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$00,$00,$00,$0d,$00,$00 ;0
.byte $00,$00,$00,$00,$08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;1
.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ;2
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ;3
.byte $40,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f ;4
.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$5b,$5c,$5d,$5e,$5f ;5
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;6
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;7
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;8
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;9
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;a
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;b
.byte $60,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ;c
.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$7b,$7c,$7d,$7e,$7f ;d
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;e
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7e ;f
;====bss storage (size=22,016 bytes)====
bss = *
trackbuf = bss+0 ;(9216) ;room for 18 x 512-byte sectors
clusterBuf = bss+9216 ;(1024) ;2 sectors
fatbuf = bss+10240 ;(4608) ;9 sectors
dirbuf = bss+14848 ;(7168) ;14 sectors = 224 dirents
bssEnd = bss+22016