; RANDOM
; Generates a pseudorandom number. Works best if called from a loop so that
; the value of its workspace variable (consisting of lowB and hiB) is
; constantly stirred.	

	device	pic16c55,xt_osc,wdt_off,protect_off
	reset	start

	org	8
hiB	ds	1	; MSB of 16-bit random number.
lowB	ds	1	; LSB of 16-bit random number.
temp	ds	1	; Temporary counter for delay.
temp2	ds	1	; Temporary counter for delay.

; Device data and reset vector
	org	0

start	mov	!rb,#0		; Output to show sequence on LEDs.
	mov	lowB,#13	; Arbitrary starting values
	mov	hiB,#99 	; for the shift register.
:loop	call	Random
	mov	rb,lowB 	; Display 8-bit random numbers
	call	delay		; on LEDs connected to RB.
	jmp	:loop		; Endless loop
; Random number generator.
Random	mov	w,hiB		; First, ensure that hiB and lowB aren't
	OR	w,lowB		; all zeros. If they are, NOT hiB to FFh.
	snz			; Otherwise, leave hiB and lowB as is.
	NOT	hiB
	mov	w,#80h		; We want to XOR hiB.7, hiB.6, hiB.4
	snb	hiB.6		; and lowB.3 together in W. Rather than
	XOR	hiB,w		; try to line up these bits, we just
	snb	hiB.4		; check to see whether a bit is a 1. If it
	XOR	hiB,w		; is, XOR 80h into hiB. If it isn't,
	snb	lowB.3		; do nothing. When we're done, the
	XOR	hiB,w		; XOR of the 4 bits will be in hiB.7.
	mov	w,<<hiB 	; Move hiB.7 into carry. 
        rl 	lowB 		; Rotate c into lowB.0, lowB.7 into c. 
	rl 	hiB 		; Rotate c into hiB.0. 
	ret 			; Delay loop for program demo. Remove when using just Random. 
delay 	djnz 	temp,delay 
	djnz 	temp2,delay 
	ret 

