]> git.sur5r.net Git - cc65/blob - libsrc/apple2/open.s
Use .assert
[cc65] / libsrc / apple2 / open.s
1 ;
2 ; Oliver Schmidt, 30.12.2004
3 ;
4 ; int open (const char* name, int flags, ...);
5 ;
6 ; Be sure to keep the value priority of closeallfiles lower than that of
7 ; closeallstreams (which is the high level C file I/O counterpart and must be
8 ; called before closeallfiles).
9
10         .export         _open, closedirect, freebuffer
11         .destructor     closeallfiles, 17
12
13         .import         pushname, popname
14         .import         errnoexit, oserrexit
15         .import         __aligned_malloc, _free
16         .import         addysp, incsp4, pushax, popax
17
18         .include        "zeropage.inc"
19         .include        "errno.inc"
20         .include        "fcntl.inc"
21         .include        "mli.inc"
22         .include        "filedes.inc"
23
24 _open:
25         ; Throw away all parameters except name
26         ; and flags occupying together 4 bytes
27         dey
28         dey
29         dey
30         dey
31         jsr     addysp
32
33         ; Start with first fdtab slot
34         ldy     #$00
35
36         ; Check for free fdtab slot
37 :       lda     fdtab + FD::REF_NUM,y
38         beq     found
39
40         ; Advance to next fdtab slot
41         .assert .sizeof(FD) = 4, error
42         iny
43         iny
44         iny
45         iny
46
47         ; Check for end of fdtab
48         cpy     #MAX_FDS * .sizeof(FD)
49         bcc     :-
50
51         ; Load errno codes
52         lda     #ENOMEM ^ EMFILE
53 enomem: eor     #ENOMEM
54
55         ; Cleanup stack
56         jsr     incsp4          ; Preserves A
57
58         ; Return errno
59         jmp     errnoexit
60
61         ; Save fdtab slot
62 found:  tya
63         pha
64
65         ; Alloc I/O buffer
66         lda     #$00
67         ldx     #>$0400
68         jsr     pushax          ; Preserves A
69         ldx     #>$0100
70         jsr     __aligned_malloc
71
72         ; Restore fdtab slot
73         pla
74         tay
75
76         ; Get and check I/O buffer high byte
77         txa
78         beq     enomem
79
80         ; Set I/O buffer high byte (low byte remains zero)
81         sta     fdtab + FD::BUFFER+1,y
82
83         sty     tmp2            ; Save fdtab slot
84
85         ; Get and save flags
86         jsr     popax
87         sta     tmp3
88
89         ; Get and push name
90         jsr     popax
91         jsr     pushname
92         bne     oserr1
93
94         ; Set pushed name
95         lda     sp
96         ldx     sp+1
97         sta     mliparam + MLI::OPEN::PATHNAME
98         stx     mliparam + MLI::OPEN::PATHNAME+1
99
100         ; Check for create flag
101         lda     tmp3            ; Restore flags
102         and     #O_CREAT
103         beq     open
104
105         ; PATHNAME already set
106         .assert MLI::CREATE::PATHNAME = MLI::OPEN::PATHNAME, error
107
108         ; Set all other parameters from template
109         ldx     #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
110 :       lda     CREATE,x
111         sta     mliparam + MLI::CREATE::ACCESS,x
112         dex
113         bpl     :-
114
115         ; Create file
116         lda     #CREATE_CALL
117         ldx     #CREATE_COUNT
118         jsr     callmli
119         bcc     open
120
121         ; Check for ordinary errors
122         cmp     #$47            ; "Duplicate filename"
123         bne     oserr2
124
125         ; Check for exclusive flag
126         lda     tmp3            ; Restore flags
127         and     #O_EXCL
128         beq     open
129
130         lda     #$47            ; "Duplicate filename"
131
132         ; Cleanup name
133 oserr2: jsr     popname         ; Preserves A
134
135 oserr1: ldy     tmp2            ; Restore fdtab slot
136
137         ; Cleanup I/O buffer
138         pha                     ; Save oserror code
139         jsr     freebuffer
140         pla                     ; Restore oserror code
141
142         ; Return oserror
143         jmp     oserrexit
144
145 open:   ldy     tmp2            ; Restore fdtab slot
146
147         ; Set allocated I/O buffer
148         ldx     fdtab + FD::BUFFER+1,y
149         sta     mliparam + MLI::OPEN::IO_BUFFER         ; A = 0
150         stx     mliparam + MLI::OPEN::IO_BUFFER+1
151
152         ; Open file
153         lda     #OPEN_CALL
154         ldx     #OPEN_COUNT
155         jsr     callmli
156         bcs     oserr2
157
158         ; Get and save fd
159         ldx     mliparam + MLI::OPEN::REF_NUM
160         stx     tmp1            ; Save fd
161
162         ; Set flags and check for truncate flag
163         lda     tmp3            ; Restore flags
164         sta     fdtab + FD::FLAGS,y
165         and     #O_TRUNC
166         beq     done
167
168         ; Set fd and zero size
169         stx     mliparam + MLI::EOF::REF_NUM
170         ldx     #$02
171         lda     #$00
172 :       sta     mliparam + MLI::EOF::EOF,x
173         dex
174         bpl     :-
175
176         ; Set file size
177         lda     #SET_EOF_CALL
178         ldx     #EOF_COUNT
179         jsr     callmli
180         bcc     done
181
182         ; Cleanup file
183         pha                     ; Save oserror code
184         lda     tmp1            ; Restore fd
185         jsr     closedirect
186         pla                     ; Restore oserror code
187         bne     oserr2          ; Branch always
188
189         ; Store fd
190 done:   lda     tmp1            ; Restore fd
191         sta     fdtab + FD::REF_NUM,y
192
193         ; Convert fdtab slot to handle
194         .assert .sizeof(FD) = 4, error
195         tya
196         lsr
197         lsr
198
199         ; Cleanup name
200         jsr     popname         ; Preserves A
201
202         ; Return success
203         ldx     #$00
204         rts
205
206 freebuffer:
207         ; Free I/O buffer
208         lda     #$00
209         ldx     fdtab + FD::BUFFER+1,y
210         jmp     _free
211
212 closeallfiles:
213         ; All open files
214         lda     #$00
215
216 closedirect:
217         ; Set fd
218         sta     mliparam + MLI::CLOSE::REF_NUM
219
220         ; Call close
221         lda     #CLOSE_CALL
222         ldx     #CLOSE_COUNT
223         jmp     callmli
224
225         .rodata
226
227 CREATE: .byte   %11000011       ; ACCESS:       Standard full access
228         .byte   $06             ; FILE_TYPE:    Standard binary file
229         .word   $0000           ; AUX_TYPE:     Load address N/A
230         .byte   $01             ; STORAGE_TYPE: Standard seedling file
231         .word   $0000           ; CREATE_DATE:  Current date
232         .word   $0000           ; CREATE_TIME:  Current time