]> git.sur5r.net Git - cc65/blob - libsrc/common/atoi.s
65c02 optimization
[cc65] / libsrc / common / atoi.s
1 ;
2 ; Ullrich von Bassewitz, 05.06.1998
3 ;
4 ; int atoi (const char* s);
5 ; long atol (const char* s);
6 ;
7
8         .export         _atoi, _atol
9         .import         __ctype
10         .importzp       sreg, ptr1, ptr2, tmp1
11
12 ;
13 ; Conversion routine (32 bit)
14 ;
15
16 _atoi:
17 _atol:  sta     ptr1            ; Store s
18         stx     ptr1+1
19         ldy     #0
20         sty     ptr2
21         sty     ptr2+1          ; initial value (32 bit)
22         sty     sreg
23         sty     sreg+1
24
25 ; Skip whitespace
26
27 L1:     lda     (ptr1),y
28         tax
29         lda     __ctype,x       ; get character classification
30         and     #$80            ; tab or space?
31         beq     L2              ; jump if no
32         iny
33         bne     L1
34         inc     ptr1+1
35         bne     L1              ; branch always
36
37 ; Check for a sign. The character is in X
38
39 L2:     txa                     ; get char
40         ldx     #0              ; flag: positive
41         cmp     #'+'            ; ### portable?
42         beq     L3
43         cmp     #'-'            ; ### portable?
44         bne     L5
45         dex                     ; flag: negative
46 L3:     iny
47         bne     L5
48         inc     ptr1+1
49
50 ; Store the sign flag and setup for conversion
51
52 L5:     stx     tmp1            ; remember sign flag
53
54 L6:     lda     (ptr1),y        ; get next char
55         tax
56         lda     __ctype,x       ; get character classification
57         and     #$04            ; digit?
58         beq     L8              ; done
59
60 ; Multiply ptr2 (the converted value) by 10
61
62         jsr     mul2            ; * 2
63
64         lda     sreg+1
65         pha
66         lda     sreg
67         pha
68         lda     ptr2+1
69         pha
70         lda     ptr2
71         pha                     ; Save value
72
73         jsr     mul2            ; * 4
74         jsr     mul2            ; * 8
75
76         clc
77         pla
78         adc     ptr2
79         sta     ptr2
80         pla
81         adc     ptr2+1
82         sta     ptr2+1
83         pla
84         adc     sreg
85         sta     sreg
86         pla
87         adc     sreg+1
88         sta     sreg+1          ; x*2 + x*8 = x*10
89
90 ; Get the character back and add it
91
92         txa                     ; get char back
93         sec
94         sbc     #'0'            ; make numeric value
95         clc
96         adc     ptr2
97         sta     ptr2
98         bcc     L7
99         inc     ptr2+1
100         bne     L7
101         inc     sreg
102         bne     L7
103         inc     sreg+1
104
105 ; Next character
106
107 L7:     iny
108         bne     L6
109         inc     ptr1+1
110         bne     L6
111
112 ; Conversion done. Be shure to negate the value if needed.
113
114 L8:     lda     ptr2
115         ldx     ptr2+1
116         ldy     tmp1            ; sign
117         beq     L9
118
119 ; Negate the 32 bit value in ptr2/sreg
120
121         sec
122         lda     ptr2
123         eor     #$FF
124         adc     #0
125         sta     ptr2
126         lda     ptr2+1
127         eor     #$FF
128         adc     #0
129         sta     ptr2+1
130         lda     sreg
131         eor     #$FF
132         adc     #0
133         sta     sreg
134         lda     sreg+1
135         eor     #$FF
136         adc     #0
137         sta     sreg+1
138
139 ; Done, load the low 16 bit into A/X
140
141 L9:     lda     ptr2
142         ldx     ptr2+1          ; get value
143         rts
144
145 ;
146 ; Helper functions
147 ;
148
149 mul2:
150         asl     ptr2
151         rol     ptr2+1
152         rol     sreg
153         rol     sreg+1          ; * 2
154         rts
155
156