]> git.sur5r.net Git - cc65/blob - libsrc/atari/open.s
added closeallfiles: close all files at program exit
[cc65] / libsrc / atari / open.s
1 ;
2 ; Christian Groessler, Jan-2003
3 ;
4 ; int open(const char *name,int flags,...);
5 ;
6
7         .include "atari.inc"
8         .include "fcntl.inc"
9         .include "errno.inc"
10         .include "fd.inc"
11
12         .export _open
13         .destructor     closeallfiles, 17
14
15         .import _close
16         .import clriocb
17         .import fddecusage,newfd
18         .import findfreeiocb
19         .import __do_oserror,__seterrno,incsp4
20         .import ldaxysp,addysp
21         .import __oserror
22         .importzp tmp4,tmp2
23 .ifdef  UCASE_FILENAME
24         .importzp tmp3
25         .import ucase_fn
26 .endif
27
28 .proc   _open
29
30         cpy     #4              ; correct # of arguments (bytes)?
31         beq     parmok          ; parameter count ok
32         tya                     ; parm count < 4 shouldn't be needed to be checked
33         sec                     ;       (it generates a c compiler warning)
34         sbc     #4
35         tay
36         jsr     addysp          ; fix stack, throw away unused parameters
37
38 parmok: jsr     findfreeiocb
39         beq     iocbok          ; we found one
40
41         lda     #<EMFILE        ; "too many open files"
42         ldx     #>EMFILE
43 seterr: jsr     __seterrno
44         jsr     incsp4          ; clean up stack
45         lda     #$FF
46         tax
47         rts                     ; return -1
48
49         ; process the mode argument
50
51 iocbok: stx     tmp4
52         jsr     clriocb         ; init with zero
53         ldy     #1
54         jsr     ldaxysp         ; get mode
55         ldx     tmp4
56         pha
57         and     #O_APPEND
58         beq     no_app
59         pla
60         and     #15
61         cmp     #O_RDONLY       ; DOS supports append with write-only only
62         beq     invret
63         cmp     #O_RDWR
64         beq     invret
65         lda     #OPNOT|APPEND
66         bne     set
67
68 .ifndef UCASE_FILENAME
69 invret: lda     #<EINVAL        ; file name is too long
70         ldx     #>EINVAL
71         jmp     seterr
72 .endif
73
74 no_app: pla
75         and     #15
76         cmp     #O_RDONLY
77         bne     l1
78         lda     #OPNIN
79 set:    sta     ICAX1,x
80         bne     cont
81
82 l1:     cmp     #O_WRONLY
83         bne     l2
84         lda     #OPNOT
85         bne     set
86
87 l2:     ; O_RDWR
88         lda     #OPNOT|OPNIN
89         bne     set
90
91         ; process the filename argument
92
93 cont:   ldy     #3
94         jsr     ldaxysp
95
96 .ifdef  UCASE_FILENAME
97
98         jsr     ucase_fn
99         bcc     ucok1
100 invret: lda     #<EINVAL        ; file name is too long
101         ldx     #>EINVAL
102         jmp     seterr
103 ucok1:
104
105 .endif  ; defined UCASE_FILENAME
106
107         ldy     tmp4
108
109         ;AX - points to filename
110         ;Y  - iocb to use, if open needed
111         jsr     newfd           ; maybe we don't need to open and can reuse an iocb
112                                 ; returns fd num to use in tmp2, all regs unchanged
113         bcs     doopen          ; C set: open needed
114         lda     #0              ; clears N flag
115         beq     finish
116
117 doopen: sta     ICBAL,y
118         txa
119         sta     ICBAH,y
120         ldx     tmp4
121         lda     #OPEN
122         sta     ICCOM,x
123         jsr     CIOV
124
125         ; clean up the stack
126
127 finish: php
128         txa
129         pha
130         tya
131         pha
132
133 .ifdef  UCASE_FILENAME
134         ldy     tmp3            ; get size
135         jsr     addysp          ; free used space on the stack
136 .endif  ; defined UCASE_FILENAME
137
138         jsr     incsp4          ; clean up stack
139
140         pla
141         tay
142         pla
143         tax
144         plp
145
146         bpl     ok
147         jsr     fddecusage      ; decrement usage counter of fd as open failed
148         jmp     __do_oserror
149
150 ok:     lda     tmp2            ; get fd
151         ldx     #0
152         stx     __oserror
153         rts
154
155 .endproc
156
157
158 ; closeallfiles: Close all files opened by the program.
159
160 .proc   closeallfiles
161
162         lda     #MAX_FD_INDEX-1
163 loop:   ldx     #0
164         pha
165         jsr     _close
166         pla
167         clc
168         sbc     #0
169         bpl     loop
170         rts
171
172 .endproc