Random

generates a 16-bit pseudorandom number.

Games require a source of random numbers to keep the play surprising and exciting. Streams of pseudorandom bits can be used to generate white noise or interpolate between A/D converter measurements. Random simulates a hardware pseudorandom sequence generator made up of a shift register and three exclusive-OR (XOR) gates wired up as follows:

A circuit like this generates a sequence of bits that repeats every 65,535 shifts. Because of the long interval between the same bit pattern showing up, the sequence can, for many purposes, be considered random. To use Random, just call it. Upon return, the bits previously held in hiB and lowB will have been clocked through the equivalent of the circuit above. You can then use hiB or lowB, or the two combined into a 16-bit value, as your random number. You may also use a bit of one of the variables as a coin-toss decision maker. Random can be used to generate white-noise effects. Call the routine from within a tight program loop and copy one bit of hiB or lowB to an output pin. The stream of random bits at the output produces a rushing sound in a connected speaker or amplifier.

From one call to the next, the pattern inherent in Random is very apparent. A number is doubled, truncated to 16 bits (or 8, if you're using only one of the variables), and may or may not have a 1 added to the result. If Random is used to control patterns of lights or sounds, this pattern may be objectionable. In those cases, try to borrow an element of uncertainty from the outside world. For example, continuously call Random while waiting for the user to press a switch. This is analogous to BASIC programs on PCs that seed the random number generator with the current contents of the timer.

Demonstrating Random.

To see Random in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run RANDOM.SRC. The LEDs will show the sequence of pseudorandom patterns as they cycle through the variable lowB.


; 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. 

        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
        device  pic16c55,xt_osc,wdt_off,protect_off
        reset   start
        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