1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 07:29:33 +00:00
cc65/libsrc/cbm/open.s
cuz 544ff5b900 Working on the CBM file functions
git-svn-id: svn://svn.cc65.org/cc65/trunk@1533 b7a2c559-68d2-44c3-8de9-860c34a00d81
2002-11-17 22:45:55 +00:00

172 lines
3.9 KiB
ArmAsm

;
; Ullrich von Bassewitz, 16.11.2002
;
; int open (const char* name, int flags, ...); /* May take a mode argument */
;
.export _open
.import addysp, popax
.import scratch, fnparse, fncomplete, fnset
.import opencmdchannel, closecmdchannel, readdiskerror
.import __errno, __oserror
.import fnunit
.importzp sp, tmp2, tmp3
.include "errno.inc"
.include "fcntl.inc"
.include "cbm.inc"
.include "filedes.inc"
;--------------------------------------------------------------------------
; initstdout: Open the stdout and stderr file descriptors for the screen.
.proc _open
cpy #4 ; correct # of arguments (bytes)?
beq parmok ; parameter count ok
tya ; parm count < 4 shouldn't be needed to be...
sec ; ...checked (it generates a c compiler warning)
sbc #4
tay
jsr addysp ; fix stack, throw away unused parameters
; Parameters ok. Pop the flags and save them into tmp3
parmok: jsr popax ; Get flags
sta tmp3
; Get the filename from stack and parse it. Bail out if is not ok
jsr popax ; Get name
jsr fnparse ; Parse it
cmp #0
bne error ; Bail out if problem with name
; Get a free file handle and remember it in tmp2
jsr freefd
bcs nofile
stx tmp2
; Check the flags. We cannot have:
;
; - both, read and write flags set
; - the append flag set
;
lda tmp3
and #O_RDWR
beq invflags ; Neither read nor write
cmp #O_RDWR
beq invflags ; Jump if both set
cmp #O_RDONLY
beq doread
; Write bit is set. We cannot open a file for writing without creating it,
; so check for the O_CREAT bit.
lda tmp3
and #O_CREAT
beq invflags
; If O_TRUNC is set, scratch the file, but ignore any errors
lda tmp3
and #O_TRUNC
beq notrunc
jsr scratch
; Complete the the file name
notrunc:
lda #'w'
jsr fncomplete
; Setup the real open flags
lda #LFN_WRITE
bne common
; Read bit is set. Add an 'r' to the name
doread: lda #'r'
jsr fncomplete
lda #LFN_READ
; Common read/write code. Flags in A, handle in tmp2
common: sta tmp3
jsr fnset ; Set the file name
lda tmp2
clc
adc #LFN_OFFS
ldx fnunit
tay ; Use the LFN also as SA
jsr SETLFS ; Set the file params
jsr OPEN
bcs error
; Open the the drive command channel and read it
ldx fnunit
jsr opencmdchannel
bne closeandexit
ldx fnunit
jsr readdiskerror
bne closeandexit ; Branch on error
; File is open. Mark it as open in the table
ldx tmp2
lda tmp3
sta fdtab,x
lda fnunit
sta unittab,x ; Remember
; Done. Return the handle in a/x
txa ; Handle
ldx #0
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