File: vfprintf.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (145 lines) | stat: -rw-r--r-- 3,442 bytes parent folder | download | duplicates (3)
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