From: uz Date: Sun, 27 Sep 2009 12:18:06 +0000 (+0000) Subject: Let vsprintf call vsnprintf to save code. X-Git-Tag: V2.13.0rc1~11 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5967b4845e0edd37b4eb6b73c873a4ef47f75fc7;p=cc65 Let vsprintf call vsnprintf to save code. git-svn-id: svn://svn.cc65.org/cc65/trunk@4247 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/common/vsprintf.s b/libsrc/common/vsprintf.s index 2e2752b43..c6084bdda 100644 --- a/libsrc/common/vsprintf.s +++ b/libsrc/common/vsprintf.s @@ -1,161 +1,40 @@ ; ; 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 - -; 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