;
; int open (const char* name, int flags, ...);
;
-; Be sure to keep the value priority of closeallfiles lower than that of
-; closeallstreams (which is the high level C file I/O counterpart and must be
-; called before closeallfiles).
- .export _open, closedirect, freebuffer
- .export __filetype, __auxtype
- .destructor closeallfiles, 17
+ .export _open, closedirect, freebuffer
+ .export __filetype, __auxtype, __datetime
+ .constructor raisefilelevel
+ .destructor closeallfiles, 5
- .import pushname, popname
- .import iobuf_alloc, iobuf_free
- .import addysp, incsp4, incaxy, pushax, popax
+ .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"
+ .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
dey
dey
dey
- jsr addysp
+ jsr addysp
; Start with first fdtab slot
- ldy #$00
+ ldy #$00
; Check for free fdtab slot
-: lda fdtab + FD::REF_NUM,y
- beq found
+: lda fdtab + FD::REF_NUM,y
+ beq found
; Advance to next fdtab slot
.assert .sizeof(FD) = 4, error
iny
; Check for end of fdtab
- cpy #MAX_FDS * .sizeof(FD)
- bcc :-
+ cpy #MAX_FDS * .sizeof(FD)
+ bcc :-
; Load errno code
- lda #EMFILE
+ lda #EMFILE
; Cleanup stack
-errno: jsr incsp4 ; Preserves A
+errno: jsr incsp4 ; Preserves A
; Set __errno
- jmp __directerrno
+ 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
+ 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
+ sta tmp2 ; Save fdtab slot
; Check for error
- tya ; Restore errno code
- bne errno
+ tya ; Restore errno code
+ bne errno
; Get and save flags
- jsr popax
- sta tmp3
+ jsr popax
+ sta tmp3
; Get and push name
- jsr popax
- jsr pushname
- bne oserr1
+ 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
+ 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
+ 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
+ ldx #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
+: lda CREATE,x
+ sta mliparam + MLI::CREATE::ACCESS,x
dex
- bpl :-
+ bpl :-
; Create file
- lda #CREATE_CALL
- ldx #CREATE_COUNT
- jsr callmli
- bcc open
+ lda #CREATE_CALL
+ ldx #CREATE_COUNT
+ jsr callmli
+ bcc open
; Check for ordinary errors
- cmp #$47 ; "Duplicate filename"
- bne oserr2
+ cmp #$47 ; "Duplicate filename"
+ bne oserr2
; Check for exclusive flag
- lda tmp3 ; Restore flags
- and #O_EXCL
- beq open
+ lda tmp3 ; Restore flags
+ and #O_EXCL
+ beq open
- lda #$47 ; "Duplicate filename"
+ lda #$47 ; "Duplicate filename"
; Cleanup name
-oserr2: jsr popname ; Preserves A
+oserr2: jsr popname ; Preserves A
-oserr1: ldy tmp2 ; Restore fdtab slot
+oserr1: ldy tmp2 ; Restore fdtab slot
; Cleanup I/O buffer
- pha ; Save oserror code
- jsr freebuffer
- pla ; Restore oserror code
+ pha ; Save oserror code
+ jsr freebuffer
+ pla ; Restore oserror code
; Set __oserror
- jmp __mappederrno
+ jmp __mappederrno
-open: ldy tmp2 ; Restore fdtab slot
+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
+ 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
+ lda #OPEN_CALL
+ ldx #OPEN_COUNT
+ jsr callmli
+ bcs oserr2
; Get and save fd
- ldx mliparam + MLI::OPEN::REF_NUM
- stx tmp1 ; 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
+ 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
+ stx mliparam + MLI::EOF::REF_NUM
+ ldx #$02
+ lda #$00
+: sta mliparam + MLI::EOF::EOF,x
dex
- bpl :-
+ bpl :-
; Set file size
- lda #SET_EOF_CALL
- ldx #EOF_COUNT
- jsr callmli
- bcc done
+ 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
+ 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
+done: lda tmp1 ; Restore fd
+ sta fdtab + FD::REF_NUM,y
; Convert fdtab slot to handle
.assert .sizeof(FD) = 4, error
lsr
; Cleanup name
- jsr popname ; Preserves A
+ jsr popname ; Preserves A
; Return success
- ldx #$00
- stx __oserror
+ ldx #$00
+ stx __oserror
rts
freebuffer:
; Free I/O buffer
- lda #$00
- ldx fdtab + FD::BUFFER+1,y
- jmp iobuf_free
-
-closeallfiles:
- ; All open files
- lda #$00
+ lda #$00
+ ldx fdtab + FD::BUFFER+1,y
+ jmp iobuf_free
closedirect:
; Set fd
- sta mliparam + MLI::CLOSE::REF_NUM
+ sta mliparam + MLI::CLOSE::REF_NUM
; Call close
- lda #CLOSE_CALL
- ldx #CLOSE_COUNT
- jmp callmli
+ 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
+CREATE: .byte %11000011 ; ACCESS: Standard full access
__filetype:
- .byte $06 ; FILE_TYPE: Standard binary file
+ .byte $06 ; FILE_TYPE: Standard binary file
__auxtype:
- .word $0000 ; AUX_TYPE: Load address N/A
- .byte $01 ; STORAGE_TYPE: Standard seedling file
- .word $0000 ; CREATE_DATE: Current date
- .word $0000 ; CREATE_TIME: Current time
+ .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