2 ; int vsprintf (char* Buf, const char* Format, va_list ap);
4 ; Ullrich von Bassewitz, 1.12.2000
9 .import _memcpy, __printf
17 ; ----------------------------------------------------------------------------
19 ; Static data for the _vsprintf routine
22 outdesc: ; Static outdesc structure
24 .word out ; Output function pointer
26 .word $7FFF ; Buffer size (max int)
30 ; ----------------------------------------------------------------------------
31 ; Callback routine used for the actual output.
33 ; static void out (struct outdesc* d, const char* buf, unsigned count)
34 ; /* Routine used for writing */
36 ; /* String - be shure to check the size */
37 ; while (count-- && d->ccount < d->uns) {
38 ; ((char*) d->ptr) [d->ccount] = *buf;
44 ; The assembler version assumes that the buffer is big enough and just copies
45 ; all characters into the buffer. This has to be changed for a vsnprintf like
46 ; function but is ok for now.
47 ; For simplicity, we will use memcpy to copy the stuff and will just rearrange
48 ; the stack to create a matching frame for memcpy.
50 out: ldy #4 ; d on stack
55 sta ptr1+1 ; Save d into ptr1
57 ; Get a pointer to the target buffer and store it into the stack frame
58 ; currently occupied by d
61 lda (ptr1),y ; Low byte of d->ptr
63 add (ptr1),y ; Low byte of d->ccount
65 sta (sp),y ; Store into d stackframe
67 lda (ptr1),y ; High byte of d->ptr
69 adc (ptr1),y ; High byte of d->ccount
73 ; Increment the total count by the number if bytes in this chunk. While doing
74 ; so, load count into a/x since _memcpy is a fastcall function
79 add (ptr1),y ; Low byte of d->ccount
82 txa ; High byte of count
83 adc (ptr1),y ; High byte of d->ccount
85 pla ; Restore low byte of count
87 ; We have the correct stackframe for memcpy now, call it
92 ; ----------------------------------------------------------------------------
93 ; vsprintf - formatted output into a buffer
95 ; int vsprintf (char* buf, const char* format, va_list ap)
99 ; /* Setup descriptor */
104 ; /* Do formatting and output */
105 ; _printf (&d, format, ap);
107 ; /* Terminate the result string */
108 ; buf [d.ccount++] = '\0';
110 ; /* Return bytes written */
116 pha ; Save low byte of ap
118 ; Setup the outdesc structure
122 sta outdesc+1 ; Clear ccount
124 ; Reorder the stack. Replace buf on the stack by &d, so the stack frame is
125 ; exactly as _printf expects it. Parameters will get dropped by _printf.
128 lda (sp),y ; Low byte of buf
129 sta outdesc+4 ; Store into outdesc.ptr
133 lda (sp),y ; High byte of buf
138 ; Restore low byte of ap and call _printf
143 ; Terminate the string
146 add outdesc+0 ; +ccount
155 ; Return the number of bytes written.