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