.TITLE MUL64
.IDENT /V1.0/
.SBTTL 64-BIT BY 64-BIT MULTIPLICATION ROUTINE

; ROUTINE TO MULTIPLY A 64 BIT NUMBER BY A 64 BIT NUMBER AND
; RETURN A 64 BIT RESULT.
;
; LAST EDIT: 6-NOV-1987 12:35:09 
;
; AUTHOR:	PETER STADICK
;		CARGILL INC.
;		P.O. DRAWER AR
;		RESERVE,LA 70084
;
; EDIT HISTORY: CREATED MAY-87 PJS
;		MADE SEPARATE MODULE OCT-87 PJS
;
; CALL PARAMETER LIST
;	 2(R5) = FIRST CLUNK VALUE ( INPUT PRESERVED )
;	 4(R5) = SECOND CLUNK VALUE ( INPUT PRESERVED )
;	 6(R5) = RESULT ( OUTPUT )
;	10(R5) = STATUS 1=SUCCESS OR -3=OVERFLOW ( OUTPUT )
;
; THIS ROUTINE WILL MULTIPLY THE FIRST CLUNK VALUE BY THE 
; SECOND VALUE AND RETURN A RESULT. IF AN OVERFLOW FROM THE
; MULTIPLY OCCURS THE STATUS WILL BE SET TO -3.
;
; 2(R5) * 4(R5) = 6(R5)
;         OR
; (R0) * (R1) = (R2)
;
; CARRY BIT SET ON RETURN INDICATES OVERFLOW
;
; ALL REGISTERS ARE PRESERVED
;

.PSECT CLUNK,RO,I,LCL,REL
MUL64::
	MOV R0, -(SP)		; PRESERVE REGISTERS
	MOV R1, -(SP)
	MOV R2, -(SP)
	MOV R3, -(SP)
	MOV R4, -(SP)

	MOV 2(R5),R0		; FACTOR 1
	MOV 4(R5),R1		; FACTOR 2
	MOV 6(R5),R2		; PRODUCT
	MOV #1,@10(R5)		; SET STATUS TO 1

	CLR 4(R2)		; CLEAR TOP PART OF RESULT LOCATION
	CLR 6(R2)

	MOV R0,R3		; MOVE SOURCE ADDRESSES TO R3 AND R4 BECAUSE
	MOV R1,R4		; $MUL USES R0 AND R1

	MOV (R3),R0		; SET UP FOR LOWEST WORD MULTIPLY
	MOV (R4),R1
	CALL $MUL		; USE SYSLIB MULTIPLY ROUTINE
	MOV R1,(R2)		; MOVE LOW WORD RO RESULT LOCATION
	MOV R0,2(R2)		; MOVE HIGH WORD

	MOV (R3),R0		; SET UP FOR SECOND WORD MULTIPLY
	MOV 2(R4),R1
	CALL $MUL
	ADD R1,2(R2)		; ADD HIGH WORD TO SECOND WORD RESULT
	ADC 4(R2)		; IF CARRY ADD TO THIRD WORD RESULT
	ADD R0,4(R2)		; ADD HIGH WORD TO THIRD WORD RESULT
	ADC 6(R2)		; IF CARRY ADD TO FOURTH WORD RESULT

	MOV (R3),R0		; SET UP FOR THIRD WORD MULTIPLY
	MOV 4(R4),R1
	CALL $MUL
	ADD R1,4(R2)		; ADD LOW WORD TO THIRD WORD RESULT
	ADC 6(R2)		; IF CARRY ADD TO FOURTH WORD RESULT
	ADD R0,6(R2)		; ADD HIGH WORD TO FOURTH WORD RESULT
	BCS 40$			; IF CARRY THEN OVERFLOW ERROR

	MOV (R3),R0		; SET UP FOR FOURTH WORD MULTIPLY
	MOV 6(R4),R1
	CALL $MUL
	ADD R1,6(R2)		; ADD LOW WORD TO FOURTH WORD RESULT
	BCS 40$			; IF CARRY THEN OVERFLOW ERROR
	TST R0			; CHECK HIGH WORD OF RESULT
	BNE 40$			; IF HIGH WORD NOT ZERO THEN OVERFLOW

	MOV 2(R3),R0		; SECOND WORD OF FACTOR 2 MULTIPLY BY THE
	MOV (R4),R1		; FIRST WORD OF FACTOR 1
	CALL $MUL
	ADD R1,2(R2)		; ADD LOW WORD TO SECOND WORD OF RESULT
	ADC 4(R2)		; EXTEND CARRY
	ADC 6(R2)
	BCS 40$			; IF CARRY THEN OVERFLOW
	ADD R0,4(R2)		; ADD HIGH WORD TO THIRD WORD OF RESULT
	ADC 6(R2)		; EXTEND CARRY
	BCS 40$			; IF CARRY THEN OVERFLOW

	MOV 2(R3),R0		; SECOND WORD OF FACTOR 2 MULTIPLIED BY THE
	MOV 2(R4),R1		; SECOND WORD OF FACTOR 1
	CALL $MUL
	ADD R1,4(R2)		; ADD LOW WORD TO THIRD WORD OF RESULT
	ADC 6(R2)		; EXTEND CARRY	
	BCS 40$			; IF CARRY THEN OVERFLOW
	ADD R0,6(R2)		; ADD HIGH WORD TO FORTH WORD OF RESULT        
	BCS 40$			; IF CARRY THEN OVERFLOW

	MOV 2(R3),R0		; SECOND WORD OF FACTOR 2 MULTIPLIED BY THE
	MOV 4(R4),R1		; THIRD WORD OF FACTOR 1
	CALL $MUL
	ADD R1,6(R2)		; ADD LOW WORD TO FORTH WORD OF RESULT
	BCS 40$			; IF CARRY THEN OVERFLOW
	TST R0			; HIGH WORD SHOULD BE EMPTY
	BNE 40$			; IF NOT ZERO THEN OVERFLOW

	TST 2(R3)		; CHECK THAT SECOND WORD OF FACTOR 2 
	BEQ 10$			; OR THE FOUR WORD OF FACTOR 1 IS ZERO
	TST 6(R4)		; IF NOT ZERO THEN OVERFLOW
	BNE 40$

10$:	MOV 4(R3),R0		; THIRD WORD OF FACTOR 2 MULTIPLIED BY THE
	MOV (R4),R1		; FIRST WORD OF FACTOR 1
	CALL $MUL
	ADD R1,4(R2)		; ADD LOW WORD TO THIRD WORD OF RESULT
	ADC 6(R2)		; EXTEND SIGN
	BCS 40$			; IF CARRY THEN OVERFLOW
	ADD R0,6(R2)		; ADD HIGH WORD TO FORTH WORD OF RESULT
	BCS 40$			; IF CARRY THEN OVERFLOW

	MOV 4(R3),R0		; THIRD WORD OF FACTOR 2 MULTIPLIED BY THE
	MOV 2(R4),R1		; SECOND WORD OF FACTOR 1
	CALL $MUL
	ADD R1,6(R2)		; ADD LOW WORD TO FOUR WORD OF RESULT
	BCS 40$			; IF CARRY THEN OVERFLOW
	TST R0			; HIGH WORD SHOULD BE EMPTY
	BNE 40$			; IF NOT ZERO THEN OVERFLOW

	TST 4(R3)		; CHECK THAT THIRD WORD OF FACTOR 2 AND
	BEQ 20$			; THE THIRD WORD OF FACTOR 2 OR THE FORTH
	TST 4(R4)		; WORD OF FACTOR 2 IS ZERO
	BNE 40$			; IF NOT ZERO THE OVERFLOW
	TST 6(R4)		
	BNE 40$
	
20$:	MOV 6(R3),R0		; FORTH WORD OF FACTOR 2 MULTIPLIED BY THE
	MOV (R4),R1		; FIRST	WORD OF FACTOR 1
	CALL $MUL
	ADD R1,6(R2)		; ADD LOW WORD TO FORTH WORD OF RESULT
	BCS 40$			; IF CARRY THEN OVERFLOW
	TST R0			; HIGH WORD SHOULD BE EMPTY
	BNE 40$			; IF HIGH WORD ZERO THEN ALL OKAY	

	TST 6(R3)		; CHECK THAT THE FORTH WORD OF FACTOR 2 AND
	BEQ 50$			; THE SECOND WORD OF FACTOR 1 OR
	TST 2(R4)		; THE THIRD WORD OF FACTOR 1 OR
	BNE 40$			; THE FOUR WORD OF FACTOR 1 IS ZERO
	TST 4(R4)		; IF NOT ZERO THE OVERFLOW
	BNE 40$	
	TST 6(R4)
	BEQ 50$
	
40$:	SEC
	MOV #-3,@10(R5)		; OVERFLOW CONDITION PRESENT

50$:	MOV (SP)+,R4		; RESTORE REGISTERS
	MOV (SP)+,R3
	MOV (SP)+,R2
	MOV (SP)+,R1
	MOV (SP)+,R0

	RTS PC
	
	.END
