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 (251 lines) | stat: -rw-r--r-- 6,272 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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
;
; Oliver Schmidt, 30.12.2004
;
; int open (const char* name, int flags, ...);
;

        .export         _open, closedirect, freebuffer
        .export         __filetype, __auxtype, __datetime
        .constructor    raisefilelevel
        .destructor     closeallfiles, 5

        .import         pushname, popname, __dos_type
        .import         iobuf_alloc, iobuf_free
        .import         addysp, incsp4, incaxy, pushax, popax

        .include        "zeropage.inc"
        .include        "errno.inc"
        .include        "fcntl.inc"
        .include        "mli.inc"
        .include        "filedes.inc"

        .segment        "ONCE"

raisefilelevel:
        ; Raise file level
        lda     __dos_type
        beq     :+
        inc     LEVEL
:       rts

        .code

_open:
        ; Throw away all parameters except name
        ; and flags occupying together 4 bytes
        dey
        dey
        dey
        dey
        jsr     addysp

        ; Start with first fdtab slot
        ldy     #$00

        ; Check for free fdtab slot
:       lda     fdtab + FD::REF_NUM,y
        beq     found

        ; Advance to next fdtab slot
        .assert .sizeof(FD) = 4, error
        iny
        iny
        iny
        iny

        ; Check for end of fdtab
        cpy     #MAX_FDS * .sizeof(FD)
        bcc     :-

        ; Load errno code
        lda     #EMFILE

        ; Cleanup stack
errno:  jsr     incsp4          ; Preserves A

        ; Set __errno
        jmp     __directerrno

        ; Save fdtab slot
found:  tya
        pha

        ; Alloc I/O buffer
        lda     #<(fdtab + FD::BUFFER)
        ldx     #>(fdtab + FD::BUFFER)
        jsr     incaxy
        jsr     pushax
        lda     #$00
        ldx     #>$0100
        jsr     pushax          ; Preserves A
        ldx     #>$0400
        jsr     iobuf_alloc
        tay                     ; Save errno code

        ; Restore fdtab slot
        pla
        sta     tmp2            ; Save fdtab slot

        ; Check for error
        tya                     ; Restore errno code
        bne     errno

        ; Get and save flags
        jsr     popax
        sta     tmp3

        ; Get and push name
        jsr     popax
        jsr     pushname
        bne     oserr1

        ; Set pushed name
        lda     sp
        ldx     sp+1
        sta     mliparam + MLI::OPEN::PATHNAME
        stx     mliparam + MLI::OPEN::PATHNAME+1

        ; Check for create flag
        lda     tmp3            ; Restore flags
        and     #O_CREAT
        beq     open

        ; PATHNAME already set
        .assert MLI::CREATE::PATHNAME = MLI::OPEN::PATHNAME, error

        ; Set all other parameters from template
        ldx     #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
:       lda     CREATE,x
        sta     mliparam + MLI::CREATE::ACCESS,x
        dex
        bpl     :-

        ; Create file
        lda     #CREATE_CALL
        ldx     #CREATE_COUNT
        jsr     callmli
        bcc     open

        ; Check for ordinary errors
        cmp     #$47            ; "Duplicate filename"
        bne     oserr2

        ; Check for exclusive flag
        lda     tmp3            ; Restore flags
        and     #O_EXCL
        beq     open

        lda     #$47            ; "Duplicate filename"

        ; Cleanup name
oserr2: jsr     popname         ; Preserves A

oserr1: ldy     tmp2            ; Restore fdtab slot

        ; Cleanup I/O buffer
        pha                     ; Save oserror code
        jsr     freebuffer
        pla                     ; Restore oserror code

        ; Set __oserror
        jmp     __mappederrno

open:   ldy     tmp2            ; Restore fdtab slot

        ; Set allocated I/O buffer
        ldx     fdtab + FD::BUFFER+1,y
        sta     mliparam + MLI::OPEN::IO_BUFFER         ; A = 0
        stx     mliparam + MLI::OPEN::IO_BUFFER+1

        ; Open file
        lda     #OPEN_CALL
        ldx     #OPEN_COUNT
        jsr     callmli
        bcs     oserr2

        ; Get and save fd
        ldx     mliparam + MLI::OPEN::REF_NUM
        stx     tmp1            ; Save fd

        ; Set flags and check for truncate flag
        lda     tmp3            ; Restore flags
        sta     fdtab + FD::FLAGS,y
        and     #O_TRUNC
        beq     done

        ; Set fd and zero size
        stx     mliparam + MLI::EOF::REF_NUM
        ldx     #$02
        lda     #$00
:       sta     mliparam + MLI::EOF::EOF,x
        dex
        bpl     :-

        ; Set file size
        lda     #SET_EOF_CALL
        ldx     #EOF_COUNT
        jsr     callmli
        bcc     done

        ; Cleanup file
        pha                     ; Save oserror code
        lda     tmp1            ; Restore fd
        jsr     closedirect
        pla                     ; Restore oserror code
        bne     oserr2          ; Branch always

        ; Store fd
done:   lda     tmp1            ; Restore fd
        sta     fdtab + FD::REF_NUM,y

        ; Convert fdtab slot to handle
        .assert .sizeof(FD) = 4, error
        tya
        lsr
        lsr

        ; Cleanup name
        jsr     popname         ; Preserves A

        ; Return success
        ldx     #$00
        stx     __oserror
        rts

freebuffer:
        ; Free I/O buffer
        lda     #$00
        ldx     fdtab + FD::BUFFER+1,y
        jmp     iobuf_free

closedirect:
        ; Set fd
        sta     mliparam + MLI::CLOSE::REF_NUM

        ; Call close
        lda     #CLOSE_CALL
        ldx     #CLOSE_COUNT
        jmp     callmli

closeallfiles:
        ; All open files with current level (or higher)
        lda     #$00
        jsr     closedirect

        ; Restore original file level
        lda     __dos_type
        beq     :+
        dec     LEVEL
:       rts

        .data

CREATE: .byte   %11000011       ; ACCESS:       Standard full access
__filetype:
        .byte   $06             ; FILE_TYPE:    Standard binary file
__auxtype:
        .word   $0000           ; AUX_TYPE:     Load address N/A
        .byte   $01             ; STORAGE_TYPE: Standard seedling file
__datetime:
        .word   $0000           ; CREATE_DATE:  Current date
        .word   $0000           ; CREATE_TIME:  Current time