File: vcscanf.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 (129 lines) | stat: -rw-r--r-- 3,304 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
;
; int fastcall vcscanf(const char* format, va_list ap);
;
; 2014-09-10, Greg King
;

        .export         _vcscanf

        .import         _cgetc, _cputc
        .import         popax, pushax, swapstk

        .include        "../common/_scanf.inc"


; static bool pushed;
; static char back;
;
        .bss
pushed: .res    1
back:   .res    1

        .code
; /* Call-back functions:
; ** (Note:  These prototypes must NOT be declared with fastcall!  They don't
; ** use (getfunc)'s and (ungetfunc)'s last parameter.  Leaving it out of these
; ** prototypes makes more efficient code.)
; */

; ----------------------------------------------------------------------------
; /* Read a character from the console, and return it to an internal function */
; static int get(void) {
;     static char C;
;
;     if (pushed) {
;         pushed = false;
;         return (int)back;
;         }
;     cputc(C = cgetc());       /* echo a typed character */
;     return (int)C;
;     }
;
get:    ldx     pushed
        beq     L1

; Return the old, pushed-back character (instead of getting a new one).
;
        dex                     ; ldx #>$0000
        stx     pushed
        lda     back
        rts

; Directly read the keyboard.
;
L1:     jsr     _cgetc

; Echo the character to the screen.
;
        pha
        jsr     _cputc
        pla
        ldx     #>$0000
        rts


; ----------------------------------------------------------------------------
; static int cdecl unget(int c) {
;     pushed = true;
;     return back = c;
;     }
;
unget:  ldx     #1
        stx     pushed
        jsr     popax           ; get the first argument
        sta     back
        rts


; ----------------------------------------------------------------------------
; int fastcall vcscanf(const char* format, va_list ap) {
;     /* Initiate the data structure.
;     ** Don't initiate the member that these conio functions don't use.
;     */
;     static const struct scanfdata d = {
;         (  getfunc)  get,
;         (ungetfunc)unget
;         };
;
;     /* conio is very interactive.  So, don't use any pushed-back character.
;     ** Start fresh, each time that this function is called.
;     */
;     pushed = false;
;
;     /* Call the internal function, and return the result. */
;     return _scanf(&d, format, ap);
;     }
;
; Beware:  Because ap is a fastcall parameter, we must not destroy .XA.
;
        .proc   _vcscanf

; ----------------------------------------------------------------------------
; Static, constant scanfdata structure for the _vcscanf routine.
;
        .rodata
d:      .addr   get             ; SCANFDATA::GET
        .addr   unget           ; SCANFDATA::UNGET
;       .addr   0               ; SCANFDATA::DATA (not used)

        .code
        pha                     ; Save low byte of ap
        txa
        pha                     ; Save high byte of ap
        ldx     #0
        stx     pushed

; Put &d on the stack in front of the format pointer.

        lda     #<d
        ldx     #>d
        jsr     swapstk         ; Swap .XA with top-of-stack
        jsr     pushax          ; Put format pointer back on stack

; Restore ap, and jump to _scanf which will clean up the stack.

        pla
        tax
        pla
        jmp     __scanf
        .endproc