;
; Ullrich von Bassewitz, 05.06.1998
;
; int atoi (const char* s);
; long atol (const char* s);
;

	.export		_atoi, _atol
       	.import	       	__ctype
	.importzp	sreg, ptr1, ptr2, tmp1

;
; Conversion routine (32 bit)
;

.segment "LIBCODE"
_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

; Skip whitespace

L1:	lda	(ptr1),y
	tax
	lda    	__ctype,x	; get character classification
	and	#$80	 	; 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
L3:     iny
  	bne	L5
  	inc	ptr1+1

; Store the sign flag and setup for conversion

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

; 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

; 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

; Next character

L7:	iny
   	bne	L6
   	inc	ptr1+1
   	bne	L6

; Conversion done. Be shure to negate the value if needed.

L8:	lda	ptr2
	ldx	ptr2+1
	ldy	tmp1		; sign
	beq	L9

; Negate the 32 bit value in ptr2/sreg

	sec
	lda	ptr2
	eor	#$FF
	adc	#0
	sta	ptr2
	lda	ptr2+1
	eor	#$FF
	adc	#0
	sta	ptr2+1
	lda	sreg
	eor	#$FF
	adc	#0
	sta	sreg
	lda	sreg+1
	eor	#$FF
	adc	#0
	sta	sreg+1

; Done, load the low 16 bit into A/X

L9:	lda	ptr2
	ldx	ptr2+1		; get value
	rts

;
; Helper functions
;

mul2:
	asl	ptr2
    	rol	ptr2+1
    	rol	sreg
    	rol	sreg+1		; * 2
    	rts


