8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


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 5-byte 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 1-byte result (and moves all other bytes along a position) as follows:
* Set temp-var1 to the value of location &0F divided by 2 [LSR]
* Set temp-var2 to the top 4 bits of location &0E plus the bottom 4 bits of temp-var1
* Copy bottom 2 bits of temp-var2 (bit 0 and bit 1) to the top 2 bits (bit 6 and bit 7) of temp-var3
* Set bit 5 of temp-var3 to the Carry flag status
* Set carry flag to bit 2 of temp-var2
* Copy bit 7, bit 6, bit 5, bit 4 and bit 3 of temp-var2 to bit 4, bit 3, bit 2, bit 1 and bit 0 of temp-var3
* 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 temp-var1 in the previous cycle (or 0 if this is the first cycle))
* Set temp-var4 to temp-var3 EOR location &11
* Set location &0D to temp-var4
* 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 5-byte value is used as the mantissa for a Floating-Point 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

 


 Back to 8BS
Or