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