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