
/+
/
/ Usage
/
/	char *
/	ctime(buffer);
/	struct TIME {
/		int	year;	/* G.TIYR  year - 1900	*/
/		int	month;	/* G.TIMO  Jan. = 1	*/
/		int	day;	/* G.TIDA		*/
/		int	hour;	/* G.TIHR  00 .. 23	*/
/		int	minute;	/* G.TIMI  00 .. 59	*/
/		int	second;	/* G.TISC  00 .. 59	*/
/		int	tick;	/* G.TICT  00 .. tsec-1	*/
/		int	tsec;	/* G.TICP  tick/second	*/
/	} buffer;
/
/	dayofweek(buffer);
/	struct TIME buffer;
/
/ Description
/
/	Ctime() converts the time information in buffer such as returned by
/	rtime() to a character string in the format:
/
/		Sun Sep 16 01:03:52 1973\0\0
/
/	All the fields have constant width.  Note that there are two
/	trailing <null>'s for the benefit of programs converted from
/	Unix (where the year is followed by a <newline>).
/
/	Ctime(0) returns the current time of day, calling rtime() internally.
/
/	The format of the returned information is identical to 
/	the Unix function of the same name except that the Unix function
/	has a trailing newline which is omitted here.
/
/	dayofweek() returns the day of the week (Sunday = 0) for the
/	date information in the argument buffer.
/
/ Bugs
/
/	There is no range checking on the information passed.
/
/-
/

/
/ Define offsets into the time buffer, note that this matches RSX11-M
/
G.TIYR	=	0		/ Year
G.TIMO	=	2		/ Month
G.TIDA	=	4		/ Date
G.TIHR	=	6		/ Hour
G.TIMI	=	10		/ Minute
G.TISC	=	12		/ Second
G.TICT	=	14		/ Ticks
G.TICP	=	16		/ Ticks per second


montab:	.word	0-1+6		/ Thirty days hath September
	.word	31.-1+6		/ All the rest I don't remember
	.word	59.-1+6
	.word	90.-1+6
	.word	120.-1+6
	.word	151.-1+6
	.word	181.-1+6
	.word	212.-1+6
	.word	243.-1+6
	.word	273.-1+6
	.word	304.-1+6
	.word	334.-1+6

month:	.ascii	/JanFebMarAprMayJunJulAugSepOctNovDec/

wkday:	.ascii	/SunMonTueWedThuFriSat/

tbuf:	.asciz	/Sun Sep 16 01:03:52 1973/
	.byte	0	/04	
	.even


	.globl dayofw,__csav,__cret
dayofw:
	jsr	r0,__csav		/ Link environments
	mov	12(r5),r4		/ R4 -> time buffer
	mov	G.TIDA(r4),r0		/ R0 := day
	mov	G.TIMO(r4),r1		/ R1 := month
	dec	r1			/ Month range from 0 .. 11
	asl	r1			/ Need month as a word index
	mov	G.TIYR(r4),r2		/ Get year
	sub	$72.,r2			/ into RT11 format (needed?)
	mov	r2,-(sp)		/ save year
	dec	r2			/ divide year-1
	asr	r2			/ by
	asr	r2			/ 4
	add	(sp),r2			/ Magic begins, ...
	inc	r2			/
	add	r2,r0			/ Enhanced day
	bit	$3,(sp)+		/ Test for leap year
	bne	0f			/ Br if no leap
	cmp	$2*1,r1			/ Magic continues, ...
	adc	r0			/
0:
	add	montab(r1),r0
1:
	sub	$7,r0			/ Slow divide by
	bpl	1b			/ 7 to get day of week
	add	$7,r0			/ Get into range 0 .. 6
	jmp	__cret			/ and off we go
/
/
/
	.globl ctime,rtime,__div2
ctime:
	jsr	r0,__csav		/ Link environments
	mov	12(r5),r4		/ R4 -> time buffer
	bne	0f			/ Br if user supplied one
	sub	$8.*2,sp		/ Null arg. make a time buffer
	mov	sp,r4			/ r4 -> time buffer
	mov	r4,-(sp)		/ and
	call	rtime			/ get the
	tst	(sp)+			/ time right now
0:
	mov	r4,-(sp)		/ Get day of week
	call	dayofw			/
	mov	r0,(sp)			/ Multiply
	asl	r0			/ by
	add	(sp)+,r0		/ three
	add	$wkday,r0		/ point to table
	mov	$tbuf,r3		/ R3 -> output buffer
	movb	(r0)+,(r3)+		/ move
	movb	(r0)+,(r3)+		/ 'em
	movb	(r0)+,(r3)+		/ out.
	inc	r3			/ skip blank
	mov	G.TIMO(r4),r0		/ Month
	asl	r0			/ times
	add	G.TIMO(r4),r0		/ three
	add	$month-3,r0		/ point to table
	movb	(r0)+,(r3)+		/ move
	movb	(r0)+,(r3)+		/ 'em
	movb	(r0)+,(r3)+		/ out.
	inc	r3			/ skip it
/
/ Note, the following code requires day/hour/minute/second ordering
/
	mov	r4,r2			/ r2 -> buffer
	add	$G.TIDA,r2		/ at the right place
	call	conv			/ Day
	call	conv			/ Hour
	call	conv			/ Minute
	call	conv			/ Second
	clr	r0			/ High-order year
	mov	G.TIYR(r4),r1		/ Year - 1900
	add	$1900.,r1		/ Year
	mov	$100.,r2		/ Get year mod 100
	call	__div2			/ simple
	mov	r2,-(sp)		/ Save last two digits
	mov	r1,r0			/ Get first two digits
	call	conv2			/ Stuff them
	mov	(sp)+,r0		/ and the
	call	conv2			/ Last two, too
	mov	$tbuf,r0		/ Return tbuf
	jmp	__cret			/ to the user
/
/
/ Convert an offset from the time buffer to a two digit number
/
/ Calling sequence:
/
/	mov	entry_pointer,r2
/	mov	text_pointer,r3
/	call	conv
/
/ Return:
/	r0,r1 destroyed,
/	r2 updated
/	r3 updated (by three)
/
conv:
	mov	(r2)+,r0		/ Get the value, update r2
	call	conv2			/ Convert two digits
	inc	r3			/ Skip one
	return				/ That's all
/
/
/ Convert a small integer to two ascii digits
/
/ Calling sequence
/
/	mov	value,r0
/	mov	text_pointer,r3
/	call	conv2
/
/ Return
/	r0,r1 destroyed
/	r3 Updated by 2
/
conv2:
	mov	$'0-1,r1		/ Initialize quotient
0:	
	inc	r1			/ Up the quotient
	sub	$10.,r0			/ Divide by
	bge	0b			/ ten
	add	$10.+'0,r0		/ Fix up remainder
	movb	r1,(r3)+		/ Write it
	movb	r0,(r3)+		/ out.
	return				/ and exit
