The BBC and Master Computer Public Domain Library
Or
Page Last Altered:
831E Calculate next Random Number Seed value
Submitted by Steve Fewell
Routine:CalcRNDSeed
Name: Calculate the Next Random Number Seed value
Starting Address: &831E
Entry criteria: The Random Number Seed (&0D&11) contain a 5byte Random Number Seed value.
Exit: The Random Number Seed (&0D&11) contain the next Random Number Seed value (based on a specific
calculated sequence).
Description:
This routine calculates the next seed value (in sequence) from the current seed value (in locations &0D&11).
The calculation is repeated 4 times (once for each byte to be calculated), during each cycle a new byte is calculated and
the other 4 bytes are moved along a position within the Random Number seed value. This enables the calculation to produce
varied (non duplicate) results and to always return a valid 'random' result (i.e. never evaluating to a value of 0, which
would be useless as a seed value). The calculation is designed not to give frequent duplicate values (which would put the
routine into a repitive loop).
This routines sets Y to 4 at the start and repeats the Random Number seed calculation loop (decrementing Y for each loop),
until Y is 0.

Each Random Number seed calculation loop obtains a 1byte result (and moves all other bytes along a position) as follows:
 * Set tempvar1 to the value of location &0F divided by 2 [LSR]
 * Set tempvar2 to the top 4 bits of location &0E plus the bottom 4 bits of tempvar1
 * Copy bottom 2 bits of tempvar2 (bit 0 and bit 1) to the top 2 bits (bit 6 and bit 7) of tempvar3
 * Set bit 5 of tempvar3 to the Carry flag status
 * Set carry flag to bit 2 of tempvar2
 * Copy bit 7, bit 6, bit 5, bit 4 and bit 3 of tempvar2 to bit 4, bit 3, bit 2, bit 1 and bit 0 of tempvar3
 * ROR location &11 (move the bits right, set bit 7 to carry and set carry to the bit lost during the move)
 (where carry is bit 2 of tempvar1 in the previous cycle (or 0 if this is the first cycle))
 * Set tempvar4 to tempvar3 EOR location &11
 * Set location &0D to tempvar4
 * Set location &11 to the byte value at location &10
 * Set location &10 to the byte value at location &0F
 * Set location &0F to the byte value at location &0E
 * Set location &0E to the byte value at location &0D
After the 4 cycles, the location &11 is populated with the value of location &0D value from the previous Random
Number Seed value.
This 5byte value is used as the mantissa for a FloatingPoint value in order to generate a random floating point value
between 0 and 1.
Example 1:
This example shows the calculation of the first &831E call (where the Random Number Seed is currently set to the
initial values: location &0D=>&41; location &0E=>&52; location &0F=>&57;
location &10=>&00 and location &11=>&00.
On entry Carry flag = 0 (?).
On entry: &0D=&41; &0E=&52; &0F=&57; &10=&00; &11=&11.
Y = 4 (number of cycles to process).
[Cycle 1:]
ROR &11 (00000000) => &11 = &00, Carry = 0.
A = &10 => A = &00.
X = A => X = &00.
ROR A => A = &00, carry = 0.
&11 = A => &11 = &00.
A = &0F => A = &57.
&10 = A => &10 = &57.
LSR A (01010111) => A = 00101011 (&2B), carry = 1.
EOR &0E (01010010) => A = 01111001 (&79).
AND #&0F => A = &09.
EOR &0E (01010010) => A = 01011011 (&5B).
ROR A => A = 10101101, carry = 1.
ROR A => A = 11010110, carry = 1.
ROR A => A = 11101011, carry = 0.
ROR A => A = 01110101 (&75), carry = 1.
EOR &11 (00000000) => A = 01110101 (&75).
&11 = X => &11 = &00.
&0F = &0E => &0F = &52.
&0E = &0D => &0E = &41.
&0D = A => &0D = &75.
Now: &0D=&75; &0E=&41; &0F=&52; &10=&57; &11=&00.
Y = Y  1 => Y = 3.
[Cycle 2:]
ROR &11 (00000000) => &11 = 10000000 (&80) [as Carry was 1], Carry = 0.
A = &10 => A = &57.
X = A => X = &57.
ROR A (01010111) => A = 00101011 (&2B), carry = 1.
&11 = A => &11 = &2B.
A = &0F => A = &52.
&10 = A => &10 = &52.
LSR A (01010010) => A = 00101001 (&29), carry = 0.
EOR &0E (01000001) => A = 01101000 (&68).
AND #&0F => A = &08.
EOR &0E (01000001) => A = 01001001 (&49).
ROR A => A = 00100100, carry = 1.
ROR A => A = 10010010, carry = 0.
ROR A => A = 01001001, carry = 0.
ROR A => A = 00100100 (&24), carry = 1.
EOR &11 (00101011) => A = 00001111 (&0F).
&11 = X => &11 = &57.
&0F = &0E => &0F = &41.
&0E = &0D => &0E = &75.
&0D = A => &0D = &0F.
Now: &0D=&0F; &0E=&75; &0F=&41; &10=&52; &11=&57.
Y = Y  1 => Y = 2.
[Cycle 3:]
ROR &11 (01010111) => &11 = 10101011 (&AB), Carry = 1.
A = &10 => A = &52.
X = A => X = &52.
ROR A (01010010) => A = 10101001 (&A9), carry = 0.
&11 = A => &11 = &A9.
A = &0F => A = &41.
&10 = A => &10 = &41.
LSR A (01000001) => A = 00100000 (&20), carry = 1.
EOR &0E (01110101) => A = 01010101 (&55).
AND #&0F => A = &05.
EOR &0E (01110101) => A = 01110000 (&70).
ROR A => A = 10111000, carry = 0.
ROR A => A = 01011100, carry = 0.
ROR A => A = 00101110, carry = 0.
ROR A => A = 00010111 (&17), carry = 0.
EOR &11 (10101001) => A = 10111110 (&BE).
&11 = X => &11 = &52.
&0F = &0E => &0F = &75.
&0E = &0D => &0E = &0F.
&0D = A => &0D = &BE.
Now: &0D=&BE; &0E=&0F; &0F=&75; &10=&41; &11=&52.
Y = Y  1 => Y = 1.
[Cycle 4:]
ROR &11 (01010010) => &11 = 00101001 (&29), Carry = 0.
A = &10 => A = &41.
X = A => X = &41.
ROR A (01000001) => A = 00100000 (&20), carry = 1.
&11 = A => &11 = &20.
A = &0F => A = &75.
&10 = A => &10 = &75.
LSR A (01110101) => A = 00111010 (&3A), carry = 1.
EOR &0E (00001111) => A = 00110101 (&35).
AND #&0F => A = &05.
EOR &0E (00001111) => A = 00001010 (&0A).
ROR A => A = 10000101, carry = 0.
ROR A => A = 01000010, carry = 1.
ROR A => A = 10100001, carry = 0.
ROR A => A = 01010000 (&75), carry = 1.
EOR &11 (00100000) => A = 01110000 (&70).
&11 = X => &11 = &41.
&0F = &0E => &0F = &0F.
&0E = &0D => &0E = &BE.
&0D = A => &0D = &70.
Now: &0D=&70; &0E=&BE; &0F=&0F; &10=&75; &11=&41.
Y = Y  1 => Y = 0.
The new seed value is: &0D=&70; &0E=&BE; &0F=&0F; &10=&75; &11=&41.
Table showing the initial sequence of Random Number Seed values
(based on the initial startup value and assuming the Seed value is not explicitly reset at any time [using RND(x)]).
Sequence# 
&0D 
&0E 
&0F 
&10 
&11 






Initial values 
&41 
&52 
&57 
&00 
&00 
1 (831E called once) 
&70 
&BE 
&0F 
&75 
&41 
2 (831E called twice) 
&2E 
&DB 
&60 
&41 
&70 
3 
&47 
&8F 
&02 
&2D 
&2E 
4 
&44 
&34 
&75 
&3E 
&47 
5 
&E5 
&D6 
&7E 
&CC 
&44 
6 
&C7 
&33 
&51 
&8B 
&E5 
7 
&8A 
&E4 
&94 
&D6 
&C7 
8 
&15 
&D8 
&02 
&A5 
&8A 
9 
&FA 
&3B 
&00 
&7F 
&15 
10 
&3E 
&B6 
&3F 
&BC 
&FA 
11 
&48 
&31 
&7C 
&A5 
&3E 
12 
&BE 
&91 
&AA 
&91 
&48 
13 
&C3 
&A6 
&CE 
&E1 
&BE 
14 
&C9 
&6A 
&8B 
&9A 
&C3 
15 
&DA 
&22 
&E9 
&7B 
&C9 
16 
&90 
&33 
&D9 
&2F 
&DA 
17 
&85 
&91 
&D5 
&84 
&90 
18 
&75 
&99 
&72 
&1B 
&85 
19 
&F8 
&16 
&2E 
&A4 
&75 
20 
&4B 
&88 
&78 
&33 
&F8 






After setting seed value to 1 [RND(1)] 
&FF 
&FF 
&FF 
&FF 
&40 
#1 
&FF 
&07 
&00 
&80 
&FF 
#2 
&F8 
&FF 
&7F 
&C0 
&FF 






After setting seed value to &FFFFFFFF 
&E0 
&7D 
&BD 
&DE 
&17 
#1 
&78 
&BD 
&80 
&38 
&E0 
#2 
&C5 
&DF 
&97 
&17 
&78 
Disassembly for the Calculate next Random Number Seed value routine
831E 

160 004 
A0 04 
LDY#&04 
8320 
f 
102 017 
66 11 
ROR &11 
8322 

165 016 
A5 10 
LDA &10 
8324 

170 
AA 
TAX 
8325 
j 
106 
6A 
ROR A 
8326 

133 017 
85 11 
STA &11 
8328 

165 015 
A5 0F 
LDA &0F 
832A 

133 016 
85 10 
STA &10 
832C 
J 
074 
4A 
LSR A 
832D 
E 
069 014 
45 0E 
EOR &0E 
832F 
) 
041 015 
29 0F 
AND#&0F 
8331 
E 
069 014 
45 0E 
EOR &0E 
8333 
j 
106 
6A 
ROR A 
8334 
j 
106 
6A 
ROR A 
8335 
j 
106 
6A 
ROR A 
8336 
j 
106 
6A 
ROR A 
8337 
E 
069 017 
45 11 
EOR &11 
8339 

134 017 
86 11 
STX &11 
833B 

166 014 
A6 0E 
LDX &0E 
833D 

134 015 
86 0F 
STX &0F 
833F 

166 013 
A6 0D 
LDX &0D 
8341 

134 014 
86 0E 
STX &0E 
8343 

133 013 
85 0D 
STA &0D 
8345 

136 
88 
DEY 
8346 

208 216 
D0 D8 
BNE 40 > &8320 
8348 
` 
096 
60 
RTS 
Or