/* 
This program is part of the ZRANDOM True Random Number Generator (TRNG).

Copyright (c) 2002 Westphal Electronic 
Every owner of a ZRANDOM hardware device is allowed to use or change 
this source code. 

The ZRANDOM hardware device is available at: 
      Westphal Electronic 
      Kritzegraben 6
      07743 Jena
      Germany
      Fax: +49 3641 228802
      email: info@westphal-electronic.de
      Internet: www.westphal-electronic.de

Compilation under Linux with:  gcc -O1 zrand1.c ( option is -O1 not -01 )
Compile as root and make available for other users by:  chmod +s a.out
Execution: ./a.out
*/

#include <asm/io.h>
#include <unistd.h>

#define portaddress 0x220 /* Hex code of the I/O-port address 
	    		     selected on the ISA card */

long int i,rep,error,randbit,byte1,byte2;
long int imax=1000000,repmax=20;

/*******************************************************************/
new_random_bit() /* Creates one random bit */
/* 
   Important note:
   The delays must be greater (or equal) 5 usec to certainly avoid 
   random bit correlations. The function usleep(5) does not work 
   as expected, the delay is much longer than 5 microseconds. 
   To get 5 usec delay time you may use a calibrated counting loop.
   The maximum random bit generation rate should not exceed 50000/sec. 
   With a Pentimum II/300MHz about 150000 port accesses/s are possible.
*/
{
byte1=0; byte2=0;
rep=0; /* Check repetitions (more than repmax is very unprobable) */
while ((byte1==byte2)&&(rep<repmax))
  {
  byte1=inb(portaddress);  /* read port */
  /* usleep(5);   delay >= 5 us */
  byte2=inb(portaddress);  /* read port */
  /* usleep(5);   delay >= 5 us */  
  rep++;
  }
if (rep>=repmax) error=1; 
if (byte1<byte2) randbit=0; else randbit=1;
} 
/*******************************************************************/


main()
{

/* Get permission t use I/O-port */ 
   ioperm(portaddress,7,1);  
   
printf(" \n");
printf(" Generation of 20 True Random Bits by use of ZRANDOM TRNG\n");
printf(" ========================================================\n\n");
error=0;
i=1;
while ((i<=imax)&&(error==0))
  {
    new_random_bit();
    /* printf(" randbit = %d\n",randbit); */
    i++;
  }
printf(" ----- End -----\n\n"); 
if (error==1)
   printf(" **** Error! Check port address and hardware. ****\n\n"); 
}
