.TITLE S2CLNK
.IDENT /V1.0/
.SBTTL DETERMINE DIFFERENCE BETWEEN TWO CLUNK DATES (S2CLNK)

; THIS ROUTINE WILL SUBTRACT TWO CLUNK VALUES AND RETURN
; THE NUMBER OF DAYS, HOURS, MINUTES AND SECONDS DIFFERENCE
; BETWEEN THE TWO. IT WILL ALSO TELL YOU WHICH ONE IS GREATER.
;
; LAST EDIT: 6-NOV-1987 10:52:31 
;
; AUTHOR:	PETER STADICK
;		CARGILL INC.
;		P.O. DRAWER AR
;		RESERVE,LA 70084
;
; EDIT HISTORY: CREATED MAY-87 PJS
;		MADE SEPERATE MODULE OCT-87 PJS
;
; CALLING PARAMETER LIST
;	 2(R5) = FIRST CLUNK VALUE ( INPUT PRESERVED )
;	 4(R5) = SECOND CLUNK VALUE ( INPUT PRESERVED )
;	 6(R5) = SIGN (OUTPUT)
;	10(R5) = UNSIGNED NUMBER OF DAYS (OUTPUT)
;	12(R5) = UNSIGNED NUMBER OF HOURS (OUTPUT)
;	14(R5) = UNSIGNED NUMBER OF MINUTES (OUTPUT)
;	16(R5) = UNSIGNED NUMBER OF SECONDS (OUTPUT)
;	20(R5) = STATUS 1=SUCCESS OR -3=OVERFLOW (OUTPUT)
;
; THIS ROUTINE EXPECTS A DEC STANDARD CALL SITE WITH THE LIST OF ADDRESSES
; IN THE ABOVE FORMAT. THE ROUTINE WILL FIRST SUBTRACT THE THE TWO CLUNK
; VALUES. IF THE FIRST VALUE IS GREATER THEN THE SECOND VALUE THE SIGN
; WILL BE POSITIVE. IF THE SECOND VALUE IS GREATER THEN THE FIRST THE SIGN
; WILL BE NEGITIVE. THE DAYS VALUE IS RETURNED AS AN UNSIGNED INTEGER
; 0..65536 OF THE DAYS DIFFERENCE BETWEEN THE TWO CLUNK VALUES. IF THE VALUE
; IS GREATER THEN THIS AN OVERFLOW ERROR IS RETURNED AND NO OTHER RETURNED 
; VALUES CAN BE TRUSTED. THE HOURS WILL BE A NUMBER 0..23 AND ALWAYS POSITIVE.
; THE MINUTES AND SECONDS WILL BE A NUMBER 0..59 AND ALWAYS POSITIVE.
;
; ONLY R5 AND SP ARE PRESERVED
;
.PSECT CLUNK,RO,I,LCL,REL
S2CLNK::
	MOV R5, -(SP)		; SAVE POINTER FOR LATER USE...
	MOV R5,R3		; USE R3 AS ADDRESS TO INPUT PARAMTERS

	MOV 2(R3),R0		; PICK UP ADDRESS OF CLUNK
	MOV 6(R0),-(SP)		;  AND MOVE TO BUFFER
	MOV 4(R0),-(SP)	
	MOV 2(R0),-(SP)
	MOV  (R0),-(SP)
	MOV SP,R0
 
	MOV 4(R3),R1		; PICK UP ADDRESS OF SECOND CLUNK
	MOV 6(R1),-(SP)		; AND MOVE TO BUFFER
	MOV 4(R1),-(SP)
	MOV 2(R1),-(SP)
	MOV  (R1),-(SP)
	MOV SP,R1

	MOV R2,-(SP)		; FIRST WORK BUFFER
	MOV R2,-(SP)
	MOV R2,-(SP)
	MOV R2,-(SP)
	MOV SP,R2

	MOV #000000,-(SP)	; SECOND WORK BUFFER
	MOV #000311,-(SP)	; PUT DAY VALUE IN BUFFER
	MOV #025151,-(SP)
	MOV #140000,-(SP)
	MOV SP,R4

		; BUILD CALL SITE ON STACK
	MOV #1,@6(R3)		; ASSUME SIGN POSITIVE
	MOV R5,-(SP)		; IDS VALUE LOCATION
	MOV SP,R5
	MOV R5,-(SP)		; ADDRESS OF IDS
	MOV R2,-(SP)
	MOV R1,-(SP)
	MOV R0,-(SP)
	MOV SP,R5
	SUB #2,R5		; ADJUST ADDRESS
	JSR PC, SUB64		; SUBTRACT TO FIND DIFFERENCE 
	BCC S10			; BRANCH IF POSTIVE RESULT

	MOV #-1,@6(R3)		; SET SIGN NEGITIVE

	MOV R2,6(R5)
	MOV R0,4(R5)		; SWAP POSITION OF DATES
	MOV R1,2(R5)
	JSR PC, SUB64		; SUBTRACT AGAIN TO FIND POSITIVE DIFFERENCE
S10:
	MOV R0,-(SP)		; INCREASE PARAMETER BLOCK SIZE
	SUB #2,R5
	MOV R0,10(R5)		; RESULT - NUMBER OF DAYS
	MOV R1,6(R5)		; REMAINDER
	MOV R4,4(R5)		; DIVISOR - CLUNKS PER DAY
	MOV R2,2(R5)		; DIVIDEND - DIFFERENCE BETWWEN CLUNKS
	JSR PC, DIV64		; DIVIDE TO FIND NUMBER OF DAYS
	BCS SERRD
	TST 2(R0)		; CHECK FOR OVERFLOW
	BNE SERRD
	MOV (R0),@10(R3)	; RESULT NUMBER OF DAYS

	MOV #000000,6(R4)	; PUT HOUR VALUE IN DIVISOR BUFFER
	MOV #000010,4(R4)
	MOV #060704,2(R4)
	MOV #064000,(R4)

	MOV R0,10(R5)		; RESULT - NUMBER OF HOURS
	MOV R2,6(R5)		; REMAINDER
	MOV R4,4(R5)		; DIVISOR - CLUNKS PER HOURS
	MOV R1,2(R5)		; DIVIDEND - DIFFERENCE BETWWEN CLUNKS
	JSR PC, DIV64		; DIVIDE TO FIND NUMBER OF HOURS
	BCS SERRD
	MOV (R0),@12(R3)	; RESULT NUMBER OF HOURS

	MOV #000000,6(R4)	; PUT MINUTE VALUE IN DIVISOR BUFFER
	MOV #000000,4(R4)
	MOV #021703,2(R4)
	MOV #043000,(R4)

	MOV R0,10(R5)		; RESULT - NUMBER OF MINUTES
	MOV R1,6(R5)		; REMAINDER
	MOV R4,4(R5)		; DIVISOR - CLUNKS PER MINUTE
	MOV R2,2(R5)		; DIVIDEND - DIFFERENCE BETWWEN CLUNKS
	JSR PC, DIV64		; DIVIDE TO FIND NUMBER OF MINUTES
	BCS SERRD
	MOV (R0),@14(R3)	; RESULT NUMBER OF MINUTES

	MOV #000000,6(R4)	; PUT SECOND VALUE IN DIVISOR BUFFER
	MOV #000000,4(R4)
	MOV #000230,2(R4)
	MOV #113200,(R4)

	MOV R0,10(R5)		; RESULT - NUMBER OF SECONDS
	MOV R2,6(R5)		; REMAINDER
	MOV R4,4(R5)		; DIVISOR - CLUNKS PER SECOND
	MOV R1,2(R5)		; DIVIDEND - DIFFERENCE BETWWEN CLUNKS
	JSR PC, DIV64		; DIVIDE TO FIND NUMBER OF SECONDS
	BCS SERRD
	MOV (R0),@16(R3)	; RESULT NUMBER OF SECONDS
	
SDONE:	
	MOV R0,SP		; ADJUST SP BACK
	ADD #10,SP
	MOV (SP)+, R5		; GET ARG POINTER BACK FROM STACK
	MOV #1,@20(R5)		; SET GOOD STATUS
	BR  SDONE1

SERRD:	
	MOV R0,SP		; ADJUST SP BACK
	ADD #10,SP
	MOV (SP)+, R5		; RESTORE ARG POINTER
	MOV #-3,@20(R5)		; SET STATUS TO OVERFLOW

SDONE1:
	RTS PC

	.END
