home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-02-16 | 25.5 KB | 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
-
-