;VERSION060 SET 1

;/** TT_MulDiv **************************************/

	XDEF	_TT_MulDiv
	CNOP	0,4

	IFND VERSION060


_TT_MulDiv:		;'(a*b/c)

	move.l	d2,a0
	
	movem.l	4(sp),d0-d2

	muls.l	d1,d1:d0
	divs.l	d2,d1:d0

	move.l	a0,d2
	rts

	ELSE

_TT_MulDiv:
	
	move.l	d2,a0
	
	movem.l	4(sp),d0-d2

	fmove.l	d0,fp0
	fmul.l	d1,fp0
	fdiv.l	d2,fp0
	fmove.l	fp0,d0
	
	move.l	a0,d2
	rts
	
	ENDC

;/** TT_MulFix **************************************/

	XDEF	_TT_MulFix
	CNOP	0,4

	IFND	VERSION060

_TT_MulFix:

	movem.l	4(sp),d0/d1
	muls.l	d1,d1:d0
	
	bmi.s		.negativ

	add.l		#$8000,d0
	bhs.s		.nooverflow
	addq.l	#1,d1

.nooverflow:
	move		d1,d0
	swap		d0
	rts

	CNOP	0,4

.negativ:
	sub.l		#$8000,d0
	bhs.s		.nooverflow2
	subq.l	#1,d1
	
.nooverflow2:
	move		d1,d0
	swap		d0
	rts
	
	ELSE
	
_TT_MulFix:
	
	movem.l	4(sp),d0/d1
	fmove.l	d0,fp0
	fmul.l	d1,fp0
	fblt		.negativ
	fadd.l	#$8000,fp0
	fmul.x	#0.0000152587890625,fp0		;' x 1/65536
	fmove.l	fp0,d0
	rts

	CNOP	0,4
	
.negativ:
	fsub.l	#$8000,fp0
	fmul.x	#0.0000152587890625,fp0		;' x 1/65536
	fmove.l	fp0,d0
	rts

	ENDC

;/** Add64 **************************************/

	XDEF	_Add64
	CNOP	0,4
	
_Add64:
	movem.l	4(sp),a0/a1
	movem.l	(a0),d0/d1
	add.l		(a1)+,d0
	bhs.s		.nooverflow
	
	addq.l	#1,d1

.nooverflow:
	add.l		(a1),d1
	
	move.l	12(sp),a0
	movem.l	d0/d1,(a0)
	rts

;/** Sub64 **************************************/

	XDEF	_Sub64
	CNOP	0,4
	
_Sub64:
	movem.l	4(sp),a0/a1
	movem.l	(a0),d0/d1
	sub.l		(a1)+,d0
	bhs.s		.nooverflow
	
	subq.l	#1,d1

.nooverflow:
	sub.l		(a1),d1
	
	move.l	12(sp),a0
	movem.l	d0/d1,(a0)
	rts

;/** MulTo64 **************************************/


	XDEF	_MulTo64
	CNOP	0,4

	IFND	VERSION060
	
_MulTo64:
	movem.l	4(sp),d0/d1/a0
	muls.l	d1,d1:d0
	movem.l	d0/d1,(a0)
	rts

	ELSE
	
_MulTo64:	;'based on ADoom (C) Peter McGavin
	movem.l	4(sp),d0/d1/a0

	movem.l	d2-d5,-(sp)

	clr.b		d5          ; clear sign tag
	tst.l		d0          ; multiplier negative?
	bge		.not1
	neg.l		d0
	or.b		#1,d5

.not1
	tst.l		d1          ; multiplicand negative?
	bge		.not2
	neg.l		d1
	eor.b		#1,d5

.not2
	move.l	d0,d2       ; mr
	move.l	d0,d3       ; mr
	move.l	d1,d4       ; md
	swap		d3          ; hi_mr in lo d3
	swap		d4          ; hi_md in lo d4

	mulu.w	d1,d0       ; [1] lo_mr * lo_md
	mulu.w	d3,d1       ; [2] hi_mr * lo_md
	mulu.w	d4,d2       ; [3] lo_mr * hi_md
	mulu.w	d4,d3       ; [4] hi_mr * hi_md

	clr.l		d4
	swap		d0
	add.w		d1,d0
	addx.l	d4,d3
	add.w		d2,d0
	addx.l	d4,d3
	swap		d0

	clr.w		d1
	clr.w		d2

	swap		d1
	swap		d2
	add.l		d2,d1
	add.l		d3,d1

	tst.b		d5          ; check sign of result
	beq		.skip

	not.l		d0
	not.l		d1
	addq.l	#1,d0
	addx.l	d4,d1

.skip
	movem.l	d0/d1,(a0)

	movem.l	(sp)+,d2-d5
	rts

	ENDC

;/** Div64by32 **************************************/

	XDEF	_Div64by32
	CNOP	0,4

_Div64by32:
	move.l	4(sp),a0
	movem.l	(a0),d0/d1
	divs.l	8(sp),d1:d0
	rts


	END

