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
|