This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches. git-svn-id: svn://svn.cc65.org/cc65/trunk@3 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
208
libsrc/atari/open.s
Normal file
208
libsrc/atari/open.s
Normal file
@@ -0,0 +1,208 @@
|
||||
;
|
||||
; Christian Groessler, May-2000
|
||||
;
|
||||
; int open(const char *name,int flags,...);
|
||||
; returns fd
|
||||
;
|
||||
|
||||
UCASE_FILENAME = 1 ; comment it out if filename shouldn't be uppercased
|
||||
|
||||
.include "atari.inc"
|
||||
.include "../common/fmode.inc"
|
||||
.include "../common/errno.inc"
|
||||
.export _open
|
||||
.import __do_oserror,__seterrno,incsp4
|
||||
.import ldaxysp,addysp,subysp
|
||||
.import _strupr,__oserror
|
||||
.importzp tmp4,sp
|
||||
.ifdef UCASE_FILENAME
|
||||
.importzp tmp3,ptr4
|
||||
.endif
|
||||
|
||||
.proc _open
|
||||
|
||||
cpy #4 ; correct # of arguments (bytes)?
|
||||
beq parmok ; parameter count ok
|
||||
tya ; parm count < 4 shouldn't be needed to be checked
|
||||
sec ; (it generates a c compiler warning)
|
||||
sbc #4
|
||||
tay
|
||||
jsr addysp ; fix stack, throw away unused parameters
|
||||
|
||||
parmok: jsr findfreeiocb
|
||||
beq iocbok ; we found one
|
||||
|
||||
lda #<EMFILE ; "too many open files"
|
||||
ldx #>EMFILE
|
||||
seterr: jsr __seterrno
|
||||
jsr incsp4 ; clean up stack
|
||||
lda #$FF
|
||||
tax
|
||||
rts ; return -1
|
||||
|
||||
; process the mode argument
|
||||
; @@@TODO: append not handled yet!
|
||||
|
||||
iocbok: stx tmp4
|
||||
jsr clriocb ; init with zero
|
||||
ldy #1
|
||||
jsr ldaxysp ; get mode
|
||||
ldx tmp4
|
||||
cmp #O_RDONLY
|
||||
bne l1
|
||||
lda #OPNIN
|
||||
set: sta ICAX1,x
|
||||
bne cont
|
||||
|
||||
l1: cmp #O_WRONLY
|
||||
bne l2
|
||||
lda #OPNOT
|
||||
bne set
|
||||
|
||||
l2: ; O_RDWR
|
||||
lda #OPNOT|OPNIN
|
||||
bne set
|
||||
|
||||
; process the filename argument
|
||||
|
||||
cont: ldy #3
|
||||
jsr ldaxysp
|
||||
|
||||
.ifdef UCASE_FILENAME
|
||||
; we make sure that the filename doesn't contain lowercase letters
|
||||
; we copy the filename we got onto the stack, uppercase it and use this
|
||||
; one to open the iocb
|
||||
; we're using tmp3, ptr4
|
||||
|
||||
; save the original pointer
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
|
||||
; now we need the length of the name
|
||||
ldy #0
|
||||
loop: lda (ptr4),y
|
||||
beq str_end
|
||||
cmp #ATEOL ; we also accept Atari EOF char as end of string
|
||||
beq str_end
|
||||
iny
|
||||
bne loop ; not longer than 255 chars (127 real limit)
|
||||
toolong:lda #<EINVAL ; file name is too long
|
||||
ldx #>EINVAL
|
||||
jmp seterr
|
||||
|
||||
str_end:iny ; room for terminating zero
|
||||
cpy #128 ; we only can handle lenght < 128
|
||||
bcs toolong
|
||||
sty tmp3 ; save size
|
||||
jsr subysp ; make room on the stack
|
||||
|
||||
; copy filename to the temp. place on the stack
|
||||
lda #0 ; end-of-string
|
||||
sta (sp),y ; Y still contains length + 1
|
||||
dey
|
||||
loop2: lda (ptr4),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl loop2 ; bpl: this way we only support a max. length of 127
|
||||
|
||||
; uppercase the temp. filename
|
||||
ldx sp+1
|
||||
lda sp
|
||||
jsr _strupr
|
||||
|
||||
; leave X and Y pointing to the modified filename
|
||||
lda sp
|
||||
ldx sp+1
|
||||
|
||||
.endif ; defined UCASE_FILENAME
|
||||
|
||||
ldy tmp4
|
||||
|
||||
jsr newfd ; maybe we don't need to open and can reuse an iocb
|
||||
bcc noopen
|
||||
|
||||
sta ICBAL,y
|
||||
txa
|
||||
sta ICBAH,y
|
||||
ldx tmp4
|
||||
lda #OPEN
|
||||
sta ICCOM,x
|
||||
jsr CIOV
|
||||
|
||||
; clean up the stack
|
||||
|
||||
php
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
.ifdef UCASE_FILENAME
|
||||
ldy tmp3 ; get size
|
||||
jsr addysp ; free used space on the stack
|
||||
.endif ; defined UCASE_FILENAME
|
||||
|
||||
jsr incsp4 ; clean up stack
|
||||
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
plp
|
||||
|
||||
bpl ok
|
||||
jmp __do_oserror
|
||||
|
||||
ok: txa
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
ldx #0
|
||||
stx __oserror
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
; find a free iocb
|
||||
; no entry parameters
|
||||
; return ZF = 0/1 for not found/found
|
||||
; index in X if found
|
||||
; all registers destroyed
|
||||
|
||||
.proc findfreeiocb
|
||||
|
||||
ldx #0
|
||||
ldy #$FF
|
||||
loop: tya
|
||||
cmp ICHID,x
|
||||
beq found
|
||||
txa
|
||||
clc
|
||||
adc #$10
|
||||
tax
|
||||
cmp #$80
|
||||
bcc loop
|
||||
inx ; return ZF cleared
|
||||
found: rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
; clear iocb except for ICHID field
|
||||
; expects X to be index to IOCB (0,$10,$20,etc.)
|
||||
; all registers destroyed
|
||||
|
||||
.proc clriocb
|
||||
|
||||
inx ; don't clear ICHID
|
||||
ldy #15
|
||||
lda #0
|
||||
loop: sta ICHID,x
|
||||
dey
|
||||
inx
|
||||
bne loop
|
||||
rts
|
||||
|
||||
.endproc
|
||||
Reference in New Issue
Block a user