]> git.sur5r.net Git - cc65/commitdiff
Rewrote vfprintf() in assembler
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 1 Dec 2000 15:05:46 +0000 (15:05 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 1 Dec 2000 15:05:46 +0000 (15:05 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@511 b7a2c559-68d2-44c3-8de9-860c34a00d81

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

index 5496152500d80ac731446a9d3630fed28562b18c..a106748185cac89fde7b316616ae07c678148b3c 100644 (file)
@@ -35,6 +35,5 @@ sprintf.s
 strtok.s
 strxfrm.s
 vcprintf.s
-vfprintf.s
 vprintf.s
 vsprintf.s
index 1d06712db01f28ec56cd18a4a57eab83bf8a8d1b..2f45a2ac43cd5cd97245f3ca51bb13186d98592a 100644 (file)
@@ -13,7 +13,7 @@
 
 C_OBJS = fclose.o fgets.o fprintf.o calloc.o _fopen.o\
         fputs.o fread.o fwrite.o gets.o realloc.o bsearch.o strxfrm.o\
-        _hextab.o vfprintf.o fdopen.o strtok.o\
+        _hextab.o fdopen.o strtok.o\
         _afailed.o fopen.o fgetc.o fputc.o puts.o gets.o perror.o getchar.o\
         vprintf.o vsprintf.o sprintf.o abort.o qsort.o putchar.o\
         errormsg.o cprintf.o vcprintf.o freopen.o locale.o fsetpos.o\
@@ -83,6 +83,7 @@ S_OBJS =      _fdesc.o        \
                strupper.o      \
                tolower.o       \
                toupper.o       \
+               vfprintf.o      \
                zerobss.o
 
 
index 3f95f8e6b067008c01774705669dede275f995b1..b164e887ddd674b40e3d21d1f014af244271bf1c 100644 (file)
@@ -60,11 +60,10 @@ _printf:
        lda     (ptr1),y
        jsr     pushax
 
-; Push va_list (last parameter to vfprintf)
+; Load va_list (last and __fastcall__ parameter to vfprintf)
 
        lda     ptr1
        ldx     ptr1+1
-       jsr     pushax
 
 ; Call vfprintf
 
diff --git a/libsrc/common/vfprintf.c b/libsrc/common/vfprintf.c
deleted file mode 100644 (file)
index 17596b5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * vfprintf.c
- *
- * Ullrich von Bassewitz, 11.08.1998
- */
-
-
-
-#include <stdarg.h>
-#include <stdio.h>
-#include "_printf.h"
-
-
-
-static void out (struct outdesc* d, const char* buf, unsigned count)
-/* Routine used for writing */
-{
-    /* Write to the file */
-    if (fwrite (buf, count, 1, (FILE*) d->ptr) == -1) {
-       d->ccount = -1;
-    } else {
-       d->ccount += count;
-    }
-}
-
-
-
-int vfprintf (FILE* f, const char* format, va_list ap)
-{
-    struct outdesc d;
-
-    /* Setup descriptor */
-    d.fout = out;
-    d.ptr  = f;
-
-    /* Do formatting and output */
-    _printf (&d, format, ap);
-
-    /* Return bytes written */
-    return d.ccount;
-}
-
-
-
-
diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s
new file mode 100644 (file)
index 0000000..a445c5b
--- /dev/null
@@ -0,0 +1,158 @@
+;
+; int vprintf (FILE* f, const char* Format, va_list ap);
+;
+; Ullrich von Bassewitz, 1.12.2000
+;
+
+       .export         _vfprintf
+       .import         pushax, popax, push1
+       .import         _fwrite, __printf
+       .importzp       sp, ptr1, ptr2
+
+       .macpack        generic
+
+
+.data
+
+; ----------------------------------------------------------------------------
+;
+; Static data for the _vfprintf routine
+;
+
+outdesc:                       ; Static outdesc structure
+       .word   0               ; ccount
+       .word   out             ; Output function pointer
+       .word   0               ; ptr
+       .word   0               ; uns
+
+.code
+
+; ----------------------------------------------------------------------------
+; Callback routine used for the actual output.
+;
+; static void out (struct outdesc* d, const char* buf, unsigned count)
+; /* Routine used for writing */
+; {
+;     /* Write to the file */
+;     if (fwrite (buf, count, 1, (FILE*) d->ptr) == -1) {
+;         d->ccount = -1;
+;     } else {
+;         d->ccount += count;
+;     }
+; }
+
+out:
+
+; About to call
+;
+;      fwrite (buf, count, 1, (FILE*) d->ptr);
+;
+; Since Buf and Count are already in place, we will just push the last
+; two parameters. The fwrite function will remove Buf and Count on exit.
+
+       jsr     push1
+       ldy     #7              ; Offset of D+1 on stack
+       lda     (sp),y
+       sta     ptr1+1
+       dey                     ; Offset of D on stack (6)
+       lda     (sp),y
+       sta     ptr1                           
+       dey                     ; Offset of ptr+1 in struct outdesc (5)
+       lda     (ptr1),y
+       tax
+       dey
+       lda     (ptr1),y
+       jsr     pushax          ; Push D->ptr
+       jsr     _fwrite
+               sta     ptr2            ; Save function result
+       stx     ptr2+1
+
+; Pop the last parameter from stack and store it in ptr1. This means that
+; the stack is clean now.
+
+       jsr     popax
+       sta     ptr1
+       stx     ptr1+1
+
+; Load the offset of ccount in struct outdesc
+
+       ldy     #$00
+
+; Check the return code. Checking the hig byte against $FF is ok here.
+
+               lda     ptr2+1
+       cmp     #$FF
+       bne     @Ok
+
+; We had an error. Store -1 into d->ccount
+
+       sta     (ptr1),y
+       iny
+       sta     (ptr1),y
+       rts
+
+; Result was ok, count bytes written
+
+@Ok:   lda     (ptr1),y
+       add     ptr1
+       sta     (ptr1),y
+       iny
+       lda     (ptr1),y
+       adc     ptr1+1
+       sta     (ptr1),y
+       rts
+
+
+; ----------------------------------------------------------------------------
+; Callback routine used for the actual output.
+;
+; int vfprintf (FILE* f, const char* format, va_list ap)
+; {
+;     struct outdesc d;
+;
+;     /* Setup descriptor */
+;     d.fout = out;
+;     d.ptr  = f;
+;
+;     /* Do formatting and output */
+;     _printf (&d, format, ap);
+;
+;     /* Return bytes written */
+;     return d.ccount;
+; }
+
+_vfprintf:
+       pha                     ; Save low byte of ap
+
+; Setup the outdesc structure
+
+       lda     #0
+       sta     outdesc
+       sta     outdesc+1       ; Clear ccount
+
+; Reorder the stack. Replace f on the stack by &d, so the stack frame is
+; exactly as _printf expects it. Parameters will get dropped by _printf.
+
+       ldy     #2              ;
+       lda     (sp),y          ; Low byte of f
+       sta     outdesc+4       ;
+       lda     #<outdesc
+       sta     (sp),y
+       iny
+       lda     (sp),y          ; High byte of f
+       sta     outdesc+5
+       lda     #>outdesc
+       sta     (sp),y
+
+; Restore low byte of ap and call _printf
+
+       pla
+       jsr     __printf
+
+; Return the number of bytes written
+
+       lda     outdesc
+       ldx     outdesc+1
+       rts
+
+