Random numbers support
The following example will show how Knuths random generator from pages 221-222 in Numerical Recipes in Pascal, 1st edition can be created as an external module and then linked into a Pascal P-code module.
nil
then the structure is a allocated with a new
operation.
The mechanism expects nil
to be identical to '0' when seen as an integer.
OS-9 Pascal edition
{ Returns a uniform random deviate between 0.0 and 1.0. Set idum to any negative value to initialize or reinitialize the sequence. } PROGRAM SupportRand; TYPE stateptr = ^state; state = RECORD Idum, Ran3Inext, Ran3Extp : integer; Ran3Ma : ARRAY [1..55] OF real END; { Initialize the storage for the random generator and randomize based on system time. } PROCEDURE randomize(VAR b:stateptr); VAR y, m, d, h, mi, s : integer; BEGIN IF b = nil THEN NEW(b); b^.Idum := -1; systime(y, m, d, h, mi, s); IF y <> 0 THEN b^.Idum := -h * 1330 + mi * 30 + s; END; FUNCTION random(VAR b:stateptr):real; (* CONST * mbig=1000000000;mseed=161803398;mz=0;fac=1.0e-9; * var * i,ii,k,mj,mk : longint; *) CONST mbig = 4.0e6; mseed = 1618033.0; mz = 0.0; fac = 2.5e-7; { 1/mbig } VAR i,ii,k : integer; mj,mk : real; BEGIN IF b = nil THEN randomize(b); IF b^.Idum < 0 THEN BEGIN mj := mseed + b^.Idum; IF mj >= 0.0 THEN mj := mj - mbig * trunc(mj/mbig) ELSE mj := mbig - abs(mj) + mbig * trunc(abs(mj)/mbig); (* mj := mj mod mbig; *) b^.Ran3Ma[55] := mj; mk := 1; FOR i := 1 TO 54 DO BEGIN ii := 21 * i mod 55; b^.Ran3Ma[ii] := mk; mk := mj-mk; IF mk < mz THEN mk := mk+mbig; mj := b^.Ran3Ma[ii] END; FOR k := 1 TO 4 DO BEGIN FOR i := 1 TO 55 DO BEGIN b^.Ran3Ma[i] := b^.Ran3Ma[i]-b^.Ran3Ma[1+((i+30) mod 55)]; IF b^.Ran3Ma[i] < mz THEN b^.Ran3Ma[i] := b^.Ran3Ma[i] + mbig; END END; b^.Ran3Inext := 0; b^.Ran3Extp := 31; b^.Idum := 1 END; b^.Ran3Inext := b^.Ran3Inext+1; IF b^.Ran3Inext = 56 THEN b^.Ran3Inext := 1; b^.Ran3Extp := b^.Ran3Extp+1; IF b^.Ran3Extp = 56 THEN b^.Ran3Extp := 1; mj := b^.Ran3Ma[b^.Ran3Inext]-b^.Ran3Ma[b^.Ran3Extp]; IF mj < mz THEN mj := mj+mbig; b^.Ran3Ma[b^.Ran3Inext] := mj; random := mj*fac; END; BEGIN {no main program, this is a standalone subroutine module} END.
Compilation to be linked as an external module
First we compile the SupportRandom.pas file into a P-code file with the name SupportRandom.prun.
OS9: pascal <SupportRandom.pas : o=SupportRandom.prun
Note the numbers of the procedures you want to make into external subroutines.
PROC NAME PSEC PSIZE LOCAL STACK CSEC CSIZE DEBUG 0 SUPPORTR 6 7 0 7 7 0 0 1 RANDOMIZ 1 91 12 19 2 0 0 2 RANDOM 2 823 20 25 6 0 0 921 32 51 0
The second step is to translate it into assembly form.
OS9:pascals pascalt.prun #20K Enter the name of the pcode file to be translated. SupportRandom.prun Enter the name of the 6809 assembly language file to be produced. SupportRandom.asm Translate all procedures? (Y or N)? n Produce external definition file (Y or N)? y Enter the name of the external definition file to be produced. SupportRandom.e Enter a list of procedure numbers to translate. A zero value will terminate the list. A negative value will back out a previously selected entry. 1 2 0 List of procedures selected for translation. 1 2 Is this list correct. (Y or N)? y Enter a pathlist to be used as the external module pathlist and module name. random Translate line numbers in pcode file (Y or N)? y Begin translation of ... Proc Name Psize Csize 1 RAND 682 0
Assemble the module. The file PascalDefs must be present in the data directory.
OS9:asm SupportRandom.asm o=SupportRandom
The external module is created in the execution directory with the file name SupportRandom
.
It is recommended to choose a naming convention that shows that these files are not commands.
The module is now available for other programs to link to. Keep the SupportRandom.e
for this occasion.
When you have compiled your program, which uses random numbers, then the output is a file called PCODEF
. This is then linked to the support module.
Run the linkage editor.
OS9:pascale <SupportRandom.e :PCODEF
Run the program.
OS9:pascaln PCODEF