File: open.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (177 lines) | stat: -rw-r--r-- 4,065 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;
; Christian Groessler, Jan-2003
;
; int open(const char *name,int flags,...);
;

        .include "atari.inc"
        .include "fcntl.inc"
        .include "errno.inc"
        .include "fd.inc"
        .include "zeropage.inc"

        .export _open
        .destructor     closeallfiles, 5

        .import _close
        .import clriocb
        .import fddecusage,newfd
        .import findfreeiocb
        .import incsp4
        .import ldaxysp,addysp
        .import __oserror
.ifdef  UCASE_FILENAME
        .import ucase_fn
.endif

.proc   _open

        dey                     ; parm count < 4 shouldn't be needed to be checked
        dey                     ;       (it generates a c compiler warning)
        dey
        dey
        beq     parmok          ; parameter count ok
        jsr     addysp          ; fix stack, throw away unused parameters

parmok: jsr     findfreeiocb
        beq     iocbok          ; we found one

        lda     #<EMFILE        ; "too many open files"
seterr: jsr     __directerrno
        jsr     incsp4          ; clean up stack
        lda     #$FF
        tax
        rts                     ; return -1

        ; process the mode argument

iocbok: stx     tmp4
        jsr     clriocb         ; init with zero
        ldy     #1
        jsr     ldaxysp         ; get mode
        ldx     tmp4
        pha
        and     #O_APPEND
        beq     no_app
        pla
        and     #15
        cmp     #O_RDONLY       ; DOS supports append with write-only only
        beq     invret
        cmp     #O_RDWR
        beq     invret
        lda     #OPNOT|APPEND
        bne     set

.ifndef UCASE_FILENAME
invret: lda     #<EINVAL        ; file name is too long
        jmp     seterr
.endif

no_app: pla
        and     #15
        cmp     #O_RDONLY
        bne     l1
        lda     #OPNIN
set:    sta     ICAX1,x
        bne     cont

l1:     cmp     #O_WRONLY
        bne     l2
        lda     #OPNOT
        bne     set

l2:     ; O_RDWR
        lda     #OPNOT|OPNIN
        bne     set

        ; process the filename argument

cont:   ldy     #3
        jsr     ldaxysp

.ifdef  UCASE_FILENAME
.ifdef  DEFAULT_DEVICE
        ldy     #$80
.else
        ldy     #$00
.endif
        sty     tmp2            ; set flag for ucase_fn
        jsr     ucase_fn
        bcc     ucok1
invret: lda     #<EINVAL        ; file name is too long
        jmp     seterr
ucok1:

.endif  ; defined UCASE_FILENAME

        ldy     tmp4

        ;AX - points to filename
        ;Y  - iocb to use, if open needed
        jsr     newfd           ; maybe we don't need to open and can reuse an iocb
                                ; returns fd num to use in tmp2, all regs unchanged
        bcs     doopen          ; C set: open needed
        lda     #0              ; clears N flag
        beq     finish

doopen: sta     ICBAL,y
        txa
        sta     ICBAH,y
        ldx     tmp4
        lda     #OPEN
        sta     ICCOM,x
        jsr     CIOV

        ; clean up the stack

finish: php
        txa
        pha
        tya
        pha

.ifdef  UCASE_FILENAME
        ldy     tmp3            ; get size
        jsr     addysp          ; free used space on the stack
.endif  ; defined UCASE_FILENAME

        jsr     incsp4          ; clean up stack

        pla
        tay
        pla
        tax
        plp

        bpl     ok
        sty     tmp3            ; remember error code
        lda     #CLOSE
        sta     ICCOM,x
        jsr     CIOV            ; close IOCB again since open failed
        jsr     fddecusage      ; and decrement usage counter of fd
        lda     tmp3            ; put error code into A
        jmp     __mappederrno

ok:     lda     tmp2            ; get fd
        ldx     #0
        stx     __oserror
        rts

.endproc


; closeallfiles: Close all files opened by the program.

.proc   closeallfiles

        lda     #MAX_FD_INDEX-1
loop:   ldx     #0
        pha
        jsr     _close
        pla
        clc
        sbc     #0
        bpl     loop
        rts

.endproc