;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; Random Number Generator   # 01    Tylisha C. Andersen
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

; General-purpose random number generator.
; Uses a 'Linear feedback shift register'.
; Note: won't work if the seed is zero.
;   Assumes ds = cs
;   Returns eax = result

Proc        rand

            push  cx
            mov   eax, [seed]
            mov   cx, 33

rloop:      add   eax, eax
            jnc   $+4
            xor   al, 197
            loop  rloop

            mov   [seed], eax

            pop   cx
            ret

seed        dd    1

EndP        rand


;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; Random Number Generator   # 02    Mikko Hyvarinen
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

random  proc
        imul eax,[seed],1107030247
        add eax,97177
        mov [seed],eax
        shr eax,15
        ret
seed    dd 0
random  endp


;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; Random Number Generator   # 03    Tylisha C. Andersen
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

; True random number generator.  Not a pseudo-random RNG!
; Uses the system clock countdown timer.  Very slow.
;   Returns eax = result

Proc        true_rand

            push  cx                ; save registers
            push  edx

            mov   cx, 100           ; 100 iterations
            cli                     ; no interrupts allowed

p1_loop:    mov   al, 06h           ; set timer command
            out   43h, al
            call  p1_null
            in    al, 40h           ; read low byte of timer
            xor   dl, al            ; xor into edx
            call  p1_null
            in    al, 40h           ; read high byte of timer
            xor   dl, al            ; xor into edx

            rol   edx, 7            ; rotate left by 7
            loop  p1_loop           ; loop back

            sti                     ; enable interrupts
            xchg  eax, edx          ; result in eax

            pop   edx               ; restore registers
            pop   cx
p1_null:    ret                     ; return

EndP        true_rand
