]> git.sur5r.net Git - cc65/blob - libsrc/cbm/filename.s
fb8c9978e8c0abb58046713c53334556fe3df455
[cc65] / libsrc / cbm / filename.s
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, fncmd, fnbuf
10
11         .import         SETNAM
12         .import         __curunit, __filetype
13         .importzp       ptr1, tmp1
14
15         .include        "ctype.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
26 nameloop:
27         lda     (ptr1),y        ; Get next char from filename
28         beq     namedone        ; Jump if end of name reached
29
30 ; Check for valid chars in the file name. We allow letters, digits, plus some
31 ; additional chars from a table.
32
33         ldx     #fncharcount-1
34 namecheck:
35         cmp     fnchars,x
36         beq     nameok
37         dex
38         bpl     namecheck
39         tax
40         lda     __ctype,x
41         and     #CT_ALNUM
42         beq     invalidname
43
44 ; Check the maximum length, store the character
45
46 nameok: ldx     tmp1
47         cpx     #16             ; Maximum length reached?
48         bcs     invalidname
49         lda     (ptr1),y        ; Reload char
50         jsr     fnadd           ; Add character to name
51         iny                     ; Next char from name
52         inc     tmp1            ; Increment length of name
53         bne     nameloop        ; Branch always
54
55 ; Invalid file name
56
57 invalidname:
58         lda     #33             ; Invalid file name
59
60 ; Done, we've successfully parsed the name.
61
62 namedone:
63         rts
64
65 .endproc
66
67
68 ;------------------------------------------------------------------------------
69 ; fnparse: Parse a full filename passed in in a/x. Will set the following
70 ; variables:
71 ;
72 ;       fnlen   -> length of filename
73 ;       fnbuf   -> filename including drive spec
74 ;       fnunit  -> unit from spec or default unit
75 ;
76 ; Returns an error code in A or zero if all is ok.
77
78 .proc   fnparse
79
80         sta     ptr1
81         stx     ptr1+1          ; Save pointer to name
82
83 ; For now we will always use the default unit
84
85         jsr     fndefunit
86
87 ; Check the name for a drive spec
88
89         ldy     #0
90         lda     (ptr1),y
91         cmp     #'0'
92         beq     digit
93         cmp     #'1'
94         bne     nodrive
95
96 digit:  sta     fnbuf+0
97         iny
98         lda     (ptr1),y
99         cmp     #':'
100         bne     nodrive
101
102 ; We found a drive spec, copy it to the buffer
103
104         sta     fnbuf+1
105         iny                     ; Skip colon
106         bne     drivedone       ; Branch always
107
108 ; We did not find a drive spec, always use drive zero
109
110 nodrive:
111         lda     #'0'
112         sta     fnbuf+0
113         lda     #':'
114         sta     fnbuf+1
115         ldy     #$00            ; Reposition to start of name
116
117 ; Drive spec done. We do now have a drive spec in the buffer.
118
119 drivedone:
120         lda     #2              ; Length of drive spec
121         sta     fnlen
122
123 ; Copy the name into the file name buffer. The subroutine returns an error
124 ; code in A and zero flag set if the were no errors.
125
126         jmp     fnparsename
127
128 .endproc
129
130 ;--------------------------------------------------------------------------
131 ; fndefunit: Use the default unit
132
133 .proc   fndefunit
134
135         lda     __curunit
136         sta     fnunit
137         rts
138
139 .endproc
140
141 ;--------------------------------------------------------------------------
142 ; fnset: Tell the kernal about the file name
143
144 .proc   fnset
145
146         lda     fnlen
147         ldx     #<fnbuf
148         ldy     #>fnbuf
149         jmp     SETNAM
150
151 .endproc
152
153 ;--------------------------------------------------------------------------
154 ; fncomplete: Complete a filename by adding ",t,m" where t is the file type
155 ; and m is the access mode passed in in the A register
156 ;
157 ; fnaddmode: Add ",m" to a filename, where "m" is passed in A
158
159 fncomplete:
160         pha                     ; Save mode
161         jsr     fnaddcomma      ; Add a comma
162         lda     __filetype
163         jsr     fnadd           ; Add the type
164         pla
165 fnaddmode:
166         pha
167         jsr     fnaddcomma
168         pla
169
170 fnadd:  ldx     fnlen
171         inc     fnlen
172         sta     fnbuf,x
173         rts
174
175 fnaddcomma:
176         lda     #','
177         bne     fnadd
178
179 ;--------------------------------------------------------------------------
180 ; Data
181
182 .bss
183
184 fnunit: .res    1
185 fnlen:  .res    1
186
187 .data
188 fncmd:  .byte   's'     ; Use as scratch command
189 fnbuf:  .res    35      ; Either 0:0123456789012345,t,m
190                         ; Or     0:0123456789012345=0123456789012345
191 .rodata
192 ; Characters that are ok in filenames besides digits and letters
193 fnchars:.byte   ".,-_+()"
194 fncharcount = *-fnchars
195
196
197