]> git.sur5r.net Git - cc65/blob - libsrc/atari/open.s
Added o65 symbol export capability
[cc65] / libsrc / atari / open.s
1 ;
2 ; Christian Groessler, May-2000
3 ;
4 ; int open(const char *name,int flags,...);
5 ;
6
7 UCASE_FILENAME  = 1             ; comment it out if filename shouldn't be uppercased
8
9         .include "atari.inc"
10         .include "../common/fmode.inc"
11         .include "../common/errno.inc"
12         .export _open
13         .import clriocb
14         .import fddecusage,newfd
15         .import findfreeiocb
16         .import __do_oserror,__seterrno,incsp4
17         .import ldaxysp,addysp,subysp
18         .import _strupr,__oserror
19         .importzp tmp4,tmp2,sp
20 .ifdef  UCASE_FILENAME
21         .importzp tmp3,ptr4
22 .endif
23
24 .proc   _open
25
26         cpy     #4              ; correct # of arguments (bytes)?
27         beq     parmok          ; parameter count ok
28         tya                     ; parm count < 4 shouldn't be needed to be checked
29         sec                     ;       (it generates a c compiler warning)
30         sbc     #4
31         tay
32         jsr     addysp          ; fix stack, throw away unused parameters
33
34 parmok: jsr     findfreeiocb
35         beq     iocbok          ; we found one
36
37         lda     #<EMFILE        ; "too many open files"
38         ldx     #>EMFILE
39 seterr: jsr     __seterrno
40         jsr     incsp4          ; clean up stack
41         lda     #$FF
42         tax
43         rts                     ; return -1
44
45         ; process the mode argument
46         ; @@@TODO: append not handled yet!
47
48 iocbok: stx     tmp4
49         jsr     clriocb         ; init with zero
50         ldy     #1
51         jsr     ldaxysp         ; get mode
52         ldx     tmp4
53         cmp     #O_RDONLY
54         bne     l1
55         lda     #OPNIN
56 set:    sta     ICAX1,x
57         bne     cont
58
59 l1:     cmp     #O_WRONLY
60         bne     l2
61         lda     #OPNOT
62         bne     set
63
64 l2:     ; O_RDWR
65         lda     #OPNOT|OPNIN
66         bne     set
67
68         ; process the filename argument
69
70 cont:   ldy     #3
71         jsr     ldaxysp
72
73 .ifdef  UCASE_FILENAME
74         ; we make sure that the filename doesn't contain lowercase letters
75         ; we copy the filename we got onto the stack, uppercase it and use this
76         ; one to open the iocb
77         ; we're using tmp3, ptr4
78
79         ; save the original pointer
80         sta     ptr4
81         stx     ptr4+1
82
83         ; now we need the length of the name
84         ldy     #0
85 loop:   lda     (ptr4),y
86         beq     str_end
87         cmp     #ATEOL          ; we also accept Atari EOF char as end of string
88         beq     str_end
89         iny
90         bne     loop            ; not longer than 255 chars (127 real limit)
91 toolong:lda     #<EINVAL        ; file name is too long
92         ldx     #>EINVAL
93         jmp     seterr
94
95 str_end:iny                     ; room for terminating zero
96         cpy     #128            ; we only can handle lenght < 128
97         bcs     toolong
98         sty     tmp3            ; save size
99         jsr     subysp          ; make room on the stack
100
101         ; copy filename to the temp. place on the stack
102         lda     #0              ; end-of-string
103         sta     (sp),y          ; Y still contains length + 1
104         dey
105 loop2:  lda     (ptr4),y
106         sta     (sp),y
107         dey
108         bpl     loop2           ; bpl: this way we only support a max. length of 127
109
110         ; uppercase the temp. filename
111         ldx     sp+1
112         lda     sp
113         jsr     _strupr
114
115         ; leave X and Y pointing to the modified filename
116         lda     sp
117         ldx     sp+1
118
119 .endif  ; defined UCASE_FILENAME
120
121         ldy     tmp4
122
123         ;AX - points to filename
124         ;Y  - iocb to use, if open needed
125         jsr     newfd           ; maybe we don't need to open and can reuse an iocb
126                                 ; returns fd num to use in tmp2, all regs unchanged
127         bcs     doopen          ; C set: open needed
128         lda     #0              ; clears N flag
129         beq     finish
130
131 doopen: sta     ICBAL,y
132         txa
133         sta     ICBAH,y
134         ldx     tmp4
135         lda     #OPEN
136         sta     ICCOM,x
137         jsr     CIOV
138
139         ; clean up the stack
140
141 finish: php
142         txa
143         pha
144         tya
145         pha
146
147 .ifdef  UCASE_FILENAME
148         ldy     tmp3            ; get size
149         jsr     addysp          ; free used space on the stack
150 .endif  ; defined UCASE_FILENAME
151
152         jsr     incsp4          ; clean up stack
153
154         pla
155         tay
156         pla
157         tax
158         plp
159
160         bpl     ok
161         jsr     fddecusage      ; decrement usage counter of fd as open failed
162         jmp     __do_oserror
163
164 ok:     lda     tmp2            ; get fd
165         ldx     #0
166         stx     __oserror
167         rts
168
169 .endproc