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