; long atol (const char* s);
;
- .export _atoi, _atol
- .import negeax, __ctype
- .importzp sreg, ptr1, ptr2, tmp1
+ .export _atoi, _atol
+ .import negeax, __ctype
+ .importzp sreg, ptr1, ptr2, tmp1
.include "ctype.inc"
;
_atoi:
-_atol: sta ptr1 ; Store s
- stx ptr1+1
- ldy #0
- sty ptr2
- sty ptr2+1 ; initial value (32 bit)
- sty sreg
- sty sreg+1
+_atol: sta ptr1 ; Store s
+ stx ptr1+1
+ ldy #0
+ sty ptr2
+ sty ptr2+1 ; initial value (32 bit)
+ sty sreg
+ sty sreg+1
; Skip whitespace
-L1: lda (ptr1),y
- tax
- lda __ctype,x ; get character classification
- and #CT_SPACE_TAB ; tab or space?
- beq L2 ; jump if no
- iny
- bne L1
- inc ptr1+1
- bne L1 ; branch always
+L1: lda (ptr1),y
+ tax
+ lda __ctype,x ; get character classification
+ and #CT_SPACE_TAB ; tab or space?
+ beq L2 ; jump if no
+ iny
+ bne L1
+ inc ptr1+1
+ bne L1 ; branch always
; Check for a sign. The character is in X
-L2: txa ; get char
- ldx #0 ; flag: positive
- cmp #'+' ; ### portable?
- beq L3
- cmp #'-' ; ### portable?
- bne L5
- dex ; flag: negative
+L2: txa ; get char
+ ldx #0 ; flag: positive
+ cmp #'+' ; ### portable?
+ beq L3
+ cmp #'-' ; ### portable?
+ bne L5
+ dex ; flag: negative
L3: iny
- bne L5
- inc ptr1+1
+ bne L5
+ inc ptr1+1
; Store the sign flag and setup for conversion
-L5: stx tmp1 ; remember sign flag
+L5: stx tmp1 ; remember sign flag
-L6: lda (ptr1),y ; get next char
- tax
- lda __ctype,x ; get character classification
- and #$04 ; digit?
- beq L8 ; done
+L6: lda (ptr1),y ; get next char
+ tax
+ lda __ctype,x ; get character classification
+ and #$04 ; digit?
+ beq L8 ; done
; Multiply ptr2 (the converted value) by 10
- jsr mul2 ; * 2
-
- lda sreg+1
- pha
- lda sreg
- pha
- lda ptr2+1
- pha
- lda ptr2
- pha ; Save value
-
- jsr mul2 ; * 4
- jsr mul2 ; * 8
-
- clc
- pla
- adc ptr2
- sta ptr2
- pla
- adc ptr2+1
- sta ptr2+1
- pla
- adc sreg
- sta sreg
- pla
- adc sreg+1
- sta sreg+1 ; x*2 + x*8 = x*10
+ jsr mul2 ; * 2
+
+ lda sreg+1
+ pha
+ lda sreg
+ pha
+ lda ptr2+1
+ pha
+ lda ptr2
+ pha ; Save value
+
+ jsr mul2 ; * 4
+ jsr mul2 ; * 8
+
+ clc
+ pla
+ adc ptr2
+ sta ptr2
+ pla
+ adc ptr2+1
+ sta ptr2+1
+ pla
+ adc sreg
+ sta sreg
+ pla
+ adc sreg+1
+ sta sreg+1 ; x*2 + x*8 = x*10
; Get the character back and add it
- txa ; get char back
- sec
- sbc #'0' ; make numeric value
- clc
- adc ptr2
- sta ptr2
- bcc L7
- inc ptr2+1
- bne L7
- inc sreg
- bne L7
- inc sreg+1
+ txa ; get char back
+ sec
+ sbc #'0' ; make numeric value
+ clc
+ adc ptr2
+ sta ptr2
+ bcc L7
+ inc ptr2+1
+ bne L7
+ inc sreg
+ bne L7
+ inc sreg+1
; Next character
-L7: iny
- bne L6
- inc ptr1+1
- bne L6
+L7: iny
+ bne L6
+ inc ptr1+1
+ bne L6
; Conversion done. Load the low 16 bit into A/X
; Negate the value if necessary, otherwise we're done
- ldy tmp1 ; sign
- beq L9 ; Branch if positive
+ ldy tmp1 ; sign
+ beq L9 ; Branch if positive
; Negate the 32 bit value in ptr2/sreg
; Helper functions
;
-mul2: asl ptr2
- rol ptr2+1
- rol sreg
- rol sreg+1 ; * 2
+mul2: asl ptr2
+ rol ptr2+1
+ rol sreg
+ rol sreg+1 ; * 2
L9: rts