Routines |
Prev: 54219 | Up: Map | Next: 54283 |
This routine uses a linear congruential generator to generate a new pseudo-random number based upon a seed value. The seed value is stored at 54219, is initially set to the value in the least significant byte of the FRAMES system variable, and subsequently set to the previously generated pseudo-random number. On entering this routine, the A register holds the range for the random number (e.g. 5 means this routine will generate a random number in the range 0-4 inclusive). A range of less than 2 is not allowed, so if A is less than this then it will be set to 2.
The nth pseudo-random number, R(n) is given by:
R(n) = (aR(n - 1) + b) mod c
Where a = 254, b = 253 and c = 65,537.
The instructions between 54235 and 54261 inclusive generate and store the next pseudo-random number based upon the previous one.
The term (aR(n - 1) + b) is calculated as a 24-bit integer by the instructions between 54235 and 54250 inclusive.
The modulo operation is carried out by the instructions between 54252 and 54261 as follows. The divisor, c, has the value 65,537, which can be expressed as:
2562 + 2560
The 24-bit dividend (stored in the registers A, H and L) has the value:
2562A + 2561H + 2560L
This can be expressed as:
2562A + 2561H + 2560A + 2560(L - A)
Since A is an integer, then:
2562A + 2560A
must be an integer multiple of the divisor. We can therefore drop these terms, and those that are left constitute the remainder that we are seeking:
2561H + 2560(L - A)
or:
HL - A
|
||||||||||||
54222 | CP 2 | If range is less than 2 then set it to 2 | ||||||||||
54224 | JP NC,54229 | |||||||||||
54227 | LD A,2 | |||||||||||
54229 | LD (54221),A | Store range at 54211 | ||||||||||
54232 | PUSH HL | Store HL | ||||||||||
54233 | PUSH DE | Store DE | ||||||||||
54234 | PUSH BC | Store BC | ||||||||||
54235 | LD DE,(54219) | Load DE with seed | ||||||||||
54239 | LD H,E | Load least significant byte of random seed into H | ||||||||||
54240 | LD L,253 | Set L to 253 | ||||||||||
54242 | LD A,D | Load most significant byte (MSB) of random seed into A | ||||||||||
At this point, the three registers A, H and L encode a 24-bit number whose value is (256 × seed + 253)
|
||||||||||||
54243 | OR A | Reset carry flag | ||||||||||
54244 | SBC HL,DE | Subtract seed from HL and decrement A if carry flag is set | ||||||||||
54246 | SBC A,0 | |||||||||||
54248 | SBC HL,DE | Subtract seed from HL and decrement A if carry flag is set | ||||||||||
54250 | SBC A,0 | |||||||||||
At this point, the three registers A, H and L encode a 24-bit number whose value is (254 × seed + 253)
|
||||||||||||
54252 | LD E,A | Calculate (AHL mod 65,537) loading result into HL, and if this is negative then add one (as zero in HL can represent both zero and 65,536) | ||||||||||
54253 | LD D,0 | |||||||||||
54255 | SBC HL,DE | |||||||||||
54257 | JP NC,54261 | |||||||||||
54260 | INC HL | |||||||||||
54261 | LD (54219),HL | Store HL (new seed) at 54219 | ||||||||||
At this point, HL contains a new pseudo-random 16-bit number
|
||||||||||||
54264 | PUSH HL | Copy 16-bit pseudo-random number from HL into DE | ||||||||||
54265 | POP DE | |||||||||||
54266 | LD A,(54221) | Load A with range as stored previously | ||||||||||
54269 | DEC A | Decrease range by 1 to get maximum value as we want the output to range from 0 to (A-1) and load result into B (loop counter) | ||||||||||
54270 | LD B,A | |||||||||||
In the following loop we are obtaining the number of times that 65,536 goes into RANGE × DE. In other words, (RANGE × DE) is divided by 65,536 and the integer part of the result is loaded into A. A is therefore limited to values between zero, and the value A had on entering this routine minus one, inclusive.
|
||||||||||||
54271 | XOR A | Set A to zero | ||||||||||
54272 | ADD HL,DE | Add DE to HL | ||||||||||
54273 | JP NC,54277 | If DE has not crossed the 65,535 - 0 boundary then skip ahead to 54277 | ||||||||||
54276 | INC A | Increase A (count of number of times DE rolls over from 65,535 to 0) | ||||||||||
54277 | DJNZ 54272 | Decrease B and loop back to 54272 | ||||||||||
54279 | POP BC | Restore BC | ||||||||||
54280 | POP DE | Restore DE | ||||||||||
54281 | POP HL | Restore HL | ||||||||||
54282 | RET | Return |
Prev: 54219 | Up: Map | Next: 54283 |