ORION's Random Number Generator

Software listing



DOS (GWBasic)



PROGRAM RNGTEST




      10 ADRES=0                                                                  
20 BASEA=&H2F8
30 BASEB=&H3F8
40 OUT BASEA+4,2
50 OUT BASEB+4,2
60 CLS
70 FOR J=1 TO 30000:NEXT J
80 IF (INP(BASEA+5) AND 1)>0 THEN PRINT "COMM-1 IS USED": ADRES= BASEA
90 IF (INP(BASEB+5) AND 1)>0 THEN PRINT "COMM-2 IS USED": ADRES= BASEB
100 IF ADRES = 0 THEN PRINT "RNG not found": STOP
110 FOR I = 1 TO 10
120 IF (INP(ADRES+5) AND 1)= 0 THEN GOTO 120
130 PRINT INP(ADRES)
140 NEXT I


DOS (C++)



PROGRAM RTEST



#include "conio.h">
#include "string.h"
#include "bios.h"
#include "stdio.h"
#include "dos.h"
#include "math.h"
#include "stdlib.h"
#include "io.h"
#include "time.h"

int com_ready(int BASE_ADDRESS);
int read_com(int BASE_ADDRESS);
long i,lsr,n_cycles=100,j,bit[8],total,tbit;
int BASE;
long n_old,no;
double sdtot,mce,sd,z,chi2,chi2tot,x[257],Z[257],f;
unsigned char n;
FILE *fp;
char sys[][40]={" ",
"mode com1:9600,n,8,1",
"mode com2:9600,n,8,1"};
void main(int argc, char **argv)
{
clrscr();
if(argc>=2)
{
system(sys[ atoi(argv[1])] );
if(atoi(argv[1])==1)BASE=0x3f8;
else BASE=0x2f8;
}
else
{
printf("rtest [com] [number of cycles]\n");
BASE=0x2f8;system(sys[2]);
itoa(10,argv[2],10);
}
printf("press escape to exit\n");
fp=fopen("test","w+t");
outp(BASE+4,2); /*rts high*/
delay(300); /*give time to settle*/
for(;;)
{
if(com_ready(BASE))
{
n=read_com(BASE);
printf("\n%d",n);
if(getch()==0x1b) /*escape*/
{
clrscr();break;
}
}
}
printf("wait for display...");
n=read_com(BASE);
for(;;)
{
for(i=0;i<=255;i++)x[i]=0;
mce=sd=z=chi2=tbit=0;
for(i=1;i<=n_cycles;i++)
{
for(j=1;j<=256;j++)
{
for(;;)
{
if(com_ready(BASE))break;
}
n=read_com(BASE);
if(n&1) bit[0]++;else bit[0]--;
if(n&2) bit[1]++;else bit[1]--;
if(n&4) bit[2]++;else bit[2]--;
if(n&8) bit[3]++;else bit[3]--;
if(n&16) bit[4]++;else bit[4]--;
if(n&32) bit[5]++;else bit[5]--;
if(n&64) bit[6]++;else bit[6]--;
if(n&128)bit[7]++;else bit[7]--;
x[n]++;
}
}
mce=n_cycles;
sd=sqrt(mce*255)/16.0;
for(i=0;i<=255;i++)
{
z=(x[i]-mce)/sd;
chi2+=(z*z);
Z[i]=z;
}
chi2tot+=chi2;total++;sdtot+=sd;
clrscr();
printf("run : %ld\n",total);
printf("chi2 : %f\nsd : %f\n",chi2,sd);
for(j=0;j<8;j++)printf("bit %ld : %ld\n",j,bit[j]);
for(j=0;j<8;j++)tbit+=bit[j];
printf("\ntotal bit : %ld\n",tbit);

if(total==atoi(argv[2]))
{
printf("\n\npress any key to display result");
getch();
clrscr();
rewind(fp);
fprintf(fp,"cycles : %ld",n_cycles);
fprintf(fp,"\nruns : %ld",total);
fprintf(fp,"\nmean chi2 : %f",chi2tot/total);
fprintf(fp,"\nmean sd : %f",sdtot/total);
for(j=0;j<=7;j++)fprintf(fp,"\nbit %ld : %ld",j,bit[j]);
tbit=0;
for(j=0;j<=7;j++)tbit+=bit[j];
fprintf(fp,"\n\ntotal bit : %ld",tbit);

printf("cycles : %ld",n_cycles);
printf("\nruns : %ld",total);
printf("\nmean chi2 : %f",chi2tot/total);
printf("\nmean sd : %f",sdtot/total);
for(j=0;j<=7;j++)printf("\nbit %ld : %ld",j,bit[j]);
printf("\n\ntotal bit : %ld",tbit);
fclose(fp);break;
}
}
getch();
}

int init_com(int com)
{
int BASE_ADDRESS;
if(com==1)
{
system("mode com1:9600,n,8,1");
BASE_ADDRESS=0x3f8;
}
if(com==2)
{
system("mode com2:9600,n,8,1");
BASE_ADDRESS=0x2f8;
}
outp(BASE_ADDRESS+4,2); /*rts high*/
delay(300); /*give time to settle*/
return BASE_ADDRESS;
}

int com_ready(int BASE_ADDRESS)
{
if(((int)inp(BASE_ADDRESS+5))&1)return 1;
else return 0;
}


int read_com(int BASE_ADDRESS)
{
return inp(BASE_ADDRESS);
}

PROGRAM RAND3




#include "conio.h"
#include "string.h"
#include "bios.h"
#include "graphics.h"
#include "stdio.h"
#include "dos.h"
#include "stdlib.h"
#include "io.h"
void m_c(int n);
void initgraphic(void);
void leavegraphic(void);
void clear(void);
int BASE,Exp,yy,ms1,ms2,ms3,ms4,status,x=240,x2=240,xx;
char key,string[40];
unsigned barr[256],lsr,lcr,bal,bah;
void baud_rate(int b);
char sys[][40]={" ",
"mode com1:9600,n,8,1",
"mode com2:9600,n,8,1"};
void main(int argc, char **argv)
{
if(argc==2)
{
system(sys[ atoi(argv[1])] );
printf("press escape to exit\n");
if(atoi(argv[1])==1)BASE=0x3f8;

else BASE=0x2f8;
}
else
{
BASE=0x2f8;system(sys[2]);
}
outp(BASE+4,2);/*rts high*/
delay(300);
for(;;)
{
lsr=(int)inp(BASE+5);
if(lsr&1)
{
ms1=inp(BASE);
printf("\n%d",ms1);if(getch()==0x1b)break;
}
}
initgraphic();
setcolor(LIGHTRED);
rectangle(0,0,getmaxx(),getmaxy());
for(int y=0;y<=256;y+=8)line(0,y,getmaxx(),y);
settextjustify(1,1);
outtextxy(getmaxx()/2,400,"press space bar to reset");
outtextxy(getmaxx()/2,420,"press escape to end");
moveto(320,240);
lsr=inp(BASE+5);
for(;;)
{
lsr=inp(BASE+5);
if(lsr&1)
{
if(lsr&0x12)
{
restorecrtmode();exit(0);
}
ms1=inp(BASE);
barr[ms1]++;
putpixel(barr[ms1],ms1,YELLOW);
}
if(kbhit())
{
key=getch();
if(key==0x1b)break;
if(key==' ')clear();
}
}
restorecrtmode();
}

void initgraphic(void)
{
int driver,mode;
detectgraph(&driver,&mode);
mode=VGAHI;
registerfarbgidriver(EGAVGA_driver_far);
registerfarbgifont(small_font_far);
registerfarbgifont(triplex_font_far);
initgraph(&driver,&mode,"");
delay(0);
}

void leavegraphic(void)
{
closegraph();
restorecrtmode();normvideo();window(1,1,80,25);clrscr();
}

void baud_rate(int b)
{
unsigned lcr=0,bal=0,bah=0;
lcr=inp(b+3);
lcr|=128;
outp(b+3,lcr);
bal=inp(b);
bah=inp(b+1);
outp(b+3,lcr&0x7f);
lcr=bah<<8;
lcr|=bal;
printf("\n%x",lcr);getch();
}

void clear(void)
{
extern int xx,x,x2;
for(int j=0;j<256;j++)barr[j]=0;
xx=x=x2=0;
cleardevice();
setcolor(LIGHTRED);
rectangle(0,0,getmaxx(),getmaxy());
for(int y=0;y<=256;y+=8)line(0,y,getmaxx(),y);
moveto(320,240);
lsr=inp(BASE+5);
}


PROGRAM PK




#include "conio.h"
#include "stdio.h"
#include "dos.h"
#include "stdlib.h"
#include "math.h"
#include "graphics.h"
#include "io.h"

int INTR,dummy,ready;
void bell(void);
void init_com(void);
long Ro=40,dev=1;
char key,string1[40],string2[40],string3[40];
void leavegraphic(void);
void initgraphic(void);
int sample,read_com(int BASE_ADDRESS);
int r_draw,r_old,BASE=0x2f8,msec=10;
long N_trials=1024;

void main(int argc, char **argv)
{
clrscr();
if(argc==4)
{
if(atoi(argv[1])==1)BASE=0x3f8;
N_trials=atol(argv[2]);
msec=atoi(argv[3]);
}
else
{
printf("\npkexp [com] [number of trials] [msec between trials]\n");
exit(0);
}
init_com();
initgraphic();

for(long n=1;n<=N_trials;n++)
{
if(kbhit())
{
if(getch()==0x1b)break;/*escape*/
}
r_old=Ro;
sample=read_com(BASE);
dev=-dev;
if(sample&4)Ro+=dev;
else Ro-=dev;
if(r_old>Ro)
{
setcolor(0);
r_draw=r_old;
}
else
{
setcolor(15);
r_draw=Ro;
}
if(r_draw<0)r_draw=0;
circle(320,240,r_draw);
delay(msec);
}
sprintf(string1,"number of trials : %ld",N_trials);
sprintf(string2,"dev : %ld",Ro-40);
sprintf(string3,"Z score : %f",(Ro-40)/sqrt(N_trials));
settextjustify(0,1);
setcolor(15);
outtextxy(230,400,string1);
outtextxy(230,410,string2);
outtextxy(230,420,string3);
getch();
leavegraphic();
}

void init_com(void)
{
outp(BASE+3,0x80); /* set dlab bit */
outp(BASE,0xc); /* Baudrate=115200/0xc=9600 */
outp(BASE+1,0); /* msb Baudrate=0 */
outp(BASE+3,3); /* 8 bit no parity 1 stopbit */
outp(BASE+4,0xa); /* rts high enable interrupts*/
delay(300); /* give time to settle */
}

int com_ready(int BASE_ADDRESS)
{
if(((int)inp(BASE_ADDRESS+5))&1)return 1;
else return 0;
}

int read_com(int BASE_ADDRESS)
{
return inp(BASE_ADDRESS);
}

void leavegraphic(void)
{
closegraph();
restorecrtmode();normvideo();window(1,1,80,25);clrscr();
}

void initgraphic(void)
{
int driver,mode;
detectgraph(&driver,&mode);
mode=VGAHI;
registerfarbgidriver(EGAVGA_driver_far);
initgraph(&driver,&mode,"");
setpalette(15,0);
setpalette(0,15);
settextjustify(1,1);
outtextxy(320,400,"ENTER TO START");
circle(320,240,Ro);
floodfill(320,240,15);
for(;;)if(getch()==13)break;
setcolor(0);
outtextxy(320,400,"ENTER TO START");
setcolor(15);
}



Macintosh (TURBO-PASCAL)




PROGRAM rng_test


;

{ Very simple rngtest program for Mac }
{ Does not conform to Mac Interface standards }

Uses Memtypes, Quickdraw, Osintf, Toolintf;

CONST
buflen = 1024; { bufferlength in bytes }
inpoort = -6; { drivername .Ain }
uitpoort = -7; { drivername .Aout }
{ use -8 and -9 for printerport}
VAR
gebeuren :EventRecord;
inbuffer :Packed ARRAY [1..buflen] OF Byte;
serconfig :INTEGER;
status :Oserr;
uitbuffer :Packed ARRAY [1..buflen] OF Byte;


{ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }


function read_com(VAR bt :Integer ): Boolean;

VAR
inwerk :Packed ARRAY [1..4096] OF CHAR;
error :OSErr;
inteller :Longint;
BEGIN
read_com:=false;
error := Sergetbuf ( inpoort, inteller );
IF inteller > 0 THEN BEGIN
error := Fsread ( inpoort, inteller, @inwerk );
bt := Ord(inwerk[1]);
read_com:=true;
END;
END;{ van functie read_com }

{ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }


PROCEDURE init_com;
VAR
error: OSErr;
serconfig: Integer;

BEGIN
status := Ramsdopen ( Sporta ); { Opens RAM io-drivers }
IF status <> 0 THEN BEGIN { status<>0 ==> impossible to open }
WRITELN ( 'communicationport not available' );
WRITE ( 'Hit return ==>' );
READLN;
HALT;
END;

{ samenstellen van configuration: }
{ 1 stopbit, 87 data bits, no pariteit,lijnsnelheid 9600 Baud }

serconfig := Data8 OR Stop10 OR Noparity OR Baud9600;
error := Serreset ( inpoort , serconfig );
error := Serreset ( uitpoort, serconfig );
error := Sersetbuf ( inpoort , @inbuffer , buflen );
error := Sersetbuf ( uitpoort , @uitbuffer , buflen );
END; {init_com}

{ - - - - - - - - - - - - M A I N - - - - - - - - - - - - - - - - }

VAR bt,i,cycle,j, devbits,RUN,nruns,devbitscum :Integer;
ticks, sombits,N, expbits,tt :Longint;
x :Array[1..255] of Integer;
b :Array[1..8] of LongInt;
hasTimeOut :Boolean;
chi2,dev,mean,sd,ncum :REAL;
filvar :TEXT;
pathname :String[255];
expb,bb :Longint;

label 999;

BEGIN
init_com;
WRITELN('TURBO RNGtest --- ');
WRITELN('This program tests the RNG connected to the modemport at maximum speed');
WRITELN('Each run consists of 256 * 32 samples');
WRITELN('The number of bits 1 - bits 0 generated on each position within the byte');
WRITELN('as well as the total number of bit 1 - bit 0 is calculated');
WRITELN('A chi2 checking all byte patterns (df = 255) is given after each run.');
WRITELN('Also cumulative bit data are stored');
WRITELN;
WRITELN('The theoretical cumulative sd is also written to a datafile (RNGTESTDATA)');
WRITELN('for plotting convenience');
WRITELN;
WRITELN('Enter number of runs:');
READLN(nruns);
Delay(10,tt);

pathname:='RNGTESTDATA';
REWRITE(filvar, pathname);
WRITELN(filvar,'run n d1 d2 d3 d4 d5 d6 d7 d8 chi2 totdev totdevcum sd sdm');
devbits:=0;
devbitscum:=0;
ncum:=0.0;

FOR RUN :=1 TO nruns DO
BEGIN

WRITELN('run:', run, ' is sampling');
FOR i:=1 to 256 DO x[i]:=0;
FOR i:=1 to 8 DO b[i]:=0;
N := 256*32;
mean := N / 256;
sombits:=0;
chi2:=0.;

FOR cycle:=1 to N DO BEGIN
ticks := TickCount;
REPEAT
hasTimeout :=(TickCount - ticks) > 100;
UNTIL read_com(bt) or hasTimeout;

if hasTimeOut THEN
BEGIN
WRITELN('Time Out; RNG is not working');
goto 999;
END;
x[bt+1]:=x[bt+1]+1;
END;

FOR i:=1 to 256 DO
BEGIN
dev := x[i]-mean;
chi2 := chi2 + dev*dev/mean;
b[1] := b[1] + x[i] * (i AND $01);
b[2] := b[2] + x[i] * ((i AND $02) Shr 1);
b[3] := b[3] + x[i] * ((i AND $04) Shr 2);
b[4] := b[4] + x[i] * ((i AND $08) Shr 3);
b[5] := b[5] + x[i] * ((i AND $10) Shr 4);
b[6] := b[6] + x[i] * ((i AND $20) Shr 5);
b[7] := b[7] + x[i] * ((i AND $40) Shr 6);
b[8] := b[8] + x[i] * ((i AND $80) Shr 7);
END;
ClearScreen;

WRITE('results run:', run,' chi2 test:');
WRITELN(chi2:6:2);
ncum :=N * 8.0 + ncum; {cumulative number of sampled bits}
sd := 0.5*sqrt(ncum);
WRITELN('cumbits:', ncum:8:0,' sd:', sd:6:2);
WRITE(filvar,run,' ',N,' ');
sombits:=0;
expb := 128*32;
FOR i:=1 to 8 DO
BEGIN
sombits:=sombits + b[i];
bb := b[i] - expb;
WRITE(bb,' ');
WRITE(filvar,bb,' ');
END;
WRITELN;
expbits:= 4*N;
devbits:= sombits-expbits;
devbitscum := devbitscum+devbits;
WRITELN('expected number of one-bits:',expbits);
WRITELN('total number of one-bits:',sombits,' cum.deviation = ',devbitscum );
IF chi2 > 300 then
WRITELN('RNG may be suspect');
WRITELN(filvar,chi2:6:2,' ', devbits, ' ', devbitscum,' ',sd:6:2, ' ', -sd:6:2);
END; {run}
CLOSE(filvar);

999:
Ramsdclose ( Sporta );
WRITELN;
WRITELN;
WRITELN('Press mousebutton to quit');
while not Button do;
END. { of rng test }


{ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }

PROGRAM PK_test




(some procedures can be found in RNG_test)


PROCEDURE cirkel ( x, y, r0, r :INTEGER );
VAR
rechthoek1,rechthoek2 : Rect; { structuur in Quickdraw }

BEGIN

rechthoek1.top := y-r0;
rechthoek1.left := x-r0;
rechthoek1.bottom := y+r0;
rechthoek1.right := x+r0;
rechthoek2.top := y-r;
rechthoek2.left := x-r;
rechthoek2.bottom := y+r;
rechthoek2.right := x+r;




IF (r> r0) THEN
BEGIN
ForeColor(BlackColor);
FrameOval(rechthoek2);
END
ELSE
BEGIN
ForeColor(WhiteColor);
FrameOval(rechthoek1);
END;

END; { van procedure cirkel }


{ - - - - - - - - - - - - - - - - - M A I N PK- - - - - - - - - - - - - - - - }
VAR ntrials, R0,r1, R, nruns,dly, RUN, trial, bt, dev, diff,rr :Integer;
x,y,i :Integer;
p :Pattern;
rechthoek1 :Rect;
z :Real;
ticks,tt :Longint;
hasTimeOut :Boolean;
filvar :TEXT;
pathname, id, direction :String[255];

label 999;

BEGIN
For i:=0 to 7 DO
BEGIN
p[i]:=$FF;
END;
init_com;
WRITELN('This is a very simple PKtest (v1.0) using the RNG connected to the modem-port');
WRITELN('Bit-4 of the random byte is used to decide if the radius of the circle');
WRITELN('is going to be incremented or decremented.');
WRITELN;
WRITELN('The subject can choose a target direction because potential first order');
WRITELN('non-randomness is balanced by changing the meaning of the bits after each sample');
WRITELN;

WRITE('TURBO PKtest --- enter number of runs:');
READLN(nruns);
WRITE('TURBO PKtest --- enter number of trials per run:');
READLN(ntrials);
WRITE('TURBO PKtest --- enter delay between trials:');
READLN(dly);
WRITE('Enter ID (data are stored in a file with this name):');
READLN(id);
Clearscreen;
R0:=40;
R:=R0;
dev := 1;

pathname:=id;
REWRITE(filvar, pathname);

FOR RUN :=1 TO nruns DO
BEGIN
R:=R0;
r1:=R0;
dev := 1;
WRITELN;
WRITELN('Choose a targetdirection for run ', run,' (type large or small followed by RETURN)');
READLN(direction);
Clearscreen;
WRITELN('Hit return to start run:', run, ' of ',nruns, ' Target=', direction);
READLN;
Clearscreen;

{first original circle}
x:=240;
y:= 139;
rechthoek1.top := y-r0;
rechthoek1.left := x-r0;
rechthoek1.bottom := y+r0;
rechthoek1.right := x+r0;
FillOval(rechthoek1, p);

FOR trial:=1 to ntrials DO BEGIN
ticks := TickCount;
REPEAT
hasTimeout :=(TickCount - ticks) > 100;
UNTIL read_com(bt) or hasTimeout;

if hasTimeOut THEN
BEGIN
ForeColor(BlackColor);
WRITELN('Time Out; RNG is not working');
goto 999;
END;
IF (bt AND $10) > 0 THEN R := R+dev ELSE R:=R-dev;
IF R < 0 then rr:=0 else rr:=R;
dev := -dev; {to balance first order non randomness}
cirkel ( 240, 139, r1, rr ); {update circle}
r1:=rr; {update old r-value}
Delay(dly,tt);

END;

Delay(100,tt);
Clearscreen;
ForeColor(BlackColor);

diff:= R-R0;
z := Float(diff) / sqrt(ntrials);
WRITELN('resuls run:', run);
WRITELN('target:', direction,' total # trials:',ntrials);
WRITELN('# large - # small = ', diff, ' z=',z:6:2);
WRITELN(filvar,RUN,' ',ntrials,' ',direction,' ',diff,' ',z:6:2);

END; {run}
CLOSE(filvar);

999:
Ramsdclose ( Sporta );
WRITELN;
WRITELN;
WRITELN('Press mousebutton to quit');
while not Button do;
END. { van programma terminal }