]> git.sur5r.net Git - cc65/commitdiff
Rewrote _fopen in assembler
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 23 Nov 2002 17:52:38 +0000 (17:52 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 23 Nov 2002 17:52:38 +0000 (17:52 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1607 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/common/.cvsignore
libsrc/common/Makefile
libsrc/common/_file.h
libsrc/common/_fopen.c [deleted file]
libsrc/common/_fopen.s [new file with mode: 0644]

index 0939e9b105c619cb64e831eeda4abf25dce9f792..46556ea50ec8139fbc30240d37351c3eae2bc012 100644 (file)
@@ -1,6 +1,5 @@
 *.lst
 _afailed.s
-_fopen.s
 _hextab.s
 _scanf.s
 abort.s
index a6daff361b76d5031a07be581a2c080f3e8469a3..94129707b9b1b89b4bacff2cb7c6dd326855ad9a 100644 (file)
@@ -12,7 +12,6 @@
        @$(AS) -g -o $@ $(AFLAGS) $<
 
 C_OBJS =       _afailed.o      \
-               _fopen.o        \
                _hextab.o       \
                _scanf.o        \
                abort.o         \
@@ -56,6 +55,7 @@ C_OBJS =      _afailed.o      \
 
 S_OBJS =       _fdesc.o        \
                _file.o         \
+               _fopen.o        \
                _hadd.o         \
                _heap.o         \
                _oserror.o      \
index e8ba411a31f07af210da9221cadb50da0f882173..f1f9af306bc6a709770a48441acba8809782db84 100644 (file)
@@ -34,7 +34,7 @@ extern FILE _filetab [FOPEN_MAX];
 
 
 
-FILE* _fopen (const char* name, const char* mode, FILE* f);
+FILE* __fastcall__ _fopen (const char* name, const char* mode, FILE* f);
 /* Open the specified file and fill the descriptor values into f */
 
 FILE* _fdesc (void);
diff --git a/libsrc/common/_fopen.c b/libsrc/common/_fopen.c
deleted file mode 100644 (file)
index ce6a718..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * _fopen.c
- *
- * Ullrich von bassewitz, 17.06.1997
- */
-
-
-
-#include <fcntl.h>
-#include <errno.h>
-#include "_file.h"
-
-
-
-static unsigned char amode_to_bmode (const char* mode)
-/* Convert ASCII mode (like for fopen) to binary mode (for open) */
-{
-    unsigned char binmode;
-
-    switch (*mode++) {
-        case 'w':
-            binmode = O_WRONLY | O_CREAT | O_TRUNC;
-            break;
-        case 'r':
-            binmode = O_RDONLY;
-            break;
-        case 'a':
-            binmode = O_WRONLY | O_CREAT | O_APPEND;
-            break;
-       default:
-            return 0;  /* invalid char */
-    }
-
-    while (1) {
-        switch (*mode++) {
-            case '+':
-                /* always to r/w in addition to anything already set */
-                binmode |= O_RDWR;
-                break;
-            case 'b':
-                /* currently ignored */
-                break;
-            case '\0':
-                /* end of mode string reached */
-                return binmode;
-            default:
-                /* invalid char in mode string */
-                return 0;
-        }
-    }
-}
-
-
-
-FILE* _fopen (const char* name, const char* mode, FILE* f)
-/* Open the specified file and fill the descriptor values into f */
-{
-    int          fd;
-    unsigned char binmode;
-
-
-    /* Convert ASCII mode to binary mode */
-    if ((binmode = amode_to_bmode (mode)) == 0) {
-       /* Invalid mode */
-       _errno = EINVAL;
-        return 0;
-    }
-
-    /* Open the file */
-    fd = open (name, binmode);
-    if (fd == -1) {
-               /* Error - _oserror is set */
-               return 0;
-    }
-
-    /* Remember fd, mark the file as opened */
-    f->f_fd    = fd;
-    f->f_flags = _FOPEN;
-
-    /* Return the file descriptor */
-    return f;
-}
-
-
-
diff --git a/libsrc/common/_fopen.s b/libsrc/common/_fopen.s
new file mode 100644 (file)
index 0000000..abf67dd
--- /dev/null
@@ -0,0 +1,124 @@
+;
+; Ullrich von Bassewitz, 22.11.2002
+;
+; FILE* __fastcall__ _fopen (const char* name, const char* mode, FILE* f);
+; /* Open the specified file and fill the descriptor values into f */
+;
+
+        .export         __fopen
+
+        .import         _open
+        .import         pushax, incsp4, return0
+        .importzp       sp, ptr1
+
+
+        .include        "errno.inc"
+        .include        "fcntl.inc"
+        .include        "_file.inc"
+
+
+; ------------------------------------------------------------------------
+; Code
+
+.proc   __fopen
+
+        sta     f
+        stx     f+1             ; Save f
+
+; Get a pointer to the mode string
+
+        ldy     #1
+        lda     (sp),y
+        sta     ptr1+1
+        dey
+        lda     (sp),y
+        sta     ptr1
+
+; Look at the first character in mode
+
+        ldx     #$00            ; Mode will be in X
+        lda     (ptr1),y        ; Get first char from mode
+        cmp     #'w'
+        bne     @L1
+        ldx     #(O_WRONLY | O_CREAT | O_TRUNC)
+        bne     @L3
+@L1:    cmp     #'r'
+        bne     @L2
+        ldx     #O_RDONLY
+        bne     @L3
+@L2:    cmp     #'a'
+        bne     invmode
+        ldx     #(O_WRONLY | O_CREAT | O_APPEND)
+
+; Look at more chars from the mode string
+
+@L3:    iny                     ; Next char
+        beq     invmode
+        lda     (ptr1),y
+        beq     modeok          ; End of mode string reached
+        cmp     #'+'
+        bne     @L4
+        txa
+        ora     #O_RDWR         ; Always do r/w in addition to anything else
+        tax
+        bne     @L3
+@L4:    cmp     #'b'
+        beq     @L3             ; Binary mode is ignored
+
+; Invalid mode
+
+invmode:
+        lda     #EINVAL
+        sta     __errno
+        lda     #0
+        sta     __errno+1
+        tax
+        jmp     incsp4
+
+; Mode string successfully parsed. Store the binary mode onto the stack in
+; the same place where the mode string pointer was before. The call open()
+
+modeok: ldy     #$00
+        txa                     ; Mode -> A
+        sta     (sp),y
+        tya
+        iny
+        sta     (sp),y
+        ldy     #4              ; Size of arguments in bytes
+        jsr     _open           ; Will cleanup the stack
+
+; Check the result of the open() call
+
+        cpx     #$FF
+        bne     openok
+        cmp     #$FF
+        bne     openok
+        jmp     return0         ; Failure, errno/_oserror already set
+
+; Open call succeeded
+
+openok: ldy     f
+        sty     ptr1
+        ldy     f+1
+        sty     ptr1+1
+        ldy     #_FILE_f_fd
+        sta     (ptr1),y        ; f->f_fd = fd;
+        ldy     #_FILE_f_flags
+        lda     #_FOPEN
+        sta     (ptr1),y        ; f->f_flags = _FOPEN;
+
+; Return the pointer to the file structure
+
+        lda     ptr1
+        ldx     ptr1+1
+        rts
+
+.endproc
+
+; ------------------------------------------------------------------------
+; Data
+
+.bss
+f:      .res    2
+
+