Subversion Repositories Kolibri OS

Rev

Rev 6419 | Blame | Compare with Previous | 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.         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