From: cuz Date: Sat, 23 Nov 2002 23:05:00 +0000 (+0000) Subject: Rewrote fread in assembler X-Git-Tag: V2.12.0~2021 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=8070250984f7cbea0d389b3dc9d05d96371f628a;p=cc65 Rewrote fread in assembler git-svn-id: svn://svn.cc65.org/cc65/trunk@1616 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/common/.cvsignore b/libsrc/common/.cvsignore index c77b59e04..63075a253 100644 --- a/libsrc/common/.cvsignore +++ b/libsrc/common/.cvsignore @@ -13,7 +13,6 @@ fgetpos.s fgets.s fputc.s fputs.s -fread.s freopen.s fseek.s fsetpos.s diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index a4548f163..672d05114 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -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 index d0d3df3bc..000000000 --- a/libsrc/common/fread.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * fread.c - * - * Ullrich von Bassewitz, 02.06.1998 - */ - - - -#include -#include -#include -#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 index 000000000..bcad7f9b7 --- /dev/null +++ b/libsrc/common/fread.s @@ -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 +