X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libsrc%2Fcbm%2Ffilename.s;h=e5884bbdf960f6815d050c21722a9c381f21d1a9;hb=7e5149d7f55f6773179f2c06aa9511bedab6c9f4;hp=572be21e4fa203f7301a8eacd46c5a9e8332b443;hpb=6d498d81872e506d0e1f069d01a9d4d43a962639;p=cc65 diff --git a/libsrc/cbm/filename.s b/libsrc/cbm/filename.s index 572be21e4..e5884bbdf 100644 --- a/libsrc/cbm/filename.s +++ b/libsrc/cbm/filename.s @@ -4,46 +4,83 @@ ; File name handling for CBM file I/O ; - .export fnparse, fnset, fncomplete - .export fnunit, fnlen, fncmd, fnbuf + .export fnparse, fnparsename, fnset + .export fnadd, fnaddmode, fncomplete, fndefunit + .export fnunit, fnlen, fnisfile, fncmd, fnbuf .import SETNAM - .import __curunit, __filetype - .importzp ptr1 + .import curunit, __filetype + .importzp ptr1, tmp1 .include "ctype.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 the maximum length, store the character + + 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 @@ -63,54 +100,58 @@ 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 +; Assume this is a standard file on disk -; Check for valid chars in the file name. We allow letters, digits, plus some -; additional chars from a table. + sta fnisfile - ldx #fncharcount-1 -namecheck: - cmp fnchars,x - beq nameok - dex - bpl namecheck - tax - lda __ctype,x - and #CT_ALNUM - beq invalidname +; Special treatment for directory. If the file name is "$", things are +; actually different: $ is directory for unit 0, $0 dito, $1 is directory +; for unit 1. For simplicity, we won't check anything else if the first +; character of the file name is '$'. -; Check the maximum length, store the character + lda (ptr1),y ; Get first character + cmp #'$' ; + bne fnparsename -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 +; Juggle stuff -; Invalid file name + ldx fnbuf+0 ; unit + stx fnbuf+1 + sta fnbuf+0 -invalidname: - lda #33 ; Invalid file name +; Add the file mask -; Done, we've successfully parsed the name. + lda #':' + sta fnbuf+2 + lda #'*' + sta fnbuf+3 + lda #4 + sta fnlen -namedone: +; No need to check the name. Length is already 2 + + lda #0 ; ok flag + sta fnisfile ; This is not a real file rts .endproc +;-------------------------------------------------------------------------- +; fndefunit: Use the default unit + +.proc fndefunit + + lda curunit + sta fnunit + rts + +.endproc ;-------------------------------------------------------------------------- ; fnset: Tell the kernal about the file name @@ -127,43 +168,35 @@ namedone: ;-------------------------------------------------------------------------- ; 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 - -.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 +; +; fnaddmode: Add ",m" to a filename, where "m" is passed in A + +fncomplete: + pha ; Save mode + lda __filetype + jsr fnaddmode ; Add the type + pla +fnaddmode: + pha + lda #',' + jsr fnadd + pla + +fnadd: ldx fnlen + inc fnlen + sta fnbuf,x + rts ;-------------------------------------------------------------------------- ; Data .bss -fnunit: .res 1 -fnlen: .res 1 +fnunit: .res 1 +fnlen: .res 1 +fnisfile: .res 1 ; Flags standard file (as opposed to "$") .data -fncmd: .byte 's' ; Use as scratch command -fnbuf: .res 22 ; 0:0123456789012345,t,m - -.rodata -; Characters that are ok in filenames besides digits and letters -fnchars:.byte ".,-_+()" -fncharcount = *-fnchars - - +fncmd: .byte 's' ; Use as scratch command +fnbuf: .res 35 ; Either 0:0123456789012345,t,m + ; Or 0:0123456789012345=0123456789012345