From: cuz Date: Fri, 1 Dec 2000 15:05:46 +0000 (+0000) Subject: Rewrote vfprintf() in assembler X-Git-Tag: V2.12.0~3029 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=9333d5a83905fabb493538b11df56500d7180631;p=cc65 Rewrote vfprintf() in assembler git-svn-id: svn://svn.cc65.org/cc65/trunk@511 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/common/.cvsignore b/libsrc/common/.cvsignore index 549615250..a10674818 100644 --- a/libsrc/common/.cvsignore +++ b/libsrc/common/.cvsignore @@ -35,6 +35,5 @@ sprintf.s strtok.s strxfrm.s vcprintf.s -vfprintf.s vprintf.s vsprintf.s diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index 1d06712db..2f45a2ac4 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -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 diff --git a/libsrc/common/printf.s b/libsrc/common/printf.s index 3f95f8e6b..b164e887d 100644 --- a/libsrc/common/printf.s +++ b/libsrc/common/printf.s @@ -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 index 17596b5d2..000000000 --- a/libsrc/common/vfprintf.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * vfprintf.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 */ -{ - /* 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 index 000000000..a445c5b8d --- /dev/null +++ b/libsrc/common/vfprintf.s @@ -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 + +; Restore low byte of ap and call _printf + + pla + jsr __printf + +; Return the number of bytes written + + lda outdesc + ldx outdesc+1 + rts + +