Subversion Repositories Kolibri OS

Rev

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