]> 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 93519a6e83b58341eae03cf42394b832f2e6bde2..ea3ae543bb3213d49c4d38bb5fcacc74fac2872a 100644 (file)
@@ -1,22 +1,28 @@
 ;
-; Christian Groessler, May-2000
+; Christian Groessler, Jan-2003
 ;
 ; 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"
+       .include "fcntl.inc"
+       .include "errno.inc"
+       .include "fd.inc"
+
        .export _open
-       .import __do_oserror,__seterrno,incsp4
-       .import ldaxysp,addysp,subysp
-       .import _strupr,__oserror
-       .importzp tmp4,sp
+        .destructor     closeallfiles, 17
+
+       .import _close
+       .import clriocb
+       .import fddecusage,newfd
+       .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,59 +93,27 @@ 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
 
        ldy     tmp4
 
+       ;AX - points to filename
+       ;Y  - iocb to use, if open needed
        jsr     newfd           ; maybe we don't need to open and can reuse an iocb
-       bcc     noopen
+                               ; returns fd num to use in tmp2, all regs unchanged
+       bcs     doopen          ; C set: open needed
+       lda     #0              ; clears N flag
+       beq     finish
 
-       sta     ICBAL,y
+doopen:        sta     ICBAL,y
        txa
        sta     ICBAH,y
        ldx     tmp4
@@ -131,7 +123,7 @@ loop2:      lda     (ptr4),y
 
        ; clean up the stack
 
-       php
+finish:        php
        txa
        pha
        tya
@@ -151,13 +143,10 @@ loop2:    lda     (ptr4),y
        plp
 
        bpl     ok
+       jsr     fddecusage      ; decrement usage counter of fd as open failed
        jmp     __do_oserror
 
-ok:    txa
-       lsr     a
-       lsr     a
-       lsr     a
-       lsr     a
+ok:    lda     tmp2            ; get fd
        ldx     #0
        stx     __oserror
        rts
@@ -165,44 +154,18 @@ ok:       txa
 .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
-       dey
-       inx
-       bne     loop
+       sbc     #0
+       bpl     loop
        rts
 
 .endproc