home *** CD-ROM | disk | FTP | other *** search
- page ,132
- ;
- ;***********************************************************************
- ;* Here are data declarations for use by RINIT, IVNI, IUNI, VNI, UNI. *
- ;* All routines are written for use with LAHEY Fortran Compiler *
- ;* Version 2.22 and above. *
- ;* *
- ;* Authors: G. Marsaglia, B. Narasimhan and Arif Zaman *
- ;* Supercomputer Computations Research Institute *
- ;* and *
- ;* Department of Statistics *
- ;* Florida State University *
- ;* Tallahassee, Fl 32306-3033. *
- ;***********************************************************************
- ;
- .MODEL small ;Use small memory model
- TITLE 'A Random Number Generator for PC's.'
- ;
- ;---------------Equates-----------------
- ;
- arg_offset equ 6 ;Offset of argument.
- c_low equ 0cbb1h
- c_high equ 74h ;C = 7654321 initially.
- cons_low equ 55e5h
- cons_high equ 159ah ;Constant = 362436069.
- no_of_bits equ 32
- top_of_list equ 168
- init_i_val equ top_of_list
- init_j_val equ 84
- ;
- datseg segment para
- ;
- ; Table for Generator (Default values).
- ;
- unitabl dd 0F83CEE7Bh
- dd 0A83E5AD3h
- dd 036200BBh
- dd 0FA5764F6h
- dd 0A13CBFC4h
- dd 565A191Eh
- dd 14D4CCFBh
- dd 7F5AD22Ch
- dd 03528F2Eh
- dd 0E81E32DDh
- dd 71C47276h
- dd 0AA0F8045h
- dd 3C3F1C78h
- dd 0E8CE101Dh
- dd 0CCC12691h
- dd 47196DBFh
- dd 074A6DFFh
- dd 03FB675Eh
- dd 60436236h
- dd 072F0247h
- dd 0C7E9185h
- dd 0CE579EAEh
- dd 01864E96h
- dd 0A526C5C6h
- dd 0F582EB0Dh
- dd 0AFE827F4h
- dd 55CED836h
- dd 26124C49h
- dd 7049AEE1h
- dd 49552795h
- dd 0D1602ED6h
- dd 051C65CEh
- dd 0AEF3CC37h
- dd 0A83880ABh
- dd 0AE7EE06Ah
- dd 0D64D988Bh
- dd 0A96BC73h
- dd 0ECEF4297h
- dd 6C18300Dh
- dd 22F3A897h
- dd 0B4D760ADh
- dd 0AC838383h
- dd 0FD04E68Fh
- ;
- i dw 164
- j dw 80 ;Indices I and J.
- c dd 0EADA75CCh ;Constant C.
- mod169 db 169
- mod179 db 179
- multiplier db 53
- carry db 1 ;Carry bit (Default).
- stored_val dd 122a70c3h
- datseg ends
- ;
- ;***********************************************************************
- ;* Subroutine RINIT takes an 8-digit number as argument. Use as *
- ;* CALL RINIT(I) *
- ;* *
- ;* Purpose: Seeds the table and prepares pointers for use by other *
- ;* routines. *
- ;* *
- ;* This is set up for use with LAHEY Fortran Compiler Version 2.22 and *
- ;* above. *
- ;* *
- ;* Authors: G. Marsaglia, B. Narasimhan and A. Zaman *
- ;* Supercomputer Computations Research Institute *
- ;* and *
- ;* Department of Statistics *
- ;* Florida State University *
- ;* Tallahassee, Fl 32306-3033. *
- ;***********************************************************************
- ;
- .CODE
- rseg segment
- ;
- assume cs:rseg, ds:datseg
- rinit proc Far
- public rinit
- ;
- ; Usual LAHEY stuff....
- ;
- push bp ;Save caller's BP.
- mov bp,sp ;Ready to address.
- ;
- mov ax,datseg ;DATA segment.
- mov ds,ax
- ;
- ; Load parameter and strip two digits at a time to get four seed values.
- ;
- les si,DWORD PTR[bp].arg_offset
- mov ax,Word Ptr es:[si]
- mov dx,Word Ptr es:[si]+2
- mov cx,10000
- div cx
- mov cl,100
- div cl
- mov bx,ax ;BH = K, BL = L.
- mov ax,dx
- div cl
- mov dl,ah
- mov dh,al ;DH = J, DL = I.
- ;
- ; Add one to all to make sure they are non-zero.
- ;
- inc dl
- inc dh
- inc bh
- inc bl
- ;
- ; DL = I, DH = J, BL = L, BH = K.
- ;
- xor si,si ;Table Index.
- labl01:
- ;
- ; Result will be in [BP,DI].
- ;
- xor di,di
- xor bp,bp
- mov cx,no_of_bits ;Bit counter.
- labl02:
- shl di,1
- rcl bp,1 ;Result *= 2.
- mov al,dh ;AL = J.
- mul bh ;AX = J * K.
- div mod179
- mov al,ah ;AL = AX mod 179.
- mul dl ;AX = AX * I.
- div mod179
- mov dl,dh ;I = J.
- mov dh,bh ;J = K.
- mov bh,ah ;K = new K.
- ;
- mov al,bl ;AL = L.
- mul multiplier
- inc ax
- div mod169
- mov bl,ah ;L = 53*L+1 mod 169.
- ;
- mov al,bl ;AL = new L.
- mul bh ;AX = L * K.
- and ax,63 ;Mod 64.
- cmp ax,32
- jl labl03
- inc di ;Set low bit.
- labl03:
- loop labl02
- ;
- mov WORD PTR unitabl[si],di
- mov WORD PTR unitabl[si+2],bp ;Save value.
- add si,4 ;Bump pointer.
- cmp si,172 ;Seeded 86 entries?
- jne labl01
- ;
- ; Set indices.
- ;
- mov i,init_i_val
- mov j,init_j_val
- ;
- ; Set carry to zero.
- ;
- mov carry,0
- ;
- ; Set constants.
- ;
- mov WORD PTR c,c_low
- mov WORD PTR c+2,c_high
- ;
- ; Ready the first value.
- ;
- mov ax,offset stored_val
- mov bx,seg stored_val
- push bx
- push ax
- call Far Ptr ivni
- pop ax
- pop ax
- ;
- ; Epilogue...
- ;
- pop bp
- ret
- rinit endp
- ;
- ;***********************************************************************
- ;* This proc contains the following functions. *
- ;* *
- ;* IVNI : A function that returns a signed random integer between *
- ;* -2**31 and 2**31-1. *
- ;* IUNI : A function that returns a positive random integer *
- ;* between 0 and 2**31-1. *
- ;* VNI : A function that returns a signed random uniform between *
- ;* -1 and 1. *
- ;* UNI : A function that returns a positive random uniform *
- ;* between 0 and 1. *
- ;* *
- ;* All routines mix a subtract-with-borrow generator and an *
- ;* arithmetic sequence: *
- ;* x(n) = x(n-22) - x(n-43) - carry mod 2**32-5. *
- ;* c = c + 362436069 mod 2**32. *
- ;* result = x(n) - c mod 2**32. *
- ;* *
- ;* This is set up for use with LAHEY Fortran Compiler Version 2.22 and *
- ;* above. *
- ;* *
- ;* Authors: G. Marsaglia, B. Narasimhan and A. Zaman *
- ;* Supercomputer Computations Research Institute *
- ;* and *
- ;* Department of Statistics *
- ;* Florida State University *
- ;* Tallahassee, Fl 32306-3033. *
- ;***********************************************************************
- ;
- assume cs:rseg, ds:datseg
- ivni proc Far ;First entry point.
- public ivni
- mov ax,datseg
- mov ds,ax
- mov ax,Word Ptr stored_val
- mov bx,Word Ptr stored_val+2
- jmp save_and_get_next
- ;
- iuni label Far ;Second entry point.
- public iuni
- mov ax,datseg
- mov ds,ax
- mov ax,Word Ptr stored_val
- mov bx,Word Ptr stored_val+2
- and bx,7fffh ;Mask sign bit.
- jmp save_and_get_next
- ;
- vni label Far ;Third entry point.
- public vni
- mov ax,datseg
- mov ds,ax
- mov ax,Word Ptr stored_val
- mov bx,Word Ptr stored_val+2
- mov di,ax ;Sign is last bit.
- jmp normalize
- ;
- uni label Far ;Fourth entry point.
- public uni
- mov ax,datseg
- mov ds,ax
- mov ax,Word Ptr stored_val
- mov bx,Word Ptr stored_val+2
- xor di,di ;Sign should be zero.
- ;
- ; Normalize the number.
- ;
- normalize:
- mov cx,no_of_bits ;Bit counter.
- labl04:
- shl ax,1 ; Shift left.
- rcl bx,1
- jc labl05
- loop labl04
- jmp save_and_get_next ;Store zero.
- labl05:
- add cx,94
- mov al,ah
- mov ah,bl
- mov bl,bh
- mov bh,cl
- test di,1
- jz labl06
- stc
- labl06:
- rcr bx,1
- rcr ax,1
- ;
- save_and_get_next:
- push bp
- mov bp,sp
- les si,DWord Ptr [bp].arg_offset ;Load result address.
- mov Word Ptr es:[si],ax
- mov Word Ptr es:[si]+2,bx
- pop bp
- ;
- mov di,j ;Load index j.
- mov cx,Word Ptr unitabl[di]
- mov dx,Word Ptr unitabl[di]+2 ;U(j) in DX, CX.
- ;
- sub di,4 ;j <- j - 4.
- jns update_j
- mov di,168
- update_j:
- mov j,di
- ;
- mov si,i ;Load index i.
- mov ah,carry ;Load carry.
- sahf
- sbb cx,Word Ptr unitabl[si]
- sbb dx,Word Ptr unitabl[si]+2 ;U(j)-U(i) in DX, CX.
- lahf
- mov carry,ah ;Save carry.
- jnc dont_modify
- ;
- ;Negative.
- ;
- sub cx,5 ;Subtract 5.
- sbb dx,0
- dont_modify:
- ;
- ;Save result.
- ;
- mov Word Ptr unitabl[si],cx
- mov Word Ptr unitabl[si]+2,dx
- ;
- sub si,4 ;i <- i - 4.
- jns update_i
- mov si,168
- update_i:
- mov i,si
-
- ;
- ;Prepare arithmetic sequence.
- ;
- mov ax,Word Ptr c
- mov bx,Word Ptr c+2
- sub ax,cons_low
- sbb bx,cons_high
- mov Word Ptr c,ax
- mov Word Ptr c+2,bx
- ;
- sub cx,ax
- sbb dx,bx
- mov Word Ptr stored_val,cx
- mov Word Ptr stored_val+2,dx ;Save for next time.
- ret
- ivni endp
- ;
- rseg ends
- END
-