]> git.sur5r.net Git - cc65/blob - libsrc/cbm/open.s
Renamed the defines in symdefs.h to something more meaningful. They were named
[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, 17
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