]> git.sur5r.net Git - cc65/blob - libsrc/common/vsnprintf.s
10dc7fa1dc4ee02f51764ec4312b57b4cd4f1c60
[cc65] / libsrc / common / vsnprintf.s
1 ;
2 ; int vsnprintf (char* Buf, size_t size, const char* Format, va_list ap);
3 ;
4 ; Ullrich von Bassewitz, 2009-09-26
5 ;
6
7         .export         _vsnprintf
8         .import         ldaxysp, popax, incsp2, incsp6
9         .import         _memcpy, __printf
10         .importzp       sp, ptr1
11
12         .macpack        generic
13
14 .data
15
16 ; ----------------------------------------------------------------------------
17 ;
18 ; Static data for the _vsnprintf routine
19 ;
20
21 outdesc:                        ; Static outdesc structure
22 ccount: .word   0               ; ccount
23 func:   .word   out             ; Output function pointer
24 bufptr: .word   0               ; ptr
25 bufsize:.word   0               ; Buffer size
26
27 .code
28
29 ; ----------------------------------------------------------------------------
30 ; Callback routine used for the actual output.
31 ;
32 ; static void out (struct outdesc* d, const char* buf, unsigned count)
33 ; /* Routine used for writing */
34 ;
35 ; Since we know, we're called with a pointer to our static outdesc structure,
36 ; we don't need the pointer passed on the stack.
37
38 out:
39
40 ; Calculate the space left in the buffer. If no space is left, don't copy
41 ; any characters
42
43         lda     bufsize                 ; Low byte of buffer size
44         sec
45         sbc     ccount+0                ; Low byte of bytes already written
46         sta     ptr1
47         lda     bufsize+1
48         sbc     ccount+1
49         sta     ptr1+1
50         bcs     @L0                     ; Space left
51         lda     #0
52         sta     ptr1
53         sta     ptr1+1
54
55 ; Replace the pointer to d by a pointer to the write position in the buffer
56 ; for the call to memcpy that follows.
57
58 @L0:    lda     bufptr+0
59         clc
60         adc     ccount+0
61         ldy     #4
62         sta     (sp),y
63
64         lda     bufptr+1
65         adc     ccount+1
66         iny
67         sta     (sp),y
68
69 ; Get Count from stack
70
71         jsr     popax
72
73 ; outdesc.ccount += Count;
74
75         pha
76         clc
77         adc     ccount+0
78         sta     ccount+0
79         txa
80         adc     ccount+1
81         sta     ccount+1
82         pla
83
84 ; if (Count > Left) Count = Left;
85
86         cpx     ptr1+1
87         bne     @L1
88         cmp     ptr1
89 @L1:    bcc     @L2
90         lda     ptr1
91         ldx     ptr1+1
92
93 ; Jump to memcpy, which will cleanup the stack and return to the caller
94
95 @L2:    jmp     _memcpy
96
97
98 ; ----------------------------------------------------------------------------
99 ; vsprintf - formatted output into a buffer
100 ;
101 ; int __fastcall__ vsnprintf (char* buf, size_t size, const char* format, va_list ap);
102 ;
103
104 _vsnprintf:
105         pha                     ; Save low byte of ap
106
107 ; Setup the outdesc structure
108
109         lda     #0
110         sta     ccount+0
111         sta     ccount+1        ; Clear ccount
112
113 ; Get the size parameter and replace it by a pointer to outdesc. This is to
114 ; build a stack frame for the call to _printf.
115 ; If size is zero, there's nothing to do.
116
117         ldy     #2
118         lda     (sp),y
119         sta     ptr1
120         lda     #<outdesc
121         sta     (sp),y
122         iny
123         lda     (sp),y
124         sta     ptr1+1
125         ora     ptr1
126         beq     L9
127
128         lda     #>outdesc
129         sta     (sp),y
130
131 ; Write size-1 to outdesc.uns
132
133         ldx     ptr1
134         ldy     ptr1+1
135         dex
136         bne     L1
137         dey
138 L1:     stx     bufsize+0
139         sty     bufsize+1
140
141 ; Copy buf to the outdesc.ptr
142
143         ldy     #5
144         jsr     ldaxysp
145         sta     bufptr+0
146         stx     bufptr+1
147
148 ; Restore low byte of ap and call _printf
149
150         pla
151         jsr     __printf
152
153 ; Terminate the string
154
155         lda     ccount+0
156         ldx     ccount+1
157         cpx     bufsize+1
158         bne     L2
159         cmp     bufsize+0
160 L2:     bcc     L3
161         lda     bufsize+0
162         ldx     bufsize+1
163         clc
164 L3:     adc     bufptr+0
165         sta     ptr1
166         txa
167         adc     bufptr+1
168         sta     ptr1+1
169
170         lda     #0
171         tay
172         sta     (ptr1),y
173
174 ; Return the number of bytes written and drop buf
175
176         lda     ccount+0
177         ldx     ccount+1
178         jmp     incsp2
179
180 ; Bail out if size is zero
181
182 L9:     lda     #0
183         tax
184         jmp     incsp6          ; Drop parameters
185
186