]> git.sur5r.net Git - cc65/blob - libsrc/cbm/filename.s
Changed most "backticks" (grave accents) into apostrophes.
[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, 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
26 nameloop:
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
43 invalidname:
44         lda     #33             ; Invalid file name
45
46 ; Done, we've successfully parsed the name.
47
48 namedone:
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
82 digit:  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
96 nodrive:
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
105 drivedone:
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
174 fncomplete:
175         pha                     ; Save mode
176         lda     __filetype
177         jsr     fnaddmode       ; Add the type
178         pla
179 fnaddmode:
180         pha
181         lda     #','
182         jsr     fnadd
183         pla
184
185 fnadd:  ldx     fnlen
186         inc     fnlen
187         sta     fnbuf,x
188         rts
189
190 ;--------------------------------------------------------------------------
191 ; Data
192
193 .bss
194
195 fnunit:         .res    1
196 fnlen:          .res    1
197 fnisfile:       .res    1       ; Flags standard file (as opposed to "$")
198
199 .data
200 fncmd:          .byte   's'     ; Use as scratch command
201 fnbuf:          .res    35      ; Either 0:0123456789012345,t,m
202                                 ; Or     0:0123456789012345=0123456789012345