File: vcprintf.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 (149 lines) | stat: -rw-r--r-- 3,454 bytes parent folder | download | duplicates (2)
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
146
147
148
149
;
; int __fastcall__ vcprintf (const char* Format, va_list ap);
;
; Ullrich von Bassewitz, 2.12.2000
;

        .export         _vcprintf
        .import         pushax, popax, popptr1
        .import         __printf, _cputc
        .importzp       sp, ptr1, ptr2, ptr3, tmp1

        .macpack        generic


.data

; ----------------------------------------------------------------------------
;
; Static data for the _vsprintf routine
;

outdesc:                        ; Static outdesc structure
        .word   0               ; ccount
        .word   out             ; Output function pointer
        .word   0               ; ptr
        .word   0               ; uns

.code

; ----------------------------------------------------------------------------
; Callback routine used for the actual output.
;
; static void __cdecl__ out (struct outdesc* d, const char* buf, unsigned count)
; /* Routine used for writing */
; {
;     /* Fast screen output */
;     d->ccount += count;
;     while (count) {
;         cputc (*buf);
;         ++buf;
;         --count;
;     }
; }
;
; We're using ptr1 and tmp1, since we know that the cputc routine will not use
; them (they're also used in cputs, so they must be safe).

out:    jsr     popax           ; count
        sta     ptr2
        eor     #$FF
        sta     outdesc+6
        txa
        sta     ptr2+1
        eor     #$FF
        sta     outdesc+7

        jsr     popptr1         ; buf

        jsr     popax           ; d
        sta     ptr3
        stx     ptr3+1

; Sum up the total count of characters

        ldy     #0              ; ccount in struct outdesc
        sty     tmp1            ; Initialize tmp1 while we have zero available
        lda     (ptr3),y
        add     ptr2
        sta     (ptr3),y
        iny
        lda     (ptr3),y
        adc     ptr2+1
        sta     (ptr3),y

; Loop outputting characters

@L1:    inc     outdesc+6
        beq     @L4
@L2:    ldy     tmp1
        lda     (ptr1),y
        iny
        bne     @L3
        inc     ptr1+1
@L3:    sty     tmp1
        jsr     _cputc
        jmp     @L1

@L4:    inc     outdesc+7
        bne     @L2
        rts

; ----------------------------------------------------------------------------
; vcprintf - formatted console i/o
;
; int __fastcall__ vcprintf (const char* format, va_list ap)
; {
;     struct outdesc d;
;
;     /* Setup descriptor */
;     d.fout = out;
;
;     /* Do formatting and output */
;     _printf (&d, format, ap);
;
;     /* Return bytes written */
;     return d.ccount;
; }

_vcprintf:
        sta     ptr1            ; Save ap
        stx     ptr1+1

; Setup the outdesc structure

        lda     #0
        sta     outdesc
        sta     outdesc+1       ; Clear ccount

; Get the format parameter and push it again

        ldy     #1
        lda     (sp),y
        tax
        dey
        lda     (sp),y
        jsr     pushax

; Replace the passed format parameter on the stack by &d - this creates
; exactly the stack frame _printf expects. Parameters will get dropped
; by _printf.

        ldy     #2              ; Low byte of d
        lda     #<outdesc
        sta     (sp),y
        iny
        lda     #>outdesc
        sta     (sp),y

; Restore ap and call _printf

        lda     ptr1
        ldx     ptr1+1
        jsr     __printf

; Return the number of bytes written.

        lda     outdesc         ; ccount
        ldx     outdesc+1
        rts