2.11BSD/sys/pdp/toy.s

/ April 9, 2000 - modified to probe for the TOY clock rather than checking
/	the cpu type for 93 or 94.

/ the notes say that the TOY clock uses 24 hour time, but then later on
/ mention flags dealing with AM/PM...  So, code is present but disabled
/ to handle 12 hour time.  If this code is needed change the 0 below to
/ a 1.

toy24=0

/ extraneous flag bit possible in the day field.  this "should never
/ happen", but if it does change the 0 to a 1 below.

dayflags=0

	.globl	TOYCSR
TOYCSR	= 177526

	.globl	_toyclk, nofault
	.text
_toyclk:
	jsr	r5,csv			/ callable from C, save regs
	sub	$8.,sp			/ need 8 byte scratch area
tdata = -20
	clr	-(sp)
	mov	$1f, nofault		/ catch trap if no toy clock
	tst	*$TOYCSR
	inc	(sp)
1:
	clr	nofault			/ done with trap catcher
	tst	(sp)+			/ did we see a toy clock?
	beq	err			/ no, go return "error"
	jsr	pc,initoy		/ initialize the clock for reading
	mov	r5,(sp)
	add	$tdata,(sp)		/ pointer to scratch area
	jsr	pc,_gettoy		/ read the toy clock
	mov	(sp),r2			/ pointer to scratch area
	mov	$8.,r3			/ number of bytes of clock data
2:
	clr	r1
	bisb	(r2),r1			/ fetch byte of clock data (!sign ext)
.if	toy24
	cmp	r3,$5			/ are we on the hours field?
	bne	3f			/ no - br
	bic	$240,r1			/ clear am/pm flags
3:
.endif
	jsr	pc,bcd			/ convert 2 nybbles bcd to binary
.if	toy24
	cmp	r3,$5			/ hours field?
	bne	4f			/ no - skip am/pm stuff
	tstb	(r2)			/ $200 = am/pm in use
	bpl	4f			/ not am/pm, skip it
	cmp	r1,$12.			/ exactly 12?
	bne	5f			/ no - br
	clr	r1			/ make midnight
5:
	bitb	$40,(r2)		/ PM?
	beq	4f			/ no  - br
	add	$12.,r1			/ convert to 24 hour time
.endif
4:
	movb	r1,(r2)+		/ store converted/correct binary value
	sob	r3,2b			/ continue on for rest of the bytes
	sub	$7,r2			/ back up to seconds field
.if	dayflags
	bicb	$177770,4(r2)		/ clear possible excess bits in day
.endif
	mov	$bounds,r3		/ do bounds checking now, not 100ths
1:
	movb	(r2)+,r1		/ get byte of clock data
	cmpb	r1,(r3)+		/ below lo bound?
	blo	err			/ yes - br
	cmpb	r1,(r3)+		/ above hi bound
	bhi	err			/ yes - br
	cmp	r3,$bounds+14.		/ at end (7 limits * 2 bytes per = 14)?
	blo	1b			/ no - br
	sub	$8.,r2			/ back to seconds field
	movb	7(r2),r0		/ fetch the year of century
	cmp	r0,$90.			/ are we a "90s" system?
	bhis	1f			/ yep - br
	add	$100.,r0		/ next century for years 00 - 89
1:
	movb	r0,7(r2)		/ store fixed up year
	decb	6(r2)			/ convert 1-12 month to 0-11
	mov	r2,(sp)			/ pointer to the toy clock data
	jsr	pc,_tm2t		/ convert to a 32bit # of seconds time
	br	ret
err:
	clr	r0			/ a double precision value
	clr	r1			/ of 0 signals an error
ret:
	jmp	cret			/ return
	.data
bounds:
	.byte	0,59.			/ seconds lo,hi
	.byte	0,59.			/ minutes lo,hi
	.byte	0,23.			/ hours lo,hi
	.byte	0,7			/ day of week lo,hi
	.byte	1,31.			/ day of month lo,hi
	.byte	1,12.			/ month of year lo,hi
	.byte	0,99.			/ year of century lo,hi
	.text
initoy:
	tst	*$TOYCSR		/ strobe the clock register
	clr	-(sp)			/ save previous high byte of register
	movb	*$TOYCSR+1,(sp)		/ only bit 8 belongs to TOY!
	bic	$1,(sp)			/ make sure bit 8 (TOY bit) is clear
	mov	$2,r2			/ number of double words to send clock
1:
	mov	$35305,r0		/ first word of recognition code
	jsr	pc,toyload		/ send it to clock
	mov	$56243,r0		/ second word
	jsr	pc,toyload		/ send it
	sob	r2,1b			/ do the whole thing twice
	tst	(sp)+			/ clean stack
	rts	pc

/ send contents of r0 to the TOY.  2(sp) has the old bits 9-15, bit 8
/ has been cleared.

toyload:
	mov	$16.,r1			/ number of bits to send
1:
	mov	r0,r3			/ scratch copy
	bic	$177776,r3		/ clear all but bit being sent
	bis	2(sp),r3		/ merge in old_csr_bits
	movb	r3,*$TOYCSR+1		/ send bit to clock
	asr	r0			/ shift pattern down
	sob	r1,1b			/ do all 16 bits in the word
	rts	pc

	.globl	_gettoy
_gettoy:				/ (void)gettoy(&char[8]);
	jsr	r5,csv			/ C callable
	mov	4(r5),r2		/ buffer address
	mov	$4,r3			/ number of words in buffer
1:
	mov	$16.,r4			/ number of bits in word
2:
	movb	*$TOYCSR+1,r0		/ low bit of top byte is a clock bit
	asr	r0			/ put it in carry
	ror	r1			/ ripple in at top end of r1
	sob	r4,2b			/ do all 16 bits
	mov	r1,(r2)+		/ store the word in the buffer
	sob	r3,1b			/ do all 4 words
	jmp	cret			/ and return

bcd:
	clr	r0
	div	$16.,r0
	mov	r1,-(sp)
	mov	r0,r1
	mul	$10.,r1
	add	(sp)+,r1
	rts	pc

	.globl	_tm2t
_tm2t:
	jsr	r5,csv
	mov	4(r5),r4
	movb	1(r4),r1
	mov	r1,-(sp)
	clr	-(sp)
	movb	2(r4),r0
	mul	$74,r0
	mov	r1,-(sp)
	mov	r0,-(sp)
	mov	$7020,-(sp)
	sxt	-(sp)
	movb	3(r4),r1
	mov	r1,-(sp)
	clr	-(sp)
	jsr	pc,lmul
	add	$10,sp
	mov	r1,-(sp)
	mov	r0,-(sp)
	mov	$50600,-(sp)
	mov	$1,-(sp)
	mov	r4,-(sp)
	jsr	pc,_ndays		/ return value in r1
	tst	(sp)+
	dec	r1
	mov	r1,-(sp)
	sxt	-(sp)
	jsr	pc,lmul
	add	$10,sp
	add	(sp)+,r0
	add	(sp)+,r1
	adc	r0
	add	(sp)+,r0
	add	(sp)+,r1
	adc	r0
	add	(sp)+,r0
	add	(sp)+,r1
	adc	r0
	jmp	cret

_leap:				/ r2 = year number, r1 clobbered
	mov	r2,r1
	add	$3554,r1
	sxt	r0
	div	$620,r0
	tst	r1
	bne	2f
	br	3f
1:
	clr	r0		/ return false
	br	4f
2:
	mov	r2,r1
	sxt	r0
	div	$144,r0
	tst	r1
	jeq	1b
	bit	$3,r2
	jne	1b
3:
	mov	$1,r0		/ return true
4:
	rts	pc
	.data
mdays:
	.byte 37,34,37,36,37,36,37,37,36,37,36,37,0
	.even
	.text
_ndays:
	jsr	r5,csv
	mov	4(r5),r0
	movb	5(r0),r4
	mov	$106,r2
	jbr	3f
1:
	add	$555,r4
	jsr	pc,*$_leap		/ r2 has year in it already
	add	r0,r4
	inc	r2
3:
	mov	4(r5),r0
	movb	7(r0),r0
	cmp	r2,r0
	jlt	1b
	clr	r3
	jbr	8f
4:
	clr	r0
	cmp	$1,r3
	jne	5f
	jsr	pc,*$_leap	/ r2 has year
5:
	movb	mdays(r3),r1
	add	r1,r0
	add	r0,r4
	inc	r3
8:
	mov	4(r5),r0
	movb	6(r0),r0
	cmp	r3,r0
	jlt	4b
	mov	r4,r1		/ return value in r1 not r0
	jmp	cret