]> git.sur5r.net Git - cc65/blob - libsrc/cbm/open.s
Merge pull request #31 from greg-king5/cbm-chain
[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, fnisfile
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         tax
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     dowrite
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 ; Read bit is set. Add an 'r' to the name
123
124 doread: lda     #'r'
125         jsr     fnaddmode       ; Add the mode to the name
126         lda     #LFN_READ
127         bne     common          ; Branch always
128
129 ; If O_TRUNC is set, scratch the file, but ignore any errors
130
131 dowrite:
132         lda     tmp3
133         and     #O_TRUNC
134         beq     notrunc
135         jsr     scratch
136
137 ; Complete the the file name. Check for append mode here.
138
139 notrunc:
140         lda     tmp3            ; Get the mode again
141         and     #O_APPEND       ; Append mode?
142         bne     append          ; Branch if yes
143
144 ; Setup the name for create mode
145
146         lda     #'w'
147         jsr     fncomplete      ; Add type and mode to the name
148         jmp     appendcreate
149
150 ; Append bit is set. Add an 'a' to the name
151
152 append: lda     #'a'
153         jsr     fnaddmode       ; Add open mode to file name
154 appendcreate:
155         lda     #LFN_WRITE
156
157 ; Common read/write code. Flags in A, handle in tmp2
158
159 common: sta     tmp3
160         jsr     fnset           ; Set the file name
161
162         lda     tmp2
163         clc
164         adc     #LFN_OFFS
165         ldx     fnunit
166         ldy     fnisfile        ; Is this a standard file on disk?
167         beq     nofile          ; Branch if not
168         tay                     ; Use the LFN also as SA for files
169 nofile:                         ; ... else use SA=0 (read)
170         jsr     SETLFS          ; Set the file params
171
172         jsr     OPEN
173         bcs     oserror
174
175 ; Open the the drive command channel and read it
176
177         ldx     fnunit
178         jsr     opencmdchannel
179         bne     closeandexit
180         ldx     fnunit
181         jsr     readdiskerror
182         bne     closeandexit    ; Branch on error
183
184 ; File is open. Mark it as open in the table
185
186         ldx     tmp2
187         lda     tmp3
188         sta     fdtab,x
189         lda     fnunit
190         sta     unittab,x       ; Remember
191
192 ; Done. Return the handle in a/x
193
194         txa                     ; Handle
195         ldx     #0
196         stx     __oserror       ; Clear _oserror
197         rts
198
199 .endproc
200
201
202