]> git.sur5r.net Git - cc65/commitdiff
Let vsprintf call vsnprintf to save code.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 27 Sep 2009 12:18:06 +0000 (12:18 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 27 Sep 2009 12:18:06 +0000 (12:18 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@4247 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/common/vsprintf.s

index 2e2752b433a1f782472bc861dd5493a32ff36d73..c6084bdda7591072c46c310b70f91216a7a297ed 100644 (file)
 ;
 ; int vsprintf (char* Buf, const char* Format, va_list ap);
 ;
-; Ullrich von Bassewitz, 1.12.2000
+; Ullrich von Bassewitz, 2009-09-26
 ;
 
        .export         _vsprintf
-       .import         pushax, popax
-       .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 sure 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
+       .import         ldax0sp, pushax, staxysp
+       .import         _vsnprintf
 
 
 ; ----------------------------------------------------------------------------
 ; 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';
+; int vsprintf (char* buf, const char* format, va_list ap);
 ;
-;     /* Return bytes written */
-;     return d.ccount;
-; }
 
 
 _vsprintf:
        pha                     ; Save low byte of ap
+        txa
+        pha                     ; Save high byte of op
 
-; 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
+; Build a stackframe for vsnprintf. To do that, we move format one word down,
+; and store 0x7FF (INT_MAX) as size.
 
-; Return the number of bytes written.
+        jsr     ldax0sp         ; Get format
+        jsr     pushax          ; And push it
+        lda     #$7F
+        ldx     #$FF            ; INT_MAX
+        ldy     #2
+        jsr     staxysp
 
-        lda     outdesc         ; ccount
-        ldx     outdesc+1
-       rts
+; Retrieve ap and contine by jumping to _vsnprintf, which will cleanup the stack
 
+        pla
+        tax
+        pla
+        jmp     _vsnprintf