]> git.sur5r.net Git - cc65/blobdiff - libsrc/cbm/open.s
no TGI_ERR_NO_MEM or TGI_ERR_NO_IOCB anymore: replaced by TGI_ERR_NO_RES
[cc65] / libsrc / cbm / open.s
index 5d8cb269be11ae8680b448fdf7dd436a67eebd60..8678d358281b877410f132c1698ceebbc7d1a801 100644 (file)
@@ -3,34 +3,68 @@
 ;
 ; 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).
+
 
         .export         _open
+        .destructor     closeallfiles, 17
 
+        .import         SETLFS, OPEN, CLOSE
         .import         addysp, popax
-        .import         scratch, fnparse, fncomplete, fnset
-        .import         getdiskerror
-        .import         __errno, __oserror
+        .import         scratch, fnparse, fnaddmode, fncomplete, fnset
+        .import         opencmdchannel, closecmdchannel, readdiskerror
+        .import         __oserror
         .import         fnunit
+        .import         _close
         .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.
+; closeallfiles: Close all open files.
+
+.proc   closeallfiles
+
+        ldx     #MAX_FDS-1
+loop:   lda     fdtab,x
+        beq     next            ; Skip unused entries
+
+; Close this file
+
+        txa
+        pha                     ; Save current value of X
+        ldx     #0
+        jsr     _close
+        pla
+        tax
+
+; Next file
+
+next:   dex
+        bpl     loop
+
+        rts
+
+.endproc
+
+;--------------------------------------------------------------------------
+; _open
 
 .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
+; 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
+       dey
+       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
 
@@ -50,26 +84,15 @@ parmok: jsr     popax           ; Get flags
         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.
+; Check the flags. We cannot have both, read and write flags set, and we cannot
+; open a file for writing without creating it.
 
         lda     tmp3
-        and     #O_CREAT
-        beq     invflags
+        and     #(O_RDWR | O_CREAT)
+        cmp     #O_RDONLY       ; Open for reading?
+        beq     doread          ; Yes: Branch
+        cmp     #(O_WRONLY | O_CREAT)   ; Open for writing?
+        bne     invflags        ; No: Invalid open mode
 
 ; If O_TRUNC is set, scratch the file, but ignore any errors
 
@@ -78,11 +101,16 @@ parmok: jsr     popax           ; Get flags
         beq     notrunc
         jsr     scratch
 
-; Complete the the file name
+; Complete the the file name. Check for append mode here.
 
 notrunc:
-        lda     #'w'
-        jsr     fncomplete
+        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
 
@@ -92,7 +120,7 @@ notrunc:
 ; Read bit is set. Add an 'r' to the name
 
 doread: lda     #'r'
-        jsr     fncomplete
+        jsr     fnaddmode       ; Add the mode to the name
         lda     #LFN_READ
 
 ; Common read/write code. Flags in A, handle in tmp2
@@ -110,26 +138,18 @@ common: sta     tmp3
         jsr     OPEN
         bcs     error
 
-; Read the error channel
+; Open the the drive command channel and read it
 
         ldx     fnunit
-        jsr     getdiskerror
-        cmp     #0
-        beq     isopen          ; Branch if no error
-
-; We had an error, close the file
-
-        pha
-        lda     tmp2
-        clc
-        adc     #LFN_OFFS
-        jsr     CLOSE
-        pla
-        bne     error           ; Branch always
+        jsr     opencmdchannel
+        bne     closeandexit
+        ldx     fnunit
+        jsr     readdiskerror
+        bne     closeandexit    ; Branch on error
 
 ; File is open. Mark it as open in the table
 
-isopen: ldx     tmp2
+        ldx     tmp2
         lda     tmp3
         sta     fdtab,x
         lda     fnunit
@@ -161,7 +181,18 @@ invflags:
         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