; File name handling for CBM file I/O
;
- .export fnparse, fnset, fncomplete
+ .export fnparse, fnparsename, fnset
+ .export fnadd, fnaddmode, fncomplete, fndefunit
.export fnunit, fnlen, fncmd, fnbuf
+ .import SETNAM
.import __curunit, __filetype
- .importzp ptr1
+ .importzp ptr1, tmp1
.include "ctype.inc"
- .include "cbm.inc"
-;--------------------------------------------------------------------------
-; fnparse: Parse a filename passed in in a/x. Will set the following
+;------------------------------------------------------------------------------
+; fnparsename: Parse a filename (without drive spec) passed in in ptr1 and y.
+
+.proc fnparsename
+
+ lda #0
+ sta tmp1 ; Remember length of name
+
+nameloop:
+ lda (ptr1),y ; Get next char from filename
+ beq namedone ; Jump if end of name reached
+
+; Check for valid chars in the file name. We allow letters, digits, plus some
+; additional chars from a table.
+
+ ldx #fncharcount-1
+namecheck:
+ cmp fnchars,x
+ beq nameok
+ dex
+ bpl namecheck
+ tax
+ lda __ctype,x
+ and #CT_ALNUM
+ beq invalidname
+
+; Check the maximum length, store the character
+
+nameok: ldx tmp1
+ cpx #16 ; Maximum length reached?
+ bcs invalidname
+ lda (ptr1),y ; Reload char
+ jsr fnadd ; Add character to name
+ iny ; Next char from name
+ inc tmp1 ; Increment length of name
+ bne nameloop ; Branch always
+
+; Invalid file name
+
+invalidname:
+ lda #33 ; Invalid file name
+
+; Done, we've successfully parsed the name.
+
+namedone:
+ rts
+
+.endproc
+
+
+;------------------------------------------------------------------------------
+; fnparse: Parse a full filename passed in in a/x. Will set the following
; variables:
;
; fnlen -> length of filename
; fnbuf -> filename including drive spec
; fnunit -> unit from spec or default unit
-
+;
+; Returns an error code in A or zero if all is ok.
.proc fnparse
sta ptr1
stx ptr1+1 ; Save pointer to name
-; For now we're always using the default unit
+; For now we will always use the default unit
- lda __curunit
- sta fnunit
+ jsr fndefunit
; Check the name for a drive spec
ldy #0
lda (ptr1),y
- sta fnbuf+0
cmp #'0'
beq digit
cmp #'1'
bne nodrive
-digit: iny
+digit: sta fnbuf+0
+ iny
lda (ptr1),y
cmp #':'
bne nodrive
sta fnbuf+1
ldy #$00 ; Reposition to start of name
-; Drive spec done. Copy the name into the file name buffer. Check that all
-; file name characters are valid and that the maximum length is not exceeded.
+; Drive spec done. We do now have a drive spec in the buffer.
drivedone:
lda #2 ; Length of drive spec
sta fnlen
-nameloop:
- lda (ptr1),y ; Get next char from filename
- beq namedone ; Jump if end of name reached
-
-; Check for valid chars in the file name. We allow letters, digits, plus some
-; additional chars from a table.
-
- ldx #fncharcount-1
-namecheck:
- cmp fnchars,x
- beq nameok
- dex
- bpl namecheck
- tax
- lda __ctype,x
- and #CT_ALNUM
- beq invalidname
-
-; Check the maximum length, store the character
+; Copy the name into the file name buffer. The subroutine returns an error
+; code in A and zero flag set if the were no errors.
-nameok: ldx fnlen
- cpx #16 ; Maximum length reached?
- bcs invalidname
- lda (ptr1),y ; Reload char
- sta fnbuf,x ; Store into buffer
- inc fnlen ; Count characters
- iny ; Next char from name
- bne nameloop ; Branch always
+ jmp fnparsename
-; Invalid file name
+.endproc
-invalidname:
- lda #33 ; Invalid file name
+;--------------------------------------------------------------------------
+; fndefunit: Use the default unit
-; Done, we've successfully parsed the name.
+.proc fndefunit
-namedone:
+ lda __curunit
+ sta fnunit
rts
.endproc
-
;--------------------------------------------------------------------------
; fnset: Tell the kernal about the file name
;--------------------------------------------------------------------------
; fncomplete: Complete a filename by adding ",t,m" where t is the file type
; and m is the access mode passed in in the A register
+;
+; fnaddmode: Add ",m" to a filename, where "m" is passed in A
+
+fncomplete:
+ pha ; Save mode
+ jsr fnaddcomma ; Add a comma
+ lda __filetype
+ jsr fnadd ; Add the type
+ pla
+fnaddmode:
+ pha
+ jsr fnaddcomma
+ pla
+
+fnadd: ldx fnlen
+ inc fnlen
+ sta fnbuf,x
+ rts
-.proc fncomplete
-
- pha ; Save mode
- ldx fnlen
- lda #','
- sta fnbuf,x
- inx
- lda __filetype
- sta fnbuf,x
- inx
- lda #','
- sta fnbuf,x
- inx
- pla
- sta fnbuf,x
- inx
- stx fnlen
- rts
-
-.endproc
+fnaddcomma:
+ lda #','
+ bne fnadd
;--------------------------------------------------------------------------
; Data
.data
fncmd: .byte 's' ; Use as scratch command
-fnbuf: .res 22 ; 0:0123456789012345,t,m
-
+fnbuf: .res 35 ; Either 0:0123456789012345,t,m
+ ; Or 0:0123456789012345=0123456789012345
.rodata
; Characters that are ok in filenames besides digits and letters
fnchars:.byte ".,-_+()"
fncharcount = *-fnchars
+