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