merge 64-bit fixes from Fernando Lucas Rodriguez <fernando_lr@terra.es>
[debian/gcpegg] / reg_pseudo.c
1 /* PROGRAM:     eggsh
2  * FILE:        $Header: /home/egg/src/RCS/reg_pseudo.c,v 1.1 1998/12/31 22:04:39 ghn Exp $
3  * PURPOSE:     PEAR (Bradish box/micro-REG) hardware interface
4  * AUTHOR:      Greg Nelson
5  * DATE:        98-04-12
6  *
7  * REVISED:     $Log: reg_pseudo.c,v $
8  * REVISED:     Revision 1.1  1998/12/31 22:04:39  ghn
9  * REVISED:     Initial revision
10  * REVISED:
11  * REVISED:     Revision 1.3  1998/08/01 18:50:39  ghn
12  * REVISED:     Added John's byte-order-independence changes and PSEUDO support.
13  * REVISED:
14  * REVISED:     Revision 1.2  1998/08/01 17:13:51  ghn
15  * REVISED:     Added John's Solaris support and DUMPREG option.
16  * REVISED:
17  * REVISED:     Revision 1.1  1998/07/21 11:37:41  ghn
18  * REVISED:     Initial revision
19  * REVISED:
20  * Copyright 1998 - Greg Nelson
21  * Redistributable under the terms of the GNU Public Licence (GPL)
22  */
23
24 /* Define this to dump samples from the REG which we actually use into
25    a file named dumpreg.dat.  */
26 /* #define DUMPREG */
27
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <time.h>
31
32 #include "global.h"
33 #include "genlib.h"
34 #include "reg.h"
35 #include "lecuyer.h"
36
37 #define MAXDEV  20
38
39 static int32 oldbits[MAXDEV], bitsleft[MAXDEV];
40
41 #ifdef DUMPREG
42 static FILE *dumpfile;                /* REG dump file handle */
43 static unsigned char dumpbuf[1024];   /* REG dump buffer */
44 static int dumpptr = 0;               /* Pointer into dump buffer */
45 #endif
46
47 static int32 OpenDev(DevOpts *opts) {
48     int32 seed;
49     int i;
50
51     seed = time(NULL);
52     LEsetSeed(seed);
53
54     for (i = 0; i < 37; i++) {
55         seed = (seed << 3) ^ LEnextByte();
56     }
57     LEsetSeed(seed);
58     seed = LEnextByte();
59     for (i = 0; i < (seed & 0x37); i++) {
60         (void) LEnextByte();
61     }
62     return 0;
63 }
64
65 static int32 Sample(int32 dd, uint16 bits) {
66   int32 bc, sum;
67   uint8 c1;
68
69   sum = bc = 0;
70   while (bc < bits) {
71     if (bitsleft[dd]) {
72       sum += (oldbits[dd] & 0x01);
73       oldbits[dd] >>= 1;
74       bitsleft[dd]--;
75       bc++;
76     } else {
77       c1 = LEnextByte();
78 #ifdef DUMPREG
79       dumpbuf[dumpptr++] = c1;
80       if (dumpptr >= sizeof(dumpbuf)) {
81         fwrite(dumpbuf, sizeof(dumpbuf), 1, dumpfile);
82         dumpptr = 0;
83       }
84 #endif
85       oldbits[dd] = c1;
86       bitsleft[dd] = 8;
87     }
88   }
89
90   return sum;
91 }
92
93 #define SAMP_PERIOD     1000    /* msec */
94 #define MARGIN          .95     /* how much to headroom to allow in
95                                    speed measurement */
96
97 static int32 EvalSpeed(int32 dd) {
98   struct timeval start, end;
99   int32 bitct, samp;
100
101   gettimeofday(&start, NULL);
102   bitct = 0;
103   while (1) {
104     gettimeofday(&end, NULL);
105     if (deltams(&end, &start) >= SAMP_PERIOD) break;
106     samp = Sample(dd, 1);
107     bitct++;
108   }
109
110   return (int32)(bitct * MARGIN);
111 }
112
113 static int32 Discard(int32 dd) {
114   int32 disc;
115   
116   disc = bitsleft[dd];
117   bitsleft[dd] = 0;
118   return disc;
119 }
120
121 static int32 CloseDev(int32 dd) {
122   return 0;
123 }
124
125 /*  Driver description table.  */
126
127 REG_driver REG_pseudo = {
128                         "PSEUDO", 
129                         2000,
130                         OpenDev,
131                         EvalSpeed,
132                         Sample,
133                         Discard,
134                         CloseDev
135                       };