| The Hobbit (v1.0) | Routines |
| Prev: 9BF4 | Up: Map | Next: 9C3D |
|
Returns a random number in A in the range -C to +C (signed). The random byte is produced from the seed at B5FE (set from the R register in 6C27), the counter at $B602 and a byte fetched from memory.
The random bytes come from memory itself. A 16-bit counter at $B602 is increased on every call and used as an address; the byte found there (and one a little further on) is mixed with the previous result. So the program code, the tables and even the ROM serve as the game's random number table, and the R register seed from the start of the game (6C27) decides where the sequence begins. A result equal to the previous one is thrown away.
The way it narrows the random byte down to the range is unusual: B is set to 2*C, and then the random byte is halved (SRL A) until it is no more than B. Finally C is subtracted. Because 0-255 has to be halved several times, the upper half of the range gets far more than its share: with C=10, values 0-10 of the byte (results -10 to 0) mostly come only from the original byte being 0-10 directly, while 11-20 are hit by many different starting values. For C=10 the results come out approximately: each of -10 to -1: 1/256; 0: 16/256; +1 to +5: 31/256 each; +6 to +10: 15/256 each.
|
||||||||||||
| 9BFD | PUSH IX | |||||||||||
| 9BFF | PUSH BC | |||||||||||
| 9C00 | LD C,A | C = the range | ||||||||||
| 9C01 | SLA A | B = twice the range... | ||||||||||
| 9C03 | JR NC,$9C07 | |||||||||||
| 9C05 | LD A,$FF | ...capped at 255 | ||||||||||
| 9C07 | LD B,A | |||||||||||
| 9C08 | LD IX,$B602 | Advance the 16-bit counter at $B602-$B603 | ||||||||||
| 9C0C | INC (IX+$01) | |||||||||||
| 9C0F | JR NZ,$9C14 | |||||||||||
| 9C11 | INC (IX+$00) | |||||||||||
| 9C14 | LD IX,($B602) | IX = the counter, used as an ADDRESS: it points somewhere in memory | ||||||||||
| 9C18 | LD A,($B5FE) | A = the seed... | ||||||||||
| 9C1B | ADC A,(IX+$00) | ...plus the byte at that address... | ||||||||||
| 9C1E | ADD IX,DE | (move on by DE, whatever it happens to hold) | ||||||||||
| 9C20 | XOR (IX+$01) | ...exclusive-ORed with the byte after | ||||||||||
| 9C23 | PUSH HL | |||||||||||
| 9C24 | LD HL,$B5FE | |||||||||||
| 9C27 | CP (HL) | The same as the previous random number? | ||||||||||
| 9C28 | POP HL | |||||||||||
| 9C29 | JR Z,$9C08 | Yes: try again | ||||||||||
| 9C2B | LD ($B5FE),A | Save it as the new seed | ||||||||||
| 9C2E | CP B | Is it within 0 to 2 x range? | ||||||||||
| 9C2F | JR C,$9C38 | |||||||||||
| 9C31 | JR Z,$9C38 | |||||||||||
| 9C33 | SRL A | No: halve it and try again (this is what skews the results) | ||||||||||
| 9C35 | JP $9C2E | |||||||||||
| 9C38 | SUB C | Subtract the range to give -range to +range | ||||||||||
| 9C39 | POP BC | |||||||||||
| 9C3A | POP IX | |||||||||||
| 9C3C | RET | |||||||||||
| Prev: 9BF4 | Up: Map | Next: 9C3D |