Subversion Repositories Kolibri OS

Rev

Rev 6419 | Details | Compare with Previous | 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
        xor     ecx, ecx
40
        ; make random numbers and put them into buffer
41
  @@:
42
        imul    eax, 29943829
43
        dec     eax
44
        mov     [m0+ecx*4], eax
45
        inc     ecx
46
        cmp     ecx, 5
47
        jb      @r
48
        push    edi
49
        mov     edi, 19
50
  @@:
51
        call    MRandom
52
        fstp    st0
53
        dec     edi
54
        jnz     @r
55
        pop     edi
56
        ret
57
 
58
endp
59
 
60
 
61
proc MRandom
62
 
63
        call    MBRandom                ; random bits
64
        mov     edx, eax                ; fast conversion to float
65
        shr     eax, 12
66
        or      eax, 3ff00000h
67
        shl     edx, 20
68
        mov     dword[temprng+4], eax
69
        mov     dword[temprng], edx
70
        fld1
71
        fld     [temprng]               ; partial memory stall here
72
        fsubr   st0, st1
73
        ret
74
 
75
endp
76
 
77
 
78
proc MIRandom, max, min                 ; make random integer in desired interval
79
 
80
        call    MBRandom                ; make random number
81
        mov     edx, [max]
82
        mov     ecx, [min]
83
        sub     edx, ecx
84
        js      .error                  ; max < min
85
        inc     edx                     ; max - min + 1
86
        mul     edx                     ; multiply random number by interval and truncate
87
        lea     eax, [edx+ecx]          ; add min
88
        ret
89
 
90
  .error:
91
        mov     eax, 80000000h          ; error exit
92
        ret
93
 
94
endp
95
 
96
 
97
proc MBRandom
98
 
99
        push    edi
100
        mov     eax, [mf3]
101
        mul     [m3]                    ; x[n-4]
102
        mov     ecx, eax
103
        mov     eax, [m2]               ; x[n-3]
104
        mov     edi, edx
105
        mov     [m3], eax
106
        mul     [mf2]
107
        add     ecx, eax
108
        mov     eax, [m1]               ; x[n-2]
109
        adc     edi, edx
110
        mov     [m2], eax
111
        mul     [mf1]
112
        add     ecx, eax
113
        mov     eax, [m0]               ; x[n-1]
114
        adc     edi, edx
115
        mov     [m1], eax
116
        mul     [mf0]
117
        add     eax, ecx
118
        adc     edx, edi
119
        add     eax, [mc]
120
        adc     edx, 0
121
        mov     [m0], eax
122
        mov     [mc], edx
123
        pop     edi
124
        ret
125
 
126
endp