From 79396d8acdba71d9d5e2ce52a906cb19faa67775 Mon Sep 17 00:00:00 2001 From: cuz Date: Sat, 23 Nov 2002 22:51:25 +0000 Subject: [PATCH] Rewrote fwrite in assembler git-svn-id: svn://svn.cc65.org/cc65/trunk@1614 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/common/.cvsignore | 1 - libsrc/common/Makefile | 2 +- libsrc/common/fwrite.c | 51 ---------------- libsrc/common/fwrite.s | 129 +++++++++++++++++++++++++++++++++++++++ libsrc/common/vfprintf.s | 3 +- 5 files changed, 131 insertions(+), 55 deletions(-) delete mode 100644 libsrc/common/fwrite.c create mode 100644 libsrc/common/fwrite.s diff --git a/libsrc/common/.cvsignore b/libsrc/common/.cvsignore index 3f648ea4f..c77b59e04 100644 --- a/libsrc/common/.cvsignore +++ b/libsrc/common/.cvsignore @@ -18,7 +18,6 @@ freopen.s fseek.s fsetpos.s ftell.s -fwrite.s getchar.s gets.s gmtime.s diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index ba1d3b697..a4548f163 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -30,7 +30,6 @@ C_OBJS = _afailed.o \ fseek.o \ fsetpos.o \ ftell.o \ - fwrite.o \ getchar.o \ gets.o \ gmtime.o \ @@ -74,6 +73,7 @@ S_OBJS = _fdesc.o \ fopen.o \ fprintf.o \ free.o \ + fwrite.o \ getcpu.o \ isalnum.o \ isalpha.o \ diff --git a/libsrc/common/fwrite.c b/libsrc/common/fwrite.c deleted file mode 100644 index a363ad362..000000000 --- a/libsrc/common/fwrite.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * fwrite.c - * - * Ullrich von Bassewitz, 04.06.1998 - */ - - - -#include -#include -#include -#include "_file.h" - - - -size_t fwrite (const 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 */ - if ((f->f_flags & _FERROR) != 0) { - /* Cannot write to stream */ - return 0; - } - - /* How many bytes to write? */ - bytes = size * count; - - if (bytes) { - /* Write the data. */ - if (write (f->f_fd, buf, bytes) == -1) { - /* Write error */ - f->f_flags |= _FERROR; - return 0; - } - } - - /* Don't waste time with expensive calculations, assume the write was - * complete and return the count of items. - */ - return count; -} - - - diff --git a/libsrc/common/fwrite.s b/libsrc/common/fwrite.s new file mode 100644 index 000000000..845792c77 --- /dev/null +++ b/libsrc/common/fwrite.s @@ -0,0 +1,129 @@ +; +; Ullrich von Bassewitz, 22.11.2002 +; +; size_t __fastcall__ fwrite (const void* buf, size_t size, size_t count, FILE* f); +; /* Write to a file */ +; + + .export _fwrite + + .import _write + .import pushax, incsp6, addysp, ldaxysp, pushwysp, return0 + .import tosumulax, tosudivax + + .importzp ptr1 + + .include "errno.inc" + .include "_file.inc" + + +; ------------------------------------------------------------------------ +; Code + +.proc _fwrite + +; 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 write() + + 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 write: 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 write in this case + + cpx #0 + bne @L3 + cmp #0 + bne @L3 + +; The number of bytes to write is zero, just return count + + ldy #5 + jsr ldaxysp ; Get count + ldy #10 + jmp addysp ; Drop params, return + +; Call write(). This will leave the original 3 params on the stack + +@L3: jsr pushax + jsr _write + +; Check for errors in write + + cpx #$FF + bne @L4 + cmp #$FF + bne @L4 + +; Error in write. Set the stream error flag and bail out. _oserror and/or +; errno are already set by write(). + + lda f + sta ptr1 + lda f+1 + sta ptr1+1 + ldy #_FILE_f_fd + lda (ptr1),y + ora #_FERROR + sta (ptr1),y + bne @L1 ; Return zero + +; Write was ok. Return the number of items successfully written. Since we've +; checked for bytes == 0 above, size cannot be zero here, so the division is +; safe. + +@L4: jsr pushax ; Push number of bytes written + ldy #5 + jsr ldaxysp ; Get size + jsr tosudivax ; bytes / size -> a/x + jmp incsp6 ; Drop params, return + +.endproc + +; ------------------------------------------------------------------------ +; Data + +.bss +f: .res 2 + diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s index ecab1bd90..0a7f3f7ec 100644 --- a/libsrc/common/vfprintf.s +++ b/libsrc/common/vfprintf.s @@ -61,8 +61,7 @@ out: lda (ptr1),y tax dey - lda (ptr1),y - jsr pushax ; Push D->ptr + lda (ptr1),y ; Load D->ptr jsr _fwrite sta ptr2 ; Save function result stx ptr2+1 -- 2.39.5