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

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

index c77b59e04258e338c8c70cd444b71605aa2c6a4c..63075a2538ad89d5acae6723a7f69f383b50b944 100644 (file)
@@ -13,7 +13,6 @@ fgetpos.s
 fgets.s
 fputc.s
 fputs.s
-fread.s
 freopen.s
 fseek.s
 fsetpos.s
index a4548f163fe69dd931c271b6dd742a6dd46bed3d..672d05114f0625f3e97598d95f53dafb49037947 100644 (file)
@@ -25,7 +25,6 @@ C_OBJS =      _afailed.o      \
                fgets.o         \
                fputc.o         \
                fputs.o         \
-               fread.o         \
                freopen.o       \
                fseek.o         \
                fsetpos.o       \
@@ -72,6 +71,7 @@ S_OBJS =      _fdesc.o        \
                fmisc.o         \
                fopen.o         \
                fprintf.o       \
+               fread.o         \
                free.o          \
                fwrite.o        \
                getcpu.o        \
diff --git a/libsrc/common/fread.c b/libsrc/common/fread.c
deleted file mode 100644 (file)
index d0d3df3..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * fread.c
- *
- * Ullrich von Bassewitz, 02.06.1998
- */
-
-
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "_file.h"
-
-
-
-size_t fread (void* buf, size_t size, size_t count, FILE* f)
-{
-    int bytes;
-
-    /* Is the file open? */
-    if ((f->f_flags & _FOPEN) == 0) {
-               _errno = EINVAL;                /* File not open */
-       return 0;
-    }
-
-    /* Did we have an error or EOF? */
-    if ((f->f_flags & (_FERROR | _FEOF)) != 0) {
-               /* Cannot read from stream */
-               return 0;
-    }
-
-    /* How many bytes to read? */
-    bytes = size * count;
-
-    if (bytes) {
-
-       /* Read the data. */
-       bytes = read (f->f_fd, buf, bytes);
-
-        switch (bytes) {
-
-            case -1:
-                /* Read error */
-                f->f_flags |= _FERROR;
-                return 0;
-
-            case 0:
-                /* End of file */
-                f->f_flags |= _FEOF;
-                /* FALLTHROUGH */
-
-            default:
-                /* Unfortunately, we cannot avoid the divide here... */
-                return bytes / size;
-        }
-
-    } else {
-
-       /* 0 bytes read */
-       return count;
-
-    }
-}
-
-
-
diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s
new file mode 100644 (file)
index 0000000..bcad7f9
--- /dev/null
@@ -0,0 +1,142 @@
+;
+; Ullrich von Bassewitz, 22.11.2002
+;
+; size_t __fastcall__ fread (void* buf, size_t size, size_t count, FILE* f);
+; /* Read from a file */
+;
+
+        .export         _fread
+
+        .import         _read
+        .import         pushax, incsp6, addysp, ldaxysp, pushwysp, return0
+        .import         tosumulax, tosudivax
+
+        .importzp       ptr1, tmp1
+
+        .include        "errno.inc"
+        .include        "_file.inc"
+
+
+; ------------------------------------------------------------------------
+; Code
+
+.proc   _fread
+
+; Save f and place it into ptr1
+
+       sta     f
+       sta     ptr1
+       stx     f+1
+       stx     ptr1+1
+
+; Check if the file is open
+
+       ldy     #_FILE_f_flags
+       lda     (ptr1),y
+       and     #_FOPEN                 ; Is the file open?
+               bne     @L2                     ; Branch if yes
+
+; File not open
+
+       lda     #EINVAL
+       sta     __errno
+       lda     #0
+       sta     __errno+1
+@L1:    jsr     incsp6
+        jmp     return0
+
+; Check if the stream is in an error state
+
+@L2:   lda     (ptr1),y                ; get f->f_flags again
+       and     #_FERROR
+       bne     @L1
+
+; Build the stackframe for read()
+
+        ldy     #_FILE_f_fd
+        lda     (ptr1),y
+        ldx     #$00
+        jsr     pushax                  ; f->f_fd
+
+        ldy     #9
+        jsr     pushwysp                ; buf
+
+; Stack is now: buf/size/count/f->fd/buf
+; Calculate the number of bytes to read: count * size
+
+        ldy     #7
+        jsr     pushwysp                ; count
+        ldy     #9
+        jsr     ldaxysp                 ; Get size
+        jsr     tosumulax               ; count * size -> a/x
+
+; Check if the number of bytes is zero. Don't call read in this case
+
+        cpx     #0
+        bne     @L3
+        cmp     #0
+        bne     @L3
+
+; The number of bytes to read is zero, just return count
+
+        ldy     #5
+        jsr     ldaxysp                 ; Get count
+        ldy     #10
+        jmp     addysp                  ; Drop params, return
+
+; Call read(). This will leave the original 3 params on the stack
+
+@L3:    jsr     pushax
+        jsr     _read
+
+; Check for errors in read
+
+        cpx     #$FF
+        bne     @L5
+        cmp     #$FF
+        bne     @L5
+
+; Error in read. Set the stream error flag and bail out. _oserror and/or
+; errno are already set by read().
+
+        lda     #_FERROR
+@L4:    sta     tmp1
+        lda     f
+        sta     ptr1
+        lda     f+1
+        sta     ptr1+1
+        ldy     #_FILE_f_flags
+        lda     (ptr1),y
+        ora     tmp1
+        sta     (ptr1),y
+        bne     @L1                     ; Return zero
+
+; Read was ok, check for end of file.
+
+@L5:    cmp     #0                      ; Zero bytes read?
+        bne     @L6
+        cpx     #0
+        bne     @L6
+
+; Zero bytes read. Set the EOF flag
+
+        lda     #_FEOF
+        bne     @L4                     ; Set flag and return zero
+
+; Return the number of items successfully read. Since we've checked for
+; bytes == 0 above, size cannot be zero here, so the division is safe.
+
+@L6:    jsr     pushax                  ; Push number of bytes read
+        ldy     #5
+        jsr     ldaxysp                 ; Get size
+        jsr     tosudivax               ; bytes / size -> a/x
+        jmp     incsp6                  ; Drop params, return
+
+.endproc
+
+; ------------------------------------------------------------------------
+; Data
+
+.bss
+f:     .res    2
+