Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6419 | hidnplayr | 1 | ; ----------------------------- MOTHER.ASM ----------------------------- |
2 | ; Mother-of-All random number generator by Agner Fog 1998 |
||
3 | ; 32-bit mode version for 80x86 and compatible microprocessors |
||
4 | ; |
||
5 | ; MRandom returns a floating point number between 0 and 1. |
||
6 | ; MRandomInit must be called before the first call to MRandom. |
||
7 | ; |
||
8 | ; C++ prototypes: |
||
9 | ; extern "C" void MRandomInit (int seed); |
||
10 | ; extern "C" double MRandom (void); |
||
11 | ; extern "C" int MIRandom (int min, int max); |
||
12 | ; |
||
13 | ; © 1998, 2004 Agner Fog. |
||
14 | ; GNU General Public License www.gnu.org/copyleft/gpl.html |
||
15 | ; ---------------------------------------------------------------------- |
||
16 | |||
17 | ; The MRandom function is optimized for the Pentium microprocessor. |
||
18 | |||
19 | iglobal |
||
20 | mf3 dd 2111111111 ; factors |
||
21 | mf2 dd 1492 |
||
22 | mf1 dd 1776 |
||
23 | mf0 dd 5115 |
||
24 | endg |
||
25 | |||
26 | |||
27 | uglobal |
||
28 | m0 dd ? ; history buffer |
||
29 | m1 dd ? |
||
30 | m2 dd ? |
||
31 | m3 dd ? |
||
32 | mc dd ? |
||
33 | temprng dq ? ; used for conversion to float |
||
34 | endg |
||
35 | |||
36 | |||
37 | proc init_random |
||
38 | |||
39 | mcall 26, 10 ; seed |
||
40 | xor ecx, ecx |
||
41 | ; make random numbers and put them into buffer |
||
42 | @@: |
||
43 | imul eax, 29943829 |
||
44 | dec eax |
||
45 | mov [m0+ecx*4], eax |
||
46 | inc ecx |
||
47 | cmp ecx, 5 |
||
48 | jb @r |
||
49 | push edi |
||
50 | mov edi, 19 |
||
51 | @@: |
||
52 | call MRandom |
||
53 | fstp st0 |
||
54 | dec edi |
||
55 | jnz @r |
||
56 | pop edi |
||
57 | ret |
||
58 | |||
59 | endp |
||
60 | |||
61 | |||
62 | proc MRandom |
||
63 | |||
64 | call MBRandom ; random bits |
||
65 | mov edx, eax ; fast conversion to float |
||
66 | shr eax, 12 |
||
67 | or eax, 3ff00000h |
||
68 | shl edx, 20 |
||
69 | mov dword[temprng+4], eax |
||
70 | mov dword[temprng], edx |
||
71 | fld1 |
||
72 | fld [temprng] ; partial memory stall here |
||
73 | fsubr st0, st1 |
||
74 | ret |
||
75 | |||
76 | endp |
||
77 | |||
78 | |||
79 | proc MIRandom, max, min ; make random integer in desired interval |
||
80 | |||
81 | call MBRandom ; make random number |
||
82 | mov edx, [max] |
||
83 | mov ecx, [min] |
||
84 | sub edx, ecx |
||
85 | js .error ; max < min |
||
86 | inc edx ; max - min + 1 |
||
87 | mul edx ; multiply random number by interval and truncate |
||
88 | lea eax, [edx+ecx] ; add min |
||
89 | ret |
||
90 | |||
91 | .error: |
||
92 | mov eax, 80000000h ; error exit |
||
93 | ret |
||
94 | |||
95 | endp |
||
96 | |||
97 | |||
98 | proc MBRandom |
||
99 | |||
100 | push edi |
||
101 | mov eax, [mf3] |
||
102 | mul [m3] ; x[n-4] |
||
103 | mov ecx, eax |
||
104 | mov eax, [m2] ; x[n-3] |
||
105 | mov edi, edx |
||
106 | mov [m3], eax |
||
107 | mul [mf2] |
||
108 | add ecx, eax |
||
109 | mov eax, [m1] ; x[n-2] |
||
110 | adc edi, edx |
||
111 | mov [m2], eax |
||
112 | mul [mf1] |
||
113 | add ecx, eax |
||
114 | mov eax, [m0] ; x[n-1] |
||
115 | adc edi, edx |
||
116 | mov [m1], eax |
||
117 | mul [mf0] |
||
118 | add eax, ecx |
||
119 | adc edx, edi |
||
120 | add eax, [mc] |
||
121 | adc edx, 0 |
||
122 | mov [m0], eax |
||
123 | mov [mc], edx |
||
124 | pop edi |
||
125 | ret |
||
126 | |||
127 | endp> |