	IFND	INT32VER
	;------------------------------------------------------------------
	; Created by Peter Thompson
	; Multiply/square routines written on New Year's Day 1992
	; & debugged on 2nd January, when I was feeling better....
	; Division macros written & partially debugged on 2nd Jan.
	; Further testing and debugging on 9th of Jan.
	;------------------------------------------------------------------
	; $MUSIC="Vince Jones/It all ends up in tears, Enya/Watermark,
	;         Paul Simon/Graceland, Clannad/Fuaim, Phil Keaggy/Sunday's
	;	  Child, Phil Keaggy/Master and the Musician, Farrell &
	;	  Farrell/Superpower"
	;------------------------------------------------------------------
	;  Numbers are all integers.
	;  Only registers containing results, and/or d1, are altered by
	; these macros.
	;  Macros may require up to 80 bytes of stack space.
	; Flag	State after any multiply/square macro
	; X	undefined.
	; N	Set if result is negative, clear otherwise.
	; Z	Set if result is zero, clear otherwise.
	; V	if set, an overflow HAS taken place;
	;	if clear, an overflow MAY have taken place.
	; C	undefined.
	;  None of these routines can be trusted to return a correct
	; overflow flag, unless specified by name to do so. It is your
	; responsiblity to make sure your numbers are small enoungh.
	;------------------------------------------------------------------

INT32VER	EQU	100

	;- MUL32 macro - general 32 bit multiply.
	;- Input:	d0 contains a 32-bit signed or unsigned number.
	;-		d1 contains a 32-bit signed or unsigned number.
	;- Output:	d0 contains the product of the inputs.
	;- Alters:	d1

MUL32:	MACRO			; d0 d1 d2 d3
	movem.l	d2-d3,-(SP)	; ab cd -- --
	move.l	d1,d2		; ab cd cd --
	swap	d1		; ab dc cd --
	move.l	d0,d3		; ab dc cd ab
	swap	d3		; ab dc cd ba
	mulu	d0,d1		; ab BC cd ba
	mulu	d2,d3		; ab BC cd AD
	mulu	d2,d0		; BD BC cd AD
	add.l	d1,d3		; BD BC cd 12
	swap	d3		; BD BC cd 21
	clr.w	d3		; BD BC cd 20
	add.l	d3,d0		; ++ BC cd 20
	movem.l	(SP)+,d2-d3	; ++ BC -- --
	ENDM

	;- SSQR32 macro - signed 32-bit square.
	;- Input:	d0 contains a 32-bit signed number.
	;- Output:	d0 contains the square of the input.

SSQR32:	MACRO
	tst.l	d0
	bmi.S	*+4	;->ss32a
	neg.l	d0
	mulu	d0,d0	;ss32a:
	ENDM

	;- USQR32 macro - unsigned 32-bit square.
	;- Input:	d0 contains a 32-bit unsigned number.
	;- Output:	d0 contains the square of the input.

USQR32:	MACRO
	mulu	d0,d0
	ENDM

	;- GSQR32 macro - general 32-bit square.
	;- Input:	d0 contains a 32-bit signed or unsigned number.
	;- Output:	d0 contains the square of the input.
	;- Alters:	d1

GSQR32:	MACRO			; d0 d1
	move.l	d0,d1	
	swap	d1		; ab ba
	mulu	d0,d1		; ab AB
	mulu	d0,d0		; BB AB
	swap	d1
	clr.w	d1		; BB B0
	add.l	d1,d1
	add.l	d1,d0
	ENDM

	;- UDIV32 macro - 32-bit unsigned division.
	;- Input:	d0 contains the 32-bit unsigned dividend.
	;-		d1 contains the 32-bit unsigned divisor.
	;- Output:	d0 contains the 32-bit unsigned quotient.
	;-		d1 contains the 32-bit unsigned remainder.

UDIV32:	MACRO
	movem.l	d2-d3,-(SP)
	moveq	#0,d2
	moveq	#31,d3
	lsl.l	#1,d0
	roxl.l	#1,d2		;ud32a:
	sub.l	d1,d2
	bcc.S	*+4		;->ud32b
	add.l	d1,d2
	roxl.l	#1,d0		;ud32b:
	dbra	d3,*-10		;->ud32a
	not.l	d0
	move.l	d2,d1
	movem.l	(SP)+,d2-d3
	ENDM

	;- SDIV32 macro - 32-bit signed division.
	;- Input:	d0 contains the 32-bit signed dividend.
	;-		d1 contains the 32-bit signed divisor.
	;- Output:	d0 contains the 32-bit signed quotient.
	;-		d1 contains the 32-bit signed remainder.
	;- Let a be the dividend, b the divisor, c the quotient and d the
	;- remainder. Then both of the following hold:
	;- 		(1) a = b*c+d
	;-		(2) abs(a) = abs(b)*abs(c)+abs(d)

SDIV32:	MACRO
	movem.l	d2-d3,-(SP)
	move.l	d0,d2
	eor.l	d1,d2
	move.l	d0,d3
	bpl.S	*+4		;->sd32a
	neg.l	d0
	tst.l	d1		;sd32a:
	bpl.S	*+4		;->sd32b
	neg.l	d1
	UDIV32			;sd32b:
	tst.l	d3
	bpl.S	*+4		;->sd32c:
	neg.l	d1
	tst.l	d2		;sd32c:
	bpl.S	*+4		;->sd32d
	neg.l	d0
	movem.l	(SP)+,d2-d3	;sd32d:
	ENDM

	ENDC
