gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/asm/sm83/rand.s
1 ;/***************************************************************************
2 ; * *
3 ; * Module : rand.s *
4 ; * *
5 ; * Purpose : A rand() generator using the linear congruential method *
6 ; * *
7 ; * Version : 1.01, January 7 1998 *
8 ; * Added _initrand to set seed without recompiling *
9 ; * 1, January 6 1998 *
10 ; * *
11 ; * Author : Luc Van den Borre ( Homepage : NOC.BASE.ORG ) *
12 ; * *
13 ; **************************************************************************/
14
15 ;; Why use an algorithm for generating random numbers?
16 ;;
17 ;; - Given a certain seed value, the same sequence of random numbers is generated
18 ;; every time. This is a good thing when debugging (reproducible). On the other
19 ;; hand, you've got 2^16 seed values, each of which will produce a sequence of
20 ;; numbers that stays different for any of the other sequences for 'an appreciable
21 ;; time.' (I can't say how long exactly.)
22 ;;
23 ;; - The linear congruential method is one of the 'best' random number generators
24 ;; around. However, this implementation uses a 16 bit accumulator, while at least
25 ;; 32 bits are needed for a generator that passes all the statistical tests.
26 ;; Still, I'm relatively confident that this is random enough for even the most
27 ;; demanding game.
28 ;;
29 ;; Compare this to getting random values from one of the hardware registers
30 ;; (not reproducible, might not have all values). An array might be the best bet
31 ;; if you don't need a lot of values (or have lots of memory spare),
32 ;; or if you want values to be within a certain range.
33 ;; And both would be faster than this. Also, this definitely isn't the fastest
34 ;; algorithm I know, and certainly for games less strict algorithms might be
35 ;; appropriate (shift and xor ?).
36 ;; It's your choice - but if you're doing Monte Carlo physics simulations on the
37 ;; GameBoy, this is a safe bet!
38
39 .area _DATA
40 ___rand_seed::
41 .randlo: ; Storage for last random number (or seed)
42 .ds 0x01
43 .randhi:
44 .ds 0x01
45
46 .area _HOME
47
48 ;; Random number generator using the linear congruential method
49 ;; X(n+1) = (a*X(n)+c) mod m
50 ;; with a = 17, m = 65536 and c = $5c93 (arbitrarily)
51 ;; The seed value is also chosen arbitrarily as $a27e
52 ;; Ref : D. E. Knuth, "The Art of Computer Programming" , Volume 2
53 ;;
54 ;; Exit conditions
55 ;; DE = Random number [0,2^16-1]
56 ;;
57 ;; Registers used:
58 ;; A, HL (need not be saved) and DE (return register)
59 ;;
60
61 _rand:: ; Banked
62 _randw:: ; Banked
63 ld hl, #.randlo
64 ld a, (hl+)
65 ld e, a
66 ld d, (hl) ; D = randhi
67
68 ; HL = 17 * DE + 0x5C93
69 ld h, d
70 ld l, e
71
72 add hl, hl
73 add hl, hl
74 add hl, hl
75 add hl, hl
76 add hl, de
77 ld de, #0x5C93
78 add hl, de
79
80 ld d, l
81 ld e, h ; de = return value
82
83 ld hl, #.randlo
84 ld a, d
85 ld (hl+), a
86 ld (hl), e
87
88 ;; Note D is the low byte,E the high byte. This is intentional because
89 ;; the high byte can be slightly 'more random' than the low byte, and I presume
90 ;; most will cast the return value to a uint8_t. As if someone will use this, tha!
91 ret
92
93 ;; This sets the seed value. Call it whenever you like
94 ;;
95 ;; Exit conditions
96 ;; None
97 ;;
98 ;; Registers used:
99 ;; A, HL (need not be saved) and DE (return register)
100 ;;
101
102 _initrand::
103 LDA HL,2(SP)
104 .initrand::
105 LD A,(HL+)
106 LD (.randlo),A
107 LD A,(HL)
108 LD (.randhi),A
109 RET
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.