
*	Maxon C++:
*
*	Library-Modul "strtoint.o"
*
*	Jens Gelhar 06.11.91
*
*	All rights reversed - warranty void

	xdef	_strtovl,strtovl__PCcPPci
	xdef	_strtouvl,strtouvl__PCcPPci
	xdef	_strtol,strtol__PCcPPci
	xdef	_strtoul,strtoul__PCcPPci
	xdef	_atol,atol__PCc
	xdef	_atoi,atoi__PCc
	xdef	_uintmult

	xref	_errno

_atol:
atol__PCc:
_atoi:
atoi__PCc:	move.l d1,-(a7)
	pea 10.w
	clr.l -(a7)
	move.l 8+8(a7),-(a7)
	bsr _strtovl
atoiin	lea 12(a7),a7
	tst.l d1
	bmi.b minus
	bne.b overflow
	tst.l d0
	bpl.b atoiok
overflow
	move.l #$7FFFFFFF,d0
	bra.b atoiok
minus	addq.l #1,d1
	bne.b underflow
	tst.l d0
	bmi.b atoiok
underflow
	move.l #$80000000,d0
atoiok	move.l (a7)+,d1
	rts

_strtol:
strtol__PCcPPci:
	move.l d1,-(a7)
	move.l 8+8(a7),-(a7)            ; Parameter kopieren
	move.l 8+8(a7),-(a7)
	move.l 8+8(a7),-(a7)
	bsr.b _strtovl
	bra.b atoiin

_strtoul:
strtoul__PCcPPci:
	move.l d1,-(a7)
	move.l 8+8(a7),-(a7)            ; Parameter kopieren
	move.l 8+8(a7),-(a7)
	move.l 8+8(a7),-(a7)
	bsr.b _strtouvl
	lea 12(a7),a7
	tst.l d1
	beq.b stul1
	moveq #-1,d0
stul1:	move.l (a7)+,d1
	rts

_strtouvl:
strtouvl__PCcPPci:
	movem.l d2-d4/a0,-(a7)
	move.l 4*4+4(a7),a0     ; Zeiger auf Zeichenkette
	bsr Overread
	tst.b d2
	beq warnix
	move.l 4*4+12(a7),d4
	cmp.b #'+',d2
	bne.b ulconv
	move.b (a0)+,d2
ulconv	bsr.b Convert
	bra End

_strtovl:
strtovl__PCcPPci:	; Stack-Parameter: char*, char**, int base
	movem.l d2-d4/a0,-(a7)
	move.l 4*4+4(a7),a0     ; Zeiger auf Zeichenkette
	bsr Overread
	tst.b d2
	beq warnix
	move.l 4*4+12(a7),d4    ; Basis?
	cmp.b #'-',d2
	bne.b positiv
	move.b (a0)+,d2
	beq warnix
	; Zahl mit "-":
	bsr.b Convert
	tst.l d1
	bpl.b negativ
	moveq #0,d0
	move.l #$80000000,d1
	bra ERanEnd
negativ	not.l d0
	not.l d1
	addq.l #1,d0
	bhs End
	addq.l #1,d1
	bra ERanEnd

positiv	cmp.b #'+',d2
	bne.b posit1
	move.b (a0)+,d2
	beq warnix
posit1	bsr.b Convert
	tst.l d1
	bpl End
	moveq #-1,d0
	move.l #$7FFFFFFF,d1
	bra ERanEnd

Convert:
	; String a0, erste Ziffer d2, Basis-Parameter d4
	moveq #0,d0
	moveq #0,d1
	cmp.w #2,d4
	blo.b whichbase
	cmp.w #36,d4
	blo.b isitanumber
whichbase
	; ersma' Basis feststellen:
	cmp.b #'0',d2
	bne.b decimal
	move.b (a0)+,d2
	moveq #8,d4
	cmp.b #'x',d2
	beq.b Hex
	cmp.b #'X',d2
	bne.b thisbase
Hex	move.b (a0)+,d2
	moveq #16,d4
	bra.b isitanumber
decimal	blo.b mumpitz
	cmp.b #'9',d2
	bhi.b mumpitz
	moveq #10,d4
isitanumber:	; d2 wäre erste Ziffer - aber ist es eine?
	bsr.b whichdigit
	cmp.w d4,d3
	bhs.b mumpitz
thisbase
	bsr.b whichdigit
	cmp.w d4,d3
	bhs.b convEnde
	move.l d3,-(a7)
	move.l d4,d2
	moveq #0,d3
	bsr _uintmult
	add.l (a7)+,d0
	bhs.b nocarry
	addq.l #1,d1
nocarry	move.b (a0)+,d2
	bne.b thisbase
convEnde
	rts
mumpitz	; Zahl ohne Ziffer!
	move.l #1001,_errno
	rts

whichdigit:	; d2.b in Ziffer wandeln (nach d3)
	moveq #0,d3
	move.b d2,d3
	sub.b #'0',d3
	blo.b nodigitatall
	cmp.w #9,d3
	bls.b adigit
	subq.w #'A'-'0'-10,d3
	cmp.w #10,d3
	blo.b nodigitatall
	cmp.w #36,d3
	blo.b adigit
	sub.w #'a'-'A',d3
	cmp.w #10,d3
	blo.b nodigitatall
	cmp.w #36,d3
	blo.b adigit
nodigitatall	moveq #-1,d3
adigit	rts

warnix:	; keine Zahl da!
	move.l #1001,_errno
	moveq #0,d0
	moveq #0,d1
	bra.b End
ERanEnd	move.l #1000,_errno
End
	move.l 4*4+8(a7),d2
	beq.b ret
	subq.l #1,a0
	exg d2,a0               ; Zeiger auf Rest
	move.l d2,(a0)
ret	movem.l (a7)+,d2-d4/a0
	rts

Overread:	; Spaces etc. überlesen, erstes Zeichen nach d2
	move.b (a0)+,d2
	beq.b ovrret
	cmp.b #' ',d2
	bls.b Overread
ovrret	rts

_uintmult:	; d0|d1 *= d2|d3, d7 = überlauf-flag
	movem.l d4-d7,-(a7)
	move.l d0,d4
	move.l d1,d5
	moveq #63,d6    ; Zähler
	moveq #0,d0
	moveq #0,d1
	moveq #0,d7
multLoop	asl.l #1,d0
	roxl.l #1,d1
	blo.b multOvr
	asl.l #1,d2
	roxl.l #1,d3
	bhs.b multNext
	add.l d5,d1
	blo.b multOvr
	add.l d4,d0
	bhs.b multNext
	addq.l #1,d1
	blo.b multOvr
multNext dbra d6,multLoop
multRet	movem.l (a7)+,d4-d7
	rts
multOvr	moveq #-1,d0
	moveq #-1,d1
	move.l #1000,_errno
	bra.b multRet

	end
