; Routine for converting an ASCII string to a 64 bit integer in any base.
; X-Calibre, Diamond Crew 2000

ParseRadixUnsigned	PROC
; Input:	Pointer to zero-terminated string in ESI, radix in EDI
; Output:	Parsed number in EDX::EAX
; Uses:		EAX, EBX, ECX, EDX, ESI, EDI

	xor		ebx, ebx

	; result in EDX::EAX
	xor		eax, eax
	xor		edx, edx

	mov		al, [esi]
	inc		esi
	test	eax, eax
	jz		@@endOfParsing

	sub		eax, 30h
	.IF eax > 9
		sub		eax, 7
	.ENDIF

	mov		bl, [esi]

@@smallParseLoop:
	; ASCII to number conversion
	sub		ebx, 30h
	inc		esi
	mul		edi
	.IF ebx > 9
		sub		ebx, 7
	.ENDIF
	add		eax, ebx
	mov		bl, [esi]
	jc		@@carry
	test	ebx, ebx
	jnz		@@smallParseLoop
	
	ret

@@carry:
	inc		edx
	test	ebx, ebx
	jz		@@endOfParsing

@@bigParseLoop:
	; ASCII to number conversion
	mov		ecx, eax
	mov		eax, edx
	sub		ebx, 30h
	inc		esi
	mul		edi
	xchg	eax, ecx
	mul		edi
	.IF ebx > 9
		sub		ebx, 7
	.ENDIF
	add		eax, ebx
	mov		bl, [esi]
	adc		edx, ecx

	test	ebx, ebx
	jnz		@@bigParseLoop

@@endOfParsing:
	ret
ParseRadixUnsigned	ENDP

ParseRadixSigned	PROC
; Input:	Pointer to zero-terminated string in ESI, radix in EDI
; Output:	Parsed number in EDX::EAX
; Uses:		EAX, EBX, ECX, EDX, ESI, EDI

	.code
	; If string does not start with a '-', consider it positive
	cmp		byte ptr [esi], '-'
	jne		ParseRadixUnsigned

	; Number is negative, first parse the absolute value
	inc		esi

	call	ParseRadixUnsigned

	; Now negate the absolute value to get the negative result
	neg		edx
	neg		eax
	sbb		edx, 0

	ret
ParseRadixSigned	ENDP
