]> git.sur5r.net Git - cc65/blob - libsrc/common/vfprintf.s
Issue 814
[cc65] / libsrc / common / vfprintf.s
1 ; vfprintf.s
2 ;
3 ; int fastcall vfprintf(FILE* f, const char* Format, va_list ap);
4 ;
5 ; 2005-02-08, Ullrich von Bassewitz
6 ; 2005-02-11, Greg King
7
8         .export         _vfprintf
9         .import         push1, pushwysp, incsp6
10         .import         _fwrite, __printf
11         .importzp       sp, ptr1
12
13         .macpack        generic
14
15
16 .data
17
18 ; ----------------------------------------------------------------------------
19 ; Static data for the _vfprintf routine
20 ;
21 outdesc:                        ; Static outdesc structure
22 ccount: .res    2
23         .word   out             ; Output function pointer
24 ptr:    .res    2               ; Points to output file
25         .res    2               ; (Not used by this function)
26
27 .code
28
29 ; ----------------------------------------------------------------------------
30 ; Callback routine used for the actual output.
31 ;
32 ; Since we know, that this routine is always called with "our" outdesc, we
33 ; can ignore the passed pointer d, and access the data directly. While this
34 ; is not very clean, it gives better and shorter code.
35 ;
36 ; static void cdecl out (struct outdesc* d, const char* buf, unsigned count)
37 ; /* Routine used for writing */
38 ; {
39 ;     register size_t cnt;
40 ;
41 ;     /* Write to the file */
42 ;     if ((cnt = fwrite(buf, 1, count, ptr)) == 0) {
43 ;         ccount = -1;
44 ;     } else {
45 ;         ccount += cnt;
46 ;     }
47 ; }
48
49 ; About to call
50 ;
51 ;       fwrite (buf, 1, count, ptr);
52 ;
53 out:    ldy     #5
54         jsr     pushwysp        ; Push buf
55         jsr     push1           ; Push #1
56         ldy     #7
57         jsr     pushwysp        ; Push count
58         lda     ptr
59         ldx     ptr+1
60         jsr     _fwrite
61         sta     ptr1            ; Save function result
62         stx     ptr1+1
63
64 ; Check the return value.
65
66         ora     ptr1+1
67         bne     @Ok
68
69 ; We had an error. Store -1 into ccount
70
71 .ifp02
72         lda     #<-1
73 .else
74         dec     a
75 .endif
76         sta     ccount
77         bne     @Done           ; Branch always
78
79 ; Result was ok, count bytes written
80
81 @Ok:    lda     ptr1
82         add     ccount
83         sta     ccount
84         txa
85         adc     ccount+1
86 @Done:  sta     ccount+1
87         jmp     incsp6          ; Drop stackframe
88
89
90 ; ----------------------------------------------------------------------------
91 ; vfprintf - formatted output
92 ;
93 ; int fastcall vfprintf(FILE* f, const char* format, va_list ap)
94 ; {
95 ;     static struct outdesc d = {
96 ;         0,
97 ;         out
98 ;     };
99 ;
100 ;     /* Setup descriptor */
101 ;     d.ccount = 0;
102 ;     d.ptr  = f;
103 ;
104 ;     /* Do formatting and output */
105 ;     _printf (&d, format, ap);
106 ;
107 ;     /* Return bytes written */
108 ;     return d.ccount;
109 ; }
110 ;
111 _vfprintf:
112         pha                     ; Save low byte of ap
113
114 ; Setup the outdesc structure
115
116         lda     #0
117         sta     ccount
118         sta     ccount+1        ; Clear character-count
119
120 ; Reorder the stack. Replace f on the stack by &d, so the stack frame is
121 ; exactly as _printf expects it. Parameters will get dropped by _printf.
122
123         ldy     #2
124         lda     (sp),y          ; Low byte of f
125         sta     ptr
126         lda     #<outdesc
127         sta     (sp),y
128         iny
129         lda     (sp),y          ; High byte of f
130         sta     ptr+1
131         lda     #>outdesc
132         sta     (sp),y
133
134 ; Restore low byte of ap and call _printf
135
136         pla
137         jsr     __printf
138
139 ; Return the number of bytes written
140
141         lda     ccount
142         ldx     ccount+1
143         rts
144
145