1; 2; Ullrich von Bassewitz, 16.11.2002 3; 4; File name handling for CBM file I/O 5; 6 7 .export fnparse, fnparsename, fnset 8 .export fnadd, fnaddmode, fncomplete, fndefunit 9 .export fnunit, fnlen, fnisfile, fncmd, fnbuf 10 11 .import curunit, __filetype 12 .importzp ptr1, tmp1 13 14 .include "ctype.inc" 15 .include "cbm.inc" 16 17 18;------------------------------------------------------------------------------ 19; fnparsename: Parse a filename (without drive spec) passed in in ptr1 and y. 20 21.proc fnparsename 22 23 lda #0 24 sta tmp1 ; Remember length of name 25 26nameloop: 27 lda (ptr1),y ; Get next char from filename 28 beq namedone ; Jump if end of name reached 29 30; Check the maximum length, store the character 31 32 ldx tmp1 33 cpx #16 ; Maximum length reached? 34 bcs invalidname 35 lda (ptr1),y ; Reload char 36 jsr fnadd ; Add character to name 37 iny ; Next char from name 38 inc tmp1 ; Increment length of name 39 bne nameloop ; Branch always 40 41; Invalid file name 42 43invalidname: 44 lda #33 ; Invalid file name 45 46; Done, we've successfully parsed the name. 47 48namedone: 49 rts 50 51.endproc 52 53 54;------------------------------------------------------------------------------ 55; fnparse: Parse a full filename passed in in a/x. Will set the following 56; variables: 57; 58; fnlen -> length of filename 59; fnbuf -> filename including drive spec 60; fnunit -> unit from spec or default unit 61; 62; Returns an error code in A or zero if all is ok. 63 64.proc fnparse 65 66 sta ptr1 67 stx ptr1+1 ; Save pointer to name 68 69; For now we will always use the default unit 70 71 jsr fndefunit 72 73; Check the name for a drive spec 74 75 ldy #0 76 lda (ptr1),y 77 cmp #'0' 78 beq digit 79 cmp #'1' 80 bne nodrive 81 82digit: sta fnbuf+0 83 iny 84 lda (ptr1),y 85 cmp #':' 86 bne nodrive 87 88; We found a drive spec, copy it to the buffer 89 90 sta fnbuf+1 91 iny ; Skip colon 92 bne drivedone ; Branch always 93 94; We did not find a drive spec, always use drive zero 95 96nodrive: 97 lda #'0' 98 sta fnbuf+0 99 lda #':' 100 sta fnbuf+1 101 ldy #$00 ; Reposition to start of name 102 103; Drive spec done. We do now have a drive spec in the buffer. 104 105drivedone: 106 lda #2 ; Length of drive spec 107 sta fnlen 108 109; Assume this is a standard file on disk 110 111 sta fnisfile 112 113; Special treatment for directory. If the file name is "$", things are 114; actually different: $ is directory for unit 0, $0 dito, $1 is directory 115; for unit 1. For simplicity, we won't check anything else if the first 116; character of the file name is '$'. 117 118 lda (ptr1),y ; Get first character 119 cmp #'$' ; 120 bne fnparsename 121 122; Juggle stuff 123 124 ldx fnbuf+0 ; unit 125 stx fnbuf+1 126 sta fnbuf+0 127 128; Add the file mask 129 130 lda #':' 131 sta fnbuf+2 132 lda #'*' 133 sta fnbuf+3 134 lda #4 135 sta fnlen 136 137; No need to check the name. Length is already 2 138 139 lda #0 ; ok flag 140 sta fnisfile ; This is not a real file 141 rts 142 143.endproc 144 145;-------------------------------------------------------------------------- 146; fndefunit: Use the default unit 147 148.proc fndefunit 149 150 lda curunit 151 sta fnunit 152 rts 153 154.endproc 155 156;-------------------------------------------------------------------------- 157; fnset: Tell the kernal about the file name 158 159.proc fnset 160 161 lda fnlen 162 ldx #<fnbuf 163 ldy #>fnbuf 164 jmp SETNAM 165 166.endproc 167 168;-------------------------------------------------------------------------- 169; fncomplete: Complete a filename by adding ",t,m" where t is the file type 170; and m is the access mode passed in in the A register 171; 172; fnaddmode: Add ",m" to a filename, where "m" is passed in A 173 174fncomplete: 175 pha ; Save mode 176 lda __filetype 177 jsr fnaddmode ; Add the type 178 pla 179fnaddmode: 180 pha 181 lda #',' 182 jsr fnadd 183 pla 184 185fnadd: ldx fnlen 186 inc fnlen 187 sta fnbuf,x 188 rts 189 190;-------------------------------------------------------------------------- 191; Data 192 193.bss 194 195fnunit: .res 1 196fnlen: .res 1 197fnisfile: .res 1 ; Flags standard file (as opposed to "$") 198 199.data 200fncmd: .byte 's' ; Use as scratch command 201fnbuf: .res 35 ; Either 0:0123456789012345,t,m 202 ; Or 0:0123456789012345=0123456789012345 203