]> git.sur5r.net Git - cc65/blob - libsrc/common/vsscanf.s
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / libsrc / common / vsscanf.s
1 ;
2 ; int __fastcall__ vsscanf (const char* str, const char* format, va_list ap);
3 ; /* Standard C function */
4 ;
5 ; 2004-11-28, Ullrich von Bassewitz
6 ; 2004-12-21, Greg King
7 ;
8
9         .export         _vsscanf
10
11         .import         popax, __scanf
12         .importzp       sp, ptr1, ptr2
13
14         .macpack        generic
15
16
17 ; ----------------------------------------------------------------------------
18 ; Structure used to pass data to the callback functions
19
20 .struct SSCANFDATA
21         STR     .addr
22         INDEX   .word
23 .endstruct
24
25
26 ; ----------------------------------------------------------------------------
27 ; static int __fastcall__ get (struct sscanfdata* d)
28 ; /* Read a character from the input string and return it */
29 ; {
30 ;     char C = d->str[d->index];
31 ;     if (C == '\0') {
32 ;         return EOF;
33 ;     }
34 ;     /* Increment index only if end not reached */
35 ;     ++d->index;
36 ;     return C;
37 ; }
38 ;
39
40 .code
41 .proc   get
42
43         sta     ptr1
44         stx     ptr1+1                  ; Save d
45
46 ; Get d->str adding the high byte of index to the pointer, so we can access
47 ; the byte in the string with just the low byte as index
48
49         ldy     #SSCANFDATA::STR
50         lda     (ptr1),y
51         sta     ptr2
52         iny
53         lda     (ptr1),y
54         ldy     #SSCANFDATA::INDEX+1
55         add     (ptr1),y
56         sta     ptr2+1
57
58 ; Load the low byte of the index and fetch the byte from the string
59
60         dey                             ; = SSCANFDATA::INDEX
61         lda     (ptr1),y
62         tay
63         lda     (ptr2),y
64
65 ; Return EOF if we are at the end of the string
66
67         bne     L1
68         lda     #$FF
69         tax
70         rts
71
72 ; Bump the index (beware: A contains the char we must return)
73
74 L1:     tax                             ; Save return value
75         tya                             ; Low byte of index
76         ldy     #SSCANFDATA::INDEX
77         add     #<1
78         sta     (ptr1),y
79         iny
80         lda     (ptr1),y
81         adc     #>1
82         sta     (ptr1),y
83
84 ; Return the char just read
85
86         txa
87         ldx     #>0
88         rts
89
90 .endproc
91
92 ; ----------------------------------------------------------------------------
93 ; static int __fastcall__ unget (int c, struct sscanfdata* d)
94 ; /* Push back a character onto the input stream */
95 ; {
96 ;     /* We do assume here that the _scanf routine will not push back anything
97 ;      * not read, so we can ignore c safely and won't check the index.
98 ;      */
99 ;     --d->index;
100 ;     return c;
101 ; }
102 ;
103
104 .code
105 .proc   unget
106
107         sta     ptr1
108         stx     ptr1+1                  ; Save d
109
110 ; Decrement the index
111
112         ldy     #SSCANFDATA::INDEX
113         lda     (ptr1),y
114         sub     #<1
115         sta     (ptr1),y
116         iny
117         lda     (ptr1),y
118         sbc     #>1
119         sta     (ptr1),y
120
121 ; Return c
122
123         jmp     popax
124
125 .endproc
126
127 ; ----------------------------------------------------------------------------
128 ; int __fastcall__ vsscanf (const char* str, const char* format, va_list ap)
129 ; /* Standard C function */
130 ; {
131 ;     /* Initialize the data structs. The sscanfdata struct will be passed back
132 ;      * to the get and unget functions by _scanf().
133 ;      */
134 ;     static       struct sscanfdata sd;
135 ;     static const struct  scanfdata  d = {
136 ;         (  getfunc)   get,
137 ;         (ungetfunc) unget,
138 ;         (void*) &sd
139 ;     };
140 ;
141 ;     sd.str   = str;
142 ;     sd.index = 0;
143 ;
144 ;     /* Call the internal function and return the result */
145 ;     return _scanf (&d, format, ap);
146 ; }
147 ;
148
149 .bss
150 sd:     .tag    SSCANFDATA
151
152 .rodata
153 d:      .addr   get
154         .addr   unget
155         .addr   sd
156
157 .code
158 .proc   _vsscanf
159
160 ; Save the low byte of ap (which is passed in a/x)
161
162         pha
163
164 ; Initialize sd and at the same time replace str on the stack by a pointer
165 ; to d
166
167         ldy     #2                      ; Stack offset of str
168         lda     (sp),y
169         sta     sd + SSCANFDATA::STR
170         lda     #<d
171         sta     (sp),y
172         iny
173         lda     (sp),y
174         sta     sd + SSCANFDATA::STR+1
175         lda     #>d
176         sta     (sp),y
177
178         lda     #$00
179         sta     sd + SSCANFDATA::INDEX
180         sta     sd + SSCANFDATA::INDEX+1
181
182 ; Restore the low byte of ap, and jump to _scanf() which will clean up the stack
183
184         pla
185         jmp     __scanf
186
187 .endproc
188