;=====================================================================
; Random Number Subroutines Implementation by: R.F. Genovese, Ph.D.
; TEKNOMETRIKA
; L-15, S-123
; 11160 Veirs Mill Road
; Wheaton, MD 20902
;=====================================================================
;we used tasm /ml /w
;---------------------------------------------------------------------
; void _seed_ran(void)
; unsigned int _get_ran(unsigned char bitsize)
;---------------------------------------------------------------------
DATASEG
PUBLIC _r_seed
_r_seed DD 55aaaaaah ;31 bit shift register
CODESEG
;---------------------------------------------------------------------
; void _seed_ran(void)
; seeds the 31 bit shift register used by the pseudorandom generator
; from BIOS ticks counter at 40h:6ch
;---------------------------------------------------------------------
PROC _seed_ran
mov ax,40h ;BIOS segment
mov es,ax
mov ax,[es:6ch] ;get ticks
mov [WORD LOW _r_seed],ax ;into lsw shift register
; we rather cheaply toggle ax and stick it in the high word
not ax
mov [WORD HIGH _r_seed],ax ;into msw shift register
ret ;that's it
ENDP _seed_ran
;---------------------------------------------------------------------
; unsigned int _get_ran(unsigned char bitsize)
; returns a pseudorandom number as an unsigned integer with
; bitsize number of bits. Maximum value of bitsize is 16. Larger
; values will be truncated to 16 bits (i.e. unsigned int size) as
; will a bitsize=0.
;---------------------------------------------------------------------
GR_BITSIZE EQU 4
GR_RESULT EQU 6
PROC _get_ran
push bp
mov bp,sp
push cx
push bx
push ax
;first get and check bitsize from caller
mov cl,[bp + GR_BITSIZE]
xor ch,ch
jcxz @@truncate
cmp cx,10h
jle @@size_ok
@@truncate:
mov cx,10h ;force 16 bit size
@@size_ok:
xor ax,ax ;initalize return value
@@gen_num:
;generate bitsize pseudorandom bits into ax by the result of
;(bit three xor bit six) of the high byte of the shift register
;the result is shifted into the cf and then into ax.
mov bx,[WORD HIGH _r_seed]
and bh,048h ;08h or 40h is result=1 else 0
cmp bh,08h
jz xor1
cmp bh,40h
jz xor1
clc ;xor result=0 so clear carry
jmp short shift_bits
xor1:
stc ;xor result=1 so set carry
;rotate the shift register with the cf becoming the lsb.
shift_bits:
rcl [WORD LOW _r_seed],1
rcl [WORD HIGH _r_seed],1
;rotate cf into our pseudorandom number in ax.
rcl ax,1
loop @@gen_num ;get all of the bits
mov [bp + GR_RESULT], ax
pop cx
pop bx
pop ax
pop bp ;clean up and pass the
ret ;number in ax to C
ENDP _get_ran
;webedone