]> git.sur5r.net Git - cc65/blob - libsrc/cbm/open.s
df66345931981c7ac62fc2baba573961c5fb79c2
[cc65] / libsrc / cbm / open.s
1 ;
2 ; Ullrich von Bassewitz, 16.11.2002
3 ;
4 ; int open (const char* name, int flags, ...);  /* May take a mode argument */
5 ;
6 ; Be sure to keep the value priority of closeallfiles lower than that of
7 ; closeallstreams (which is the high level C file I/O counterpart and must be
8 ; called before closeallfiles).
9
10
11         .export         _open
12         .destructor     closeallfiles, 5
13
14         .import         SETLFS, OPEN, CLOSE
15         .import         addysp, popax
16         .import         scratch, fnparse, fnaddmode, fncomplete, fnset
17         .import         opencmdchannel, closecmdchannel, readdiskerror
18         .import         fnunit
19         .import         _close
20         .importzp       sp, tmp2, tmp3
21
22         .include        "errno.inc"
23         .include        "fcntl.inc"
24         .include        "filedes.inc"
25
26
27 ;--------------------------------------------------------------------------
28 ; closeallfiles: Close all open files.
29
30 .proc   closeallfiles
31
32         ldx     #MAX_FDS-1
33 loop:   lda     fdtab,x
34         beq     next            ; Skip unused entries
35
36 ; Close this file
37
38         txa
39         pha                     ; Save current value of X
40         ldx     #0
41         jsr     _close
42         pla
43         tax
44
45 ; Next file
46
47 next:   dex
48         bpl     loop
49
50         rts
51
52 .endproc
53
54 ;--------------------------------------------------------------------------
55 ; _open
56
57 .proc   _open
58
59 ; Throw away any additional parameters passed through the ellipsis
60
61         dey                     ; Parm count < 4 shouldn't be needed to be...
62         dey                     ; ...checked (it generates a c compiler warning)
63         dey
64         dey
65         beq     parmok          ; Branch if parameter count ok
66         jsr     addysp          ; Fix stack, throw away unused parameters
67
68 ; Parameters ok. Pop the flags and save them into tmp3
69
70 parmok: jsr     popax           ; Get flags
71         sta     tmp3
72
73 ; Get the filename from stack and parse it. Bail out if is not ok
74
75         jsr     popax           ; Get name
76         jsr     fnparse         ; Parse it
77         cmp     #0
78         bne     oserror         ; Bail out if problem with name
79
80 ; Get a free file handle and remember it in tmp2
81
82         jsr     freefd
83         lda     #EMFILE         ; Load error code
84         bcs     seterrno        ; Jump in case of errors
85         stx     tmp2
86
87 ; Check the flags. We cannot have both, read and write flags set, and we cannot
88 ; open a file for writing without creating it.
89
90         lda     tmp3
91         and     #(O_RDWR | O_CREAT)
92         cmp     #O_RDONLY       ; Open for reading?
93         beq     doread          ; Yes: Branch
94         cmp     #(O_WRONLY | O_CREAT)   ; Open for writing?
95         beq     flagsok
96
97 ; Invalid open mode
98
99         lda     #EINVAL
100
101 ; Error entry. Sets _errno, clears _oserror, returns -1
102
103 seterrno:
104         jmp     __directerrno
105
106 ; Error entry: Close the file and exit. OS error code is in A on entry
107
108 closeandexit:
109         pha
110         lda     tmp2
111         clc
112         adc     #LFN_OFFS
113         jsr     CLOSE
114         ldx     fnunit
115         jsr     closecmdchannel
116         pla
117
118 ; Error entry: Set oserror and errno using error code in A and return -1
119
120 oserror:jmp     __mappederrno
121
122 ; If O_TRUNC is set, scratch the file, but ignore any errors
123
124 flagsok:
125         lda     tmp3
126         and     #O_TRUNC
127         beq     notrunc
128         jsr     scratch
129
130 ; Complete the the file name. Check for append mode here.
131
132 notrunc:
133         lda     tmp3            ; Get the mode again
134         ldx     #'a'
135         and     #O_APPEND       ; Append mode?
136         bne     append          ; Branch if yes
137         ldx     #'w'
138 append: txa
139         jsr     fncomplete      ; Add type and mode to the name
140
141 ; Setup the real open flags
142
143         lda     #LFN_WRITE
144         bne     common
145
146 ; Read bit is set. Add an 'r' to the name
147
148 doread: lda     #'r'
149         jsr     fnaddmode       ; Add the mode to the name
150         lda     #LFN_READ
151
152 ; Common read/write code. Flags in A, handle in tmp2
153
154 common: sta     tmp3
155         jsr     fnset           ; Set the file name
156
157         lda     tmp2
158         clc
159         adc     #LFN_OFFS
160         ldx     fnunit
161         tay                     ; Use the LFN also as SA
162         jsr     SETLFS          ; Set the file params
163
164         jsr     OPEN
165         bcs     oserror
166
167 ; Open the the drive command channel and read it
168
169         ldx     fnunit
170         jsr     opencmdchannel
171         bne     closeandexit
172         ldx     fnunit
173         jsr     readdiskerror
174         bne     closeandexit    ; Branch on error
175
176 ; File is open. Mark it as open in the table
177
178         ldx     tmp2
179         lda     tmp3
180         sta     fdtab,x
181         lda     fnunit
182         sta     unittab,x       ; Remember
183
184 ; Done. Return the handle in a/x
185
186         txa                     ; Handle
187         ldx     #0
188         stx     __oserror       ; Clear _oserror
189         rts
190
191 .endproc
192
193