cc65/libsrc/common/vfprintf.s

146 lines
3.4 KiB
ArmAsm

; vfprintf.s
;
; 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 push1, pushwysp, incsp6
.import _fwrite, __printf
.importzp sp, ptr1
.macpack generic
.data
; ----------------------------------------------------------------------------
; Static data for the _vfprintf routine
;
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 cdecl out (struct outdesc* d, const char* buf, unsigned count)
; /* Routine used for writing */
; {
; register size_t cnt;
;
; /* Write to the file */
; if ((cnt = fwrite(buf, 1, count, ptr)) == 0) {
; ccount = -1;
; } else {
; ccount += cnt;
; }
; }
; About to call
;
; fwrite (buf, 1, count, ptr);
;
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
add ccount
sta ccount
txa
adc ccount+1
@Done: sta ccount+1
jmp incsp6 ; Drop stackframe
; ----------------------------------------------------------------------------
; vfprintf - formatted output
;
; int fastcall vfprintf(FILE* f, const char* format, va_list ap)
; {
; static struct outdesc d = {
; 0,
; out
; };
;
; /* Setup descriptor */
; d.ccount = 0;
; 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 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 ptr
lda #<outdesc
sta (sp),y
iny
lda (sp),y ; High byte of f
sta ptr+1
lda #>outdesc
sta (sp),y
; Restore low byte of ap and call _printf
pla
jsr __printf
; Return the number of bytes written
lda ccount
ldx ccount+1
rts