1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
; 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
|