]> git.sur5r.net Git - cc65/blob - libsrc/common/vfprintf.s
aed6ce16dc60f290dc164d12d4f8930ce2ede685
[cc65] / libsrc / common / vfprintf.s
1 ;
2 ; int vfprintf (FILE* f, const char* Format, va_list ap);
3 ;
4 ; Ullrich von Bassewitz, 1.12.2000
5 ;
6
7         .export         _vfprintf
8         .import         pushax, popax, push1
9         .import         _fwrite, __printf
10         .importzp       sp, ptr1, ptr2
11
12         .macpack        generic
13
14
15 .data
16
17 ; ----------------------------------------------------------------------------
18 ;
19 ; Static data for the _vfprintf routine
20 ;
21
22 outdesc:                        ; Static outdesc structure
23         .word   0               ; ccount
24         .word   out             ; Output function pointer
25         .word   0               ; ptr
26         .word   0               ; uns
27
28 .code
29
30 ; ----------------------------------------------------------------------------
31 ; Callback routine used for the actual output.
32 ;
33 ; static void out (struct outdesc* d, const char* buf, unsigned count)
34 ; /* Routine used for writing */
35 ; {
36 ;     /* Write to the file */
37 ;     if (fwrite (buf, count, 1, (FILE*) d->ptr) == -1) {
38 ;         d->ccount = -1;
39 ;     } else {
40 ;         d->ccount += count;
41 ;     }
42 ; }
43
44 out:
45
46 ; About to call
47 ;
48 ;       fwrite (buf, count, 1, (FILE*) d->ptr);
49 ;
50 ; Since Buf and Count are already in place, we will just push the last
51 ; two parameters. The fwrite function will remove Buf and Count on exit.
52
53         jsr     push1
54         ldy     #7              ; Offset of D+1 on stack
55         lda     (sp),y
56         sta     ptr1+1
57         dey                     ; Offset of D on stack (6)
58         lda     (sp),y
59         sta     ptr1
60         dey                     ; Offset of ptr+1 in struct outdesc (5)
61         lda     (ptr1),y
62         tax
63         dey
64         lda     (ptr1),y
65         jsr     pushax          ; Push D->ptr
66         jsr     _fwrite
67         sta     ptr2            ; Save function result
68         stx     ptr2+1
69
70 ; Pop the last parameter from stack and store it in ptr1. This means that
71 ; the stack is clean now.
72
73         jsr     popax
74         sta     ptr1
75         stx     ptr1+1
76
77 ; Load the offset of ccount in struct outdesc
78
79         ldy     #$00
80
81 ; Check the return code. Checking the hig byte against $FF is ok here.
82
83         lda     ptr2+1
84         cmp     #$FF
85         bne     @Ok
86
87 ; We had an error. Store -1 into d->ccount
88
89         sta     (ptr1),y
90         iny
91         sta     (ptr1),y
92         rts
93
94 ; Result was ok, count bytes written
95
96 @Ok:    lda     (ptr1),y
97         add     ptr1
98         sta     (ptr1),y
99         iny
100         lda     (ptr1),y
101         adc     ptr1+1
102         sta     (ptr1),y
103         rts
104
105
106 ; ----------------------------------------------------------------------------
107 ; Callback routine used for the actual output.
108 ;
109 ; int vfprintf (FILE* f, const char* format, va_list ap)
110 ; {
111 ;     struct outdesc d;
112 ;
113 ;     /* Setup descriptor */
114 ;     d.fout = out;
115 ;     d.ptr  = f;
116 ;
117 ;     /* Do formatting and output */
118 ;     _printf (&d, format, ap);
119 ;
120 ;     /* Return bytes written */
121 ;     return d.ccount;
122 ; }
123
124 _vfprintf:
125         pha                     ; Save low byte of ap
126
127 ; Setup the outdesc structure
128
129         lda     #0
130         sta     outdesc
131         sta     outdesc+1       ; Clear ccount
132
133 ; Reorder the stack. Replace f on the stack by &d, so the stack frame is
134 ; exactly as _printf expects it. Parameters will get dropped by _printf.
135
136         ldy     #2              ;
137         lda     (sp),y          ; Low byte of f
138         sta     outdesc+4       ;
139         lda     #<outdesc
140         sta     (sp),y
141         iny
142         lda     (sp),y          ; High byte of f
143         sta     outdesc+5
144         lda     #>outdesc
145         sta     (sp),y
146
147 ; Restore low byte of ap and call _printf
148
149         pla
150         jsr     __printf
151
152 ; Return the number of bytes written
153
154         lda     outdesc
155         ldx     outdesc+1
156         rts
157
158