;===================================================================== ; 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