Imported Upstream version 5.1
[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
31 #include "global.h"
32 #include "genlib.h"
33 #include "reg.h"
34 #include "lecuyer.h"
35
36 #define MAXDEV  20
37
38 static int32 oldbits[MAXDEV], bitsleft[MAXDEV];
39
40 #ifdef DUMPREG
41 static FILE *dumpfile;                /* REG dump file handle */
42 static unsigned char dumpbuf[1024];   /* REG dump buffer */
43 static int dumpptr = 0;               /* Pointer into dump buffer */
44 #endif
45
46 static int32 OpenDev(DevOpts *opts) {
47     int32 seed;
48     int i;
49
50     seed = time(NULL);
51     LEsetSeed(seed);
52
53     for (i = 0; i < 37; i++) {
54         seed = (seed << 3) ^ LEnextByte();
55     }
56     LEsetSeed(seed);
57     seed = LEnextByte();
58     for (i = 0; i < (seed & 0x37); i++) {
59         (void) LEnextByte();
60     }
61     return 0;
62 }
63
64 static int32 Sample(int32 dd, uint16 bits) {
65   int32 bc, sum;
66   uint8 c1;
67
68   sum = bc = 0;
69   while (bc < bits) {
70     if (bitsleft[dd]) {
71       sum += (oldbits[dd] & 0x01);
72       oldbits[dd] >>= 1;
73       bitsleft[dd]--;
74       bc++;
75     } else {
76       c1 = LEnextByte();
77 #ifdef DUMPREG
78       dumpbuf[dumpptr++] = c1;
79       if (dumpptr >= sizeof(dumpbuf)) {
80         fwrite(dumpbuf, sizeof(dumpbuf), 1, dumpfile);
81         dumpptr = 0;
82       }
83 #endif
84       oldbits[dd] = c1;
85       bitsleft[dd] = 8;
86     }
87   }
88
89   return sum;
90 }
91
92 #define SAMP_PERIOD     1000    /* msec */
93 #define MARGIN          .95     /* how much to headroom to allow in
94                                    speed measurement */
95
96 static int32 EvalSpeed(int32 dd) {
97   struct timeval start, end;
98   int32 bitct, samp;
99
100   gettimeofday(&start, NULL);
101   bitct = 0;
102   while (1) {
103     gettimeofday(&end, NULL);
104     if (deltams(&end, &start) >= SAMP_PERIOD) break;
105     samp = Sample(dd, 1);
106     bitct++;
107   }
108
109   return (int32)(bitct * MARGIN);
110 }
111
112 static int32 Discard(int32 dd) {
113   int32 disc;
114   
115   disc = bitsleft[dd];
116   bitsleft[dd] = 0;
117   return disc;
118 }
119
120 static int32 CloseDev(int32 dd) {
121   return 0;
122 }
123
124 /*  Driver description table.  */
125
126 REG_driver REG_pseudo = {
127                         "PSEUDO", 
128                         2000,
129                         OpenDev,
130                         EvalSpeed,
131                         Sample,
132                         Discard,
133                         CloseDev
134                       };