;
; Ullrich von Bassewitz, 16.11.2002
;
-; int open (const char* name, int flags, ...); /* May take a mode argument */
-;
-; 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).
+; int open (const char* name, int flags, ...); /* May take a mode argument */
.export _open
- .destructor closeallfiles, 17
+ .destructor closeallfiles, 5
- .import SETLFS, OPEN, CLOSE
.import addysp, popax
.import scratch, fnparse, fnaddmode, fncomplete, fnset
.import opencmdchannel, closecmdchannel, readdiskerror
- .import __oserror
- .import fnunit
+ .import fnunit, fnisfile
.import _close
.importzp sp, tmp2, tmp3
.include "errno.inc"
.include "fcntl.inc"
.include "filedes.inc"
+ .include "cbm.inc"
;--------------------------------------------------------------------------
; Throw away any additional parameters passed through the ellipsis
- dey ; Parm count < 4 shouldn't be needed to be...
- dey ; ...checked (it generates a c compiler warning)
+ dey ; Parm count < 4 shouldn't be needed to be...
+ dey ; ...checked (it generates a c compiler warning)
+ dey
dey
- dey
- beq parmok ; Branch if parameter count ok
- jsr addysp ; Fix stack, throw away unused parameters
+ beq parmok ; Branch if parameter count ok
+ jsr addysp ; Fix stack, throw away unused parameters
; Parameters ok. Pop the flags and save them into tmp3
jsr popax ; Get name
jsr fnparse ; Parse it
- cmp #0
- bne error ; Bail out if problem with name
+ tax
+ bne oserror ; Bail out if problem with name
; Get a free file handle and remember it in tmp2
jsr freefd
- bcs nofile
+ lda #EMFILE ; Load error code
+ bcs seterrno ; Jump in case of errors
stx tmp2
; Check the flags. We cannot have both, read and write flags set, and we cannot
cmp #O_RDONLY ; Open for reading?
beq doread ; Yes: Branch
cmp #(O_WRONLY | O_CREAT) ; Open for writing?
- bne invflags ; No: Invalid open mode
+ beq dowrite
+
+; Invalid open mode
+
+ lda #EINVAL
+
+; Error entry. Sets _errno, clears _oserror, returns -1
+
+seterrno:
+ jmp __directerrno
+
+; Error entry: Close the file and exit. OS error code is in A on entry
+
+closeandexit:
+ pha
+ lda tmp2
+ clc
+ adc #LFN_OFFS
+ jsr CLOSE
+ ldx fnunit
+ jsr closecmdchannel
+ pla
+
+; Error entry: Set oserror and errno using error code in A and return -1
+
+oserror:jmp __mappederrno
+
+; Read bit is set. Add an 'r' to the name
+
+doread: lda #'r'
+ jsr fnaddmode ; Add the mode to the name
+ lda #LFN_READ
+ bne common ; Branch always
; If O_TRUNC is set, scratch the file, but ignore any errors
+dowrite:
lda tmp3
and #O_TRUNC
beq notrunc
notrunc:
lda tmp3 ; Get the mode again
- ldx #'a'
and #O_APPEND ; Append mode?
bne append ; Branch if yes
- ldx #'w'
-append: txa
- jsr fncomplete ; Add type and mode to the name
-; Setup the real open flags
+; Setup the name for create mode
- lda #LFN_WRITE
- bne common
+ lda #'w'
+ jsr fncomplete ; Add type and mode to the name
+ jmp appendcreate
-; Read bit is set. Add an 'r' to the name
+; Append bit is set. Add an 'a' to the name
-doread: lda #'r'
- jsr fnaddmode ; Add the mode to the name
- lda #LFN_READ
+append: lda #'a'
+ jsr fnaddmode ; Add open mode to file name
+appendcreate:
+ lda #LFN_WRITE
; Common read/write code. Flags in A, handle in tmp2
clc
adc #LFN_OFFS
ldx fnunit
- tay ; Use the LFN also as SA
+ ldy fnisfile ; Is this a standard file on disk?
+ beq nofile ; Branch if not
+ tay ; Use the LFN also as SA for files
+nofile: ; ... else use SA=0 (read)
jsr SETLFS ; Set the file params
jsr OPEN
- bcs error
+ bcs oserror
; Open the the drive command channel and read it
txa ; Handle
ldx #0
+ stx __oserror ; Clear _oserror
rts
-; Error entry: No more file handles
-
-nofile: lda #1 ; Too many open files
-
-; Error entry. Error code is in A.
-
-error: sta __oserror
-errout: lda #$FF
- tax ; Return -1
- rts
-
-; Error entry: Invalid flag parameter
-
-invflags:
- lda #EINVAL
- sta __errno
- lda #0
- sta __errno+1
- beq errout
-
-; Error entry: Close the file and exit
-
-closeandexit:
- pha
- lda tmp2
- clc
- adc #LFN_OFFS
- jsr CLOSE
- ldx fnunit
- jsr closecmdchannel
- pla
- bne error ; Branch always
-
.endproc
+