Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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