From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  7-SEP-1990 21:51:38.26
To:	MRGATE::"ARISIA::EVERHART"
CC:	
Subj:	Re: VMS Time formats

Received:  by crdgw1.ge.com (5.57/GE 1.70)
	 id AA07889; Fri, 7 Sep 90 21:34:48 EDT
Received: From UCBVAX.BERKELEY.EDU by CRVAX.SRI.COM with TCP; Fri,  7 SEP 90 17:53:46 PDT
Received: by ucbvax.Berkeley.EDU (5.63/1.42)
	id AA17143; Fri, 7 Sep 90 17:41:27 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 7 Sep 90 21:12:20 GMT
From: zaphod.mps.ohio-state.edu!swrinde!emory!stiatl!slammer!todd@tut.cis.ohio-state.edu  (Todd Merriman)
Organization: Software Toolz, Inc. - Atlanta, GA
Subject: Re: VMS Time formats
Message-Id: <644@slammer.UUCP>
References: <9009070224.AA25711@ucbvax.Berkeley.EDU>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

In article <9009070224.AA25711@ucbvax.Berkeley.EDU> MLEVIN@TUFTS.BITNET writes:
>Does anyone know how to convert between the 64-bit binary time
>format used in VMS system services and the Unix-style unsigned
>format which the VAX C function stat() gives for files (and vice versa)?

	.TITLE	VTOUT
	.IF DEFINED DOCUMENTATION
; ***************************************************************************
   VTOUT.MAR
   Todd Merriman

.MODULE            VTOUT
.LIBRARY           csub
.TYPE              function
.APPLICATION       conversion
.SYSTEM            vms
.AUTHOR            Raymond M. Curiel (Usenet)
.DESCRIPTION
   Convert VMS to Unix time
.ARGUMENTS
   long vtout(vmstim)
      unsigned char  vmstim [8];           /* (r) VMS time */
.NARRATIVE
   Vtout() converts the VMS time to Unix time.  VMS time is stored as a 
   quad, and the "quad" may be implemented in C as an array of 8 unsigned
   chars.
.RETURNS
   The equivalent Unix time
.LANGUAGE          
   Assembly
.FIXES             2/20/89
   Calculation off by several minutes due to signed comparison.
.ENDOC             DOCZ System Documentation
; ***************************************************************************
	.ENDC				; DOCUMENTATION
	.ENTRY VTOUT,^M<R2,R3,R4,R5,R6,R7>

	MOVL	#LIB$_INVARG,R0		;Assume Failure
	CLRL	R7			;Zero
	MOVAQ	-(SP),R5		;Allocate Storage off of Stack
	MOVAQ	-(SP),R4		;Allocate Storage off of Stack
	MOVAQ	-(SP),R3		;Allocate Storage off of Stack
	MOVL	#^X989680,(R4)		;One Second Absolute Time
	CLRL	4(R4)			;zEro High half
	MOVL	#^X4BEB4000,(R5)	;01-JAN-1970 Low Half
	MOVL	#^X007C9567,4(R5)	; High Half of unix base time.
	PUSHL	R5			;This is the Time since 1Jan70
	PUSHL	R5			;This is 1Jan70
	PUSHL	4(AP)			;This is the time to find
	CALLS	#3,G^LIB$SUBX		;Absolute time Subtract
	BLBS	R0,7$
2$:	BRW	200$			;error
5$:
	TSTL	4(R5)			;Is high half 
	BGTR	7$			; > 0 ? then continue
	BLSS	2$			; < 0 ? Then quit
	TSTL	(R5)			; If low half <= 0 ?
	BEQL	100$			; if zero return zero
7$:	MOVL	#1,R6			; Init 6
	CMPL	4(R4),4(R5)		;Check to see if Time is less
	BGTR	100$			; then smallest interval.
	BLSS	10$			;if it is all done otherwise
	CMPL	(R4),(R5)		; need to subtract 
	BGEQU	100$			;All done return value...
10$:	MOVQ	(R4),(R3)		;use r3 has address of scratch Quadword
15$:	CMPL	4(R3),4(R5)		;Check to make sure not greater
	BGTR	30$
	BLSS	20$
	CMPL	(R3),(R5)		; still checking
	BGEQU	30$
20$:	ASHL	#1,R6,R6		;multiply value by quotient by 2
	ASHQ	#1,(R3),(R3)		;multiply subtrahend by 2
	BRW	15$			;Check it again
30$:	ASHQ	#<-1>,(R3),(R3)		;Now greater backup - divide by 2
	ASHL	#<-1>,R6,R6		;Adjust quotient
	PUSHL	R5			;A - B
	PUSHL	R3			; B
	PUSHL	R5			; A
	CALLS	#3,G^LIB$SUBX		;do subtraction
	BLBC	R0,200$
	ADDL2	R6,R7			;R7 is total quotient
	BRW	7$			;Ok, now loop...
100$:	BNEQ	110$			;if equal need to add one.
	INCL	R7			;
110$:	MOVL	R7,R0			;Store it here
200$:	RET				;bye...

	.IF DEFINED DOCUMENTATION
; ***************************************************************************
.MODULE            utovt
.LIBRARY           csub
.TYPE              function
.APPLICATION       conversion
.SYSTEM            vms
.AUTHOR            Raymond M. Curiel (Usenet)
.DESCRIPTION
   Convert Unix to VMS time
.ARGUMENTS
   void utovt(unixtim,vmstim)
      long  unixtim;             /* (r) Unix time */
      unsigned char  vmstim [8];          /* (w) VMS time */
.NARRATIVE
   utovt() converts the Unix time to VMS time.  VMS time is stored as a 
   quad, and the "quad" may be implemented in C as an array of 8 unsigned
   chars.
.RETURNS
   The equivalent Unix time
.LANGUAGE          
   Assembly
.ENDOC             DOCZ System Documentation
; ***************************************************************************
	.ENDC				; DOCUMENTATION

	.ENTRY	UTOVT,^M<R2,R3,R4>

	MOVL	#LIB$_INVARG,R0		;Assume Failure
	MOVAQ	-(SP),R3		;Allocate Storage off of Stack
	MOVAQ	-(SP),R4		;Allocate Storage off of Stack
	MOVL	#^XFF676980,(R4)	;This is the low half of One Second
	MOVL	#<-1>,4(R4)		;High half of One second
	MOVL	#^X4BEB4000,(R3)	;01-JAN-1970 Low Half
	MOVL	#^X007C9567,4(R3)	; High Half of unix base time.
	MOVL	4(AP),R2		;Get Unix Time
	BLEQ	100$			;if less then zero all done
10$:	BLBC	R2,15$			;Do We need to Add yet?
	PUSHL	R3			;Result
	PUSHL	R4			;Unit to Add
	PUSHL	R3			;Current Result
	CALLS	#3,G^LIB$SUBX		;Extended add for Delta Time Value
	BLBC	R0,200$			;return w/o result
15$:	ASHQ	#1,(R4),(R4)		;Shift to left
	ASHL	#<-1>,R2,R2		;Shift to the Right
	BNEQ	10$
100$:	MOVQ	(R3),@8(AP)		;Store it here
	MOVL	#SS$_NORMAL,R0
200$:	RET


	.END

/***************************************************************************
   C test program
***************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "csub.h"

unsigned char	vtime[8];
long 	curtime,
   	cvtime;

main()
{
   int	i;

   time(&curtime);			/* get Unix time */
   SYS$GETTIM(vtime);			/* get current VMS time */
   cvtime = vtout(vtime);
   
   for (i = 7; i >= 0; i--)
   	printf("%02X",vtime[i]);
   puts("");

   printf("Unix=%ld Converted vtime=%ld\r\n",
   	curtime,cvtime);
   utovt(curtime,vtime);

   for (i = 7; i >= 0; i--)
   	printf("%02X",vtime[i]);
   puts("");
}


; ***************************************************************************
; End VTOUT.MAR
; ***************************************************************************

