diff --git a/libsrc/common/.cvsignore b/libsrc/common/.cvsignore index 44c6fff60..aab101ac4 100644 --- a/libsrc/common/.cvsignore +++ b/libsrc/common/.cvsignore @@ -33,4 +33,3 @@ strtok.s strxfrm.s vcprintf.s vprintf.s -vsprintf.s diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index dbfaf4248..1594714e9 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -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 diff --git a/libsrc/common/sprintf.s b/libsrc/common/sprintf.s index 6a1a29c4b..0788f9f35 100644 --- a/libsrc/common/sprintf.s +++ b/libsrc/common/sprintf.s @@ -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 index 6c892d94b..000000000 --- a/libsrc/common/vsprintf.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * vsprintf.c - * - * Ullrich von Bassewitz, 11.08.1998 - */ - - - -#include -#include -#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 index 000000000..b0376f4ae --- /dev/null +++ b/libsrc/common/vsprintf.s @@ -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 + +; 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 + +