]> git.sur5r.net Git - cc65/blob - libsrc/atari/open.s
__seterrno is now a common function available on all platforms with slightly
[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,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 seterr: jsr     __seterrno
43         jsr     incsp4          ; clean up stack
44         lda     #$FF
45         tax
46         rts                     ; return -1
47
48         ; process the mode argument
49
50 iocbok: stx     tmp4
51         jsr     clriocb         ; init with zero
52         ldy     #1
53         jsr     ldaxysp         ; get mode
54         ldx     tmp4
55         pha
56         and     #O_APPEND
57         beq     no_app
58         pla
59         and     #15
60         cmp     #O_RDONLY       ; DOS supports append with write-only only
61         beq     invret
62         cmp     #O_RDWR
63         beq     invret
64         lda     #OPNOT|APPEND
65         bne     set
66
67 .ifndef UCASE_FILENAME
68 invret: lda     #<EINVAL        ; file name is too long
69         ldx     #>EINVAL
70         jmp     seterr
71 .endif
72
73 no_app: pla
74         and     #15
75         cmp     #O_RDONLY
76         bne     l1
77         lda     #OPNIN
78 set:    sta     ICAX1,x
79         bne     cont
80
81 l1:     cmp     #O_WRONLY
82         bne     l2
83         lda     #OPNOT
84         bne     set
85
86 l2:     ; O_RDWR
87         lda     #OPNOT|OPNIN
88         bne     set
89
90         ; process the filename argument
91
92 cont:   ldy     #3
93         jsr     ldaxysp
94
95 .ifdef  UCASE_FILENAME
96
97         jsr     ucase_fn
98         bcc     ucok1
99 invret: lda     #<EINVAL        ; file name is too long
100         ldx     #>EINVAL
101         jmp     seterr
102 ucok1:
103
104 .endif  ; defined UCASE_FILENAME
105
106         ldy     tmp4
107
108         ;AX - points to filename
109         ;Y  - iocb to use, if open needed
110         jsr     newfd           ; maybe we don't need to open and can reuse an iocb
111                                 ; returns fd num to use in tmp2, all regs unchanged
112         bcs     doopen          ; C set: open needed
113         lda     #0              ; clears N flag
114         beq     finish
115
116 doopen: sta     ICBAL,y
117         txa
118         sta     ICBAH,y
119         ldx     tmp4
120         lda     #OPEN
121         sta     ICCOM,x
122         jsr     CIOV
123
124         ; clean up the stack
125
126 finish: php
127         txa
128         pha
129         tya
130         pha
131
132 .ifdef  UCASE_FILENAME
133         ldy     tmp3            ; get size
134         jsr     addysp          ; free used space on the stack
135 .endif  ; defined UCASE_FILENAME
136
137         jsr     incsp4          ; clean up stack
138
139         pla
140         tay
141         pla
142         tax
143         plp
144
145         bpl     ok
146         jsr     fddecusage      ; decrement usage counter of fd as open failed
147         jmp     __do_oserror
148
149 ok:     lda     tmp2            ; get fd
150         ldx     #0
151         stx     __oserror
152         rts
153
154 .endproc
155
156
157 ; closeallfiles: Close all files opened by the program.
158
159 .proc   closeallfiles
160
161         lda     #MAX_FD_INDEX-1
162 loop:   ldx     #0
163         pha
164         jsr     _close
165         pla
166         clc
167         sbc     #0
168         bpl     loop
169         rts
170
171 .endproc