]> git.sur5r.net Git - cc65/blob - libsrc/atari/open.s
Fixed _textcolor definition.
[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         .include "zeropage.inc"
12
13         .export _open
14         .destructor     closeallfiles, 5
15
16         .import _close
17         .import clriocb
18         .import fddecusage,newfd
19         .import findfreeiocb
20         .import incsp4
21         .import ldaxysp,addysp
22         .import __oserror
23 .ifdef  UCASE_FILENAME
24         .import ucase_fn
25 .endif
26
27 .proc   _open
28
29         dey                     ; parm count < 4 shouldn't be needed to be checked
30         dey                     ;       (it generates a c compiler warning)
31         dey
32         dey
33         beq     parmok          ; parameter count ok
34         jsr     addysp          ; fix stack, throw away unused parameters
35
36 parmok: jsr     findfreeiocb
37         beq     iocbok          ; we found one
38
39         lda     #<EMFILE        ; "too many open files"
40 seterr: jsr     __directerrno
41         jsr     incsp4          ; clean up stack
42         lda     #$FF
43         tax
44         rts                     ; return -1
45
46         ; process the mode argument
47
48 iocbok: stx     tmp4
49         jsr     clriocb         ; init with zero
50         ldy     #1
51         jsr     ldaxysp         ; get mode
52         ldx     tmp4
53         pha
54         and     #O_APPEND
55         beq     no_app
56         pla
57         and     #15
58         cmp     #O_RDONLY       ; DOS supports append with write-only only
59         beq     invret
60         cmp     #O_RDWR
61         beq     invret
62         lda     #OPNOT|APPEND
63         bne     set
64
65 .ifndef UCASE_FILENAME
66 invret: lda     #<EINVAL        ; file name is too long
67         jmp     seterr
68 .endif
69
70 no_app: pla
71         and     #15
72         cmp     #O_RDONLY
73         bne     l1
74         lda     #OPNIN
75 set:    sta     ICAX1,x
76         bne     cont
77
78 l1:     cmp     #O_WRONLY
79         bne     l2
80         lda     #OPNOT
81         bne     set
82
83 l2:     ; O_RDWR
84         lda     #OPNOT|OPNIN
85         bne     set
86
87         ; process the filename argument
88
89 cont:   ldy     #3
90         jsr     ldaxysp
91
92 .ifdef  UCASE_FILENAME
93 .ifdef  DEFAULT_DEVICE
94         ldy     #$80
95 .else
96         ldy     #$00
97 .endif
98         sty     tmp2            ; set flag for ucase_fn
99         jsr     ucase_fn
100         bcc     ucok1
101 invret: lda     #<EINVAL        ; file name is too long
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         sty     tmp3            ; remember error code
148         lda     #CLOSE
149         sta     ICCOM,x
150         jsr     CIOV            ; close IOCB again since open failed
151         jsr     fddecusage      ; and decrement usage counter of fd
152         lda     tmp3            ; put error code into A
153         jmp     __mappederrno
154
155 ok:     lda     tmp2            ; get fd
156         ldx     #0
157         stx     __oserror
158         rts
159
160 .endproc
161
162
163 ; closeallfiles: Close all files opened by the program.
164
165 .proc   closeallfiles
166
167         lda     #MAX_FD_INDEX-1
168 loop:   ldx     #0
169         pha
170         jsr     _close
171         pla
172         clc
173         sbc     #0
174         bpl     loop
175         rts
176
177 .endproc