]> git.sur5r.net Git - cc65/blobdiff - libsrc/atari/open.s
no TGI_ERR_NO_MEM or TGI_ERR_NO_IOCB anymore: replaced by TGI_ERR_NO_RES
[cc65] / libsrc / atari / open.s
index 7904586f2b79b48e563d50231acb5895e3956813..ea3ae543bb3213d49c4d38bb5fcacc74fac2872a 100644 (file)
@@ -1,22 +1,28 @@
 ;
-; Christian Groessler, May-2000
+; Christian Groessler, Jan-2003
 ;
 ; int open(const char *name,int flags,...);
 ;
 
-UCASE_FILENAME = 1             ; comment it out if filename shouldn't be uppercased
-
        .include "atari.inc"
-       .include "../common/fmode.inc"
-       .include "../common/errno.inc"
+       .include "fcntl.inc"
+       .include "errno.inc"
+       .include "fd.inc"
+
        .export _open
+        .destructor     closeallfiles, 17
+
+       .import _close
+       .import clriocb
        .import fddecusage,newfd
-       .import __do_oserror,__seterrno,incsp4
-       .import ldaxysp,addysp,subysp
-       .import _strupr,__oserror
-       .importzp tmp4,tmp2,sp
+       .import findfreeiocb
+       .import __do_oserror,incsp4
+       .import ldaxysp,addysp
+       .import __oserror
+       .importzp tmp4,tmp2
 .ifdef UCASE_FILENAME
-       .importzp tmp3,ptr4
+       .importzp tmp3
+       .import ucase_fn
 .endif
 
 .proc  _open
@@ -33,7 +39,6 @@ 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
@@ -41,13 +46,32 @@ seterr:     jsr     __seterrno
        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
+       pha
+       and     #O_APPEND
+       beq     no_app
+       pla
+       and     #15
+       cmp     #O_RDONLY       ; DOS supports append with write-only only
+       beq     invret
+       cmp     #O_RDWR
+       beq     invret
+       lda     #OPNOT|APPEND
+       bne     set
+
+.ifndef        UCASE_FILENAME
+invret:        lda     #<EINVAL        ; file name is too long
+       ldx     #>EINVAL
+       jmp     seterr
+.endif
+
+no_app:        pla
+       and     #15
        cmp     #O_RDONLY
        bne     l1
        lda     #OPNIN
@@ -69,50 +93,13 @@ 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
+
+       jsr     ucase_fn
+       bcc     ucok1
+invret:        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
+ucok1:
 
 .endif ; defined UCASE_FILENAME
 
@@ -167,44 +154,18 @@ ok:       lda     tmp2            ; get fd
 .endproc
 
 
-; find a free iocb
-; no entry parameters
-; return ZF = 0/1 for not found/found
-;        index in X if found
-; all registers destroyed
+; closeallfiles: Close all files opened by the program.
 
-.proc  findfreeiocb
+.proc   closeallfiles
 
-       ldx     #0
-       ldy     #$FF
-loop:  tya
-       cmp     ICHID,x
-       beq     found
-       txa
+       lda     #MAX_FD_INDEX-1
+loop:  ldx     #0
+       pha
+       jsr     _close
+       pla
        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
-       inx
-       dey
-       bne     loop
+       sbc     #0
+       bpl     loop
        rts
 
 .endproc