X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libsrc%2Fcommon%2Fvfprintf.s;h=881bf9b4219dc72ae0c19268f8eb6f65f1821813;hb=ff746b119ced0a50914175baf52e9ee196c107dc;hp=aed6ce16dc60f290dc164d12d4f8930ce2ede685;hpb=e3022d904d09fa64b41c9c714d08b9ff06b37263;p=cc65 diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s index aed6ce16d..881bf9b42 100644 --- a/libsrc/common/vfprintf.s +++ b/libsrc/common/vfprintf.s @@ -1,117 +1,104 @@ +; vfprintf.s ; -; int vfprintf (FILE* f, const char* Format, va_list ap); -; -; Ullrich von Bassewitz, 1.12.2000 +; int fastcall vfprintf(FILE* f, const char* Format, va_list ap); ; +; 2005-02-08, Ullrich von Bassewitz +; 2005-02-11, Greg King - .export _vfprintf - .import pushax, popax, push1 - .import _fwrite, __printf - .importzp sp, ptr1, ptr2 + .export _vfprintf + .import push1, pushwysp, incsp6 + .import _fwrite, __printf + .importzp sp, ptr1 - .macpack generic + .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 +outdesc: ; Static outdesc structure +ccount: .res 2 + .word out ; Output function pointer +ptr: .res 2 ; Points to output file + .res 2 ; (Not used by this function) .code ; ---------------------------------------------------------------------------- ; Callback routine used for the actual output. ; +; Since we know, that this routine is always called with "our" outdesc, we +; can ignore the passed pointer d, and access the data directly. While this +; is not very clean, it gives better and shorter code. +; ; static void out (struct outdesc* d, const char* buf, unsigned count) ; /* Routine used for writing */ ; { +; register size_t cnt; +; ; /* Write to the file */ -; if (fwrite (buf, count, 1, (FILE*) d->ptr) == -1) { -; d->ccount = -1; +; if ((cnt = fwrite(buf, 1, count, ptr)) == 0) { +; ccount = -1; ; } else { -; d->ccount += count; +; ccount += cnt; ; } ; } -out: - ; About to call ; -; fwrite (buf, count, 1, (FILE*) d->ptr); +; fwrite (buf, 1, count, 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 +out: ldy #5 + jsr pushwysp ; Push buf + jsr push1 ; Push #1 + ldy #7 + jsr pushwysp ; Push count + lda ptr + ldx ptr+1 + jsr _fwrite + sta ptr1 ; Save function result + stx ptr1+1 + +; Check the return value. + + ora ptr1+1 + bne @Ok + +; We had an error. Store -1 into ccount + +.ifp02 + lda #<-1 +.else + dec a +.endif + sta ccount + bne @Done ; Branch always ; 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 +@Ok: lda ptr1 + add ccount + sta ccount + txa + adc ccount+1 +@Done: sta ccount+1 + jmp incsp6 ; Drop stackframe ; ---------------------------------------------------------------------------- -; Callback routine used for the actual output. +; vfprintf - formatted output ; -; int vfprintf (FILE* f, const char* format, va_list ap) +; int fastcall vfprintf(FILE* f, const char* format, va_list ap) ; { -; struct outdesc d; +; static struct outdesc d = { +; 0, +; out +; }; ; ; /* Setup descriptor */ -; d.fout = out; +; d.ccount = 0; ; d.ptr = f; ; ; /* Do formatting and output */ @@ -120,39 +107,39 @@ out: ; /* Return bytes written */ ; return d.ccount; ; } - +; _vfprintf: - pha ; Save low byte of ap + pha ; Save low byte of ap ; Setup the outdesc structure - lda #0 - sta outdesc - sta outdesc+1 ; Clear ccount + lda #0 + sta ccount + sta ccount+1 ; Clear character-count ; 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 + ldy #2 + lda (sp),y ; Low byte of f + sta ptr + lda #outdesc + sta (sp),y ; Restore low byte of ap and call _printf - pla - jsr __printf + pla + jsr __printf ; Return the number of bytes written - lda outdesc - ldx outdesc+1 - rts + lda ccount + ldx ccount+1 + rts