;----------------------------------------------------------------------------
expref		=	(1<<15)
pos_expref	=	expref
neg_expref	=	(1<<31)|pos_expref
;----------------------------------------------------------------------------
;-------------------------------------
RA_mul:
	bchg	#15,d2			;4	x1 signed
	bchg	#15,d0			;4	x0 signed
	add	d2,d0			;2	x0 = x0+x1  signed
	bvc.s	RA_mul_exp_ok		;2	if no overflow, go on
	bpl.s	RA_mul_zero_f0		;2	if VS&PL, go zero f0
;here we have VS&MI meaning a magnitude overflow, unless either factor is 0
	tst.l	d3			;2	m1 != 0 ?
	beq.s	RA_mul_zero_f0		;2	else go zero f0
	tst.l	d1			;2	m0 == 0 ?
	bne.s	RA_set_ofl		;2	else go maximize f0
RA_mul_zero_f0:
	clr.l	d1			;2	m0 = 0
	clr	d0			;2	s0:x0 = 0:0
	rts				;2	exit
;-------
RA_mul_exp_ok:
	move.l	d3,d2			;2	d2 = m1
	beq.s	RA_mul_zero_f0		;2	if zero, go zero f0
	tst.l	d1			;2	m0 != 0 ?
	beq.s	RA_mul_zero_f0		;2	else go zero f0
	move.l	d4,-(sp)		;2	push d4
	move	d3,d4			;2	d4 = m1L
	mulu	d1,d2			;2	d2 = m0L*m1L  X1:X0
	swap	d1			;2	d1 = m0L:m0H
	mulu	d1,d4			;2	d4 = m0H*m1L  Y2:Y1
	clr	d2			;2	d2 = X1:0
	swap	d2			;2	d2 = 0:X1
	add.l	d4,d2			;2	d2 = (Y2:Y1)+(0:X1)
	swap	d3			;2	d3 = m1L:m1H
	move	d3,d4			;2	d4 = m1H
	mulu	d1,d4			;2	d4 = m0H*m1H  Z3:Z2
	swap	d1			;2	d1 = m0H:m0L
	mulu	d3,d1			;2	d1 = m1H*m0L  T2:T1
	add.l	d2,d1			;2	c.d1 = (T2:T1)+(Y2:Y1)+X1 ck.K2:P1
	move	d1,d2			;2	d2 = P1
	clr	d1			;2	c.d1 = ck.K2:0
	swap	d1			;2	c.d1 = ck.0:K2
	roxr.w	#1,d1			;2	d1.c = (0:ck.K2).K2b0
	roxl.l	#1,d1			;2	d1 = ck:K2
	add.l	d4,d1			;2	d1 = (Z3:Z2)+(ck:K2)  P3:P2
	move.l	(sp)+,d4		;2	pull d4
	tst.l	d1			;2
	bmi.s	.d1_is_normal		;2	if bit 31 set, go keep it as_is
	roxl.w	#1,d2			;2	c = top bit of P1
	roxl.l	#1,d1			;2	d1 = normalized mantissa
	subq	#1,d0			;2	x0 -= 1
	bvs.s	RA_mul_zero_f0		;2	if x0 too low, go zero f0
.d1_is_normal:
	bchg	#15,d0			;4	x0 unsigned
	rts				;2	exit
;-------------------------------------
;Byte count: RA_mul		;102
;-------------------------------------
;-------------------------------------
RA_div:
	tst.l	d3			;2	m1 == 0 ?
	bne.s	RA_div_proceed		;2	else proceed normally
RA_set_ofl:	;here we have a magnitude overflow, to flag with VS&NE&MI
	moveq	#-1,d1			;2	d1 = $FFFFFFFF
	lsr.l	#1,d1			;2	d1 = $7FFFFFFF  x=1
	move	d1,d0			;2	d0 = $FFFF
	addx	d1,d1			;2	d1 = $FFFFFFFF
	rts				;2	exit with VS*NE
;-------
;NB: The real sign remains in d0 bit 31 after RA_set_ofl
;-------
;
RA_div_proceed:
	bchg	#15,d2			;4	x1 signed
	bchg	#15,d0			;4	x0 signed
	sub	d2,d0			;2	x0 = x0-x1  signed
	bvc.s	RA_div_exp_diff_ok	;2	if no overflow, go on
	bcc.s	RA_div_zero_f0		;2	if VS&CC, go zero f0
	tst.l	d1			;2	m0 == 0 ?
	bne.s	RA_max_float		;2	else go maximize f0
RA_div_zero_f0:
	clr.l	d1			;2	m0 = 0
	clr	d0			;2	s0:x0 = 0:0
	rts				;2	exit
;-------
RA_div_exp_diff_ok:
	tst.l	d1			;2	m0 != 0 ?
	beq.s	RA_div_zero_f0		;2	else go zero f0
	addq	#1,d0			;2	adjust x0 for quotient
	bvs.s	RA_max_float		;2	if x0 too high, go maximize f0
	clr.l	d2			;2	preclear quotient mantissa
	move.l	d4,-(sp)		;2	push d4
	moveq	#32-1,d4		;2	allow 32 bits in mantissa
	cmp.l	d3,d1			;2	Would top quotient bit be set ?
	bhs.s	.div_set		;2	then go do so now
	subq	#1,d0			;2	x0 -= 1
	bvs.s	RA_div_zero_f0		;2	if x0 too low, go zero f0
	asl.l	#1,d1			;2	realign m1, causing carry set
.div_loop:				;---	loop start
	bcs.s	.div_set		;2	go set&subtract after carry out
	cmp.l	d3,d1			;2	else compare if subtraction OK
	blo.s	.div_step		;2	if not, then skip set&subtract
.div_set:
	sub.l	d3,d1			;2	subract divisor from dividend
	bset	d4,d2			;2	set bit in quotient mantissa
.div_step:
	asl.l	#1,d1			;2	shift dividend, may cause carry 
	dbra	d4,.div_loop		;4	loop back for all quotient bits
	move.l	(sp)+,d4		;2	pull d4
	move.l	d2,d1			;2	m1 = quotient mantissa
	bchg	#15,d0			;2	x0 unsigned
	rts				;2
;-------------------------------------
;Byte count: RA_div		;86
;-------------------------------------
;-------------------------------------
RA_max_float:
	moveq	#-1,d1			;2	m0 = $FFFFFFFF
	move	d1,d0			;2	x0 = $FFFF
	rts				;2	exit
;-------------------------------------
;Byte count: RA_max_float	;6
;-------------------------------------
;-------------------------------------
RA_align_f0f1:
	sub	d0,d2			;2	d2 = s1:x1-x0
	blo.s	.align_f1		;2	if x1<x0 go align f1
	beq.s	.exit			;2	if x1==x0 go exit
.align_f0:				;-	x1>x0 => align f0 here
	add	d2,d0			;2	d0 = s0:x1
	cmp	#32,d2			;4	shift < 32 bits ?
	bhs.s	RA_fix_d2_zero_f0	;2	else go zero f0
	lsr.l	d2,d1			;2	m1 >>= (x1-x0)
	move	d0,d2			;2	d2 = s1:x1
.exit:
	rts				;2	exit
;-------
.align_f1:				;-	x1>x0 => align f0 here
	neg	d2			;2	d2 =s1:x0-x1
	cmp	#32,d2			;4	shift < 32 bits
	bhs.s	RA_zero_f1		;2	else go zero f1
.shift_f1:
	lsr.l	d2,d3			;2	m1 >>= (x0-x1)
	move	d0,d2			;2	d2 = s1:x0
	rts				;2	exit
;-------
RA_zero_f1:
	clr.l	d3			;2	m1 = 0
	clr.l	d2			;2	s1:x1 = 0:0
	rts				;2	exit
;-------
RA_fix_d2_zero_f0:
	move	d0,d2			;2	d2 = s1:x1
RA_zero_f0:
	clr.l	d1			;2	m0 = 0
	clr.l	d0			;2	s0:x0 = 0:0
	rts				;2	exit
;-------------------------------------
;Byte count: RA_align_f0f1	;48
;-------------------------------------
;-------------------------------------
RA_sub:
	bchg	#31,d2			;4	f1 = -f1
RA_add:
	bsr.s	RA_align_f0f1		;2	align(f0,f1)
	eor.l	d0,d2			;2	d2 = s0^s1:garbage
	bmi.s	RA_add_sub		;2	if signs differ, go handle it
	add.l	d3,d1			;2	m0 = m0+m1
	bcc.s	.add_add_exit		;2	if no carry, go exit OK
	roxr.l	#1,d1			;2	rotate carry right into m0
	addq	#1,d0			;2	x0 += 1
	bcc.s	RA_max_float		;2	if x0 overflows, go maximize f0
.add_add_exit:
	beq.s	RA_zero_f0		;2	if sum is zero, go zero f0
	rts				;2	exit
;-------
RA_add_sub:
	tst.l	d0			;2	f0 negative ?
	bpl.s	.have_sub_order		;2	else go keep correct order
	exg	d1,d3			;2	exchange order of m0 and m1
.have_sub_order:
	sub.l	d3,d1			;2	m0 = mx-my
	bcc.s	RA_norm_f0		;2	if no carry, go normalize f0
	neg.l	d1			;2	m0 = -m0
	bchg	#31,d0			;4	f0 = -f0
	bra.s	RA_norm_f0		;2
;-------------------------------------
;Byte count: RA_add & sub	;42
;-------------------------------------
;-------------------------------------
RA_int_f0:
	sub	#pos_expref+32,d0	;4	d0 = s0:x0-(pos_expref+32)
	bhs.s	RA_max_int		;2	if too high, go maximize f0 int
	neg	d0			;2	d0 = s0:(pos_expref+32)-x0
	cmp	#32,d0			;4	binimals < 32 ?
	bhs.s	RA_zero_f0		;2	else, go zero f0
	lsr.l	d0,d1			;2	shift out binimals
	tst.l	d0			;2	f0 negative ?
	bpl.s	.done			;2	else go keep d1
	neg.l	d1			;2	m0 = -m0
.done:
	rts				;2	exit
;-------------------------------------
;Byte count: RA_int_f0		;24
;-------------------------------------
;-------------------------------------
RA_max_int:
	moveq	#-1,d1			;2	m0 = $FFFFFFFF
	lsr.l	#1,d1			;2	m0 = $7FFFFFFF
	tst.l	d0			;2	f0 positive
	bmi.s	.exit			;2	else maximize negative
	not.l	d1			;2	m0 = $80000000
.exit:
	rts				;2	exit
;-------------------------------------
;Byte count: RA_max_int		;12
;-------------------------------------
;-------------------------------------
RA_uint_f0:
	tst.l	d0			;2	f0 positive ?
	bmi.s	RA_zero_f0		;2	else go zero f0 uint
	sub	#expref+32,d0		;4	d0 = s0:x0-(expref+32)
	bhi.s	RA_max_uint		;2	if too high, go maximize f0 uint
	beq.s	.done			;2	if exact, go exit with f0 uint
	neg	d0			;2	d0 = s0:(expref+32)-x0
	cmp	#32,d0			;4	binimals < 32 ?
	bhs.s	RA_zero_f0		;2	else, go zero f0 uint
	lsr.l	d0,d1			;2	shift out binimals  m0 = uint
.done:
	rts				;2	exit
;-------------------------------------
;Byte count: RA_uint_f0		;24
;-------------------------------------
;-------------------------------------
RA_max_uint:
	moveq	#-1,d1			;2	m0 = $FFFFFFFF
	rts				;2	exit
;-------------------------------------
;Byte count: RA_max_uint		;4
;-------------------------------------
;-------------------------------------
RA_ufloat_f0:
	move.l	#pos_expref+32,d0	;6	s0:x0 = 0:expref+32
RA_norm_f0:
	tst.l	d1			;2	m0 != 0 ?
	beq.s	RA_zero_f0		;2	else go zero f0
	bmi.s	.exit			;2	if b31 set,  exit (f0 normalized)
.loop:						;loop start
	subq	#1,d0			;2	;x0 -= 1
	bcs.w	RA_zero_f0		;2	;if x0 too low, go zero float
	asl.l	#1,d1			;2	;shift m0 left
	bpl.s	.loop			;2	;loop back until bit 31 set
.exit:
	rts				;2	;exit to caller
;-------------------------------------
;Byte count: RA_ufloat_f0 etc	;22
;-------------------------------------
;-------------------------------------
RA_float_f0:
	tst.l	d1			;2	int_in_m0 < 0 ?
	bpl.s	RA_ufloat_f0		;2	else go float as unsigned
	move.l	#neg_expref+32,d0	;6	s0:x0 = 1:expref+32
	neg.l	d1			;2	m0 = -integer_in_m0
	bra.s	RA_norm_f0			;2
;-------------------------------------
;Byte count: RA_float_f0	;14
;-------------------------------------
;-------------------------------------
RA_float_f1:
	exg	d0,d2			;2
	exg	d1,d3			;2
	bsr.s	RA_norm_f0		;2
	exg	d0,d2			;2
	exg	d1,d3			;2
	rts				;2
;-------------------------------------
;Byte count: RA_float_f1		;12
;-------------------------------------
;-------------------------------------
RA_ufloat_f1:
	move.l	#pos_expref+32,d2	;6	s1:x1 = 0:expref+32
RA_norm_f1:
	exg	d0,d2			;2
	exg	d1,d3			;2
	bsr.s	RA_norm_f0		;2
	exg	d0,d2			;2
	exg	d1,d3			;2
	rts				;2
;-------------------------------------
;Byte count: RA_norm_f1		;18
;-------------------------------------
