
*	Maxon C++:
*
*	Library-Modul "strtodoub"
*
*	Jens Gelhar 28.10.91

	xdef	_strtod,strtod__PCcPPc
	xdef	_atof,atof__PCc

	xref	_errno,GetDoubmath,_pwr10

i3edpNeg	= -60
i3edpAdd	= -66
i3edpMul	= -78

_atof:
atof__PCc:	clr.l -(a7)
	move.l 8(a7),-(a7)
	bsr.b strtod__PCcPPc
	addq.l #8,a7
	rts

_strtod:
strtod__PCcPPc:	; Stack-Parameter: const char*, char**
	movem.l d2/d3/d4/a0/a1/a6,-(a7)
	move.l 6*4+4(a7),a0
	bsr.b Conv
	move.l 6*4+8(a7),d2
	beq.b oikeia
	subq.l #1,a0
	exg d2,a0
	move.l d2,(a0)
oikeia:	movem.l (a7)+,d2/d3/d4/a0/a1/a6
	rts

Conv:	; von (a0) nach d0|d1
	jsr GetDoubmath
overrd:	move.b (a0)+,d4
	beq Wargarnix
	cmp.b #' ',d4
	blo.b overrd
	cmp.b #'-',d4
	bne.b cvlr1
	move.b (a0)+,d4
	bsr.b cvlr2
	jmp i3edpNeg(a6)
cvlr1:	cmp.b #'+',d4
	bne.b cvlr2
	move.b (a0)+,d4
cvlr2:	subq.l #1,a0
	bsr DoubleIntString
	moveq #0,d2
cvlr3:	; gibt's noch mehr Ziffern?
	move.b (a0)+,d4
	cmp.b #'0',d4
	blo.b cvlr4
	cmp.b #'9',d4
	bhi.b cvlr4
	addq.l #1,d2
	bra.b cvlr3
cvlr4:	tst.l d2
	beq.b cvlr5
	move.l a0,-(a7)
	movem.l d0/d1,-(a7)
	bsr Zehnhoch
	movem.l (a7)+,d2/d3
	jsr i3edpMul(a6)
	move.l (a7)+,a0
	move.b -1(a4),d4
cvlr5:	cmp.b #'.',d4
	bne.b cvlr7
	; Nachkommastellen:
	movem.l d0/d1,-(a7)
	move.l a0,-(a7)
	bsr DoubleIntString
	move.l a0,d2
	sub.l (a7)+,d2
	neg.l d2
	move.l a0,-(a7)
	movem.l d0/d1,-(a7)
	bsr.b Zehnhoch
	movem.l (a7)+,d2/d3
	jsr i3edpMul(a6)
	move.l (a7)+,a0
	movem.l (a7)+,d2/d3
	move.l a0,-(a7)
	jsr i3edpAdd(a6)
	move.l (a7)+,a0
cvlr6:	; noch mehr Nachkommastellen?
	move.b (a0)+,d4
	cmp.b #'0',d4
	blo.b cvlr7
	cmp.b #'9',d4
	bls.b cvlr6
cvlr7:	; Exponententeil?
	cmp.b #'e',d4
	beq.b cvExponent
	cmp.b #'E',d4
	bne.b cvRet
cvExponent:	movem.l d0/d1,-(a7)
	cmp.b #'-',(a0)
	bne.b cvPosExpo
	addq.l #1,a0
	bsr IntString
	neg.l d0
	bra.b cvExpoD0
cvPosExpo:
	cmp.b #'+',(a0)
	bne.b cvUnsigExpo
	addq.l #1,a0
cvUnsigExpo:
	bsr IntString
cvExpoD0:	move.w d0,d2
	bsr.b Zehnhoch
	movem.l (a7)+,d2/d3
	pea 1(a0)
	jsr i3edpMul(a6)
	move.l (a7)+,a0
cvRet:	rts

Wargarnix:	move.l #1001,_errno
	moveq #0,d0
	moveq #0,d1
	rts


Zehnhoch:	; Potenz d2
	ext.l d2
	move.l d2,-(a7)
	jsr _pwr10
	move.l (a7)+,d2
	rts

DoubleIntString:	; Ab a0 Ziffernfolge als "Double" lesen
	bsr.b IntString
	tst.l d0
	bne.b nonzero
	tst.l d1
	bne.b nonzero
	rts
nonzero	move.l d2,-(a7)
	move.l #$3FF+52,d2
	exg d0,d1

	cmp.l #$00200000,d0
	bhs.b zugross
	; Linksshifts:
zuklein	cmp.l #$00100000,d0
	bhs.b mountdoub
	asl.l #1,d1
	roxl.l #1,d0
	subq.w #1,d2
	bra.b zuklein

zugross	; Rechstshifts:
	cmp.l #$00200000,d0
	blo.b mountdoub
	lsr.l #1,d0
	roxr.l #1,d1
	addq.w #1,d2
	bra.b zugross
mountdoub
	swap d2
	asl.l #4,d2
	and.l #$000FFFFF,d0
	or.l d2,d0
	move.l (a7)+,d2
	rts

IntString:	; Ab a0 "int" lesen, nach d0|d1
	moveq #0,d0
	moveq #0,d1
	move.l d4,-(a7)
intsLoop
	; d0|d1 *= 10:
	moveq #0,d4
	move.b (a0)+,d4
	sub.b #'0',d4
	cmp.w #9,d4
	bhi.b intsEnd
	move.l d0,-(a7)
	move.l d1,-(a7)
	asl.l #1,d0
	roxl.l #1,d1
	asl.l #1,d0
	roxl.l #1,d1
	add.l (a7)+,d1
	add.l (a7)+,d0
	bhs.b intscarry
	addq.l #1,d1
intscarry
	asl.l #1,d0
	roxl.l #1,d1
	add.l d4,d0
	bhs.b intscarry1
	addq.l #1,d1
intscarry1
	cmp.l #$7FFFFFFF/5,d1
	bls.b intsLoop

	addq.l #1,a0
intsEnd	move.l (a7)+,d4
	subq.l #1,a0
	rts

	end
