; ; int vfprintf (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 ; Load 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 ; ---------------------------------------------------------------------------- ; vfprintf - formatted 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