[net.sources] Random Number Generator

ronw@faust.UUCP (07/26/85)

Does anyone out there have 8088 source for a random number generator?

mark@hp-pcd.UUCP (mark) (07/30/85)

;; Strip off all lines that begin with ;;
;; The following routine is pretty good if you only need a 64K period.
;; Just ensure that there are no label conflicts and you can merge it into
;; your program (MASM 1.25) or if you want to assemble a stand-alone object
;; you will have to add the appropriate header and tail.
;; Note that the seeder routine (SRAND) makes a INT 21 call to get the clock
;; value from MS-DOS.  This will have to be deleted (or modified) it not
;; running under MS-DOS.
;; Enjoy.  Mark Rowe, Corvallis, Or.  hp-pcd!mark


RandC		equ	13849		; Linear congruential offset
RandF		equ	23392		; Skip value for result of 64K
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;		Random number generator (and seeder)		(04/17/85)
;     The Rand routine generates a random number from the previous random
;  number via the linear congruential method.  The formula is as follows:
;		X(n+1) = (55994*X(n) + 13849) mod 65537
;  The value is returned in AX as a 16 bit unsigned integer from 0 to 65535.
;  The result of 65536 is trapped and skipped over (since 65536 is too big to
;  store in 16 bits).  The period is 64K.  The initial seed is zero if not
;  altered via a call to Srand.  The AX and DX registers are altered.
;     The Srand routine sets the seed for the random number generator (Rand).
;  If the value of AX is nonzero then it becomes the random number seed and
;  no registers are altered.  If AX is zero then the seed is generated from
;  the current clock value and the AX, BX, CX and DX registers are altered.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rand:
	mov	AX,CS:[RandX]		; Set DX:AX to previous random number
	xor	DX,DX
	or	AX,AX			; Skip multiply code if zero
	jz	Rand1
	mul	CS:[RandA]		; Compute product mod 65537 (in DL:AX)
	sub	AX,DX
	mov	DL,0
	adc	AX,0
	jnz	Rand1
	inc	DL
Rand1:	add	AX,RandC		; Compute sum (in DL:AX)
	adc	DL,0
	jz	Rand2			; Jif sum < 64K
	dec	AX			; AX=sum mod 65537
	jns	Rand2			; Jif result not 64K
	mov	AX,RandF		; AX=value following 64K
Rand2:	mov	CS:[RandX],AX		; Store new random number
	ret				; Return with AX=new random number
Srand:
	or	AX,AX			; Test parameter (AX)
	jnz	Srand1			; Jif parameter is nonzero
	mov	AH,2CH			; Get current time
	int	21H
	mov	AL,CH			; Convert time to seconds/100)
	mul	byte ptr CS:Sixty
	mov	CH,0
	add	AX,CX
	mov	CX,DX
	mul	word ptr CS:Sixty
	mov	DL,CH
	add	AX,DX
	mul	word ptr CS:Hundred
	mov	CH,0
	add	AX,CX
Srand1:	mov	CS:[RandX],AX		; Set random number seed to AX
	ret
Sixty		dw	60		; Constant multiplier
Hundred		dw	100		; Constant multiplier
RandA		dw	55994		; Linear congruential multiplier
RandX		dw	0		; Random number (initially zero)