.TITLE C2DATE
.IDENT /V1.0/
.SBTTL CONVERT CLUNKS TO SYSTEM TIME AND DATE
;
; CONVERTS CLUNKS TO SYSTEM TIME AND DATE
;
; LAST EDIT: 6-NOV-1987 12:06:23 
;
; *** USE THE SAME CALLING SQUENCE AS D2CLNK...
;
;
;			--- AUTHORED BY ---
;
;			BOB ROCK
;			NORTHEAST ELECTRONICS DIV.
;			NORTHERN TELECOM INC.
;			AIRPORT RD.
;			CONCORD, N.H. 03301
;			(603) 224-6511 EXT 347
;
;	FORTRAN CALLABLE ROUTINE TO COVERT TO AND FROM
;	DATATRIEVE CLUNKS AND RSX-11 FORMAT TIME AND DATE
;
;		BY BOB ROCK	APR-81
;
;	BASIC PLUS-2
;		CALL C2DATE BY REF (CLUNKS%(),C.DATE$,C.TIME$,STATUS%)
;
;			CLUNKS% IS A 4 WORD INTEGER ARRAY
;			C.DATE$ MUST BE A 9 CHAR MIN. STRING
;			C.TIME$ MUST BE A 8 CHAR MIN. STRING
;			STATUS% RETURNS FOLLOWING RESULTS:
;				1 = SUCCESS
;				-1 = ERROR - DATE WAS PRIOR TO 1900
;				-2 = ERROR - DATE AFTER 1999
;                               -3 = ERROR - CLUNK OVERFLOW
;
;  NOTE:
;    FORMAT OF LONG WORDS IS LSW,...,MSW
;
;  THIS ROUTINE HAS BEEN MODIFIED BY PHILIP HANNAY, CARGILL GRAIN LAB,
;    3444 DIGHT AV S, MINNEAPOLIS, MN. 55407,  (612)-721-8531, FOR
;    OUR USE.  THE MODIFICATIONS ARE ACTUALLY CORRECTIONS, ONE
;    TO DETECT ILLEGAL CHARACTERS IN THE ASCII YEAR INPUT, THE OTHER
;    TO DO CORRECT DECIMAL TO BINARY CONVERSION OF THE MINUTES AND
;    SECONDS OF THE ASCII TIME INPUT.  JULY 6, 1982.  THIS ROUTINE
;    USES THE STANDARD DEC CALL SITE SO IT CAN BE CALLED BY FORTRAN OR
;    BY OMSI PASCAL V2.0 WITH NO CHANGES.
;
;  IT WAS FURTHER MODIFIED BY BOB THOMAS,CARGILL,INC.,P.O. BOX 9300
;    MPLS,MN,55440, (612)475-5432. THOSE FURTHER MODIFICATIONS
;    WERE TO CORRECT THE VALUES FOR 1 SEC, 1 MIN AND 1 HOUR. IN
;    ADDITION THE ADD64 ROUTINE WAS REWRITTEN TO PROVIDE FOR CASCADING 
;    CARRY BITS (SUCH AS THOSE THAT OCCUR ON 05-JUN-86 17:09:27).
;
;  PETER STADICK OCT-NOV '87 - BROKEN ROUTINES INTO SEPERATE MODULES
;    AND MODIFYIED TO ALLOW THEM TO BE BUILD INTO A SUPERVISOR MODE
;    LIBRARY. ALSO ADDED DEC CALL SITE TO ADD, SUBTRACT, MULTIPLY AND
;    DIVIDE ROUTINES SO THEY CAN BE CALLED FROM FORTRAN, PASCAL, ETC..
;    PETER STADICK, CARGILL INC, P.O. DRAWER AR, RESERVE,LA 70084
;    (504)-536-4111.
;
.PSECT CLUNK,RO,I,LCL,REL
C2DATE::
	MOV R5, -(SP)		; SAVE POINTER FOR LATER USE...

		; CREATE STACK BUFFER SPACE
STKSIZ=136.	; NUMBER OF BYTES IN VARIABLE STACK FRAME.
TEMP1=128.	; OFFSETS INTO STACK FRAME WERE BUFFER CAN BE FOUND
TEMP3=120.
BSEC=118.
BMIN=116.
BHOUR=114.
BDAY=112.
BMONTH=110.
BYEAR=108.
DATE=98.	; { DATE BUFFER IS 5 WORDS }
TIME=90.	; { TIME BUFFER IS 4 WORDS }
	MOV #0,R0		; CREATE TWO 4 WORD BUFFERS
	MOV #23.,R1		; AND SIX 1 WORD BUFFERS
10$:	MOV R0,-(SP)		; AND DATE AND TIME BUFFERS ON STACK
	SOB R1,10$


	; 28 DAYS IN A MONTH - 24,192,000,000,000 CLUNKS
DAY28=82.
	MOV #000000,-(SP)	; MSW
	MOV #013000,-(SP)
	MOV #121621,-(SP)
	MOV #000000,-(SP)	; LSW

	; 29 DAYS IN A MONTH - 25,056,000,000,000 CLUNKS
DAY29=74.
	MOV #000000,-(SP)	; MSW
	MOV #013311,-(SP)
	MOV #146722,-(SP)
	MOV #140000,-(SP)	; LSW

	; 30 DAYS IN A MONTH - 25,920,000,000,000 CLUNKS
DAY30=24.
	MOV #000000,-(SP)	; MSW
	MOV #013622,-(SP)
	MOV #174144,-(SP)
	MOV #100000,-(SP)	; LSW

	; 31 DAYS IN A MONTH - 26,787,000,000,000 CLUNKS
DAY31=16.
	MOV #000000,-(SP)	; MSW
	MOV #014134,-(SP)
	MOV #021316,-(SP)
	MOV #040000,-(SP)	; LSW

	; NON-LEAP YEAR (365 DAYS) - 306,600,000,000,000 CLUNKS
DAY365=50.
	MOV #000001,-(SP)	; MSW
	MOV #017321,-(SP)
	MOV #074306,-(SP)
	MOV #140000,-(SP)	; LSW

	; LEAP YEAR (366 DAYS) - 307,440,000,000,000 CLUNKS
DAY366=42.
	MOV #000001,-(SP)	; MSW
	MOV #017632,-(SP)
	MOV #121460,-(SP)
	MOV #100000,-(SP)	; LSW

	; CLUNKS PER MONTH TABLE
CLDAY=18.
	MOV SP,R0
	ADD #DAY31,R0
	MOV SP,R1
	ADD #DAY30,R1
	MOV R0,-(SP)		; DEC HAS 31 DAYS
	MOV R1,-(SP)		; NOV HAS 30 DAYS
	MOV R0,-(SP)		; OCT HAS 31 DAYS
	MOV R1,-(SP)		; SEP HAS 30 DAYS
	MOV R0,-(SP)		; AUG HAS 31 DAYS
	MOV R0,-(SP)		; JUL HAS 31 DAYS
	MOV R1,-(SP)		; JUN HAS 30 DAYS
	MOV R0,-(SP)		; MAY HAS 31 DAYS
	MOV R1,-(SP)		; APR HAS 30 DAYS
	MOV R0,-(SP)		; MAR HAS 31 DAYS
	MOV #0,-(SP)		; FEB-SET BY APPROPRIATE ROUTINE FOR LEAP YEAR
	MOV R0,-(SP)		; JAN HAS 31 DAYS

		;MAKE A LOCAL COPY OF DATE AND TIME
CLUNKS=10.
	MOV 2(R5),R4		; PICK UP ADDRESS OF CLUNK
	MOV 6(R4),-(SP)		;  AND MOVE TO BUFFER
	MOV 4(R4),-(SP)
	MOV 2(R4),-(SP)
	MOV  (R4),-(SP)

		; GENERATE SUBROUTINE CALL SITE ON STACK
	MOV R0,-(SP)		; IDS VALUE LOCATION
	MOV SP,R0
	MOV R0,-(SP)		; ADDRESS OF IDS LOCATION
	MOV R0,-(SP)		; PARAMETER SPACE 1
	MOV R0,-(SP)		; PARAMETER SPACE 2
	MOV R0,-(SP)		; PARAMETER SPACE 3
	MOV SP,R5
	SUB #2,R5		; R5 NOW HAS ADDRESS OF CALL SITE
				; PARAMETER BLOCK

		; SUBTRACT THE OFFSET FOR REFERENCE TO BASE YEAR (1900)
;	MOV #CLUNKS,R0		; (R2) = (R0) - (R1)
;	MOV #OFFSET,R1
;	MOV #CLUNKS,R2
	
	; MOVE OFFSET VALUE TO TEMP3
	MOV SP,R0
	ADD #TEMP3,R0
	MOV #000000, (R0)	; LSW	
	MOV #072215,2(R0)	
	MOV #015304,4(R0)
	MOV #000056,6(R0)	; MSW

	MOV SP,2(R5)		; 6(R5) = 2(R5) - 4(R5)
	ADD #CLUNKS,2(R5)
	MOV R0,4(R5)		; TEMP3 BUFFER
	MOV 2(R5),6(R5)		; CLUNKS BUFFER
	JSR PC, SUB64
	BCC 15$			; BRANCH IF YEAR LESS THAN 1900
	JMP ERR1

		; SUBTRACT YEARS UNTIL FOUND

15$:	CLR BYEAR(SP)		; YEAR COUNTER = 0
	BR START

COUNTY:
	BIT #3,BYEAR(SP)	;DETERMINE IF LEAP YEAR (BITS 0-2 CLEAR)
	BEQ ST1			; BR IF LEAP YEAR

START:	MOV SP,4(R5)
	ADD #DAY365,4(R5)
	BR ST2

ST1:	MOV SP,4(R5)
	ADD #DAY366,4(R5)

ST2:	MOV SP,2(R5)
	ADD #CLUNKS,2(R5)	; SUBTRACT A 365 DAY YEAR
	MOV SP,6(R5)
	ADD #TEMP1, 6(R5)
	JSR PC, SUB64
	BCS CHKYR

	INC BYEAR(SP)
	MOV TEMP1(SP),  CLUNKS(SP)	; MOVE THE RESULT BACK TO CLUNKS
	MOV TEMP1+2(SP),CLUNKS+2(SP)
	MOV TEMP1+4(SP),CLUNKS+4(SP)
	MOV TEMP1+6(SP),CLUNKS+6(SP)
	BR COUNTY

CHKYR:	CMP BYEAR(SP),#100.			;MUST BE DURING THIS CENTURY ONLY...
	BLO COUNTM
	JMP ERR2

		; DETERMINE THE MONTH...

COUNTM:
	MOV #1, BMONTH(SP)	; NOTE: JAN IS MONTH 1
	MOV SP,R3
	ADD #CLDAY,R3		;  TABLE POINTER

	TST BYEAR(SP)		; NOTE -  1900 WAS NOT A LEAP YEAR !
	MOV SP,R0
	BEQ 5$
	BIT #3, BYEAR(SP)	; IS THIS A LEAP YEAR?
	BEQ 10$			; BR IF YES
5$:	ADD #DAY28,R0
	MOV R0,CLDAY+2(SP)	;  ELSE SET FOR 28 DAYS
	BR 20$
10$:	ADD #DAY29,R0
	MOV R0,CLDAY+2(SP)	; LEAP YEAR...

20$:	MOV SP,2(R5)
	ADD #CLUNKS,2(R5)
	MOV (R3),   4(R5)	; CLUNKS PER MONTH TABLE
	MOV SP,6(R5)
	ADD #TEMP1, 6(R5)
	JSR PC, SUB64
	BCS COUNTD

	INC BMONTH(SP)		;BUMP THE MONTH COUNTER
	INC R3
	INC R3
	MOV TEMP1(SP),  CLUNKS(SP)	; AND RETURN THE RESULT TO CLUNKS
	MOV TEMP1+2(SP),CLUNKS+2(SP)
	MOV TEMP1+4(SP),CLUNKS+4(SP)
	MOV TEMP1+6(SP),CLUNKS+6(SP)
	BR 20$

		; NOW TAKE CARE OF THE REMAINING DAYS...

COUNTD:

	MOV #1,BDAY(SP)		;FIRST DAY OF MONTH IS ALWAYS 1...

	; A DAY - 864,000,000,000 CLUNKS
	MOV SP,R1
	ADD #TEMP3,R1
	MOV #140000, (R1)	; LSW
	MOV #025151,2(R1)
	MOV #000311,4(R1)
	MOV #000000,6(R1)	; MSW

	MOV SP,2(R5)
	ADD #CLUNKS,2(R5)
	MOV R1,4(R5)
	MOV SP,6(R5)
	ADD #TEMP1, 6(R5)
10$:	JSR PC, SUB64
	BCS COUNTH

	INC BDAY(SP)
	MOV TEMP1(SP),  CLUNKS(SP)
	MOV TEMP1+2(SP),CLUNKS+2(SP)
	MOV TEMP1+4(SP),CLUNKS+4(SP)
	MOV TEMP1+6(SP),CLUNKS+6(SP)
	BR 10$

COUNTH:
	CLR BHOUR(SP)		;FIRST HOUR OF DAY IS 00...

	; A HOUR - 36,000,000,000 CLUNKS
	MOV SP,R1
	ADD #TEMP3,R1
	MOV #064000, (R1)	; LSW
	MOV #060704,2(R1)
	MOV #000010,4(R1)
	MOV #000000,6(R1)	; MSW

	MOV SP,2(R5)
	ADD #CLUNKS,2(R5)
	MOV R1, 4(R5)
	MOV SP,6(R5)
	ADD #TEMP1, 6(R5)
10$:	JSR PC, SUB64
	BCS COUNTN

	INC BHOUR(SP)
	MOV TEMP1(SP), CLUNKS(SP)
	MOV TEMP1+2(SP),CLUNKS+2(SP)
	MOV TEMP1+4(SP),CLUNKS+4(SP)
	MOV TEMP1+6(SP),CLUNKS+6(SP)
	BR 10$

		; COUNT THE MINUTES...

COUNTN:
	CLR BMIN(SP)		;FIRST MINUTE OF HOUR IS 00..

	; A MINUTE - 600,000,000 CLUNKS
	MOV SP,R1
	ADD #TEMP3,R1
	MOV #043000, (R1)	; LSW
	MOV #021703,2(R1)
	MOV #000000,4(R1)
	MOV #000000,6(R1)	; MSW

	MOV SP,2(R5)
	ADD #CLUNKS,2(R5)
	MOV R1,4(R5)
	MOV SP,6(R5)
	ADD #TEMP1, 6(R5)
10$:	JSR PC, SUB64
	BCS COUNTS

	INC BMIN(SP)
	MOV TEMP1(SP),  CLUNKS(SP)
	MOV TEMP1+2(SP),CLUNKS+2(SP)
	MOV TEMP1+4(SP),CLUNKS+4(SP)
	MOV TEMP1+6(SP),CLUNKS+6(SP)
	BR 10$

		; COUNT THE SECONDS

COUNTS:
	CLR BSEC(SP)

	; A SECOND - 10,000,000 CLUNKS
	MOV SP,R1
	ADD #TEMP3,R1
	MOV #113200, (R1)	; LSW
	MOV #000230,2(R1)
	MOV #000000,4(R1)
	MOV #000000,6(R1)	; MSW

	MOV SP,2(R5)
	ADD #CLUNKS,2(R5)
	MOV R1,4(R5)
	MOV SP,6(R5)
	ADD #TEMP1, 6(R5)
10$:	JSR PC, SUB64
	BCS CONVRT

	INC BSEC(SP)
	MOV TEMP1(SP),  CLUNKS(SP)
	MOV TEMP1+2(SP),CLUNKS+2(SP)
	MOV TEMP1+4(SP),CLUNKS+4(SP)
	MOV TEMP1+6(SP),CLUNKS+6(SP)
	BR 10$

		; CONVERT THE BINARY NUMBERS TO ASCII STRINGS

CONVRT:
	MOV SP,R0
	ADD #DATE,R0		;USE THE SYSTEM LIBRARY FUNCTION
	CMP BDAY(SP),#10.		;WANT TO RIGHT JUSTIFY THIS IF DAY < 10.
	BHIS 5$			;  NONE NEEDED
	MOVB #40,(R0)+		;   PAD WITH SPACE AND SHIFT RIGHT
5$:	MOV SP,R1
	ADD #BYEAR,R1
	CALL $DAT

		;CONVERT LAST TWO CHAR OF MONTH TO LOWER CASE...

	BISB #40,DATE+4(SP)
	BISB #40,DATE+5(SP)

	MOV SP,R0
	ADD #TIME,R0		;USE THE SYSTEM LIBRARY FUNCTION
	MOV SP,R1
	ADD #BHOUR,R1
	MOV #3,R2		; FORMAT HH:MM:SS
	CALL $TIM

	MOV SP,R3

	ADD #STKSIZ,SP		;ADJUST SP BACK
	MOV (SP)+,R5		;GET ARG POINTER BACK FROM STACK

	MOV 4(R5),R0		;GET POINTER TO DATE STRING
	MOV R3,R1
	ADD #DATE,R1		;  AND POINTER TO DATE
	MOV #9.,R2		;  USE LENGTH AS COUNTER
10$:	MOVB (R1)+,(R0)+
	SOB R2,10$

	MOV 6(R5),R0		;GET POINTER TO TIME STRING
	MOV R3,R1
	ADD #TIME,R1		; LIKE ABOVE
	MOV #8.,R2
20$:	MOVB (R1)+,(R0)+
	SOB R2,20$

	MOV #1, @10(R5)		; PUT SUCCESS STATUS
	RTS PC

ERR1:
	ADD #STKSIZ,SP		;ADJUST SP BACK

	MOV (SP)+,R5		; PUT ERROR STATUS 
	MOV #-1, @10(R5)
	RTS PC

ERR2:
	ADD #STKSIZ,SP		;ADJUST SP BACK

	MOV (SP)+,R5		; PUT ERROR STATUS 
	MOV #-2, @10(R5)
	RTS PC

	.END
