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

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

index 44c6fff6037dca01a1b7d09fc1c751becbb0133d..aab101ac4a73b7623375ba6f7395bd2d90a5f934 100644 (file)
@@ -33,4 +33,3 @@ strtok.s
 strxfrm.s
 vcprintf.s
 vprintf.s
-vsprintf.s
index dbfaf4248c94280149e013bbf12642f65be6f909..1594714e97348ad98c800a7d5869458b931a9811 100644 (file)
@@ -15,7 +15,7 @@ C_OBJS = fclose.o fgets.o calloc.o _fopen.o\
         fputs.o fread.o fwrite.o gets.o realloc.o bsearch.o strxfrm.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 abort.o qsort.o putchar.o\
+        vprintf.o abort.o qsort.o putchar.o\
         errormsg.o vcprintf.o freopen.o locale.o fsetpos.o\
         fgetpos.o rewind.o fseek.o ftell.o
 
@@ -87,6 +87,7 @@ S_OBJS =      _fdesc.o        \
                tolower.o       \
                toupper.o       \
                vfprintf.o      \
+               vsprintf.o      \
                zerobss.o
 
 
index 6a1a29c4b6c79bb022674c2171b25d549d42191e..0788f9f35b23dd4832ab70374e39a9d87ee90e74 100644 (file)
@@ -54,13 +54,12 @@ _sprintf:
        dey
        bpl     @L2
 
-; Push va_list (last parameter to vsprintf)
+; Load va_list (last and __fastcall__ parameter to vsprintf)
 
-       lda     ptr1
-       ldx     ptr1+1
-       jsr     pushax
+       lda     ptr1
+       ldx     ptr1+1
 
-; Call vfprintf
+; Call vsprintf
 
        jsr     _vsprintf
 
diff --git a/libsrc/common/vsprintf.c b/libsrc/common/vsprintf.c
deleted file mode 100644 (file)
index 6c892d9..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * vsprintf.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 */
-{
-    /* String - be shure to check the size */
-    while (count-- && d->ccount < d->uns) {
-       ((char*) d->ptr) [d->ccount] = *buf;
-       ++buf;
-       ++d->ccount;
-    }
-}
-
-
-
-int vsprintf (char* buf, const char* format, va_list ap)
-{
-    struct outdesc d;
-
-    /* Setup descriptor */
-    d.fout = out;
-    d.ptr  = buf;
-    d.uns  = 0x7FFF;
-
-    /* Do formatting and output */
-    _printf (&d, format, ap);
-
-    /* Terminate the result string */
-    buf [d.ccount++] = '\0';
-
-    /* Return bytes written */
-    return d.ccount;
-}
-
-
-
diff --git a/libsrc/common/vsprintf.s b/libsrc/common/vsprintf.s
new file mode 100644 (file)
index 0000000..b0376f4
--- /dev/null
@@ -0,0 +1,165 @@
+;                                                      
+; int vsprintf (char* Buf, const char* Format, va_list ap);
+;
+; Ullrich von Bassewitz, 1.12.2000
+;
+
+       .export         _vsprintf
+       .import         pushax, popax, push1
+       .import         _memcpy, __printf
+       .importzp       sp, ptr1
+
+       .macpack        generic
+
+
+.data
+
+; ----------------------------------------------------------------------------
+;
+; Static data for the _vsprintf routine
+;
+
+outdesc:                       ; Static outdesc structure
+       .word   0               ; ccount
+       .word   out             ; Output function pointer
+       .word   0               ; ptr
+       .word   $7FFF           ; Buffer size (max int)
+
+.code
+
+; ----------------------------------------------------------------------------
+; Callback routine used for the actual output.
+;
+; static void out (struct outdesc* d, const char* buf, unsigned count)
+; /* Routine used for writing */
+; {
+;     /* String - be shure to check the size */
+;     while (count-- && d->ccount < d->uns) {
+;        ((char*) d->ptr) [d->ccount] = *buf;
+;        ++buf;
+;        ++d->ccount;
+;     }
+; }
+;
+; The assembler version assumes that the buffer is big enough and just copies
+; all characters into the buffer. This has to be changed for a vsnprintf like
+; function but is ok for now.
+; For simplicity, we will use memcpy to copy the stuff and will just rearrange
+; the stack to create a matching frame for memcpy.
+
+out:   ldy     #4                      ; d on stack
+       lda     (sp),y
+       sta     ptr1
+       iny
+       lda     (sp),y
+       sta     ptr1+1                  ; Save d into ptr1
+
+; Get a pointer to the target buffer and store it into the stack frame
+; currently occupied by d
+
+       dey                             ; d->ptr
+       lda     (ptr1),y                ; Low byte of d->ptr
+       ldy     #0
+       add     (ptr1),y                ; Low byte of d->ccount
+       ldy     #4
+       sta     (sp),y                  ; Store into d stackframe
+       iny
+       lda     (ptr1),y                ; High byte of d->ptr
+       ldy     #1
+       adc     (ptr1),y                ; High byte of d->ccount
+       ldy     #5
+       sta     (sp),y
+
+; Increment the total count by the number if bytes in this chunk. While doing
+; so, load count into a/x since _memcpy is a fastcall function
+
+       jsr     popax                   ; Get count
+       pha                             ; Save low byte
+       ldy     #0
+               add     (ptr1),y                ; Low byte of d->ccount
+       sta     (ptr1),y
+       iny
+       txa                             ; High byte of count
+       adc     (ptr1),y                ; High byte of d->ccount
+       sta     (ptr1),y
+       pla                             ; Restore low byte of count
+
+; We have the correct stackframe for memcpy now, call it
+
+       jmp     _memcpy
+
+
+; ----------------------------------------------------------------------------
+; vsprintf - formatted output into a buffer
+;
+; int vsprintf (char* buf, const char* format, va_list ap)
+; {
+;     struct outdesc d;
+;
+;     /* Setup descriptor */
+;     d.fout = out;
+;     d.ptr  = buf;
+;     d.uns  = 0x7FFF;
+;
+;     /* Do formatting and output */
+;     _printf (&d, format, ap);
+;
+;     /* Terminate the result string */
+;     buf [d.ccount++] = '\0';
+;
+;     /* Return bytes written */
+;     return d.ccount;
+; }
+
+
+_vsprintf:
+       pha                     ; Save low byte of ap
+
+; Setup the outdesc structure
+
+       lda     #0
+       sta     outdesc
+       sta     outdesc+1       ; Clear ccount
+
+; Reorder the stack. Replace buf 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 buf
+       sta     outdesc+4       ; Store into outdesc.ptr
+       lda     #<outdesc
+       sta     (sp),y
+       iny
+       lda     (sp),y          ; High byte of buf
+       sta     outdesc+5
+       lda     #>outdesc
+       sta     (sp),y
+
+; Restore low byte of ap and call _printf
+
+       pla
+       jsr     __printf
+
+; Terminate the string
+
+       lda     outdesc+4       ; buf
+       add     outdesc+0       ; +ccount
+       sta     ptr1
+       lda     outdesc+5
+       adc     outdesc+1
+       sta     ptr1+1
+       ldy     #0
+       tya
+       sta     (ptr1),y
+
+; Return the number of bytes written. The carry is clear here because of the
+; last addition which will never overflow for sane code.
+
+       lda     outdesc         ; ccount
+       ldx     outdesc+1
+       adc     #1              ; Account for terminator
+       bcc     @L9
+       inx
+@L9:   rts
+
+