;==================================================
;  PROGRAM TITLE:	Random Number Generator
; 
;  WRITTEN BY:		Raymond E. Penley
;  DATE WRITTEN:	27 June 1980
;
;  WRITTEN FOR:		Pascal/Z Users Group
;
;  SUMMARY:
;	Implements a Fibonacci series Random number generator.
; 	RANDOM will return numbers from 0 to x
;
; 		Call as			  Returns
; 		-------			------------
; 	    real := RANDOM(10);		0.0 to 10.0
; 	    real := RANDOM(112);	0.0 to 112.0
; 	     I := TRUNC(RANDOM(10));      0 to 10
;
; **
;   Add these lines to your PASCAL source program:
;
;     Procedure SEEDRAND; EXTERNAL;
;     Functin RANDOM(X: Integer): REAL; external;
;
;   Also within the body of the main program
;   but BEFORE calling RANDOM(X);
; 
; 	  SEEDRAND;
;
;*** What would happen if you did not call SEEDRAND ? ***
; 
;===============================================
;
; PROCEDURE SEEDRAND;
; (* INITIAL VALUES FOR SEED1 AND SEED2 ARE HERE  *)
;
 	NAME RANDOM
 	ENTRY SEEDRAND,RANDOM
;
SEEDRAND:
	ENTR	D,2,0
;    SEED1 := 10946;
	MVI	0(IY),42
	MVI	-1(IY),194
;    SEED2 := 17711
; END;
	MVI	-2(IY),69
	MVI	-3(IY),47
	EXIT	D,0
;
;
;
; Function Random(x: integer): real;
; (*
; GLOBAL
;   SEED1, SEED2 : INTEGER		*)
; CONST
;   factor = Maxint;
;   HALFINT = 16383; (* 1/2 OF MAXINT *)
; VAR
;   x1 : real;
;   temp1, temp2, HALF_ADDER : INTEGER;

RANDOM:
	ENTR	D,2,10
; (* Take 1/2 of the seeds for the comparison test *)
;   temp1 := SEED1 DIV 2;
	MOV	L,-1(IY)
	MOV	H,0(IY)
	LXI	D,2
	DIVD	D,0
	MOV	-6(IX),H
	MOV	-7(IX),L
;   temp2 := SEED2 DIV 2;
	MOV	L,-3(IY)
	MOV	H,-2(IY)
	LXI	D,2
	DIVD	D,0
	MOV	-8(IX),H
	MOV	-9(IX),L
;   IF (temp1+temp2) >= HALFINT then{the number is too big -}
	MOV	L,-7(IX)
	MOV	H,-6(IX)
	MOV	E,-9(IX)
	MOV	D,-8(IX)
	DADD	D,0
	LXI	D,16383
	GE	D,0
;     { scale it down }
;     HALF_ADDER := temp1 + temp2 - HALFINT
	JNC	L177
	MOV	L,-7(IX)
	MOV	H,-6(IX)
	MOV	E,-9(IX)
	MOV	D,-8(IX)
	DADD	D,0
;   ELSE
	LXI	D,-16383
	DADD	D,0
	MOV	-4(IX),H
	MOV	-5(IX),L
;     HALF_ADDER := temp1 + temp2;
	JMP	L197
L177
	MOV	L,-7(IX)
	MOV	H,-6(IX)
	MOV	E,-9(IX)
	MOV	D,-8(IX)
	DADD	D,0
	MOV	-4(IX),H
	MOV	-5(IX),L
L197
;   SEED1 := SEED2;
	MOV	L,-3(IY)
	MOV	H,-2(IY)
	MOV	0(IY),H
	MOV	-1(IY),L
;   (* Restore from previous DIVision *)
;   SEED2 := HALF_ADDER * 2;
	MOV	L,-5(IX)
	MOV	H,-4(IX)
	DADD	C
	MOV	-2(IY),H
	MOV	-3(IY),L
;   (*---Convert X to real and divide by factor---*)
;   x1 := ((X*1.0)/factor);
	MOV	L,8(IX)
	MOV	H,9(IX)
	PUSH	H
	LXI	H,320
	MOV	D,A
	MOV	E,A
	PUSH	H
	PUSH	D
	CVTF	C
	MULT	D,-4
	CVTF	A,32767
	FDVD	D,-4
	LXI	H,3
	DADD	S
	XCHG
	PUSH	IX
	POP	H
	XCHG
	LXI	B,4
	LDDR
	POP	H
	POP	H
;   (*---Return random number scaled by factor---*)
;   RANDOM := ( SEED2 * x1 );
	MOV	L,-3(IY)
	MOV	H,-2(IY)
	PUSH	H
	LXI	H,-4
	DADD	S
	SPHL
	XCHG
	PUSH	IX
	POP	H
	DCX	H
	DCX	H
	DCX	H
	LXI	B,4
	LDIR
	CVTF	C
	MULT	D,-4
	LXI	H,3
	DADD	S
	XCHG
	PUSH	IX
	POP	H
	LXI	B,13
	DADD	B
	XCHG
	LXI	B,4
	LDDR
	POP	H
	POP	H
; End{ of RANDOM(X) };
	EXIT	D,2
