]> git.sur5r.net Git - cc65/blob - libsrc/conio/vcscanf.s
clrscr.s switch to text mode
[cc65] / libsrc / conio / vcscanf.s
1 ;
2 ; int fastcall vcscanf(const char* format, va_list ap);
3 ;
4 ; 2014-09-10, Greg King
5 ;
6
7         .export         _vcscanf
8
9         .import         _cgetc, _cputc
10         .import         popax, pushax, swapstk
11
12         .include        "../common/_scanf.inc"
13
14
15 ; static bool pushed;
16 ; static char back;
17 ;
18         .bss
19 pushed: .res    1
20 back:   .res    1
21
22         .code
23 ; /* Call-back functions:
24 ; ** (Note:  These prototypes must NOT be declared with fastcall!  They don't
25 ; ** use (getfunc)'s and (ungetfunc)'s last parameter.  Leaving it out of these
26 ; ** prototypes makes more efficient code.)
27 ; */
28
29 ; ----------------------------------------------------------------------------
30 ; /* Read a character from the console, and return it to an internal function */
31 ; static int get(void) {
32 ;     static char C;
33 ;
34 ;     if (pushed) {
35 ;         pushed = false;
36 ;         return (int)back;
37 ;         }
38 ;     cputc(C = cgetc());       /* echo a typed character */
39 ;     return (int)C;
40 ;     }
41 ;
42 get:    ldx     pushed
43         beq     L1
44
45 ; Return the old, pushed-back character (instead of getting a new one).
46 ;
47         dex                     ; ldx #>$0000
48         stx     pushed
49         lda     back
50         rts
51
52 ; Directly read the keyboard.
53 ;
54 L1:     jsr     _cgetc
55
56 ; Echo the character to the screen.
57 ;
58         pha
59         jsr     _cputc
60         pla
61         ldx     #>$0000
62         rts
63
64
65 ; ----------------------------------------------------------------------------
66 ; static int cdecl unget(int c) {
67 ;     pushed = true;
68 ;     return back = c;
69 ;     }
70 ;
71 unget:  ldx     #1
72         stx     pushed
73         jsr     popax           ; get the first argument
74         sta     back
75         rts
76
77
78 ; ----------------------------------------------------------------------------
79 ; int fastcall vcscanf(const char* format, va_list ap) {
80 ;     /* Initiate the data structure.
81 ;     ** Don't initiate the member that these conio functions don't use.
82 ;     */
83 ;     static const struct scanfdata d = {
84 ;         (  getfunc)  get,
85 ;         (ungetfunc)unget
86 ;         };
87 ;
88 ;     /* conio is very interactive.  So, don't use any pushed-back character.
89 ;     ** Start fresh, each time that this function is called.
90 ;     */
91 ;     pushed = false;
92 ;
93 ;     /* Call the internal function, and return the result. */
94 ;     return _scanf(&d, format, ap);
95 ;     }
96 ;
97 ; Beware:  Because ap is a fastcall parameter, we must not destroy .XA.
98 ;
99         .proc   _vcscanf
100
101 ; ----------------------------------------------------------------------------
102 ; Static, constant scanfdata structure for the _vcscanf routine.
103 ;
104         .rodata
105 d:      .addr   get             ; SCANFDATA::GET
106         .addr   unget           ; SCANFDATA::UNGET
107 ;       .addr   0               ; SCANFDATA::DATA (not used)
108
109         .code
110         pha                     ; Save low byte of ap
111         txa
112         pha                     ; Save high byte of ap
113         ldx     #0
114         stx     pushed
115
116 ; Put &d on the stack in front of the format pointer.
117
118         lda     #<d
119         ldx     #>d
120         jsr     swapstk         ; Swap .XA with top-of-stack
121         jsr     pushax          ; Put format pointer back on stack
122
123 ; Restore ap, and jump to _scanf which will clean up the stack.
124
125         pla
126         tax
127         pla
128         jmp     __scanf
129         .endproc