home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / MISC / BBENCH21.ZIP / SOURCE.ZIP / BENCHFAC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-30  |  93.8 KB  |  3,852 lines

  1. #define VERSION 2.1
  2.  
  3. /*
  4. ** User interface code for BYTE DOS benchmarks.
  5. ** BYTE Lab, 3/90.
  6. **
  7. ** This module contains the main routine. The actual benchmark routines are in
  8. ** benchcod.c ... they are accessed in this module through the benchhook
  9. ** call.
  10. **
  11. ** Revision History:
  12. **  2.0:
  13. **  5/14 - Fixed machine name update bug.- Steve.
  14. **  5/17 - Changed format dumped by /b switch. - Steve.
  15. **  5/22 - Fixed 8088/8086 display bug. - Steve.
  16. **  7/31 - Fixed shift-s bug in veiw results mode. - Steve.
  17. **  8/9  - Fixed overflow bug in miscsubs/getmhz - Steve.
  18. **  8/15 - Changed format dumped by /b switch (vendor and product). - Steve.
  19. **  8/24 - Fixed throughput elapsed time calculation in benchcod.c - RG & SA.
  20. **  2.1: Released 8/31/90
  21. **
  22. **
  23. */
  24. #include <stdio.h>
  25. #include <math.h>
  26. #include <fcntl.h>
  27. #include <sys\stat.h>
  28. #include <stdlib.h>
  29. #include <errno.h>
  30. #include <time.h>
  31. #include <io.h>
  32. #include <ctype.h>
  33. #include <string.h>
  34. #include <conio.h>
  35.  
  36. #include "win.h"    /* contains window definitions */
  37. #include "db.h"        /* contains database structure definitions */
  38. #include "iface.h"    /* contains array definitions for menus */
  39. #include "benchdefs.h"  /* global for both interface and benchmarks */
  40.  
  41. /* a useful macro */
  42. /* value of field -- uses offset into listptr, fieldname, additional offset*/
  43. #define vf(off,f)     \
  44. *((double*)((char*)(*(lp+off))+((unsigned int)(&(((db_rec*)0)->f)))))
  45.  
  46. /* other global variables */
  47.  
  48. int timeradjust;        /* For hires timer */
  49.  
  50. int oldlen;            /* For sliding bar */
  51.  
  52. int staleflag=0;        /* for results */
  53. int graphstale=0;        /* for graphs*/
  54.  
  55. int durmin;            /* duration absolute minimums and maximums */
  56. int durmax=999;
  57.  
  58. win_handle field, help, cpuwin, cpu2win;    /* global windows */
  59. win_handle fpuwin, diskwin, vidwin, textreswin;
  60. win_handle bswin;
  61.  
  62. struct help_handle helptext;
  63. int act_h_h;
  64. int help_base;
  65.  
  66. int oldcurse;        /* old cursor */
  67.  
  68. char tres_ary[TEXTRESSIZE];    /* results to be printed and displayed */
  69. int ac_t_h;            /* actual array height, after filled in */
  70.  
  71. /* default filename for results */
  72. char dumpfname[80];
  73.  
  74. /* default filename for textdb */
  75. char dbtxname[80];
  76.  
  77. /* default machine name */
  78. char machname[80];
  79.  
  80. /* struct to contain machine parameters */
  81. struct mcfig machine_config;
  82.  
  83. /* array of pointers to db fields; this constitutes the database */
  84. db_rec *comparison_data[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  85. char recs_in_db;
  86.  
  87. /* test defaults ... 0 means don't do test */
  88.  
  89. int tdef[14] = {    60,    /* sieve duration */
  90.             60,    /* sort duration */
  91.             60,    /* imath duration */
  92.             60,    /* move duration */
  93.             60,    /* fourbang duration */
  94.             60,    /* fourier duration */
  95.             60,    /* fio duration */
  96.             3,    /* logical drive for fio (a=1)*/
  97.             1,    /* do low-level disk? */
  98.             0,    /* hard disk to test */
  99.             60,    /* text duration */
  100.             60,    /* graphics duration */
  101.             1,    /* repetitions */
  102.             1    /* sound? */
  103.             };
  104.  
  105. int lastproc; /* kludge to keep graphs consistent; needed by batchgraph*/
  106.  
  107. /* for command line */
  108. unsigned char options[9] = {0,0,0,0,0,0,0,0,0};
  109. char valchar[9] = {'b','n','r','c','f','d','v','a','h'};
  110. char * strargs[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  111.  
  112. /* benchmark subroutine prototypes (benchcod.c)*/
  113. extern sieve(win_handle*,unsigned int, unsigned int actime[],    \
  114.     unsigned int *);
  115. extern sort(win_handle*,unsigned int, unsigned int actime[],     \
  116.     unsigned  int *);
  117. extern ifourbang(win_handle*,unsigned int, unsigned int,     \
  118.     unsigned int actime[], unsigned int *);
  119. extern movetest(win_handle *, unsigned int, unsigned int,     \
  120.     unsigned int acttime[][3], unsigned int iters[]);
  121. extern ffourbang (win_handle *,unsigned int,    \
  122.     unsigned int actime[],unsigned int *);
  123. extern fourier(win_handle *,unsigned int,    \
  124.     unsigned int actime[],unsigned int *);
  125. extern do_fileio(win_handle *, unsigned int, unsigned long *,     \
  126.     unsigned long *,unsigned int accrtime[], unsigned int accwtime[],    \
  127.     unsigned long);
  128. extern ll_hdthru(unsigned int, unsigned int, double  *);
  129. extern ll_diskseek(unsigned int, double, double*);
  130. extern textbench(unsigned int, unsigned int, double *);
  131. extern tscroll(unsigned int, unsigned int, double *);
  132. extern graph_bench(unsigned int, double *);
  133. extern double timetodouble(unsigned int *);
  134. extern void adjust_bar(win_handle*, int, int);
  135.  
  136. /* misc subroutine prototypes (miscsubs.asm) */
  137. extern void strip0s (char*, int);        /* fast 0 to space routine */
  138. extern void machine_detect (struct mcfig*);    /* gets machine parameters */
  139. extern int disk_check(int, int);
  140. extern int get_default(void);
  141. extern void set_default(int);
  142. extern void getpath(int, char*);
  143. extern void click(void);
  144. extern int cdir(char *);
  145.  
  146. /* window prototypes  (winsubs.asm)*/
  147. extern win_handle *mk_window( win_handle *, char *, int, int, int, int,
  148.               int, int, int, int, int, int);
  149. extern void kill_window (win_handle *);
  150. extern void hide_window (win_handle *);
  151. extern int new_cursor (int);
  152. extern void win_set_curpos (win_handle *, int, int);
  153. extern void clearscreen (void);
  154. extern int link_array (win_handle *, char *, int, int, int, int);
  155. extern int scroll(win_handle *, int);
  156. extern int chattr (win_handle *, int, int, int, int, int, int);
  157. extern int winputch (win_handle *, int, int, char);
  158. extern void win_erase_region(win_handle *, int, int, int, int);
  159. extern int winstrlen(win_handle *, int, int);
  160. extern int cgainit (void);
  161.  
  162. /* these are local and explained at their definitions */
  163. int optparse(unsigned char *, char *, char **, unsigned int, int, char**);
  164. int ffcopy( char * , char *) ;
  165. void read_defs( char *, int *, int);
  166. void limcheck(int *, int);
  167. int winprintstring( win_handle*, int, int, char*);
  168. int get_resp_line ( win_handle*, int, int, int, int, int *, int);
  169. int guess3(int*, void**, int);
  170. int graph (char*, win_handle *, char, char, char, void**, int, char*);
  171. void execute( int, int, int, int, void **);
  172. void benchhook( win_handle *, double *, int);
  173. int dump_defs( char *, int *, int);
  174. void calc_indexes (void**, int, int, int);
  175. void make_textres (void**, char*, int, int);
  176. void reviewmode(void **);
  177. void dump_array (char *, int, int, int);
  178. int alert_box( char*, int, int, int);
  179. int mod_default_box(char*, int, char*);
  180. int edit_string (win_handle *, int, int, int, char *, int, int);
  181. void controls_menu (void **);
  182. void ts_config (void);
  183. void sys_setup (void);
  184. int validpath(char *);
  185. int validfname(char *);
  186. struct help_handle *make_helpspace(char *, struct help_handle *);
  187. void kill_helpspace(struct help_handle *);
  188. int display_help (struct help_handle *, int);
  189. void edit_data(void**);
  190. char* dbrec2string( db_rec* , char *);
  191. void machtodb(db_rec **, char, struct mcfig *);
  192. int makeixgraphs(win_handle *, void**, int);
  193. int get_filename(int *, char *);
  194. void filedb(db_rec **);
  195. int batchgraph (void **, int);
  196. void switchlist(void);
  197. int delimres(void**);
  198.  
  199. void main (int argc, char **argv)
  200. {
  201.  
  202. /* local data */
  203. unsigned int acttime[3];    /* Elapsed time */
  204. int resp;
  205. int escflag=0;
  206. int i;
  207. int diskstat, breakflag;
  208.  
  209. win_handle logo, menu;
  210.  
  211. /*********************** real start ********************************/
  212.  
  213.     /* get command line args */
  214.     strargs[0] = machname;
  215.     strargs[1] = machname;
  216.     strargs[2] = dumpfname;
  217.  
  218.     if (!optparse(options, valchar, strargs, 9, argc, argv)){
  219.         printf(USAGESTRING);
  220.         exit(0);
  221.         }
  222.  
  223.     if(options[8]){
  224.         switchlist();
  225.         exit(0);
  226.         }
  227.  
  228.     /* weed out bad switches */
  229.     if((options[0]||options[1]) && !(strlen(machname))){
  230.             printf(USAGESTRING);
  231.             exit(0);
  232.             }
  233.     if(options[2] && (strlen(dumpfname))){
  234.         if (!validpath(dumpfname)){
  235.             printf(USAGESTRING);
  236.             exit(0);
  237.             }
  238.         if (!validfname(dumpfname)){
  239.             printf(USAGESTRING);
  240.             exit(0);
  241.             }
  242.         }
  243.  
  244.     /* detect machine type and set parameters*/
  245.     machine_detect(&machine_config);
  246.     machine_config.dosnowplow=0;
  247.     cgainit();
  248.     if(machine_config.MHz > 16) durmin=FASTLIMIT;
  249.     else{
  250.         if (machine_config.MHz >8) durmin=MEDLIMIT;
  251.         else durmin=SLOWLIMIT;
  252.         }
  253.  
  254.     /* adjust timer */
  255.     timeradjust=0;
  256.     start_timer();
  257.     stop_timer(acttime);
  258.     timeradjust=acttime[0];
  259.  
  260.     /* set defaults */
  261.     if(options[0] || options[1]){
  262.         machname[14]=0;
  263.         }
  264.     else strcpy(machname,NAMEDEF);
  265.  
  266.     if(options[0]) options[2]=1;
  267.  
  268.     for(i=0;i<80;i++)
  269.         dbtxname[i]=0;
  270.     dbtxname[0]=(get_default()+'A');
  271.     strcpy(dbtxname+1,":\\");
  272.     getpath((int)(dbtxname[0]-'A'), dbtxname+3);
  273.     if(dbtxname[strlen(dbtxname)-1]=='\\')
  274.         dbtxname[strlen(dbtxname)-1]=0;
  275.     if( !(options[2] && (strlen(dumpfname)) ) ){
  276.         strcpy(dumpfname, dbtxname);
  277.         strcat(dumpfname, "\\RESULTS");
  278.         }
  279.     strcat(dbtxname, "\\COMPAR.TBL");
  280.  
  281.     read_defs("bbdef.dat", tdef, 14);
  282.  
  283.     /* initialize comparison data */
  284.     recs_in_db=init_db(18, comparison_data, "bbcomp.dat");
  285.     strcpy(machine_config.machine_name,machname);
  286.     recs_in_db=add_entry_db(18, recs_in_db, comparison_data,    \
  287.          machine_config.machine_name); 
  288.     machtodb(comparison_data, recs_in_db, &machine_config);
  289.  
  290.     /* initialize windows */
  291.     field.made=logo.made=menu.made=help.made=0;
  292.     cpuwin.made=cpu2win.made=fpuwin.made=diskwin.made=vidwin.made=0;
  293.     textreswin.made=0;bswin.made=0;
  294.  
  295.     /* zap cursor */
  296.     clearscreen();
  297.     oldcurse=new_cursor(BLANK_CURSE);
  298.  
  299.     /* initialize help */
  300.     make_helpspace("bbhelp.dat", &helptext);
  301.  
  302.     /* immediate runs? */
  303.     if(options[7]||options[0])
  304.         options[3]=options[4]=options[5]=options[6]=1;
  305.     if(machine_config.fpu_type==0) options[4]=0;
  306.     if(options[3]||options[4]||options[5]||options[6]){
  307.         execute(options[3],options[4],options[5],options[6],    \
  308.             (void**) comparison_data);
  309.         }
  310.  
  311.     /* make windows */
  312.     mk_window(&field, NULL, 0, 0, 80, 26, BLUE, WHITE,
  313.                   BLUE, WHITE, 0, 1);
  314.     mk_window(&logo, NULL, 41, 13, 76, 24, BLUE, WHITE,
  315.                   BLUE, GRAY, 0, 1);
  316.     link_array(&logo, logoarray, 34, 9, 0, 0);
  317.     mk_window(&menu, "Main Menu", 42, 1, 75, 14, CYAN, WHITE,
  318.                   CYAN, BLUE, 1, 1);
  319.     winprintstring(&menu, 7, 0, " Run All Tests");
  320.     winprintstring(&menu, 7, 2, " Run CPU Tests");
  321.     winprintstring(&menu, 7, 4, " Run FPU Tests");
  322.     winprintstring(&menu, 7, 6, " Run Disk Tests");
  323.     winprintstring(&menu, 7, 8, " Run Video Tests");
  324.     winprintstring(&menu, 7, 10, "  Controls Menu ...");
  325.     menu.num_valid=main_num_valid;
  326.     menu.valid_lines=main_valid_lines;
  327.     mk_window(&help, "Information", 5, 1, 37, 22, GREEN, WHITE,
  328.                   BLACK, GRAY, 1, 1);
  329.  
  330.     chattr(&field,0,23,78,1,WHITE,BLACK);
  331.     winprintstring(&field, 5, 23, MENKEYLISTSTRING);
  332.  
  333.     /****** go into big loop ********/
  334.     help_base=0;
  335.     while(TRUE){
  336.         display_help(&helptext,0);
  337.         resp=get_resp_line(&menu, 0, 7, BLUE, WHITE, 0, 1);
  338.         switch(resp){
  339.             case -1: escflag=1;
  340.                  break;
  341.             case 0:
  342.                    if(!(CPUSPECD||FPUSPECD||DISKSPECD||VIDSPECD)){
  343.                     alert_box(NTSTRING, 0, 0, 2);
  344.                     break;
  345.                     }
  346.                 BLANKSCREEN;
  347.                 execute(1, 1, 1, 1,     \
  348.                 (void**) comparison_data);
  349.                 UNBLANKSCREEN;
  350.                 break;
  351.             case 1:
  352.                 if(!CPUSPECD){
  353.                     alert_box(NTSTRING, 0, 0, 2);
  354.                     break;
  355.                     }
  356.                 BLANKSCREEN;
  357.                 execute(1, 0, 0, 0,     \
  358.                 (void**) comparison_data);
  359.                 UNBLANKSCREEN;
  360.                 break;
  361.             case 2:
  362.                 if(!FPUSPECD){
  363.                     alert_box(NTSTRING, 0, 0, 2);
  364.                     break;
  365.                     }
  366.                 if(machine_config.fpu_type!=0){
  367.                     BLANKSCREEN;
  368.                     execute(0, 1, 0, 0,     \
  369.                     (void**) comparison_data);
  370.                     UNBLANKSCREEN;
  371.                     }
  372.                 else
  373.                     alert_box(    \
  374.                     "Can't run tests. FPU Required.",    \
  375.                     0,0,3);
  376.                 break;
  377.             case 3:
  378.                 if(!DISKSPECD){
  379.                     alert_box(NTSTRING, 0, 0, 2);
  380.                     break;
  381.                     }
  382.                 if(tdef[6]){    /* file i/o?*/
  383.                     breakflag=0;
  384.                     diskstat=disk_check(tdef[7], 1);
  385.                     while(diskstat==-1){
  386.                        if(!alert_box(DERRSTRING,    \
  387.                             YESNO, 1, 3))
  388.                             breakflag=1;
  389.                        else
  390.                           diskstat=disk_check(tdef[7],1);
  391.                        if (breakflag) break;
  392.                        }
  393.                     if (breakflag) break;
  394.                     if(diskstat==0){
  395.                         if(!alert_box(IDSSTRING,    \
  396.                             YESNO, 1, 3))
  397.                             break;
  398.                         if(!tdef[8]){
  399.                            alert_box(NTSTRING,0,0,2);
  400.                            break;
  401.                            }
  402.                         }
  403.                     }
  404.                 BLANKSCREEN;
  405.                 execute(0, 0, 1, 0,     \
  406.                 (void**) comparison_data);
  407.                 UNBLANKSCREEN;
  408.                 break;
  409.             case 4:
  410.                 if(!VIDSPECD){
  411.                     alert_box(NTSTRING, 0, 0,2);
  412.                     break;
  413.                     }
  414.                 BLANKSCREEN;
  415.                 execute(0, 0, 0, 1,     \
  416.                 (void**) comparison_data);
  417.                 UNBLANKSCREEN;
  418.                 break;
  419.             case 5:
  420.                 controls_menu((void**)comparison_data);
  421.                 winprintstring(&field, 5, 23,
  422.                      MENKEYLISTSTRING);
  423.                 break;
  424.             }
  425.         if(escflag) break;
  426.     }
  427.  
  428.     /* close help */
  429.  
  430.     kill_helpspace(&helptext);
  431.  
  432.     /* close database */
  433.     free_db(recs_in_db, comparison_data);
  434.  
  435.     /* put cursor back */
  436.  
  437.     clearscreen();
  438.     new_cursor(oldcurse);
  439. }
  440.  
  441. void benchhook( win_handle * winptr, double *resarray, int which)
  442. {
  443.  
  444. unsigned int time[5][3];
  445. unsigned int iters[5];
  446. double temparray[5] = {0, 0, 0, 0, 0};
  447. unsigned long bytesr, bytesw;
  448. unsigned long testbytes;
  449. char passmess[13];
  450.  
  451. int olddrive;
  452. int i, j, k;
  453.  
  454. /* clear parameter arrays, and results array */
  455. for (i=0;i<5;i++){
  456.     iters[i]=0;
  457.     *(resarray+i)=0;
  458.     for(j=0;j<3;j++)
  459.         time[i][j]=0;
  460.     }
  461.  
  462.  
  463. /* big loop number of repeat times */
  464.  
  465. for(k=0;k<tdef[12];k++){
  466.  
  467.     oldlen=0;    /* initialize the slidey bar */
  468.  
  469.     /* put up pass message */
  470.     if((tdef[12]>1) && (which<10)){
  471.         sprintf(passmess, "Pass %u", (k+1));
  472.         win_erase_region(winptr, 72, 23, 7, 1);
  473.         winprintstring(winptr, 72, 23, passmess);
  474.         winprintstring(winptr, 39, 23, BARSTRING );
  475.         chattr(winptr, 39, 23, 20, 1, BLACK, GREEN);
  476.     }
  477.  
  478.     /* which test? */
  479.  
  480.     switch(which){
  481.             case 0: /* sieve */
  482.                 sieve (winptr,tdef[which],time[0],iters);
  483.                 break;
  484.             case 1: /* sort */
  485.                 sort (winptr,tdef[which],time[0],iters);
  486.                 break;
  487.             case 2: /* imath */
  488.                 ifourbang (winptr,tdef[which],NIOPS,    \
  489.                     time[0],iters);
  490.                 break;
  491.             case 3:    /* move */
  492.                 movetest(winptr, tdef[which],NKTOMOVE,    \
  493.                      time, iters);
  494.                 break;
  495.             case 4: /* fourbang */
  496.                 ffourbang (winptr,tdef[which],time[0],iters);
  497.                 break;
  498.             case 5: /* fourier */
  499.                 fourier(winptr, tdef[which],time[0],iters);
  500.                 break;
  501.             case 6: /* file i/o */
  502.                 testbytes=disk_check(tdef[7], 1);
  503.                 testbytes*=1024; /* convert to bytes */
  504.  
  505.                 olddrive=get_default();
  506.                 set_default(tdef[7]-1);
  507.  
  508.                 do_fileio(winptr,tdef[which],&bytesr,    \
  509.                      &bytesw, time[0], time[1],    \
  510.                      testbytes);
  511.                 temparray[0]=timetodouble(time[0]);
  512.                 temparray[0]=bytesr/(temparray[0]);
  513.                 temparray[0]/=1024;  /* kbytes*/
  514.                 temparray[1]=timetodouble(time[1]);
  515.                 temparray[1]=bytesw/(temparray[1]);
  516.                 temparray[1]/=1024;  /* kbytes*/
  517.  
  518.                 set_default(olddrive);
  519.  
  520.                 break;
  521.  
  522.             case 8: /* low level disk */
  523.                 ll_hdthru(tdef[9],HDTHITERS,temparray);
  524.                 adjust_bar(winptr, 1, 2);
  525.                 ll_diskseek(tdef[9],    \
  526.                     temparray[0],temparray+1);
  527.                 adjust_bar(winptr, 2, 2);
  528.                 temparray[0]/=1024;    /*kbytes*/
  529.                 temparray[1]*=1000;    /*milliseconds */
  530.                 break;
  531.  
  532.             case 10: /* text */
  533.                 textbench(tdef[which],NTXCHARS,temparray);
  534.                 tscroll(tdef[which],NSCCHARS,temparray+1);
  535.                 break;
  536.  
  537.             case 11: /* graphics */
  538.                 graph_bench(tdef[which], temparray);
  539.                 if(temparray[0]==0)
  540.                     alert_box(MDASTRING, 0, 0,3);
  541.                 break;
  542.         }
  543.  
  544.     /* test-specific adjustments */
  545.     /* for cpu and fpu, convert to doubles, then iters per second */
  546.     if(which<6){
  547.         for(i=0;i<5;i++){
  548.             if(iters[i]!=0){
  549.                 temparray[i]=timetodouble(time[i]);
  550.                 if(temparray[i]!=0)
  551.                      temparray[i]=iters[i]/(temparray[i]);
  552.                 }
  553.             else
  554.                 temparray[i]=0;
  555.             }
  556.         }
  557.     if(which==2)
  558.         temparray[0] *= NIOPS;
  559.  
  560.     if(which==4)
  561.         temparray[0] *= FFITERS;
  562.  
  563.     /* running average storage */
  564.  
  565.     for(i=0;i<5;i++){
  566.         *(resarray+i)+=temparray[i];
  567.         }
  568.     }
  569.  
  570. /* average */
  571.  
  572. for(i=0;i<5;i++){
  573.     *(resarray+i)/=tdef[12];
  574.     }
  575.  
  576. return;
  577.  
  578. }
  579.  
  580.  
  581. winprintstring( win_handle* wpshand, int wpsx, int wpsy, char *wpsstring)
  582. /*   window based string printer. given asciiz string, prints as many
  583. **   characters as will fit in window. returns number written.
  584. */
  585. {
  586.  
  587. int i;
  588. char wpsch;
  589.  
  590.     for(i=0;1;i++,wpsx++){
  591.         wpsch=*(wpsstring+i);
  592.         if (wpsch==0)    break;
  593.         if (winputch (wpshand, wpsx, wpsy, wpsch)==0)  break;
  594.         }
  595.  
  596.     return i;
  597. }
  598.  
  599. int get_resp_line ( win_handle* grlhand, int defaultline, int textoff,
  600.             int grlbgc, int grlfgc, int *selecttype, int dohelp)
  601. /*   get response line. given handle, returns user's selected line.
  602. **   default line is used first. -2 on error, -1 on escape.
  603. **   sellecttype determines whether the function returns intermediate
  604. **   results. sellecttype = null on input means don't return; if
  605. **   sellectype  contains a non-null pointer, this function puts a type code **   in it.
  606. */
  607. {
  608.  
  609. int i;
  610. int barlen;
  611. char grlch;
  612.  
  613.     if(defaultline>=(grlhand->num_valid)) return -2;
  614.  
  615.  
  616.     /* clear all valid lines in window and determine def positions*/
  617.     for(i=0; i!=grlhand->num_valid; i++){
  618.         barlen=winstrlen(grlhand, textoff,    \
  619.              *((grlhand->valid_lines)+i));
  620.         chattr(grlhand, textoff, *((grlhand->valid_lines)+i),     \
  621.             barlen,    1,0,0);
  622.         }
  623.  
  624.     /* go into loop */
  625.  
  626.     i=defaultline;
  627.     barlen=winstrlen(grlhand, textoff, *((grlhand->valid_lines)+i));
  628.     chattr(grlhand, textoff, (int) *((grlhand->valid_lines)+i),    \
  629.          barlen, 1, grlbgc, grlfgc);
  630.  
  631.     while(TRUE){
  632.         grlch=0;
  633.         /* get a valid keystroke */
  634.         do{
  635.         barlen=winstrlen(grlhand, textoff,     \
  636.                 *((grlhand->valid_lines)+i));
  637.             grlch=getch();
  638.             switch(grlch){
  639.                 case ENTER:    /* These are the exits*/
  640.                       chattr(grlhand, textoff,    \
  641.                         *((grlhand->valid_lines)+i),    \
  642.                         barlen,1,0,0);
  643.                       if(selecttype!=NULL)
  644.                         *(selecttype)=1;
  645.                       return i;
  646.                 case ESC: if(selecttype!=NULL)
  647.                         *(selecttype)=1;
  648.                       return -1;    /* exit 2 */
  649.                 case TAB: grlch=DOWNARROW;
  650.                       break;
  651.                 case CTRLW:
  652.                 case CTRLS:
  653.                 case CTRLD:
  654.                     if(selecttype==NULL) break;
  655.                     *(selecttype)=grlch;
  656.                     return i;
  657.                 case  0: grlch=getch();
  658.                      switch(grlch){
  659.                         case UPARROW:
  660.                         case DOWNARROW:
  661.                         case LEFTARROW:
  662.                         case RIGHTARROW:
  663.                         case CTRLRA:
  664.                         case CTRLLA:
  665.                         case INS:
  666.                         case DEL:
  667.                         case PGUP:
  668.                         case PGDOWN: break;
  669.         
  670.                         default: grlch=0;
  671.                              break;
  672.                         }
  673.                      break;
  674.  
  675.                 default: grlch=0;
  676.                      break;
  677.                 }
  678.             } while(!grlch);
  679.     
  680.         switch(grlch){
  681.  
  682.             case PGUP:
  683.             case PGDOWN:
  684.                 if (dohelp)
  685.                     scroll(&help, (int)(grlch==PGUP));
  686.                 break;
  687.             case UPARROW:
  688.             case DOWNARROW:
  689.                 chattr(grlhand, textoff, \
  690.                     (int)*((grlhand->valid_lines)+i), \
  691.                 barlen, 1,0,0);
  692.  
  693.                 if(grlch==UPARROW)
  694.                   i=(i==0)? (grlhand->num_valid)-1 : --i;
  695.                 else
  696.                   i=(i==((grlhand->num_valid)-1))? 0: ++i;
  697.                 barlen=winstrlen(grlhand, textoff,     \
  698.                     *((grlhand->valid_lines)+i));
  699.                 chattr(grlhand, textoff, \
  700.                 (int)*((grlhand->valid_lines)+i), \
  701.                     barlen, 1, grlbgc, grlfgc);
  702.                 if(dohelp)
  703.                     display_help(&helptext, help_base+i);
  704.                 break;
  705. /* intermediate*/    case LEFTARROW:
  706. /* exits */        case RIGHTARROW:
  707.             case CTRLRA:
  708.             case CTRLLA:
  709.             case INS:
  710.             case DEL:
  711.                 if(selecttype==NULL) break;
  712.                 *(selecttype)=grlch;
  713.                 return i;
  714.             }
  715.         }
  716.  
  717.     return 0;    /* keeps the compiler happy */
  718. }
  719.  
  720. int guess3(int* res_array, void** listptr, int s_off) 
  721. /*
  722. ** function returns four offsets in array; best baseline, next two, current.
  723. ** if three comparisons are unavailable, puts -1 in place.
  724. ** s_off is the offset within structure of the test to guess on (test
  725. ** values are always stored as doubles). returns new current value.
  726. */
  727. {
  728. int curroff;
  729. int baseline;
  730. int pick[2];
  731. int bascrit;
  732. int i,j;
  733.  
  734.     /* check if current machine has values for this test */
  735.     curroff=lin_search_db(0, recs_in_db-1, listptr,    \
  736.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  737.  
  738.     if(*((double*)((char*)(*(listptr+curroff))+s_off))!=0){
  739.         /* sort on this test */
  740.         sort_db(recs_in_db, listptr, s_off, FLOATCODE);
  741.         }
  742.     else{
  743.         /* sort on processor */
  744.         sort_db(recs_in_db, listptr, offset_in_struc(db_rec, proc),    \
  745.              INTCODE);
  746.         }
  747.  
  748.     /* relocate current pointer */
  749.  
  750.     curroff=lin_search_db(0, recs_in_db-1, listptr,    \
  751.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  752.  
  753.     /* find nearest baseline */
  754.  
  755.     bascrit=(machine_config.proc_type>286)? 3 : 2;
  756.     baseline=lin_search_db(0, recs_in_db-1, listptr,    \
  757.         offset_in_struc(db_rec,basenum), INTCODE, bascrit);
  758.  
  759.     pick[0]=lin_search_db(0, recs_in_db-1, listptr,    \
  760.         offset_in_struc(db_rec,comp), INTCODE, 1);
  761.     pick[1]=lin_search_db(0, recs_in_db-1, listptr,    \
  762.         offset_in_struc(db_rec,comp), INTCODE, 2);
  763.  
  764.     /* find nearest two that have run test */
  765.  
  766. if(pick[1]<0){
  767.     for(i=curroff+1, j=curroff-1; (i<(int)recs_in_db)||(j>=0);    \
  768.         i++, j--){
  769.         if((i<(int)recs_in_db) && i!=baseline){
  770.           if(*((double*)((char *)(*(listptr+i))+s_off))!=0){
  771.             if(pick[0]!=-1){
  772.                 pick[1]=i;
  773.                 break;
  774.                 }
  775.             pick[0]=i;
  776.             }
  777.           }
  778.         if((j>=0) && j!=baseline){
  779.           if(*((double*)((char *)(*(listptr+j))+s_off))!=0){
  780.             if(pick[0]!=-1){
  781.                 pick[1]=j;
  782.                 break;
  783.                 }
  784.             pick[0]=j;
  785.             }
  786.           }
  787.            }
  788. }
  789.  
  790.     /* avoid stupidity */
  791.  
  792.     pick[0]= (pick[0]==curroff)? -1 : pick[0];
  793.     pick[1]= (pick[1]==curroff)? -1 : pick[1];
  794.     pick[0]= (pick[0]==baseline)? -1 : pick[0];
  795.     pick[1]= (pick[1]==baseline)? -1 : pick[1];
  796.  
  797.     pick[1]= (pick[0]==pick[1]) ? -1 : pick[1];
  798.  
  799.     if(pick[0]==-1){
  800.         pick[0]=pick[1];
  801.         pick[1]=-1;
  802.         }
  803.  
  804.     *(res_array)=curroff;
  805.     *(res_array+1)=pick[0];
  806.     *(res_array+2)=pick[1];
  807.     *(res_array+3)=baseline;
  808.  
  809.     return curroff;
  810. }
  811.  
  812. int graph (char* tname, win_handle *winname, char xoff, char yoff, char w, \
  813.          void** listptr,int s_off, char* leglabel)
  814. /*
  815. ** draws a four line graph at xoff, yoff, w chars wide.  s_off is the
  816. ** structure offset of the test in *listptr. Returns current offset.
  817. */
  818. {
  819. int retval;
  820. int i, j, k;
  821. int ns_off;
  822. int umultlog;
  823. double linval[4];
  824. double graffact, umult;
  825. double linelen;
  826.  
  827. int decpos, signpos;
  828.  
  829. char linlab[6];
  830. char *tempstring;
  831. char umstring[7];
  832. int lincolor[4];
  833. int bar[4];
  834.  
  835.     /* do guess */
  836.     retval=guess3(bar, listptr, s_off); 
  837.  
  838.     /* define colors */
  839.  
  840.     lincolor[0]=LT_CYAN;
  841.     lincolor[1]=PINK;
  842.     lincolor[2]=YELLOW;
  843.     lincolor[3]=LT_GREEN;
  844.  
  845.     /* clear graph region */
  846.     win_erase_region(winname,(int)xoff,(int)yoff,(int) w+1,10);
  847.  
  848.     /* truncate test name and legend label if too big */
  849.     if(strlen(tname)>(size_t)(w-(NAMESPACE+1)))
  850.         *(tname+(w-NAMESPACE))=0;
  851.     if(strlen(leglabel)>(size_t)(w-7))
  852.         *(leglabel+(w-6))=0;
  853.  
  854.     /* print out name of test*/
  855.     winprintstring(winname, xoff+NAMESPACE+1, yoff, tname);
  856.  
  857.     /* write names of machines, get linevalues */
  858.     ns_off=offset_in_struc(db_rec,name);
  859.     i=yoff+1;
  860.     graffact=0;
  861.  
  862.     for(j=0;j<4;j++){
  863.         if(*(bar+j)!=-1){
  864.             winprintstring(winname,    \
  865.                 xoff+NAMESPACE-    \
  866.                     strlen(((char*)(*(listptr+(*(bar+j))))+ns_off)), \
  867.                 i, ((char*)(*(listptr+(*(bar+j))))+ns_off));
  868.             linval[j]=*((double *)    \
  869.                 ((char *)(*(listptr+(*(bar+j))))+s_off));
  870.             graffact=(graffact>linval[j])?graffact:linval[j];
  871.             i+=2;
  872.             }
  873.         }
  874.  
  875.     /* figure units conversion */
  876.     umult=1;
  877.     umultlog=0;
  878.  
  879.     /* unruly units? */
  880.     if((graffact>=1000) || (graffact<1)){
  881.  
  882.     /* make scientific notation */
  883.         while (graffact>=10){
  884.             graffact/=10;
  885.             umult*=10;
  886.             umultlog++;
  887.             }
  888.         while ((graffact<1) && (graffact>0)){
  889.             graffact*=10;
  890.             umult/=10;
  891.             umultlog--;
  892.             }
  893.         for(j=0;j<4;j++)
  894.             linval[j]/=umult;
  895.         }
  896.     if(umultlog==0)    strcpy(umstring, " ");
  897.     else    sprintf(umstring, "x10^%d", umultlog);
  898.  
  899.     /* draw axis line */
  900.     for(j=yoff+1; j<=(i-2); j++)
  901.         winputch(winname, xoff+NAMESPACE, j, 0x0b4);
  902.  
  903.     /* create labels, draw graphs */
  904.  
  905.     i=yoff+1;
  906.     for(j=0;j<4;j++){
  907.         if(*(bar+j)!=-1){
  908.  
  909.             if(linval[j]<=0){
  910.                 winprintstring(winname, xoff+NAMESPACE+1,    \
  911.                      i, " N/A");
  912.                 i+=2;
  913.                 continue;
  914.                 }
  915.             tempstring=fcvt(linval[j], 6, &decpos, &signpos);
  916.  
  917.             if(decpos<0){
  918.                 *(linlab)='.';
  919.                 for(k=1;(k<=(-decpos))&&(k<5);k++)
  920.                     *(linlab+k)='0';
  921.                 for(;k<5;k++,tempstring++)
  922.                     *(linlab+k)=*(tempstring);
  923.                 }
  924.             else{
  925.                 strncpy(linlab, tempstring, decpos);
  926.                 *(linlab+decpos)='.';
  927.                 for(k=decpos+1;k<5;k++)
  928.                     *(linlab+k)=*(tempstring+(k-1));
  929.                 *(linlab+k)=0;
  930.                 }
  931.  
  932.             linelen = floor((w-(NAMESPACE+6))*linval[j]);
  933.             if(graffact) linelen/=graffact;
  934.             for(k=1;k<=(int)linelen;k++)
  935.                 winputch(winname, xoff+NAMESPACE+k, i, 0x0db);
  936.             chattr(winname, xoff+NAMESPACE+1,i, (int)linelen,1,
  937.                 BLACK, lincolor[j]);
  938.             winprintstring(winname, xoff+NAMESPACE+k, i, linlab);
  939.              i+=2;
  940.         }
  941.     }
  942.  
  943.     winprintstring(winname, xoff+1, i, leglabel);
  944.     winprintstring(winname, xoff+1+strlen(leglabel), i, umstring);
  945.  
  946.     return retval;
  947.  
  948. }
  949.  
  950. void read_defs ( char * defilname, int * defarray, int numtests)
  951. /*
  952. ** Looks for default settings file on disk. Reads results into defarray
  953. ** if found.
  954. */
  955. {
  956. int deffh;
  957.  
  958.     deffh=open(defilname, O_BINARY|O_RDONLY);
  959.  
  960.     if(deffh==-1)
  961.         return;
  962.  
  963.     read(deffh, (char*) defarray, numtests*(sizeof(int)));
  964.     limcheck(defarray, numtests-1);
  965.  
  966.     close(deffh);
  967.     return;
  968. }
  969. int dump_defs ( char * defilname, int * defarray, int numtests)
  970. /*
  971. ** writes defarray to defilname. Returns zero on error.
  972. */
  973. {
  974. int deffh;
  975.  
  976.     deffh=open(defilname, O_TRUNC|O_WRONLY|O_BINARY|O_CREAT, S_IWRITE);
  977.  
  978.     numtests*=sizeof(int);
  979.  
  980.     if (deffh==-1)
  981.          return 0;
  982.     if( write(deffh, (char *) defarray, numtests) < numtests){
  983.         close(deffh);
  984.         return 0; 
  985.         }
  986.  
  987.     close(deffh);
  988.     return 1;
  989. }
  990.  
  991. void limcheck(int * d_a, int numtests)
  992. /* 
  993. ** fixes limits according to speed
  994. ** if less than minimum, go to zero.
  995. */
  996. {
  997. int i;
  998. int imin, imax;
  999. int minval;
  1000.  
  1001.  
  1002.     for(i=0;i<numtests;i++){
  1003.         switch(i){
  1004.             case 6: imin=60;
  1005.                 imax=durmax;
  1006.                 if(*(d_a+i)==1)
  1007.                     minval=imin;
  1008.                 else minval=0;
  1009.                 break;
  1010.             case 7: imin=minval=1;
  1011.                 imax=26;
  1012.                 break;
  1013.             case 8: imin=minval=0;
  1014.                 imax=1;
  1015.                 break;
  1016.             case 9: imin=minval=-1;
  1017.                 imax=(machine_config.num_hard-1);
  1018.                 break;
  1019.             case 12: imin=minval=1;
  1020.                  imax=durmax;
  1021.                  break;
  1022.             default: imin=durmin;
  1023.                  imax=durmax;
  1024.                  if(*(d_a+i)==1)
  1025.                     minval=imin;
  1026.                  else minval=0;
  1027.             }
  1028.         *(d_a+i)=(*(d_a+i)<imin) ?  minval : *(d_a+i);
  1029.         *(d_a+i)=(*(d_a+i)>imax) ?  imax : *(d_a+i);
  1030.         }
  1031.  
  1032.     /* if invalid hard disk, no hard disk tests */
  1033.     if (*(d_a+9) < 0) *(d_a+8)=0;
  1034. }
  1035.  
  1036. void execute( int docpu, int dofpu, int dodisk, int dovideo,    \
  1037.           void** listptr)
  1038. /*   Executes benchmarks. Parameters passed in are flags for the 
  1039. **   tests to do. Execute builds display windows, hides them, and chains
  1040. **   to review_mode when done.
  1041. */
  1042.  
  1043. {
  1044. double tval[5];
  1045. int curval;
  1046. unsigned long tm0, tm1;
  1047.  
  1048.  
  1049. /* first update the current name */
  1050.     curval=lin_search_db(0, recs_in_db-1,listptr,    \
  1051.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  1052.     update_db(curval, listptr, offset_in_struc(db_rec, name),    \
  1053.         CHARPTRCODE, (int) machine_config.machine_name);
  1054.  
  1055. /* update processor record */
  1056.     lastproc=machine_config.proc_type;
  1057.  
  1058. if(docpu&& CPUSPECD){
  1059.     kill_window(&cpuwin);
  1060.     mk_window(&cpuwin,"CPU Tests", 0, 0, 82, 27, BLACK, WHITE,
  1061.                   BLACK, WHITE, 0, 0);
  1062.  
  1063.     /* guess and graph the screens */
  1064.     curval=batchgraph(listptr, 1);
  1065.  
  1066.     if(tdef[0]){
  1067.         win_erase_region(&cpuwin, 0, 23, 79, 1);
  1068.         winprintstring(&cpuwin, 40-strlen("Running Sieve: "),    \
  1069.             23, "Running Sieve: ");
  1070.         winprintstring(&cpuwin, 39, 23, BARSTRING );
  1071.         chattr(&cpuwin, 39, 23, 20, 1, BLACK, GREEN);
  1072.  
  1073.         benchhook(&cpuwin, tval, 0);
  1074.  
  1075.         update_db(curval,listptr, offset_in_struc(db_rec, sieveres), \
  1076.              FLOATCODE, tval[0]);
  1077.         curval=    \
  1078.         graph("BYTE Sieve",&cpuwin, 0, 1, 39, listptr,    \
  1079.             offset_in_struc(db_rec, sieveres),     \
  1080.             "Iterations per second ");
  1081.         }
  1082.  
  1083.     if(tdef[1]){
  1084.         win_erase_region(&cpuwin, 0, 23, 79, 1);
  1085.         winprintstring(&cpuwin, 40-strlen("Running Sort: "),    \
  1086.             23, "Running Sort: ");
  1087.         winprintstring(&cpuwin, 39, 23, BARSTRING );
  1088.         chattr(&cpuwin, 39, 23, 20, 1, BLACK, GREEN);
  1089.  
  1090.         benchhook(&cpuwin, tval, 1);
  1091.  
  1092.         update_db(curval,listptr, offset_in_struc(db_rec, sortres), \
  1093.              FLOATCODE, tval[0]);
  1094.         curval= \
  1095.         graph("BYTE Sort",&cpuwin, 40, 1, 39, listptr,    \
  1096.             offset_in_struc(db_rec, sortres),     \
  1097.             "Iterations per second ");
  1098.         }
  1099.     if(tdef[2]){
  1100.         win_erase_region(&cpuwin, 0, 23, 79, 1);
  1101.         winprintstring(&cpuwin, 40-strlen("Running Int. Math: "),    \
  1102.             23, "Running Int. Math: ");
  1103.         winprintstring(&cpuwin, 39, 23, BARSTRING );
  1104.         chattr(&cpuwin, 39, 23, 20, 1, BLACK, GREEN);
  1105.  
  1106.         benchhook(&cpuwin, tval, 2);
  1107.  
  1108.         update_db(curval,listptr, offset_in_struc(db_rec, imathres), \
  1109.              FLOATCODE, tval[0]);
  1110.         curval=    \
  1111.         graph("BYTE Int. Math",&cpuwin, 0, 12, 39, listptr,    \
  1112.             offset_in_struc(db_rec, imathres),     \
  1113.             "Iterations per second ");
  1114.         }
  1115.     if(tdef[3]){
  1116.         win_erase_region(&cpuwin, 0, 23, 79, 1);
  1117.         winprintstring(&cpuwin, 40-strlen("Running String Move: "),    \
  1118.             23, "Running String Move: ");
  1119.         winprintstring(&cpuwin, 39, 23, BARSTRING );
  1120.         chattr(&cpuwin, 39, 23, 20, 1, BLACK, GREEN);
  1121.  
  1122.         benchhook(&cpuwin, tval, 3);
  1123.  
  1124.         update_db(curval,listptr, offset_in_struc(db_rec, movbres), \
  1125.              FLOATCODE, tval[0]);
  1126.         update_db(curval,listptr, offset_in_struc(db_rec, movwores), \
  1127.              FLOATCODE, tval[1]);
  1128.         update_db(curval,listptr, offset_in_struc(db_rec, movweres), \
  1129.              FLOATCODE, tval[2]);
  1130.         update_db(curval,listptr, offset_in_struc(db_rec, movdores), \
  1131.              FLOATCODE, tval[3]);
  1132.         update_db(curval,listptr, offset_in_struc(db_rec, movderes), \
  1133.              FLOATCODE, tval[4]);
  1134.  
  1135.         curval=\
  1136.         graph("BYTE Byte-wide Move",&cpuwin, 40, 12, 39, listptr,    \
  1137.             offset_in_struc(db_rec, movbres),     \
  1138.             "Iterations per second ");
  1139.         }
  1140.     hide_window(&cpuwin);
  1141.     }
  1142.  
  1143. if(docpu&& SMOVESPECD){
  1144.     kill_window(&cpu2win);
  1145.     mk_window(&cpu2win,"String Move Tests", 0, 0, 82, 27, BLACK, WHITE,
  1146.                   BLACK, WHITE, 0, 0);
  1147.  
  1148.     /* graph the second batch of screens */
  1149.  
  1150.     win_erase_region(&cpu2win, 0, 23, 79, 1);
  1151.     winprintstring(&cpu2win, 40-(strlen(WINPAUSESTRING)>>1),    \
  1152.             23, WINPAUSESTRING);
  1153.     chattr(&cpu2win, 10, 23, 50, 1, BLACK, CYAN);
  1154.  
  1155.     curval=batchgraph(listptr, 2);
  1156.  
  1157.     /* to keep from being so jarring */
  1158.     tm0=clock();
  1159.     do{
  1160.         tm1=clock();
  1161.         } while((tm1-tm0)<(5*CLK_TCK));
  1162.  
  1163.  
  1164.     hide_window(&cpu2win);
  1165.     }
  1166.  
  1167.  
  1168. if(dofpu&& FPUSPECD &&(machine_config.fpu_type!=0)){
  1169.     kill_window(&fpuwin);
  1170.     mk_window(&fpuwin,"FPU Tests", 0, 0, 82, 27, BLACK, WHITE,
  1171.                   BLACK, WHITE, 0, 0);
  1172.  
  1173.     /* guess and graph the screens */
  1174.  
  1175.     curval=batchgraph(listptr,3);
  1176.  
  1177.     if(tdef[4]){
  1178.         win_erase_region(&fpuwin, 0, 23, 79, 1);
  1179.         winprintstring(&fpuwin, 40-strlen("Running Fmath: "),    \
  1180.             23, "Running Fmath: ");
  1181.         winprintstring(&fpuwin, 39, 23, BARSTRING );
  1182.         chattr(&fpuwin, 39, 23, 20, 1, BLACK, GREEN);
  1183.  
  1184.         benchhook(&fpuwin, tval, 4);
  1185.  
  1186.         update_db(curval,listptr,offset_in_struc(db_rec,fourbangres),
  1187.              FLOATCODE, tval[0]);
  1188.         curval=    \
  1189.         graph("BYTE Fmath",&fpuwin, 0, 1, 78, listptr,    \
  1190.             offset_in_struc(db_rec, fourbangres),     \
  1191.             "Iterations per second ");
  1192.         }
  1193.  
  1194.     if(tdef[5]){
  1195.         win_erase_region(&fpuwin, 0, 23, 79, 1);
  1196.         winprintstring(&fpuwin, 40-strlen("Running Fourier: "),    \
  1197.             23, "Running Fourier: ");
  1198.         winprintstring(&fpuwin, 39, 23, BARSTRING );
  1199.         chattr(&fpuwin, 39, 23, 20, 1, BLACK, GREEN);
  1200.  
  1201.         benchhook(&fpuwin, tval, 5);
  1202.  
  1203.         update_db(curval,listptr, offset_in_struc(db_rec, forres), \
  1204.              FLOATCODE, tval[0]);
  1205.         curval=    \
  1206.         graph("BYTE Fourier",&fpuwin, 0, 12, 78, listptr,    \
  1207.             offset_in_struc(db_rec, forres),     \
  1208.             "Iterations per second ");
  1209.         }
  1210.     hide_window(&fpuwin);
  1211.     }
  1212.  
  1213. if(dodisk && DISKSPECD && (tdef[8] || (disk_check(tdef[7], 1)>0) ) ){
  1214.     kill_window(&diskwin);
  1215.     mk_window(&diskwin,"Disk Tests", 0, 0, 82, 27, BLACK, WHITE,
  1216.                   BLACK, WHITE, 0, 0);
  1217.  
  1218.     /* guess and graph the screens */
  1219.     curval=batchgraph(listptr, 4);
  1220.  
  1221.  
  1222.     if(tdef[6]){
  1223.         win_erase_region(&diskwin, 0, 23, 79, 1);
  1224.         winprintstring(&diskwin, 40-strlen("Running File I/O: "),    \
  1225.             23, "Running File I/O: ");
  1226.         winprintstring(&diskwin, 39, 23, BARSTRING );
  1227.         chattr(&diskwin, 39, 23, 20, 1, BLACK, GREEN);
  1228.  
  1229.         benchhook(&diskwin, tval, 6);
  1230.  
  1231.         update_db(curval,listptr,offset_in_struc(db_rec,fiorres),
  1232.              FLOATCODE, tval[0]);
  1233.         update_db(curval,listptr,offset_in_struc(db_rec,fiowres),
  1234.              FLOATCODE, tval[1]);
  1235.         graph("BYTE File I/O Read",&diskwin, 0, 1, 39, listptr,    \
  1236.             offset_in_struc(db_rec, fiorres),     \
  1237.             "Kilobytes per second ");
  1238.         curval=    \
  1239.         graph("BYTE File I/O Write",&diskwin, 40, 1, 39, listptr,    \
  1240.             offset_in_struc(db_rec, fiowres),     \
  1241.             "Kilobytes per second ");
  1242.         }
  1243.  
  1244.     if(tdef[8]){
  1245.         win_erase_region(&diskwin, 0, 23, 79, 1);
  1246.         winprintstring(&diskwin, 40-strlen("Running Low-Levels: "),    \
  1247.             23, "Running Low-Levels: ");
  1248.         winprintstring(&diskwin, 39, 23, BARSTRING );
  1249.         chattr(&diskwin, 39, 23, 20, 1, BLACK, GREEN);
  1250.  
  1251.         benchhook(&diskwin, tval, 8);
  1252.  
  1253.         update_db(curval,listptr,offset_in_struc(db_rec, tpres), \
  1254.              FLOATCODE, tval[0]);
  1255.         update_db(curval,listptr,offset_in_struc(db_rec, seekres), \
  1256.              FLOATCODE, tval[1]);
  1257.  
  1258.         graph("BYTE Throughput",&diskwin, 0, 12, 39, listptr,    \
  1259.             offset_in_struc(db_rec, tpres),     \
  1260.             "Kilobytes per second ");
  1261.         curval=    \
  1262.         graph("BYTE Seek Test",&diskwin, 40, 12, 39, listptr,    \
  1263.             offset_in_struc(db_rec, seekres),     \
  1264.             "Milliseconds ");
  1265.         }
  1266.     hide_window(&diskwin);
  1267.     }
  1268.  
  1269. if(dovideo && VIDSPECD){
  1270.  
  1271.     curval=lin_search_db(0, recs_in_db-1, listptr,    \
  1272.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  1273.  
  1274.     if(tdef[10]){
  1275.         benchhook(&vidwin, tval, 10);
  1276.         update_db(curval,listptr, offset_in_struc(db_rec, txposres), \
  1277.              FLOATCODE, tval[0]);
  1278.         update_db(curval,listptr,offset_in_struc(db_rec,txscrollres),
  1279.              FLOATCODE, tval[1]);
  1280.         }
  1281.     if(tdef[11]){
  1282.         benchhook(&vidwin, tval, 11);
  1283.         update_db(curval,listptr, offset_in_struc(db_rec, graphres), \
  1284.              FLOATCODE, tval[0]);
  1285.         }
  1286.  
  1287.     /* clean up after video tests*/
  1288.     clearscreen();
  1289.     new_cursor(BLANK_CURSE);
  1290.  
  1291.     kill_window(&vidwin);
  1292.     mk_window(&vidwin,"Video Tests", 0, 0, 82, 27, BLACK, WHITE,
  1293.                   BLACK, WHITE, 0, 0);
  1294.  
  1295.     win_erase_region(&vidwin, 0, 23, 79, 1);
  1296.     winprintstring(&vidwin, 40-(strlen(WINPAUSESTRING)>>1),    \
  1297.             23, WINPAUSESTRING);
  1298.     chattr(&vidwin, 10, 23, 50, 1, BLACK, CYAN);
  1299.  
  1300.     /* guess and graph the screens */
  1301.     curval=batchgraph(listptr, 5);
  1302.  
  1303.     /* to keep from being so jarring */
  1304.     tm0=clock();
  1305.     do{
  1306.         tm1=clock();
  1307.         } while((tm1-tm0)<(5*CLK_TCK));
  1308.  
  1309.     hide_window(&vidwin);
  1310.     }
  1311.  
  1312.     if(options[0])    delimres(listptr);
  1313.  
  1314.     staleflag=1;
  1315.     reviewmode(listptr);
  1316. }
  1317.  
  1318. void make_textres (void** lp, char* aryptr, int trh, int trw)
  1319.  
  1320. /*
  1321. ** Creates text array (suitable for file-dumping) in memory. This
  1322. ** routine is hard-wired for the current structure definition. Any
  1323. ** changes to the record structure will make modifying this routine
  1324. ** neccesary.
  1325. */
  1326. {
  1327.  
  1328. #define linmem(col,string)  sprintf((aryptr+a_off)+col, string);a_off+=trw
  1329. #define prinmem(col,string)  sprintf((aryptr+a_off)+col, string)
  1330. #define linvmem(col,str,val) if(val) sprintf((aryptr+a_off)+col,str,val); else sprintf((aryptr+a_off)+col,"  N/A");a_off+=trw
  1331.  
  1332. int co, i286off, i386off, curo;
  1333. int comps[4];
  1334. int c1off;
  1335. int c2off;
  1336.  
  1337. int a_off, offcol, cl, i;
  1338.  
  1339.     /* find two suitable compares, and current */
  1340.     co=guess3(comps, lp, offset_in_struc(db_rec, proc));
  1341.  
  1342.     c1off=c2off=-1;
  1343.  
  1344.     /* get two unique, non -1 compares */
  1345.     for(i=1;i<4;i++){
  1346.         if(comps[i] <0) continue;
  1347.         c1off=comps[i];
  1348.         break;
  1349.         }
  1350.     for(i++ ; i<4; i++){
  1351.         if(comps[i] <0) continue;
  1352.         c2off=comps[i];
  1353.         break;
  1354.         }
  1355.  
  1356.     /* find 286 baseline */
  1357.     i286off=lin_search_db(0, recs_in_db-1, lp,    \
  1358.         offset_in_struc(db_rec,basenum), INTCODE, 2);
  1359.  
  1360.     /* find 386 baseline */
  1361.     i386off=lin_search_db(0, recs_in_db-1, lp,    \
  1362.         offset_in_struc(db_rec,basenum), INTCODE, 3);
  1363.  
  1364.     /* calculate indices */
  1365.     calc_indexes (lp, co, i286off, i386off);
  1366.  
  1367.     /****** print report to memory ******/
  1368.     /* clear array*/
  1369.     for(i=0;i<(trw*trh);i++)
  1370.         *(aryptr+i)=0;
  1371.  
  1372.     /* heading column */
  1373.     a_off=0;
  1374.     linmem(1,DOUBBAR);
  1375.     linmem(1,"BYTE DOS Benchmarks   --   Version 2.1");
  1376.     linmem(1,DOUBBAR);
  1377.     linmem(1," ");
  1378.     linmem(1," ");
  1379.  
  1380.     if(cpuwin.made){
  1381.         linmem(0," ");
  1382.         linmem(1, "CPU Tests");
  1383.         if( vf(co,sieveres) ){
  1384.             prinmem(1, "            Sieve:");
  1385.             linmem(70, "ips.");
  1386.             }
  1387.         if( vf(co,sortres) ){
  1388.             prinmem(1, "             Sort:");
  1389.             linmem(70, "ips.");
  1390.             }
  1391.         if( vf(co,imathres) ){
  1392.             prinmem(1, "     Integer Math:");
  1393.             linmem(70, "ips.");
  1394.             }
  1395.         if( vf(co,movbres) ){
  1396.             prinmem(1, "      Move (byte):");
  1397.             linmem(70, "ips.");
  1398.             }
  1399.         if( vf(co,movwores) ){
  1400.             prinmem(1, "  Move (word-odd):");
  1401.             linmem(70, "ips.");
  1402.             }
  1403.         if( vf(co,movweres) ){
  1404.             prinmem(1, " Move (word-even):");
  1405.             linmem(70, "ips.");
  1406.             }
  1407.         if( vf(co,movdores) ){
  1408.             prinmem(1, " Move (Dword-odd):");
  1409.             linmem(70, "ips.");
  1410.             }
  1411.         if( vf(co,movderes) ){
  1412.             prinmem(1, "Move (Dword-even):");
  1413.             linmem(70, "ips.");
  1414.             }
  1415.         linmem(1,SINGBAR);
  1416.         if(i286off>=0){
  1417.             linmem(1, "CPU Index (AT Class):");
  1418.             }
  1419.         if((machine_config.proc_type>286) && (i386off>=0)){
  1420.             linmem(1, "CPU Index (386 Class):");
  1421.             }
  1422.         linmem(1,SINGBAR);
  1423.         }
  1424.     if(fpuwin.made){
  1425.         linmem(0," ");
  1426.         linmem(1, "FPU Tests");
  1427.         if( vf(co,fourbangres) ){
  1428.             prinmem(1, "            Fmath:");
  1429.             linmem(70, "ips.");
  1430.             }
  1431.         if( vf(co,forres) ){
  1432.             prinmem(1, "          Fourier:");
  1433.             linmem(70, "ips.");
  1434.             }
  1435.         linmem(1,SINGBAR);
  1436.         if(i286off>=0){
  1437.             linmem(1, "FPU Index (AT Class):");
  1438.                 }
  1439.         if((machine_config.proc_type>286) && (i386off>=0)){
  1440.             linmem(1, "FPU Index (386 Class):");
  1441.             }
  1442.         linmem(1,SINGBAR);
  1443.         }
  1444.     if(diskwin.made){
  1445.         linmem(0," ");
  1446.         linmem(1, "Disk Tests");
  1447.         if( vf(co,fiorres) ){
  1448.             prinmem(1, "   File I/O  Read:");
  1449.             linmem(69, "KBps.");
  1450.             }
  1451.         if( vf(co,fiowres) ){
  1452.             prinmem(1, "   File I/O Write:");
  1453.             linmem(69, "KBps.");
  1454.             }
  1455.         if( vf(co,tpres) ){
  1456.             prinmem(1, "  Throughput Test:");
  1457.             linmem(69, "KBps.");
  1458.             }
  1459.         if( vf(co,seekres) ){
  1460.             prinmem(1, "        Seek Time:");
  1461.             linmem(70, " ms.");
  1462.             }
  1463.         linmem(1,SINGBAR);
  1464.         if(i286off>=0){
  1465.             linmem(1, "Disk Index (AT Class):");
  1466.                }
  1467.         if((machine_config.proc_type>286) && (i386off>=0)){
  1468.             linmem(1, "Disk Index (386 Class):");
  1469.                }
  1470.         linmem(1,SINGBAR);
  1471.         }
  1472.     if(vidwin.made){
  1473.         linmem(0," ");
  1474.         linmem(1, "Video Tests");
  1475.         if( vf(co,txposres) ){
  1476.             prinmem(1, "     Text Display:");
  1477.             linmem(70, "ips.");
  1478.             }
  1479.         if( vf(co,txscrollres) ){
  1480.             prinmem(1, "           Scroll:");
  1481.             linmem(70, "ips.");
  1482.             }
  1483.         if( vf(co,graphres) ){
  1484.             prinmem(1, "         Graphics:");
  1485.             linmem(70, "ips.");
  1486.             }
  1487.         linmem(1,SINGBAR);
  1488.         if(i286off>=0){
  1489.             linmem(1, "Video Index (AT Class):");
  1490.             }
  1491.         if((machine_config.proc_type>286) && (i386off>=0)){
  1492.             linmem(1, "Video Index (386 Class):");
  1493.             }
  1494.         linmem(1,SINGBAR);
  1495.         }
  1496.  
  1497.     /* footnote */
  1498.     linmem(1, " ");
  1499.     if(vf(co, seekres)){
  1500.         linmem(1,"NOTE: For all tests except disk seek time,");
  1501.         }
  1502.     else {
  1503.         linmem(1,"NOTE: For all tests and all indexes,");
  1504.         }
  1505.     linmem(1, "higher numbers indicate better performance.");
  1506.     linmem(1, " ");
  1507.     linmem(1, "AT Class indexes show performance relative to an");
  1508.     prinmem(1, "8 MHz IBM PC-AT.");
  1509.     if(machine_config.proc_type>286){
  1510.         linmem(19, "386-Class indexes are calculated");
  1511.         linmem(1, "relative to a Compaq 386/20.");
  1512.         }
  1513.     else{
  1514.         linmem(19, " ");
  1515.         }
  1516.     linmem(1, " ");
  1517.     prinmem(1, "Key:");
  1518.     if(cpuwin.made || fpuwin.made || vidwin.made){
  1519.         linmem(7,"ips.=iterations per second");
  1520.         }
  1521.     if(diskwin.made){
  1522.         linmem(7,"KBps.=kilobytes per second");
  1523.         }
  1524.     if(vf(co, seekres)){
  1525.         linmem(7,"ms.=milliseconds ");
  1526.         }
  1527.  
  1528.     /* now calculate actual array height*/
  1529.     ac_t_h=a_off/trw;
  1530.  
  1531.     /* print results columns */
  1532.  
  1533. for(i=0;i<3;i++){
  1534.     /**** test machine pass *****/
  1535.     if(i==0){
  1536.         cl=30; curo=co; 
  1537.         }
  1538.     /**** first compare pass *****/
  1539.     if(i==1){
  1540.         if(c1off<0) continue;
  1541.         cl=45; curo=c1off;
  1542.         }
  1543.     /**** second compare pass *****/
  1544.     if(i==2){
  1545.         if(c2off<0) continue;
  1546.         cl=60; curo=c2off;
  1547.         }
  1548.  
  1549.     /** the following is a sort-of macro for printing  these columns */
  1550.  
  1551.     /* print name */
  1552.     a_off=trw*4;
  1553.     offcol=cl-strlen(((char *)(*(lp+curo))    \
  1554.         +offset_in_struc(db_rec,name)))/2;
  1555.     strcpy((aryptr+a_off+offcol),    \
  1556.          ((char*)(*(lp+curo))+offset_in_struc(db_rec,name)));
  1557.     a_off+=trw;
  1558.  
  1559.     offcol=cl-2;
  1560.  
  1561.     if(cpuwin.made){
  1562.         a_off+=trw<<1;
  1563.         if(vf(co, sieveres)){
  1564.                 linvmem(offcol, "%6.2f", vf(curo, sieveres));
  1565.             }
  1566.         if(vf(co, sortres)){
  1567.                 linvmem(offcol, "%6.2f", vf(curo, sortres));
  1568.             }
  1569.         if(vf(co, imathres)){
  1570.                 linvmem(offcol, "%6.2f", vf(curo, imathres));
  1571.             }
  1572.         if(vf(co, movbres)){
  1573.                 linvmem(offcol, "%6.2f", vf(curo, movbres));
  1574.             }
  1575.         if(vf(co, movwores)){
  1576.                 linvmem(offcol, "%6.2f", vf(curo, movwores));
  1577.             }
  1578.         if(vf(co, movweres)){
  1579.                 linvmem(offcol, "%6.2f", vf(curo, movweres));
  1580.             }
  1581.         if(vf(co, movdores)){
  1582.                 linvmem(offcol, "%6.2f", vf(curo, movdores));
  1583.             }
  1584.         if(vf(co, movderes)){
  1585.                 linvmem(offcol, "%6.2f", vf(curo, movderes));
  1586.             }
  1587.         a_off+=trw;
  1588.         if(i286off>=0){
  1589.                 linvmem(offcol, "%6.2f", vf(curo, cpuat));
  1590.             }
  1591.         if((machine_config.proc_type>286) && (i386off>=0)){
  1592.                 linvmem(offcol, "%6.2f", vf(curo, cpu386));
  1593.             }
  1594.         a_off+=trw;
  1595.         }
  1596.  
  1597.     if(fpuwin.made){
  1598.         a_off+=trw<<1;
  1599.         if(vf(co, fourbangres)){
  1600.                 linvmem(offcol, "%6.2f", vf(curo, fourbangres));
  1601.             }
  1602.         if(vf(co, forres)){
  1603.                 linvmem(offcol, "%6.2f", vf(curo, forres));
  1604.             }
  1605.         a_off+=trw;
  1606.         if(i286off>=0){
  1607.                 linvmem(offcol, "%6.2f", vf(curo, fpuat));
  1608.             }
  1609.         if((machine_config.proc_type>286) && (i386off>=0)){
  1610.                 linvmem(offcol, "%6.2f", vf(curo, fpu386));
  1611.             }
  1612.         a_off+=trw;
  1613.         }
  1614.  
  1615.     if(diskwin.made){
  1616.         a_off+=trw<<1;
  1617.         if(vf(co, fiorres)){
  1618.                 linvmem(offcol, "%6.2f", vf(curo, fiorres));
  1619.             }
  1620.         if(vf(co, fiowres)){
  1621.                 linvmem(offcol, "%6.2f", vf(curo, fiowres));
  1622.             }
  1623.         if(vf(co, tpres)){
  1624.                 linvmem(offcol, "%6.2f", vf(curo, tpres));
  1625.             }
  1626.         if(vf(co, seekres)){
  1627.                 linvmem(offcol, "%6.2f", vf(curo, seekres));
  1628.             }
  1629.         a_off+=trw;
  1630.         if(i286off>=0){
  1631.                 linvmem(offcol, "%6.2f", vf(curo, diskat));
  1632.             }
  1633.         if((machine_config.proc_type>286) && (i386off>=0)){
  1634.                 linvmem(offcol, "%6.2f", vf(curo, disk386));
  1635.             }
  1636.         a_off+=trw;
  1637.         }
  1638.  
  1639.     if(vidwin.made){
  1640.         a_off+=trw<<1;
  1641.         if(vf(co, txposres)){
  1642.                 linvmem(offcol, "%6.2f", vf(curo, txposres));
  1643.             }
  1644.         if(vf(co, txscrollres)){
  1645.                 linvmem(offcol, "%6.2f", vf(curo, txscrollres));
  1646.             }    
  1647.         if(vf(co, graphres)){
  1648.                 linvmem(offcol, "%6.2f", vf(curo, graphres));
  1649.         }
  1650.         a_off+=trw;
  1651.         if(i286off>=0){
  1652.                 linvmem(offcol, "%6.2f", vf(curo, videoat));
  1653.             }
  1654.         if((machine_config.proc_type>286) && (i386off>=0)){
  1655.                 linvmem(offcol, "%6.2f", vf(curo, video386));
  1656.             }
  1657.         a_off+=trw;
  1658.  
  1659.         }
  1660.     }
  1661.  
  1662. }    
  1663.  
  1664. void calc_indexes (void** lp, int co, int i286_off, int i386_off)
  1665. /*
  1666. ** Calculates indexes. base_off is the location of the baseline in the 
  1667. ** database. co is the subject. This routine also updates the database.
  1668. */
  1669. {
  1670. double cpuindex,fpuindex,diskindex,videoindex;
  1671. double k,x;
  1672. int i,j;
  1673. int l;
  1674. int base_off;
  1675.  
  1676.     /* see if 386 is appropriate */
  1677.     if(machine_config.proc_type<386) i386_off=-1;
  1678.  
  1679.     /* Indexes are calculated by normalizing the results of
  1680.        each test against the corresponding baseline test, then
  1681.        taking the geometric mean of these normalized results in
  1682.        each category (cpu, fpu, etc.)    */
  1683.  
  1684.     /* calculate */
  1685. l=-1;
  1686. while(l<1){
  1687.     l++;
  1688.     if(l) base_off=i386_off;
  1689.     else base_off=i286_off;
  1690.  
  1691.     if(base_off<0) continue;
  1692.  
  1693.     cpuindex=0;
  1694.     if(cpuwin.made){
  1695.     /* cpu */
  1696.         for(i=0, j=0;i<8;i++){
  1697.             k=*((double*)((char*)(*(lp+co))+    \
  1698.                 (offset_in_struc(db_rec,sieveres)    \
  1699.                  +(sizeof(double)*i))));     
  1700.             x=*((double*)((char*)(*(lp+base_off))+    \
  1701.                    (offset_in_struc(db_rec,sieveres)    \
  1702.                 +((sizeof(double))*i))));
  1703.             if(k&&x){   /*x could be zero if this is a 286**/
  1704.                 j++;
  1705.                 cpuindex+=log10(k/x);
  1706.                 }
  1707.             }
  1708.         cpuindex=pow(10,(cpuindex/j));
  1709.         }
  1710.  
  1711.     fpuindex=0;
  1712.     if(fpuwin.made){
  1713.         /* fpu */
  1714.         for(i=0, j=0;i<2;i++){
  1715.             k=*((double*)((char*)(*(lp+co))+    \
  1716.                 (offset_in_struc(db_rec,fourbangres)+    \
  1717.                 ((sizeof(double))*i))));     
  1718.             x=*((double*)((char*)(*(lp+base_off))+    \
  1719.                 (offset_in_struc(db_rec,fourbangres)+    \
  1720.                 ((sizeof(double))*i))));
  1721.             if(k){
  1722.                 j++;
  1723.                 fpuindex+=log10(k/x);
  1724.                 }
  1725.             }
  1726.         fpuindex=pow(10,(fpuindex/j));
  1727.         }
  1728.  
  1729.     diskindex=0;
  1730.     if(diskwin.made){
  1731.         /* disk */
  1732.         for(i=0, j=0;i<4;i++){
  1733.             k=*((double *)((char*)(*(lp+co))+    \
  1734.                 (offset_in_struc(db_rec,fiorres)+    \
  1735.                 ((sizeof(double))*i))));     
  1736.             x=*((double *)((char*)(*(lp+base_off))+    \
  1737.                 (offset_in_struc(db_rec,fiorres)+    \
  1738.                 ((sizeof(double))*i))));
  1739.             if(k){
  1740.                 j++;
  1741.                 if(i!=3) 
  1742.                     diskindex+=log10(k/x);
  1743.                 else  /* seek time: lower is better */
  1744.                     diskindex+=log10(x/k);
  1745.                 }
  1746.             }
  1747.         diskindex=pow(10,(diskindex/j));
  1748.         }
  1749.  
  1750.     videoindex=0;
  1751.     if(vidwin.made){
  1752.         /* video */
  1753.         for(i=0, j=0;i<3;i++){
  1754.             k=*((double*)((char*)(*(lp+co))+    \
  1755.                 (offset_in_struc(db_rec,txposres)+    \
  1756.                 ((sizeof(double))*i))));     
  1757.             x=*((double*)((char*)(*(lp+base_off))+    \
  1758.                 (offset_in_struc(db_rec,txposres)+    \
  1759.                 ((sizeof(double))*i))));
  1760.             if(k){
  1761.                 j++;
  1762.                 videoindex+=log10(k/x);
  1763.                 }
  1764.             }
  1765.         videoindex=pow(10,(videoindex/j));
  1766.         }
  1767.  
  1768.  
  1769.     if(l){
  1770.         update_db(co,lp, offset_in_struc(db_rec, cpu386), \
  1771.              FLOATCODE, cpuindex);
  1772.         update_db(co,lp, offset_in_struc(db_rec, fpu386), \
  1773.              FLOATCODE, fpuindex);
  1774.         update_db(co,lp, offset_in_struc(db_rec, disk386), \
  1775.              FLOATCODE, diskindex);
  1776.         update_db(co,lp, offset_in_struc(db_rec, video386), \
  1777.              FLOATCODE, videoindex);
  1778.         }
  1779.     else{
  1780.         update_db(co,lp, offset_in_struc(db_rec, cpuat), \
  1781.              FLOATCODE, cpuindex);
  1782.         update_db(co,lp, offset_in_struc(db_rec, fpuat), \
  1783.              FLOATCODE, fpuindex);
  1784.         update_db(co,lp, offset_in_struc(db_rec, diskat), \
  1785.              FLOATCODE, diskindex);
  1786.         update_db(co,lp, offset_in_struc(db_rec, videoat), \
  1787.              FLOATCODE, videoindex);
  1788.         }
  1789.     }
  1790. return;
  1791.  
  1792. }
  1793.  
  1794. void reviewmode    (void** lp)
  1795. /* flips between hidden windows
  1796. **
  1797. **
  1798. */
  1799. {
  1800. int i;
  1801.  
  1802. win_handle smallkeylist;
  1803. win_handle ix286, ix386;
  1804.  
  1805. win_handle *valwindows[8];
  1806. int localstales[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  1807.  
  1808. int curwindex, curwinmax;
  1809. char rmch;
  1810.  
  1811.     /* Build new results array */
  1812.     if (staleflag) {
  1813.         make_textres (lp, tres_ary,    \
  1814.               TEXTRESHIGH, TEXTRESWIDE);
  1815.         }
  1816.  
  1817.     if(options[2]){
  1818.         dump_array(tres_ary, TEXTRESWIDE,ac_t_h, 1);
  1819.         options[2]=0;
  1820.         }
  1821.  
  1822.     smallkeylist.made=ix286.made=ix386.made=0;
  1823.     mk_window(&smallkeylist, NULL, 0, 23, 80, 26,     \
  1824.         BLACK,BLACK,BLACK,YELLOW, 0, 0);
  1825.     winprintstring(&smallkeylist, 1, 0, SKEYLISTSTRING);    
  1826.  
  1827.     if(textreswin.made)
  1828.         unhide_window(&textreswin);
  1829.     else
  1830.         mk_window(&textreswin, "Results Table",     \
  1831.         0, 0, 80, 24, GREEN, WHITE,BLACK, GRAY, 1, 0);
  1832.     link_array(&textreswin, tres_ary, TEXTRESWIDE, ac_t_h, 0, 0); 
  1833.  
  1834.     /* determine valid windows */
  1835.     curwindex=0;
  1836.     valwindows[curwindex] = &textreswin;
  1837.     curwindex++;
  1838.     valwindows[curwindex] = &ix286;
  1839.     curwindex++;
  1840.     if(machine_config.proc_type>286){
  1841.         valwindows[curwindex]=&ix386;
  1842.         curwindex++;
  1843.         }
  1844.     if(cpuwin.made){
  1845.         valwindows[curwindex]=&cpuwin;
  1846.         if(graphstale) localstales[curwindex]=1;
  1847.         curwindex++;
  1848.         }
  1849.     if(cpu2win.made){
  1850.         valwindows[curwindex]=&cpu2win;
  1851.         if(graphstale) localstales[curwindex]=2;
  1852.         curwindex++;
  1853.         }
  1854.     if(fpuwin.made){
  1855.         valwindows[curwindex]=&fpuwin;
  1856.         if(graphstale) localstales[curwindex]=3;
  1857.         curwindex++;
  1858.         }
  1859.     if(diskwin.made){
  1860.         valwindows[curwindex]=&diskwin;
  1861.         if(graphstale) localstales[curwindex]=4;
  1862.         curwindex++;
  1863.         }
  1864.     if(vidwin.made){
  1865.         valwindows[curwindex]=&vidwin;
  1866.         if(graphstale) localstales[curwindex]=5;
  1867.         curwindex++;
  1868.         }
  1869.     curwinmax = --curwindex;
  1870.  
  1871.     curwindex=0;
  1872.     rmch=0;
  1873.     /* get a keystroke */
  1874.     do{
  1875.         switch(getch()){
  1876.             case ESC:         /* exits */
  1877.                 hide_window(valwindows[curwindex]);
  1878.                 kill_window(&ix286);
  1879.                 kill_window(&ix386);
  1880.                 kill_window(&smallkeylist);
  1881.                 staleflag=0;
  1882.                 /* graphs are fresh only if all fresh*/
  1883.                 graphstale=0;
  1884.                 for(i=0;i<8;i++)
  1885.                     graphstale&=localstales[i];
  1886.                 return;
  1887.  
  1888.             case CTRLW:        /* dumps file */
  1889.                 if (curwindex!=0)    break;
  1890.                 winprintstring(&smallkeylist, 0, 0,     \
  1891.                     BLANKSTRING);    
  1892.                 dump_array(tres_ary, TEXTRESWIDE,ac_t_h, 0);
  1893.                 winprintstring(&smallkeylist, 1, 0,    \
  1894.                      SKEYLISTSTRING);    
  1895.                 break;
  1896.  
  1897.             case TAB:         /*pop next window*/
  1898.                 if (curwindex==0){
  1899.                     hide_window(valwindows[curwindex]);
  1900.                     hide_window(&smallkeylist);
  1901.                     curwindex++;
  1902.                     if(!(valwindows[curwindex]->made)){
  1903.                     /* must be an ungraphed 286*/
  1904.                         makeixgraphs(&ix286,     \
  1905.                             lp,0);
  1906.                         }
  1907.                     else{
  1908.                      unhide_window(valwindows[curwindex]);
  1909.                      if(localstales[curwindex]){
  1910.                         batchgraph(lp,    \
  1911.                               localstales[curwindex]);
  1912.                         localstales[curwindex]=0;
  1913.                         }
  1914.                      }
  1915.                     win_erase_region(    \
  1916.                          valwindows[curwindex],0,23,78,1);
  1917.                     winprintstring(valwindows[curwindex],\
  1918.                         0, 23, GRAPHKLSTRING);
  1919.                     break;
  1920.                     }
  1921.                 if (curwindex==curwinmax){
  1922.                     hide_window(valwindows[curwindex]);
  1923.                     curwindex=0;
  1924.                     unhide_window(&smallkeylist);
  1925.                     unhide_window(valwindows[curwindex]);
  1926.                     if(localstales[curwindex]){
  1927.                         batchgraph(lp,    \
  1928.                               localstales[curwindex]);
  1929.                         localstales[curwindex]=0;
  1930.                         }
  1931.                     break;
  1932.                     }
  1933.                 hide_window(valwindows[curwindex]);
  1934.                 curwindex++;
  1935.                 if(!(valwindows[curwindex]->made)){
  1936.                     /* must be an ungraphed 386*/
  1937.                         makeixgraphs(&ix386,     \
  1938.                             lp, 1);
  1939.                     }
  1940.                 else{
  1941.                     unhide_window(valwindows[curwindex]);
  1942.                     if(localstales[curwindex]){
  1943.                         batchgraph(lp,    \
  1944.                               localstales[curwindex]);
  1945.                         localstales[curwindex]=0;
  1946.                         }
  1947.                     }
  1948.                 win_erase_region(    \
  1949.                      valwindows[curwindex],0,23,78,1);
  1950.                 winprintstring(valwindows[curwindex],\
  1951.                     0, 23, GRAPHKLSTRING);
  1952.                 break;
  1953.  
  1954.             case  0:    /* scroll, maybe */
  1955.                  rmch=getch();
  1956.                  switch(rmch){
  1957.                     case UPARROW:
  1958.                         rmch=PGUP;
  1959.                     case PGUP:
  1960.                     case PGDOWN: 
  1961.                     case DOWNARROW:
  1962.                         if(curwindex==0){
  1963.                             scroll(&textreswin,    \
  1964.                             (int)(rmch==PGUP));
  1965.                             }
  1966.                         break;
  1967.  
  1968.                     default: break;
  1969.                     }
  1970.                 break;
  1971.  
  1972.             default: break;
  1973.             }
  1974.         } while(TRUE);
  1975. }
  1976.  
  1977.  
  1978. void dump_array(char *aryptr, int aw, int ah, int noask)
  1979. /* dumps array to file.
  1980. ** If noask is not set, Asks about overwriting. fails if edit box fails.
  1981. */
  1982. {
  1983. int dafh;
  1984. unsigned int asize, i;
  1985. char crlfbuf[2];
  1986.  
  1987.     crlfbuf[0]=CR;
  1988.     crlfbuf[1]=LF;
  1989.  
  1990.     if(noask){
  1991.         if((dafh=open(dumpfname, O_WRONLY|    \
  1992.           O_BINARY|O_CREAT|O_TRUNC,S_IWRITE))==-1){
  1993.             alert_box("File Write Error", 0, 1,3);
  1994.             return;
  1995.             }
  1996.         }
  1997.     else
  1998.         if (!get_filename(&dafh, dumpfname)) return;
  1999.  
  2000.     /* dafh is now a legitimate file handle */
  2001.  
  2002.     asize=aw*ah;
  2003.     strip0s(aryptr, asize);
  2004.     for(i=0; i<asize; i+=aw){
  2005.         if(write(dafh, aryptr+i, aw)< aw){
  2006.             close (dafh);
  2007.             alert_box("File Write Error", 0, 1,3);
  2008.             return;
  2009.             }
  2010.         write(dafh, crlfbuf, 2);
  2011.         }
  2012.  
  2013.     close (dafh);
  2014.     return;
  2015. }
  2016.  
  2017. int alert_box(char *message, int yesnocode, int beepflag, int severity)
  2018. /* puts up an appropriately sized alert box; returns y/n responses
  2019. ** if yesnocode is set to YESNO
  2020. ** Beeps if beepflag is set.
  2021. ** severity decides the color scheme.
  2022. */
  2023. {
  2024. win_handle abox;
  2025. int boxw;
  2026. char abch=-1;
  2027. unsigned long tm0, tm1;
  2028. int background;
  2029. int frame;
  2030. int text;
  2031.  
  2032.     switch(severity){
  2033.         case 3: background=RED; frame=WHITE; text=YELLOW; break;
  2034.         case 2: background=BLACK; frame=YELLOW; text=YELLOW; break;
  2035.         default: background=CYAN; frame=WHITE; text=BLUE; break;
  2036.         }
  2037.  
  2038.     abox.made=0;
  2039.     boxw=(strlen(message)>8)? strlen(message)+4: 12;
  2040.     
  2041.     mk_window(&abox, "Alert", (40-(boxw>>1)), 10, (40+(boxw>>1)) , 13,     \
  2042.         background, frame, background, text, 1, 0);
  2043.  
  2044.     winprintstring(&abox, ((abox.w-2)-strlen(message))>>1, 0, message);
  2045.  
  2046.     if (beepflag && tdef[13]) putchar(0x07);
  2047.  
  2048.     if(yesnocode==YESNO){
  2049.         while((abch!='Y') && (abch!='N')){
  2050.             if(abch==0)
  2051.                 getch();  /*filter function keys*/
  2052.             abch=toupper(getch());
  2053.             }
  2054.         kill_window(&abox);
  2055.         return (abch=='Y')? 1:0;
  2056.         }
  2057.  
  2058.     /* leave it up for a second */
  2059.  
  2060.     tm0=clock();
  2061.     do{
  2062.         tm1=clock();
  2063.         } while((tm1-tm0)<CLK_TCK);
  2064.     kill_window(&abox);
  2065.     return 0;
  2066. }
  2067.  
  2068. int mod_default_box(char* defstring, int dsmax, char* message)
  2069. /* puts up an editable box which modifies default names 
  2070. ** dsmax is the storage allocated to defstring. Returns zero
  2071. ** and leaves value unchanged on escape.
  2072. */
  2073. {
  2074. win_handle edwin;
  2075. int boxw;
  2076. int baseloc, baselen;
  2077. int retval;
  2078.  
  2079.     /* initialize */
  2080.     edwin.made=0;
  2081.  
  2082.     /* determine width --  between 20 and 40,wider of strings plus 8 */
  2083.     boxw=(strlen(message)>(strlen(defstring)))?    \
  2084.         strlen(message)+8:strlen(defstring)+8;
  2085.     boxw=(boxw>20)?boxw:20;
  2086.     boxw=(boxw<40)?boxw:40;
  2087.  
  2088.     mk_window(&edwin, "Edit", (40-(boxw>>1)), 10, (40+(boxw>>1)) , 14,     \
  2089.             BLUE, GRAY, BLUE, WHITE, 1, 0);
  2090.  
  2091.     /* put up messages */
  2092.     winprintstring(&edwin,((edwin.w-2)-strlen(message))>>1,0,message);
  2093.     baseloc=((edwin.w-2)-(dsmax-1))>>1;
  2094.     baseloc=(baseloc>1)?baseloc:1;
  2095.  
  2096.     baselen=(edwin.w-4<dsmax-1)? edwin.w-4: dsmax-1;
  2097.  
  2098.     /* edit string */
  2099.     retval=edit_string(&edwin, baseloc, 1, baselen,    \
  2100.              defstring, dsmax, 0);
  2101.  
  2102.     /* close and exit */
  2103.      kill_window(&edwin);
  2104.     return (retval) ? 1 : 0;
  2105. }
  2106.  
  2107. int edit_string(win_handle *win, int x, int y, int edlen, char * edstring,    \
  2108.         int edstrlen, int arrowflag)
  2109. /*
  2110. ** window based text input. Leaves string unchanged and returns zero on
  2111. ** escape.  Otherwise returns keystroke which finished arrows are
  2112. ** accepted if arrowflag is set, else only enter.
  2113. */
  2114.  
  2115. {
  2116. int i, o;
  2117. char *j;
  2118. char edch=-1;
  2119. char scratch[100];
  2120. char savchar;
  2121. int izeroflag;
  2122. int breakflag=0;
  2123.  
  2124.     /* bad string check */
  2125.     if (edstrlen>100) return 0;
  2126.  
  2127.     /* initialize */
  2128.     for(i=0;i<100;i++)
  2129.         scratch[i]=0;
  2130.  
  2131.     strcpy(scratch, edstring);
  2132.     *(scratch+99)=0;
  2133.  
  2134.     /* big loop */
  2135.     i=0;
  2136.     o=0;
  2137.     new_cursor(oldcurse);
  2138.     while(TRUE){
  2139.         win_erase_region(win, x, y, edlen,1);
  2140.         chattr(win,x,y, edlen, 1, WHITE,BLACK);
  2141.  
  2142.         if ((i+o)==edstrlen-1) new_cursor(BLANK_CURSE);
  2143.         else new_cursor(oldcurse);
  2144.  
  2145.         /* print only edlen trick */
  2146.         savchar=(*(scratch+o+edlen));
  2147.         *(scratch+o+edlen)=0;
  2148.         winprintstring(win, x, y, scratch+o);
  2149.         *(scratch+o+edlen)=savchar;
  2150.  
  2151.         win_set_curpos(win,x+i,y);
  2152.         edch=getch();
  2153.         switch(edch){
  2154.             case ESC:
  2155.                 new_cursor(BLANK_CURSE);
  2156.                 return 0;
  2157.             case 0:
  2158.                 edch=getch();
  2159.                 switch(edch){
  2160.                     case DEL:
  2161.                         j=scratch+i+o;
  2162.                         while(*(j+1)!=0){
  2163.                             *(j)=*(j+1);
  2164.                             j++;
  2165.                             }
  2166.                         *(j)=*(j+1);
  2167.                         break;
  2168.                     case  LEFTARROW:
  2169.                         if(i>0)
  2170.                             --i;
  2171.                         else
  2172.                             o=(o>0)?--o:0;
  2173.                         break;
  2174.                     case  RIGHTARROW:
  2175.                         if(*(scratch+i+o)==0)
  2176.                             break;
  2177.                         if ((i+o)==(edstrlen-1))
  2178.                              break;
  2179.                         if((i<(edlen-1))||    \
  2180.                         ((i+o+1)==(edstrlen-1)))
  2181.                             i++;
  2182.                         else
  2183.                             o++;
  2184.                         break;
  2185.  
  2186.                     case UPARROW:
  2187.                     case DOWNARROW:
  2188.                         if (arrowflag){
  2189.                             breakflag=1;
  2190.                             break;
  2191.                             }
  2192.  
  2193.                     default: continue;
  2194.                     }
  2195.                 break;
  2196.             case ENTER:
  2197.                 breakflag=1;
  2198.                 break;
  2199.             case BS:
  2200.                 if(i==0) izeroflag=1;
  2201.                 else     izeroflag=0;
  2202.  
  2203.                 if (izeroflag &&(o==0)) break ;
  2204.                 if(izeroflag) o--;
  2205.                 else    i--;
  2206.                 j=scratch+i+o;
  2207.                 while(*(j+1)!=0){
  2208.                     *(j)=*(j+1);
  2209.                     j++;
  2210.                     }
  2211.                 *(j)=*(j+1);
  2212.                 if(izeroflag) o++; /* put o back for looks */
  2213.                 win_erase_region(win,    \
  2214.                    x, y, edlen,1);
  2215.                 chattr(win,x,y,    \
  2216.                   edlen,1,WHITE,BLACK);
  2217.                 break;
  2218.             default:
  2219.                 if (isnprnt(edch)) break;
  2220.                 if ((i+o)==(edstrlen-1)) break;
  2221.                 *(scratch+i+o)=edch;
  2222.                 if((i<(edlen-1))||((i+o+1)==(edstrlen-1)))
  2223.                     i++;
  2224.                 else
  2225.                     o++;
  2226.                 break;
  2227.             }
  2228.         if (breakflag) break;
  2229.         }
  2230.     new_cursor(BLANK_CURSE);
  2231.     strncpy(edstring, scratch, edstrlen);
  2232.     *(edstring+edstrlen-1)=0;
  2233.  
  2234.     return edch;
  2235. }
  2236.  
  2237. void controls_menu(void** listptr)
  2238. /*
  2239. ** puts up a select box. 
  2240. **
  2241. **
  2242. */
  2243. {
  2244. win_handle cm;
  2245. int menhigh;
  2246. int cmresp;
  2247. int escflag=0;
  2248.  
  2249.     /* menu is sized according to whether or not tests were run.
  2250.        If they were, lower two choices are available */
  2251.  
  2252.     menhigh=(textreswin.made)? 12: 7;
  2253.     cm.made=0;
  2254.  
  2255.     mk_window(&cm, "Controls", 39, 2, 73, 2+menhigh, CYAN, WHITE,
  2256.                   CYAN, BLUE, 1, 0);
  2257.  
  2258.     winprintstring(&cm, 1, 0, "  Test Suite Configuration ...");
  2259.     winprintstring(&cm, 1, 2, "  System Setup ...");
  2260.     winprintstring(&cm, 1, 4, "  View/Choose Comparisons ...");
  2261.     winprintstring(&cm, 1, 6, " Review Results");
  2262.     winprintstring(&cm, 1, 8, " Save Results to File");
  2263.  
  2264.     cm.num_valid=(textreswin.made)? 5:3  ;
  2265.     cm.valid_lines=controls_valid_lines; /* predefined */
  2266.  
  2267.     winprintstring(&field,5,23,CMKEYLISTSTRING);
  2268.  
  2269.     /****** go into big loop ********/
  2270.     help_base=6;
  2271.     while(TRUE){
  2272.         display_help(&helptext, help_base);
  2273.         cmresp=get_resp_line(&cm, 0, 1, BLUE, WHITE, 0, 1);
  2274.         switch(cmresp){
  2275.             case -1: escflag=1;
  2276.                  break;
  2277.             case 0:
  2278.                 ts_config();
  2279.                 winprintstring(&field,5,23,CMKEYLISTSTRING);
  2280.                 break;
  2281.             case 1:
  2282.                 sys_setup();
  2283.                 machtodb((db_rec**)listptr,recs_in_db,    \
  2284.                     &machine_config); 
  2285.                 winprintstring(&field,5,23,CMKEYLISTSTRING);
  2286.                 break;
  2287.             case 2:
  2288.                 BLANKSCREEN;
  2289.                 edit_data(listptr);
  2290.                 UNBLANKSCREEN;
  2291.                 break;
  2292.             case 3:
  2293.                 BLANKSCREEN;
  2294.                 reviewmode(listptr);
  2295.                 UNBLANKSCREEN;
  2296.                 break;
  2297.             case 4:
  2298.                 winprintstring(&field,5,23,BLANKSTRING);
  2299.                 dump_array(tres_ary, TEXTRESWIDE,ac_t_h, 0);
  2300.                 winprintstring(&field,5,23,CMKEYLISTSTRING);
  2301.                 break;
  2302.             }
  2303.         if(escflag) break;
  2304.     }
  2305.     kill_window(&cm);
  2306.  
  2307.     /* old help screen */
  2308.     display_help (&helptext, 0);
  2309.     help_base=0;
  2310.  
  2311.     return;
  2312. }
  2313.  
  2314. void ts_config(void)
  2315. /*
  2316. ** puts up a select box. 
  2317. **
  2318. **
  2319. */
  2320. {
  2321. win_handle tsc;
  2322. int tscresp=-1;
  2323. int def;
  2324. int escflag=0;
  2325. int choicetype=0;
  2326. int tmpdef[14];
  2327. int tempval;
  2328. int i, boti, topi;
  2329. char valstring[4] = {0, 0, 0, 0};
  2330.  
  2331.     for(i=0;i<14;i++)
  2332.         tmpdef[i]=tdef[i];
  2333.  
  2334.     tsc.made=0;
  2335.  
  2336.     mk_window(&tsc, "Test Settings", 38, 0, 78, 23, CYAN, WHITE,
  2337.                   CYAN, BLUE, 1, 0);
  2338.  
  2339.     winprintstring(&tsc, 1, 0, "  Sieve Duration (s.) .........");
  2340.     winprintstring(&tsc, 1, 1, "  Sort Duration (s.) ..........");
  2341.     winprintstring(&tsc, 1, 2, "  Integer Math Duration (s.) ..");
  2342.     winprintstring(&tsc, 1, 3, "  String Move Duration (s.) ...");
  2343.  
  2344.     winprintstring(&tsc, 1, 5, "  Fmath Duration (s.) .........");
  2345.     winprintstring(&tsc, 1, 6, "  Fourier Duration (s.) .......");
  2346.  
  2347.     winprintstring(&tsc, 1, 8, "  File I/O Duration (s.) ......");
  2348.     winprintstring(&tsc, 1, 9, "  Logical Drive for File I/O ..");
  2349.     winprintstring(&tsc, 1, 10, "  Run Low-Level Disk? .........");
  2350.     winprintstring(&tsc, 1, 11, "  Test Hard Drive Unit ........");
  2351.  
  2352.     winprintstring(&tsc, 1, 13, "  Text Duration (s./mode) .....");
  2353.     winprintstring(&tsc, 1, 14, "  Graphics Duration (s./mode) .");
  2354.  
  2355.     winprintstring(&tsc, 1, 16, "  Total Suite Repetitions .....");
  2356.  
  2357.     winprintstring(&tsc, 1, 18, " Save Changes");
  2358.     winprintstring(&tsc, 1, 19, " Store Configuration as Default");
  2359.     winprintstring(&tsc, 1, 20, " Restore Default Configuration");
  2360.  
  2361.     tsc.num_valid = tsuite_num_valid;
  2362.     tsc.valid_lines=tsuite_valid_lines; /* predefined */
  2363.  
  2364.     winprintstring(&field,5,23,TSCKEYLISTSTRING);
  2365.  
  2366.     help_base=11;
  2367.     def=0;
  2368.     boti=0;topi=13;
  2369.  
  2370.     /****** go into big, big loop ********/
  2371.     while(TRUE){
  2372.         for(i=boti;i<topi;i++){
  2373.             switch(i){
  2374.                 case 7: *(valstring)=tmpdef[i]+'A'-1;
  2375.                     *(valstring+1)=':';
  2376.                     *(valstring+2)=0;
  2377.                     break;
  2378.                 case 8:
  2379.                        *(valstring)=tmpdef[i]?'Y':'N';
  2380.                        *(valstring+1)=0;
  2381.                     break;
  2382.                 case 9: if (tmpdef[i]<0){
  2383.                         strcpy(valstring," - ");
  2384.                         break;
  2385.                         }
  2386.                     itoa(tmpdef[i], valstring, 10);
  2387.                     break;
  2388.  
  2389.                 default: if (tmpdef[i]){
  2390.                         itoa(tmpdef[i],    \
  2391.                          valstring, 10);
  2392.                          }
  2393.                      else
  2394.                         strcpy(valstring,"Off");
  2395.                 }
  2396.  
  2397.             win_erase_region(&tsc, 33, tsc.valid_lines[i], 3, 1);
  2398.             winprintstring(&tsc, 33, tsc.valid_lines[i],    \
  2399.                  valstring);
  2400.             chattr(&tsc, 33, tsc.valid_lines[i], 3, 1,     \
  2401.                 WHITE, BLACK);
  2402.             }
  2403.         if(def!=tscresp) display_help(&helptext, help_base+def);
  2404.         tscresp=get_resp_line(&tsc,def,1,BLUE,WHITE,    \
  2405.                 &choicetype,1);
  2406.         if(choicetype!=1){
  2407.             def=tscresp;
  2408.             if(def>12) continue;
  2409.             tempval=tmpdef[def];
  2410.             switch(choicetype){
  2411.                 case LEFTARROW:
  2412.                     tmpdef[def]--; break;
  2413.                 case RIGHTARROW:
  2414.                     tmpdef[def]++; break;
  2415.                 case CTRLLA:
  2416.                     tmpdef[def]-=50; break;
  2417.                 case CTRLRA:
  2418.                     if(!tmpdef[def]) tmpdef[def]=1;
  2419.                     else tmpdef[def]+=50;
  2420.                     break;
  2421.                 default: break;
  2422.                 }
  2423.             limcheck(tmpdef, 13);
  2424.             if (tempval!=tmpdef[def])  click();
  2425.             if (def==9){    /* special case */
  2426.                 boti=8;topi=10;
  2427.                 }
  2428.             else{
  2429.                 boti=def;topi=def+1;
  2430.                 }
  2431.             }
  2432.         else{
  2433.             switch(tscresp){
  2434.                 case -1: escflag=1;
  2435.                      break;
  2436.                 case 13:
  2437.                      for(i=0;i<14;i++)
  2438.                         tdef[i]=tmpdef[i];
  2439.                      def=0;
  2440.                      boti=def;topi=def+1;
  2441.                      break;
  2442.                 case 14: 
  2443.                      for(i=0;i<14;i++)
  2444.                         tdef[i]=tmpdef[i];
  2445.                      dump_defs("bbdef.dat",tdef,14);
  2446.                      def=0;
  2447.                      boti=def;topi=def+1;
  2448.                      break;
  2449.                 case 15:
  2450.                      read_defs("bbdef.dat",tdef,14);
  2451.                      limcheck(tdef,13);
  2452.                      for(i=0;i<14;i++)
  2453.                         tmpdef[i]=tdef[i];
  2454.                      boti=0;topi=13;
  2455.                      def=0;
  2456.                      break;
  2457.                 default: 
  2458.                      def=tscresp;
  2459.                        boti=def;topi=def+1;
  2460.                      break;
  2461.                 }
  2462.             if(escflag) {
  2463.                 for(i=0;i<14;i++)
  2464.                     if(tmpdef[i]!=tdef[i]) break;
  2465.                 if (i==14) break;
  2466.                 if(!alert_box(    \
  2467.                     "Save Changes?[y/n]",    \
  2468.                      YESNO, 0, 2)) break;
  2469.                 for(i=0;i<14;i++)
  2470.                     tdef[i]=tmpdef[i];
  2471.                 break;
  2472.                 }
  2473.             }
  2474.     }
  2475.     kill_window(&tsc);
  2476.  
  2477.     /* old help screen */
  2478.     display_help (&helptext, 6);
  2479.     help_base=6;
  2480.  
  2481.     return;
  2482. }
  2483.  
  2484. void sys_setup(void)
  2485. /*
  2486. ** puts up a select box for machine parameters 
  2487. **
  2488. **
  2489. */
  2490. {
  2491. win_handle sys;
  2492. int sysresp=-1;
  2493. int def;
  2494. int escflag=0;
  2495. int choicetype=0;
  2496.  
  2497. struct mcfig tempmcfig;
  2498. int tmpdef[14] ={60,60,60,60,60,60,60,3,1,0,60,60,1,1};
  2499.  
  2500. int xoff, xlen;
  2501. char *gtptr;
  2502.  
  2503. int tempval;
  2504. int sign;
  2505. int snowchanged=0;
  2506. int i, boti, topi;
  2507. int posfpu[4]={0,87,287,387};
  2508. char valstring[15];
  2509. char tstring[5];
  2510. char oldname[15];
  2511.  
  2512.     /* initialize */
  2513.     for(i=0;i<15;i++)
  2514.         valstring[i]=0;
  2515.     strcpy(tempmcfig.machine_name, machine_config.machine_name);
  2516.     strcpy(oldname, machine_config.machine_name);
  2517.     tempmcfig.graphics_type=machine_config.graphics_type;
  2518.     tempmcfig.proc_type=machine_config.proc_type;
  2519.     tempmcfig.fpu_type=machine_config.fpu_type;
  2520.     tempmcfig.MHz=machine_config.MHz;
  2521.     tempmcfig.num_hard=machine_config.num_hard;
  2522.     tempmcfig.dosnowplow=machine_config.dosnowplow;
  2523.     read_defs("bbdef.dat", tmpdef, 14);
  2524.     tmpdef[13]=tdef[13];
  2525.  
  2526.     sys.made=0;
  2527.  
  2528.     mk_window(&sys, "System Configuration", 38, 3, 78, 17, CYAN, WHITE,
  2529.                   CYAN, BLUE, 1, 0);
  2530.  
  2531.     winprintstring(&sys, 1, 0, "  Machine Name ..");
  2532.  
  2533.     winprintstring(&sys, 1, 2, "  Processor ..............");
  2534.     winprintstring(&sys, 1, 3, "  Math Coprocessor .......");
  2535.     winprintstring(&sys, 1, 4, "  Video Type .............");
  2536.     winprintstring(&sys, 1, 5, "  Number of Hard Drives ..");
  2537.  
  2538.     winprintstring(&sys, 1, 7, "  Sound ..................");
  2539.     winprintstring(&sys, 1, 8, "  CGA Snow Compensation ..");
  2540.  
  2541.     winprintstring(&sys, 1, 10, " Save Changes");
  2542.     winprintstring(&sys, 1, 11, " Auto Detect");
  2543.  
  2544.     sys.num_valid = sysset_num_valid;
  2545.     sys.valid_lines=sysset_valid_lines; /* predefined */
  2546.  
  2547.     winprintstring(&field,5,23,TSCKEYLISTSTRING);
  2548.  
  2549.     help_base=27;
  2550.     def=0;
  2551.     boti=0; topi=7;
  2552.  
  2553.  
  2554.     /****** go into big, big loop ********/
  2555.     while(TRUE){
  2556.         for(i=boti;i<topi;i++){
  2557.             switch(i){
  2558.                 case 0: strcpy(valstring,    \
  2559.                         tempmcfig.machine_name);
  2560.                     xoff=21; xlen=14;
  2561.                     break;
  2562.                 case 1:
  2563.                     strcpy(valstring,"80");
  2564.                     itoa(tempmcfig.proc_type,tstring,    \
  2565.                          10);
  2566.                     strcat(valstring,tstring);
  2567.                     if (strlen(valstring)==4)
  2568.                         *(valstring+3)='x';
  2569.                     xoff=30; xlen=5;
  2570.                     break;
  2571.                 case 2:
  2572.                     xoff=30; xlen=5;
  2573.                     if(!tempmcfig.fpu_type){
  2574.                         strcpy(valstring, "None");
  2575.                         break;
  2576.                         }
  2577.                     strcpy(valstring,"80");
  2578.                     itoa(tempmcfig.fpu_type,    \
  2579.                         tstring, 10);
  2580.                     strcat(valstring,tstring);                                                    break;
  2581.                 case 3:
  2582.                     switch(tempmcfig.graphics_type){
  2583.                         case MDA: gtptr="Mono"; break;
  2584.                         case HERC:gtptr="HGC "; break;
  2585.                         case EGAM:gtptr="EGA-M";break;
  2586.                         case CGA:gtptr="CGA"; break;
  2587.                         case EGAC:gtptr="EGA-C";break;
  2588.                         case VGA:gtptr="VGA"; break;
  2589.                         }
  2590.                        strcpy(valstring, gtptr);
  2591.                        xoff=30; xlen=5;
  2592.                        break;
  2593.  
  2594.                 case 4:    itoa(tempmcfig.num_hard,    \
  2595.                         valstring, 10);
  2596.                        xoff=30; xlen=5;
  2597.                        break;
  2598.  
  2599.                 case 5: if(tmpdef[13])
  2600.                     strcpy(valstring, "On");
  2601.                     else strcpy(valstring, "Off");
  2602.                         xoff=30; xlen=5;
  2603.                     break;
  2604.  
  2605.                 case 6: if(tempmcfig.dosnowplow)
  2606.                          strcpy(valstring, "On");
  2607.                     else strcpy(valstring, "Off");
  2608.                         xoff=30; xlen=5;
  2609.                     break;
  2610.                 }
  2611.  
  2612.             win_erase_region(&sys, xoff, sys.valid_lines[i],    \
  2613.                  xlen, 1);
  2614.             winprintstring(&sys, xoff, sys.valid_lines[i],    \
  2615.                  valstring);
  2616.             chattr(&sys, xoff, sys.valid_lines[i], xlen, 1,    \
  2617.                 WHITE, BLACK);
  2618.             }
  2619.         if(sysresp!=def) display_help(&helptext, help_base+def);
  2620.         sysresp=get_resp_line(&sys,def,1,BLUE,WHITE,&choicetype,1);
  2621.          if((choicetype==DEL)||(choicetype==CTRLD)||    \
  2622.          (choicetype==INS)||(choicetype==CTRLW)||(choicetype==CTRLS)){
  2623.             def=sysresp;
  2624.             boti=0; topi=0;
  2625.             continue;
  2626.             }
  2627.         if(sysresp==0){
  2628.             def=sysresp;
  2629.             if (choicetype==1)
  2630.                 chattr(&sys, 1, 0, winstrlen(&sys, 1, 0),    1, \
  2631.                     BLUE, WHITE); /* for consistency */
  2632.             edit_string(&sys,21,0,14,    \
  2633.                 tempmcfig.machine_name, 15, 1);
  2634.             boti=def;topi=def+1;
  2635.             continue;
  2636.             }
  2637.  
  2638.         if(choicetype!=1){
  2639.             def=sysresp;
  2640.             if(def>6) continue;
  2641.             sign=((choicetype==CTRLLA)||(choicetype==LEFTARROW))?
  2642.                 -1 : +1;
  2643.             switch(def){
  2644.                 case 1: tempval=    \
  2645.                          tempmcfig.proc_type+(100*sign);
  2646.                     if((tempval<86) || (tempval>486))
  2647.                         break;
  2648.                     tempmcfig.proc_type=tempval;
  2649.                     if (tmpdef[13]) click();
  2650.                     break;
  2651.                 case 2: 
  2652.                     for(i=0;i<4;i++)
  2653.                         if(tempmcfig.fpu_type ==    \
  2654.                            posfpu[i]) break;
  2655.                     i+=sign;
  2656.                     if ((i<0) || (i>3)) break;
  2657.                     tempmcfig.fpu_type=posfpu[i];
  2658.                     if (tmpdef[13]) click();
  2659.                     break;
  2660.                 case 3: tempval=    \
  2661.                         tempmcfig.graphics_type+sign;
  2662.                     if((tempval<1) || (tempval>6))
  2663.                         break;
  2664.                     if(tempmcfig.graphics_type==CGA){
  2665.                         tempmcfig.dosnowplow=0;
  2666.                         snowchanged=1;
  2667.                         }
  2668.                     tempmcfig.graphics_type=tempval;
  2669.                     if (tmpdef[13]) click();
  2670.                     break;
  2671.                 case 4: tempval=    \
  2672.                         tempmcfig.num_hard+sign;
  2673.                     if((tempval<0) || (tempval>4))
  2674.                         break;
  2675.                     tempmcfig.num_hard=tempval;
  2676.                     if (tmpdef[13]) click();
  2677.                     break;
  2678.                 case 5: tempval=    \
  2679.                         tmpdef[13]+sign;
  2680.                     if((tempval<0) || (tempval>1))
  2681.                         break;
  2682.                     tmpdef[13]=tempval;
  2683.                     if (tmpdef[13]) click();
  2684.                     break;
  2685.                 case 6:
  2686.                     if(tempmcfig.graphics_type!=CGA)
  2687.                         break;
  2688.                      tempval=    \
  2689.                         tempmcfig.dosnowplow+sign;
  2690.                     if((tempval<0) || (tempval>1))
  2691.                         break;
  2692.                     tempmcfig.dosnowplow=tempval;
  2693.                     if (tmpdef[13]) click();
  2694.                     break;
  2695.                 }
  2696.             boti=def; topi=def+1;
  2697.             if (snowchanged) {topi=7; snowchanged=0;}
  2698.             }
  2699.         else{
  2700.             switch(sysresp){
  2701.                 case -1: escflag=1;
  2702.                      break;
  2703.                 case 7:
  2704.                     strcpy(machine_config.machine_name,    \
  2705.                          tempmcfig.machine_name);
  2706.                     machine_config.graphics_type=    \
  2707.                         tempmcfig.graphics_type;
  2708.                     machine_config.proc_type=    \
  2709.                         tempmcfig.proc_type;
  2710.                     machine_config.fpu_type=    \
  2711.                         tempmcfig.fpu_type;
  2712.                     machine_config.MHz=    \
  2713.                         tempmcfig.MHz;
  2714.                     machine_config.num_hard=    \
  2715.                         tempmcfig.num_hard;
  2716.                     machine_config.dosnowplow=    \
  2717.                         tempmcfig.dosnowplow;
  2718.                     tdef[13]=tmpdef[13];
  2719.                     dump_defs("bbdef.dat", tmpdef, 14);
  2720.                     cgainit();
  2721.                     def=0;
  2722.                     topi=boti=0;
  2723.                     break;
  2724.                 case 8: 
  2725.                      machine_detect(&tempmcfig);
  2726.                      tempmcfig.dosnowplow=0;
  2727.                      topi=7; boti=0;
  2728.                      def=0;
  2729.                      break;
  2730.                 default: 
  2731.                      topi=boti=0;
  2732.                      def=sysresp;
  2733.                      break;
  2734.                 }
  2735.             }
  2736.         if(escflag){
  2737.             /* compare structures*/
  2738.             if(!strcmp(machine_config.machine_name,    \
  2739.                  tempmcfig.machine_name) &&
  2740.                machine_config.graphics_type==    \
  2741.                 tempmcfig.graphics_type &&
  2742.                machine_config.proc_type==    \
  2743.                 tempmcfig.proc_type &&
  2744.                machine_config.fpu_type==    \
  2745.                 tempmcfig.fpu_type &&
  2746.                machine_config.MHz==    \
  2747.                 tempmcfig.MHz &&
  2748.                machine_config.num_hard==    \
  2749.                 tempmcfig.num_hard &&
  2750.                machine_config.dosnowplow==    \
  2751.                 tempmcfig.dosnowplow &&
  2752.                tdef[13]==tmpdef[13])  break;
  2753.             if(!alert_box(    \
  2754.                 "Save Changes?[y/n]",    \
  2755.                  YESNO, 0, 2)) break;
  2756.             strcpy(machine_config.machine_name,    \
  2757.                  tempmcfig.machine_name);
  2758.             machine_config.graphics_type=    \
  2759.                 tempmcfig.graphics_type;
  2760.             machine_config.proc_type=    \
  2761.                 tempmcfig.proc_type;
  2762.             machine_config.fpu_type=    \
  2763.                 tempmcfig.fpu_type;
  2764.             machine_config.MHz=    \
  2765.                 tempmcfig.MHz;
  2766.             machine_config.num_hard=    \
  2767.                 tempmcfig.num_hard;
  2768.             machine_config.dosnowplow=    \
  2769.                 tempmcfig.dosnowplow;
  2770.             tdef[13]=tmpdef[13];
  2771.             dump_defs("bbdef.dat", tmpdef, 14);
  2772.             cgainit();
  2773.             break;
  2774.             }
  2775.         }
  2776.     /* fix graphs */
  2777.     if (strcmp(machine_config.machine_name,oldname))
  2778.          graphstale=staleflag=1;
  2779.     kill_window(&sys);
  2780.  
  2781.     /* old help screen */
  2782.     display_help (&helptext, 6);
  2783.     help_base=6;
  2784.  
  2785.     return;
  2786. }
  2787.  
  2788. int validpath(char * fname)
  2789. /*
  2790. ** determines if the fname string contitutes a valid path with
  2791. ** (possibly valid) filename
  2792. */
  2793. {
  2794. char *buffer;
  2795. char *pathptr;
  2796. int i;
  2797. int retval;
  2798.  
  2799.     if (*(fname+1) == ':'){
  2800.         if((disk_check(toupper(*(fname))+1-'A', 0)) <= 0)
  2801.             return 0;
  2802.         }
  2803.  
  2804.     /* scan for last backslash */
  2805.     for(i=strlen(fname)-1; (*(fname+i)!='\\') && (i>0); i--);
  2806.  
  2807.     if (i==0) return 1; /* no path is good path */
  2808.  
  2809.  
  2810.     pathptr=(char*) malloc(i+2);
  2811.     strncpy(pathptr, fname, i);
  2812.     *(pathptr+i)=0;
  2813.     if (*(pathptr+(i-1)) ==':'){
  2814.         *(pathptr+i)='\\';
  2815.         *(pathptr+i+1)=0;
  2816.         }
  2817.     *(pathptr)=toupper(*(pathptr));
  2818.  
  2819.     /* save current path in buffer, in case the check works */
  2820.     buffer=(char *) malloc(68);
  2821.     buffer[0]=(get_default()+'A');
  2822.     strcpy(buffer+1, ":\\");
  2823.     getpath((int)(buffer[0]-'A'), buffer+3);
  2824.  
  2825.     retval = cdir(pathptr);
  2826.     cdir (buffer);
  2827.  
  2828.     free (buffer);
  2829.     free (pathptr);
  2830.  
  2831.     return retval;
  2832. }
  2833.  
  2834. int validfname(char * fname)
  2835. /*
  2836. ** finds the filename in a path string. returns 1 if filename valid, 0
  2837. ** if not.
  2838. **
  2839. */
  2840.  
  2841. {
  2842. int i;
  2843. int nameptr;
  2844. int dotloc = -1;
  2845.  
  2846.     /* scan for last backslash */
  2847.     for(i=strlen(fname)-1; (*(fname+i)!='\\') && (i>0); i--);
  2848.  
  2849.     if((i==0) && (*(fname+1)==':')) nameptr=i=3;
  2850.     else    nameptr= ++i;
  2851.  
  2852.     /* too long? */
  2853.     if((strlen(fname+nameptr)>12)||(strlen(fname+nameptr)<1))
  2854.         return 0;
  2855.  
  2856.     /* find invalid chars */
  2857.     for(;*(fname+i)!=0;i++){
  2858.         if(   (*(fname+i)<=' ') ||
  2859.               (*(fname+i)=='"') ||
  2860.               ((*(fname+i)>='*')&&(*(fname+i)<=',')) ||
  2861.               (*(fname+i)=='/') ||
  2862.               ((*(fname+i)>=':')&&(*(fname+i)<='?')) ||
  2863.               ((*(fname+i)>='[')&&(*(fname+i)<=']')) ||
  2864.               (*(fname+i)=='|') ||
  2865.               (*(fname+i)>~~ 0x07e)
  2866.             )    return 0;
  2867.         }
  2868.  
  2869.     /* find the dot */
  2870.     for(;i>=nameptr;i--){
  2871.         if(*(fname+i)=='.'){
  2872.             if(dotloc<0)    dotloc=i;
  2873.             else    /* one dot to a filename */
  2874.                 return 0;
  2875.             }
  2876.         }
  2877.  
  2878.     /* make sure dot is in the right place */
  2879.  
  2880.     if (dotloc>-1){
  2881.         if( ((dotloc-nameptr)>8) || (dotloc==nameptr) ||  \
  2882.               (strlen(fname+dotloc)>4) ) return 0;
  2883.         }
  2884.  
  2885.     return 1;
  2886. }
  2887.  
  2888. struct help_handle *make_helpspace(char *hfname, struct help_handle *hh)
  2889. /*
  2890. ** Given the proper filename, opens helpfile. Fills handle with
  2891. ** chapter offsets. Returns pointer to help handle, or 0 on 
  2892. ** error.
  2893. */
  2894. {
  2895. int hfh;
  2896. unsigned int i, j;
  2897. unsigned int crcount;
  2898. char* bufptr;
  2899. unsigned int numbytes;
  2900. int num_ptrs;
  2901.  
  2902.     hh->filehandle = 0;
  2903.  
  2904.     hfh=open(hfname, O_BINARY|O_RDONLY);
  2905.     if(hfh==-1)
  2906.         return    NULL;
  2907.  
  2908.     /* open a buffer */
  2909.      if ((bufptr=(char *)malloc(512))==NULL)
  2910.         return NULL;
  2911.  
  2912.     /* first offset is at 12; rest will be scanned */
  2913.     numbytes=(unsigned int) lseek(hfh, 12, 0);
  2914.     if(numbytes!=12){
  2915.         close(hfh);
  2916.         return NULL;/* not my file */
  2917.         }
  2918.     hh->chapter_offsets[0]=12;
  2919.  
  2920.     /* scan file for end of chapter markers (0x017) */
  2921.     /* count lines while we're at it */
  2922.     j=0;
  2923.     num_ptrs=1;
  2924.     crcount=0;
  2925.     while(num_ptrs<50){
  2926.         numbytes=read(hfh, bufptr, 512);
  2927.         if(numbytes<0){
  2928.             close(hfh);
  2929.             return NULL;    /* read error */
  2930.             }
  2931.         for(i=0;i<numbytes;i++){
  2932.             if(*(bufptr+i)== CR){
  2933.                 crcount++;
  2934.                 continue;
  2935.                 }
  2936.             if(*(bufptr+i)== 0x017){
  2937.                 hh->chapter_offsets[num_ptrs] = (512*j)+i+13;
  2938.                 num_ptrs++;
  2939.                 act_h_h=(act_h_h>crcount)?act_h_h:crcount;
  2940.                 crcount=0;
  2941.                 }
  2942.             }
  2943.         if (numbytes<512)    break; /* end of file */
  2944.         j++;
  2945.         }
  2946.  
  2947.     /* clear the rest of the array */
  2948.     for (i=num_ptrs;i<50;i++)
  2949.         hh->chapter_offsets[i] = 0;
  2950.  
  2951.     /* allocate enough memory for biggest section */
  2952.     if(((hh->arryptr)=(char*) malloc((act_h_h+1)*HWIDTH)) == NULL) {
  2953.         /* never too late to fail */
  2954.         close(hfh);
  2955.         return NULL;
  2956.         }
  2957.  
  2958.     hh->filehandle = hfh;
  2959.  
  2960.     return hh;
  2961. }
  2962.  
  2963. void kill_helpspace(struct help_handle *hh)
  2964. /*
  2965. ** cleans up after make_helpspace
  2966. **
  2967. */
  2968. {
  2969.     if (hh->filehandle == 0) return;
  2970.  
  2971.     free(hh->arryptr);
  2972.     close(hh->filehandle);
  2973.  
  2974.     hh->filehandle=0;
  2975.     return;
  2976. }
  2977.  
  2978. int display_help (struct help_handle * hh, int index)
  2979. /*
  2980. ** displays a help screen in the help window.
  2981. **
  2982. */
  2983. {
  2984. char *bufptr;
  2985. unsigned int i, crloc;
  2986. int breakflag=0;
  2987. int lincount=0;
  2988. unsigned int linoff;
  2989. unsigned int bytesread;
  2990.  
  2991.     if (hh->filehandle == 0){
  2992.         winprintstring(&help, 4, 7, NOHELPFILESTRING1);
  2993.         winprintstring(&help, 4, 8, NOHELPFILESTRING2);
  2994.         return 0;
  2995.         }
  2996.  
  2997.     /* make a line buffer */
  2998.     if((bufptr= (char*) malloc(HWIDTH+1)) == NULL)
  2999.         return 0;    /* loser */
  3000.  
  3001.  
  3002.     /* find location in file */
  3003.     lseek( hh->filehandle, hh->chapter_offsets[index], 0);
  3004.  
  3005.     /* read-in loop */
  3006.  
  3007.     do{
  3008.         /* read in a line */
  3009.         bytesread=read(hh->filehandle, bufptr, HWIDTH);
  3010.  
  3011.         /* find first cr */
  3012.         for(i=0;i<bytesread;i++){
  3013.             if(*(bufptr+i)==CR){
  3014.                 crloc=i;
  3015.                 break;
  3016.                 }
  3017.             }
  3018.         /* look for end of section mark */
  3019.         if (*(bufptr+(crloc+2)) == 0x017)
  3020.             breakflag=1;
  3021.  
  3022.         /* fix file pointer */
  3023.         lseek(hh->filehandle,    \
  3024.             (signed)((crloc+2)-bytesread),1);
  3025.  
  3026.         linoff=lincount*HWIDTH;
  3027.  
  3028.         /* copy to real array */
  3029.         for(i=0;i<crloc;i++)
  3030.             *((hh->arryptr)+linoff+i)=*(bufptr+i);
  3031.         /* zero out rest of line */
  3032.         for(;i<HWIDTH;i++)
  3033.             *((hh->arryptr)+linoff+i)=0;
  3034.  
  3035.         lincount++;
  3036.  
  3037.         } while (!breakflag);
  3038.  
  3039.     act_h_h=lincount;
  3040.     free(bufptr);
  3041.  
  3042.     /* clean out help window, if neccesary */
  3043.     if(act_h_h<20)
  3044.         win_erase_region(&help, 0, 0, 30, 19);
  3045.  
  3046.     link_array(&help, hh->arryptr, HWIDTH, act_h_h, 0, 0); 
  3047.  
  3048.     return 1;
  3049.  
  3050. }
  3051.  
  3052. int makeixgraphs(win_handle * winptr, void** lp, int which)
  3053. /*
  3054. ** Makes index graphs. Which means 286 (0) or 386 (1).
  3055. */
  3056. {
  3057. char titlestring[34];
  3058. int curroff, baseoff;
  3059. int numgraphs;
  3060. int i;
  3061. int xs[4];
  3062. int ys[4];
  3063. int ws[4];
  3064.  
  3065.  
  3066.     if (which==1){
  3067.         strcpy(titlestring, "Performance Indexes / 386 Class");
  3068.         baseoff=offset_in_struc(db_rec, cpu386);
  3069.         }
  3070.     else{
  3071.         strcpy(titlestring, "Performance Indexes / AT Class");
  3072.         baseoff=offset_in_struc(db_rec, cpuat);
  3073.         }
  3074.  
  3075.     mk_window(winptr,titlestring, 0, 0, 82, 27, BLACK, WHITE,
  3076.                   BLACK, WHITE, 0, 0);
  3077.  
  3078.     /* how many ? */
  3079.     curroff=lin_search_db(0, recs_in_db-1,lp,    \
  3080.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  3081.     numgraphs=0;
  3082.     for(i=0;i<(4*(sizeof(double)));i+=sizeof(double)){
  3083.         if(*((double*)((char*)(*(lp+curroff))+(baseoff+i)))!=0)
  3084.             numgraphs++;
  3085.         }
  3086.  
  3087.     /* determine positions and widths */
  3088.  
  3089.     switch (numgraphs){
  3090.         case 0: return 0;
  3091.         case 1: xs[0]=0; ys[0]=6; ws[0]=78;
  3092.             break;
  3093.         case 2: xs[0]=0; ys[0]=1; ws[0]=78;
  3094.             xs[1]=0; ys[1]=12; ws[1]=78;
  3095.             break;
  3096.         case 3: xs[0]=0; ys[0]=1; ws[0]=39;
  3097.             xs[1]=40; ys[1]=1; ws[1]=39;
  3098.             xs[2]=0; ys[2]=12; ws[2]=78;
  3099.             break;
  3100.         case 4: xs[0]=0; ys[0]=1; ws[0]=39;
  3101.             xs[1]=40; ys[1]=1; ws[1]=39;
  3102.             xs[2]=0; ys[2]=12; ws[2]=39;
  3103.             xs[3]=40; ys[3]=12; ws[3]=39;
  3104.             break;
  3105.         }
  3106.  
  3107.     /* guess and graph the screens */
  3108.     i=0;
  3109.     if(*((double*)((char*)(*(lp+curroff))+baseoff))!=0){
  3110.         curroff=graph("CPU Indexes",winptr, xs[i], ys[i], ws[i], lp,\
  3111.             baseoff, "Normalized Units");
  3112.         i++;
  3113.         }
  3114.     if(*((double*)((char*)(*(lp+curroff))+(baseoff+sizeof(double))))!=0){
  3115.         curroff=graph("FPU Indexes",winptr, xs[i], ys[i], ws[i], lp,\
  3116.               (baseoff+sizeof(double)),  "Normalized Units");
  3117.         i++;
  3118.         }
  3119.     if(*((double*)((char*)(*(lp+curroff))+    \
  3120.             (baseoff+(2*sizeof(double)))))!=0){
  3121.         curroff=graph("Disk Indexes",winptr, xs[i], ys[i], ws[i], lp,\
  3122.             (baseoff+(2*sizeof(double))),     \
  3123.              "Normalized Units");
  3124.         i++;
  3125.         }
  3126.     if(*((double*)((char*)(*(lp+curroff))+    \
  3127.             (baseoff+(3*sizeof(double)))))!=0){
  3128.         graph("Video Indexes",winptr, xs[i], ys[i], ws[i], lp,\
  3129.             (baseoff+(3*sizeof(double))),     \
  3130.              "Normalized Units");
  3131.         i++;
  3132.         }
  3133.  
  3134.     return 1;
  3135.  
  3136. }
  3137.  
  3138. void edit_data(void** listptr)
  3139. /*
  3140. ** puts up a select box. 
  3141. **
  3142. */
  3143. {
  3144. win_handle edat;
  3145. win_handle keylist;
  3146. win_handle sortwin;
  3147. win_handle messwin;
  3148. int edatresp;
  3149. int choice;
  3150. int def;
  3151. int badnameflag;
  3152. int eraser;
  3153. int dontstop;
  3154. int redispflag;
  3155. int comps[2];
  3156. int curroff, oldcurr;
  3157. int lastchange=1;
  3158. int datachanged=0;
  3159. int soff;
  3160. int sortcrit=0;
  3161. int sr;
  3162.  
  3163. int i;
  3164. char tempstring[80];
  3165.  
  3166.     /* initialize */
  3167.     for (i=0;i<80;i++) tempstring[i]=0;
  3168.     keylist.made=edat.made=0;
  3169.     sortwin.num_valid=8;
  3170.     sortwin.valid_lines=sortwin_valid_lines;
  3171.  
  3172.     mk_window(&keylist, NULL, 0, 21, 79, 26, BLACK,CYAN,BLACK,CYAN,    \
  3173.           0,0);
  3174.  
  3175.     mk_window(&edat, "Comparison Machines", 0, 0, 79, 22, GREEN, WHITE,
  3176.                   BLACK, GRAY, 1, 0);
  3177.  
  3178.     winprintstring(&keylist, 0,  0, " Esc - Previous Menu");
  3179.     winprintstring(&keylist, 26, 0, " Del - Delete Entry");
  3180.     winprintstring(&keylist, 46, 0, " Ins - Add Current to Defaults");
  3181.     winprintstring(&keylist, 0,  1, " ^W  - Write as text file");
  3182.     winprintstring(&keylist, 26, 1, " ^S  - Sort ...");
  3183.     winprintstring(&keylist, 46, 1, " Enter - Choose comparison (*)");
  3184.  
  3185.     winprintstring(&edat, 0, 0, DBTITLESTRING);
  3186.  
  3187.     /****** go into big loop ********/
  3188.     edat.valid_lines=edat_valid_lines;
  3189.     soff=offset_in_struc(db_rec,comp);
  3190.     def=0;
  3191.     redispflag=1;
  3192.     while(TRUE){
  3193.         if(redispflag){
  3194.  
  3195.             eraser= (recs_in_db==18) ? 18 : recs_in_db+1;
  3196.             win_erase_region(&edat, 0, 2, 77, eraser);
  3197.  
  3198.             sort_db(recs_in_db, listptr,    \
  3199.                  (offset_in_struc(db_rec,cpuat)    \
  3200.                 +sortcrit*sizeof(double)),    \
  3201.                  FLOATCODE);
  3202.             for(i=0;i<recs_in_db;i++){
  3203.                 dbrec2string((db_rec *) *(listptr+i),    \
  3204.                     tempstring);
  3205.                 winprintstring(&edat, 0, i+2, tempstring);
  3206.                 }
  3207.             edat.num_valid=i;
  3208.  
  3209.             for(i=0;i<2;i++){
  3210.                 comps[i]=lin_search_db(0,recs_in_db-1,listptr,                        soff, INTCODE, (i+1));
  3211.                 if (comps[i]>=0)
  3212.                  winputch(&edat,15,    \
  3213.                     edat.valid_lines[comps[i]],'*');
  3214.                 }
  3215.  
  3216.             redispflag=0;
  3217.             }
  3218.  
  3219.         edatresp=get_resp_line(&edat, def, 0,CYAN, WHITE, &choice, 0);
  3220.         if((choice==1) && (edatresp==-1)){
  3221.             break;
  3222.             }
  3223.         switch(choice){
  3224.             case 1 : /* enter */
  3225.                 def=edatresp;
  3226.                 curroff=lin_search_db(0,recs_in_db-1,listptr,                      offset_in_struc(db_rec,currflag),INTCODE, 1);
  3227.                 if(edatresp==curroff){
  3228.                     alert_box(    \
  3229.                     "Can't select current machine",0,0,2);
  3230.                     break;
  3231.                 }
  3232.  
  3233.                 datachanged=1;
  3234.                 graphstale=1;
  3235.  
  3236.                 comps[0]=lin_search_db(0,recs_in_db-1,listptr,                        soff, INTCODE, 1);
  3237.                 comps[1]=lin_search_db(0,recs_in_db-1,listptr,                        soff, INTCODE, 2);
  3238.                 /* turn off */
  3239.                    if((edatresp==comps[0])||(edatresp==comps[1])){
  3240.                      winputch(&edat,15,    \
  3241.                     edat.valid_lines[edatresp],' ');
  3242.                     update_db(edatresp, listptr, soff,    \
  3243.                         INTCODE, (int) 0 );
  3244.                     if((edatresp==comps[0])    \
  3245.                         &&(comps[1]>(-1)))
  3246.                         update_db(comps[1],listptr,    \
  3247.                             soff,INTCODE, (int) 1 );
  3248.                     break;
  3249.                     }
  3250.                 /* turn off and turn on */
  3251.                 if((comps[0]>(-1)) && (comps[1]>(-1))){
  3252.                     lastchange=(lastchange)? 0 : 1;
  3253.                      winputch(&edat,15,    \
  3254.                     edat.valid_lines[comps[lastchange]],    \
  3255.                     ' ');
  3256.                     update_db(comps[lastchange],    \
  3257.                         listptr, soff,    \
  3258.                         INTCODE, (int) 0 );
  3259.                      winputch(&edat,15,    \
  3260.                      edat.valid_lines[edatresp],    \
  3261.                     '*');
  3262.                     update_db(edatresp,listptr, soff,    \
  3263.                         INTCODE, (lastchange+1) );
  3264.                     break;
  3265.                     }
  3266.                 /* turn on */
  3267.                    winputch(&edat,15,edat.valid_lines[edatresp], \
  3268.                     '*');
  3269.                 i=(comps[0]>-1)? 2: 1;
  3270.                 update_db(edatresp,listptr, soff,    \
  3271.                     INTCODE, i );
  3272.                 lastchange=(i-1);
  3273.                 break;
  3274.             case DEL:
  3275.                 curroff=lin_search_db(0,    \
  3276.                     recs_in_db-1,listptr,    \
  3277.                      offset_in_struc(db_rec,currflag),    \
  3278.                        INTCODE, 1);
  3279.                 if(edatresp==curroff){
  3280.                     alert_box(    \
  3281.                     "Can't delete current machine",    \
  3282.                          0,0,2);
  3283.                     def=edatresp;
  3284.                     break;
  3285.                     }
  3286.                 if ((((db_rec*)(*(listptr+edatresp)))    \
  3287.                      ->basenum)>0){
  3288.                     alert_box(    \
  3289.                     "Can't delete baseline", 0,0,2);
  3290.                     def=edatresp;
  3291.                     break;
  3292.                     }
  3293.                 if(!alert_box(    \
  3294.                     "Confirm: Delete Record?[y/n]",    \
  3295.                      YESNO, 0, 2)){
  3296.                     def=edatresp;
  3297.                     break;
  3298.                     }
  3299.  
  3300.                 graphstale=1;
  3301.  
  3302.                 if     \
  3303.                 ((((db_rec*)(*(listptr+edatresp)))->comp)==1){
  3304.                     comps[1]=lin_search_db(0,    \
  3305.                         recs_in_db-1,listptr,    \
  3306.                         soff, INTCODE, 2);
  3307.                     if(comps[1]>(-1)){
  3308.                         update_db(comps[1],    \
  3309.                         listptr, soff,    \
  3310.                         INTCODE, (int) 1 );
  3311.                         }
  3312.                     lastchange=0;
  3313.                     }
  3314.                 if     \
  3315.                 ((((db_rec*)(*(listptr+edatresp)))->comp)==2){
  3316.                     lastchange=0;
  3317.                     }
  3318.     
  3319.                 free (*(listptr+edatresp));
  3320.                 for(i=edatresp;i<recs_in_db-1;i++){
  3321.                     *(listptr+i)=*(listptr+i+1);
  3322.                     }
  3323.                 *(listptr+i)=NULL;
  3324.                 recs_in_db--;
  3325.                 def=0;
  3326.                 redispflag=1;
  3327.                 datachanged=1;
  3328.                 break;
  3329.             case INS:
  3330.                 def=edatresp;
  3331.                 if(recs_in_db==18){
  3332.                    alert_box(    \
  3333.                    "No more room. Please delete an entry.",    \
  3334.                     0,1, 3);
  3335.                     break;
  3336.                     }
  3337.                 dontstop=1;
  3338.                 do{
  3339.                    badnameflag=0;
  3340.                    for(i=0;i<recs_in_db;i++){
  3341.                     if(!strcmp(machine_config.machine_name,
  3342.                     (((db_rec*)(*(listptr+i)))->name))){
  3343.                         if (!(((db_rec*)    \
  3344.                         (*(listptr+i)))->currflag)){
  3345.                             badnameflag=1;
  3346.                             break;
  3347.                             }
  3348.                         }
  3349.                     }
  3350.                    if(!strcmp(machine_config.machine_name,    \
  3351.                     NAMEDEF))
  3352.                     badnameflag=1;
  3353.                    if(badnameflag){
  3354.                        dontstop=mod_default_box(    \
  3355.                           machine_config.machine_name,    \
  3356.                           15,    \
  3357.                         "Name Conflicts. Please Rename:");
  3358.                     }
  3359.                    }while(badnameflag&&(dontstop));
  3360.                 if(!dontstop) break;
  3361.  
  3362.                 graphstale=1;
  3363.  
  3364.                 def=0;
  3365.                 redispflag=1;
  3366.                 machtodb((db_rec**)listptr, recs_in_db,    \
  3367.                      &machine_config);
  3368.                 recs_in_db=add_entry_db( 18,    \
  3369.                   recs_in_db,(db_rec**)listptr, machname);
  3370.                 oldcurr=lin_search_db(0,    \
  3371.                     recs_in_db-1,listptr,    \
  3372.                      offset_in_struc(db_rec,name),    \
  3373.                        CHARPTRCODE,     \
  3374.                     (int) machine_config.machine_name);
  3375.                 curroff=lin_search_db(0,    \
  3376.                     recs_in_db-1,listptr,    \
  3377.                      offset_in_struc(db_rec,currflag),    \
  3378.                        INTCODE, 1);
  3379.                 dup_rec(listptr, curroff, oldcurr);
  3380.                 /* duplication fixes */
  3381.                 update_db(curroff,listptr,    \
  3382.                     offset_in_struc(db_rec, currflag) ,    \
  3383.                     INTCODE, 1);
  3384.                 update_db(curroff,listptr,    \
  3385.                     offset_in_struc(db_rec, name) ,    \
  3386.                     CHARPTRCODE, (int) machname);
  3387.                 strcpy(machine_config.machine_name, machname);
  3388.                 sort_db(recs_in_db, listptr,    \
  3389.                      offset_in_struc(db_rec,currflag),    \
  3390.                      INTCODE);
  3391.                 dump_db(recs_in_db-1,    \
  3392.                     ((db_rec**)listptr+1),"bbcomp.dat");
  3393.                 def=0;
  3394.                 redispflag=1;
  3395.                 datachanged=1;
  3396.                 break;
  3397.             case CTRLW:
  3398.                 filedb((db_rec**)listptr);
  3399.                 def=edatresp;
  3400.                 break;
  3401.             case CTRLS:
  3402.                 sortwin.made=0;
  3403.                 mk_window(&sortwin, NULL, 59, 7, 73,    \
  3404.                      19, CYAN, WHITE,CYAN, BLUE, 1, 0);
  3405.                 winprintstring(&sortwin, 1, 0, "Sort On:");
  3406.                 winprintstring(&sortwin, 3, 2, "CPU-AT");
  3407.                 winprintstring(&sortwin, 3, 3, "FPU-AT");
  3408.                 winprintstring(&sortwin, 3, 4, "Dsk-AT");
  3409.                 winprintstring(&sortwin, 3, 5, "Vid-AT");
  3410.                 winprintstring(&sortwin, 3, 6, "CPU-386");
  3411.                 winprintstring(&sortwin, 3, 7, "FPU-386");
  3412.                 winprintstring(&sortwin, 3, 8, "Dsk-386");
  3413.                 winprintstring(&sortwin, 3, 9, "Vid-386");
  3414.                 sr=get_resp_line(&sortwin,    \
  3415.                      0, 3, BLUE, WHITE, 0, 0);
  3416.                 sortcrit=(sr<0) ? sortcrit : sr;
  3417.                 kill_window(&sortwin);
  3418.                 def=0;
  3419.                 redispflag=1;
  3420.                 break;
  3421.             default:
  3422.                 def=edatresp;
  3423.                 break;
  3424.             }
  3425.     }
  3426.  
  3427.     if(datachanged){
  3428.         messwin.made=0;
  3429.         mk_window(&messwin,NULL,25,8,40,11,GREEN,    \
  3430.              WHITE,GREEN,WHITE,1,0);
  3431.         winprintstring(&messwin, 3, 0, "Saving...");
  3432.         sort_db(recs_in_db, listptr,    \
  3433.              offset_in_struc(db_rec,currflag),INTCODE);
  3434.         dump_db(recs_in_db-1, ((db_rec**)listptr+1),"bbcomp.dat");
  3435.         kill_window(&messwin);
  3436.         staleflag=1;
  3437.         }
  3438.  
  3439.     kill_window(&edat);
  3440.     kill_window(&keylist);
  3441.     return;
  3442. }
  3443.  
  3444. char* dbrec2string( db_rec* rptr, char * string)
  3445. /*
  3446. ** converts a database record to a string. Puts the results in string.
  3447. */
  3448. {
  3449.  
  3450.     if(!(rptr->cpuat||rptr->fpuat||rptr->diskat||    \
  3451.         rptr->videoat||rptr->cpu386||rptr->fpu386||rptr->disk386||    \
  3452.         rptr->video386)){
  3453.         sprintf(string,    NODATASTRING, rptr->name);
  3454.         return string;
  3455.         }
  3456.  
  3457.     sprintf(string,    \
  3458.         "%14s   %6.2f %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f",\
  3459.         rptr->name, rptr->cpuat,rptr->fpuat,rptr->diskat,    \
  3460.         rptr->videoat,rptr->cpu386,rptr->fpu386,rptr->disk386,    \
  3461.         rptr->video386);
  3462.     return string;
  3463. }
  3464.  
  3465. void machtodb(db_rec ** listptr, char num_recs, struct mcfig * machdata)
  3466. /*
  3467. ** stuffs the current machine stuff into the current database entry.
  3468. **
  3469. */
  3470. {
  3471. int curroff;
  3472.  
  3473.     curroff=lin_search_db(0, num_recs-1,(void**) listptr,    \
  3474.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  3475.  
  3476.     (*(listptr+curroff))->proc=machdata->proc_type;
  3477.     (*(listptr+curroff))->mhz=machdata->MHz;
  3478.     strcpy(((*(listptr+curroff))->name),(machdata->machine_name));
  3479.  
  3480. }
  3481.  
  3482. int get_filename(int *fhptr, char * nameptr)
  3483.  
  3484. {
  3485.  
  3486. int yn;
  3487.  
  3488.     /* prompt for filename */
  3489.     while(TRUE){
  3490.         if(!(mod_default_box(nameptr, 80, "Name the file")))
  3491.             return 0;
  3492.         if (!validpath(nameptr)){
  3493.             alert_box("Path dosen't exist. Try Again.", 0,0,2);
  3494.             continue;
  3495.             }
  3496.         if (!validfname(nameptr)){
  3497.             alert_box("Bad filename. Try Again.", 0,0,2);
  3498.             continue;
  3499.             }
  3500.         break;
  3501.         }
  3502.  
  3503.     /*determine whether or not it exists*/
  3504.     if((*(fhptr)=open(nameptr,    \
  3505.         O_WRONLY|O_BINARY|O_CREAT|O_EXCL,S_IWRITE))==-1){
  3506.         if(errno==EEXIST){
  3507.             yn=alert_box("Overwrite Existing File? [y,n]",    \
  3508.                 YESNO, 0,2);
  3509.             if(yn){
  3510.                 if((*(fhptr)=open(nameptr, O_WRONLY|    \
  3511.                   O_BINARY|O_CREAT|O_TRUNC,S_IWRITE))==-1){
  3512.                     alert_box("File Write Error",0,1,3);
  3513.                     close(*(fhptr));
  3514.                     return 0;
  3515.                     }
  3516.                 }
  3517.             else
  3518.                 return 0;
  3519.             }
  3520.         else{
  3521.             alert_box("File Write Error", 0, 1,3);
  3522.             close(*(fhptr));
  3523.             return 0;
  3524.             }
  3525.         }
  3526.     return 1;
  3527.  
  3528. }
  3529.  
  3530.  
  3531. void filedb(db_rec ** listptr)
  3532. /* dumps the db as a textfile */
  3533. {
  3534.  
  3535. int dbfh;
  3536. int i;
  3537. char tstring[80];
  3538. char crlfbuf[2];
  3539.  
  3540. crlfbuf[0]=CR;
  3541. crlfbuf[1]=LF;
  3542.  
  3543.     if(!get_filename(&dbfh, dbtxname)) return;
  3544.  
  3545.     sprintf(tstring, DBTITLESTRING);
  3546.     strip0s(tstring, 80);
  3547.     if(write(dbfh, tstring, 77) < 77){
  3548.             close (dbfh);
  3549.             alert_box("File Write Error", 0, 1,3);
  3550.             return;
  3551.             }
  3552.     write(dbfh, crlfbuf, 2);
  3553.     write(dbfh, crlfbuf, 2);
  3554.  
  3555.     for(i=0;i<recs_in_db;i++){
  3556.         dbrec2string(*(listptr+i),tstring);
  3557.         if((*(listptr+i))->comp) tstring[15]='*';
  3558.         strip0s(tstring,80);
  3559.         if(write(dbfh, tstring, 77) < 77){
  3560.                 close (dbfh);
  3561.                 alert_box("File Write Error", 0, 1,3);
  3562.                 return;
  3563.                 }
  3564.         write(dbfh, crlfbuf, 2);
  3565.         }
  3566.     close(dbfh);
  3567.     return;
  3568.  
  3569. }
  3570.  
  3571. int batchgraph (void ** listptr, int which)
  3572. /*
  3573. ** This sets up all the graphs in a window, determined by which. This was
  3574. ** set up so execute and reviewmode can both update graph windows.
  3575. ** Returns current offset.
  3576. */
  3577. {
  3578. int curval;
  3579. int gx, gy, gw;
  3580.  
  3581. if(which==1){
  3582.  
  3583.     graph("BYTE Sieve",&cpuwin, 0, 1, 39, listptr,    \
  3584.         offset_in_struc(db_rec, sieveres), \
  3585.         "Iterations per second ");
  3586.     graph("BYTE Sort",&cpuwin, 40, 1, 39, listptr,    \
  3587.         offset_in_struc(db_rec, sortres),     \
  3588.         "Iterations per second ");
  3589.     graph("BYTE Int. Math",&cpuwin, 0, 12, 39, listptr,    \
  3590.         offset_in_struc(db_rec, imathres),     \
  3591.         "Iterations per second ");
  3592.     curval=    \
  3593.     graph("BYTE Byte-wide move",&cpuwin, 40, 12, 39, listptr,    \
  3594.         offset_in_struc(db_rec, movbres),     \
  3595.         "Iterations per second ");
  3596.     }
  3597.  
  3598.  
  3599. if(which==2){
  3600.     if(lastproc>286){
  3601.         gw=39;    gx=40; gy=1;
  3602.         }
  3603.     else{
  3604.         gw=78;    gx=0; gy=12;
  3605.         }
  3606.  
  3607.     graph("BYTE Word-Odd Move",&cpu2win, 0, 1, gw, listptr,    \
  3608.         offset_in_struc(db_rec, movwores),     \
  3609.         "Iterations per second ");
  3610.     graph("BYTE Word-Even Move",&cpu2win, gx, gy, gw, listptr,    \
  3611.         offset_in_struc(db_rec, movweres),     \
  3612.         "Iterations per second ");
  3613.  
  3614.     if(lastproc>286){
  3615.  
  3616.         graph("BYTE DWord-Odd Move",&cpu2win, 0, 12, 39, listptr,    \
  3617.             offset_in_struc(db_rec, movdores),     \
  3618.             "Iterations per second ");
  3619.         curval=    \
  3620.         graph("BYTE DWord-Even Move",&cpu2win, 40, 12, 39, listptr,    \
  3621.             offset_in_struc(db_rec, movderes),     \
  3622.             "Iterations per second ");
  3623.         }
  3624.     }
  3625.  
  3626. if(which==3){
  3627.     graph("BYTE Fmath",&fpuwin, 0, 1, 78, listptr,    \
  3628.         offset_in_struc(db_rec, fourbangres),     \
  3629.         "Iterations per second ");
  3630.     curval=    \
  3631.     graph("BYTE Fourier",&fpuwin, 0, 12, 78, listptr,    \
  3632.         offset_in_struc(db_rec, forres),     \
  3633.         "Iterations per second ");
  3634.         }
  3635.  
  3636. if(which==4){
  3637.     graph("BYTE File I/O Read",&diskwin, 0, 1, 39, listptr,    \
  3638.         offset_in_struc(db_rec, fiorres),     \
  3639.         "Kilobytes per second ");
  3640.     graph("BYTE File I/O Write",&diskwin, 40, 1, 39, listptr,    \
  3641.         offset_in_struc(db_rec, fiowres),     \
  3642.         "Kilobytes per second ");
  3643.     graph("BYTE Throughput",&diskwin, 0, 12, 39, listptr,    \
  3644.         offset_in_struc(db_rec, tpres),     \
  3645.         "Kilobytes per second ");
  3646.     curval=    \
  3647.     graph("BYTE Seek Test",&diskwin, 40, 12, 39, listptr,    \
  3648.         offset_in_struc(db_rec, seekres),     \
  3649.         "Milliseconds ");
  3650.     }
  3651.  
  3652. if(which==5){
  3653.     graph("BYTE Text Display",&vidwin, 0, 1, 39, listptr,    \
  3654.         offset_in_struc(db_rec, txposres),     \
  3655.         "Iterations per second ");
  3656.     graph("BYTE Text Scroll",&vidwin, 40, 1, 39, listptr,    \
  3657.         offset_in_struc(db_rec, txscrollres),     \
  3658.         "Iterations per second ");
  3659.     curval=    \
  3660.     graph("BYTE Graphics",&vidwin, 0, 12, 78, listptr,    \
  3661.         offset_in_struc(db_rec, graphres),     \
  3662.         "Iterations per second ");
  3663.     }
  3664.  
  3665. return curval;
  3666.  
  3667. }
  3668.  
  3669. int optparse(unsigned char * optarray, char* valarray, char **strargs,
  3670.      unsigned int numopt, int argc, char** argv)
  3671. /* 
  3672. ** command line parser. optarray comes in filled with zeros; positions
  3673. ** correspond to valid string pointers in vallarray. 
  3674. ** if strargs is null, no associated string. numop elements.
  3675. ** On return, optarray has ones in positions that are set; 
  3676. ** strargs points to strings that are placed on command line ( filenames, for
  3677. ** example).
  3678. **
  3679. ** options are always designated by '/'s or '-'s.
  3680. **
  3681. ** returns 1 on success, 0 on invalid option
  3682. **
  3683. */
  3684.  
  3685. {
  3686. char argstring[80];
  3687. int arglen;
  3688. int i, j;
  3689. int lastslash;
  3690.  
  3691.     if(argc<2) return 1;    /* nothing to do */
  3692.     strcpy(argstring, argv[1]);
  3693.     strcat(argstring, "\xff");
  3694.     for (i=2; i<argc; i++){
  3695.         strcat(argstring, argv[i]);
  3696.         strcat(argstring, "\xff");
  3697.         }
  3698.  
  3699.     arglen=strlen(argstring);
  3700.     argstring[arglen]=-1;
  3701.     arglen++;
  3702.     argstring[arglen]=-1;
  3703.     arglen++;
  3704.  
  3705.     if( (*(argstring) != '/')&&(*(argstring) != '-'))  return 0; 
  3706.     lastslash=1;
  3707.     for(i=1; i<arglen; i++){
  3708.         for (j=0;j<numopt;j++){
  3709.             if(valarray[j] == tolower(*(argstring+i))){
  3710.                 optarray[j]++;
  3711.                 if (strargs[j]!=NULL){
  3712.                       if(*(argstring+i+1)==-1)
  3713.                      i++;
  3714.                       i+=ffcopy(strargs[j], argstring+i+1);
  3715.                       }
  3716.                 lastslash=0;
  3717.                 break;
  3718.                 }
  3719.             }
  3720.         if(j!=numopt) continue;
  3721.         if(*(argstring+i)== -1) continue;
  3722.         if(lastslash||((*(argstring+i)!='/')    \
  3723.            &&(*(argstring+i)!='-')))
  3724.             return 0;
  3725.         lastslash=1;
  3726.         }
  3727.  
  3728.     return 1;
  3729. }
  3730.  
  3731. int ffcopy( char * dest, char * source)
  3732. {
  3733. int i;
  3734.     for (i=0;*(source+i)!=-1;i++)
  3735.         *(dest+i)=*(source+i);
  3736.     *(dest+i)=0;
  3737.     return i;
  3738. }
  3739.  
  3740. void switchlist(void)
  3741.  
  3742. {
  3743.     printf("\n BBENCH -- BYTE DOS Benchmarks version 2.1\n");
  3744.     printf(" BYTE Magazine, Spring 1990\n\n");
  3745.  
  3746.     printf("Valid switches:\n");
  3747.     printf("   /n \"machine name\" -- Set default name for test machine\n");
  3748.     printf("   /r [resfile.nam] -- Generate results report\n");
  3749.     printf("   /c -- Run CPU tests immediately\n");
  3750.     printf("   /f -- Run FPU tests immediately\n");
  3751.     printf("   /d -- Run disk tests immediately\n");
  3752.     printf("   /v -- Run video tests immediately\n");
  3753.     printf("   /a -- Run all tests immediately (same as /cfdv)\n");
  3754.     printf("   /h -- Display this screen\n");
  3755.  
  3756. }
  3757.  
  3758. int  delimres (void** lp)
  3759. /*
  3760. ** Creates delimited results file.
  3761. ** zero on failure
  3762. */
  3763. {
  3764. FILE *fh;
  3765. int i;
  3766. int co, i286off, i386off;
  3767. char filname[13];
  3768. char vendorname[80];
  3769. char * productname;
  3770.  
  3771.     strncpy(filname, machname, 8);
  3772.     filname[8]=0;
  3773.     for(i=0; i<strlen(filname) ;i++){
  3774.         if(   (*(filname+i)<=' ') ||
  3775.               (*(filname+i)=='\\') ||
  3776.               ((*(filname+i)>='*')&&(*(filname+i)<=',')) ||
  3777.               (*(filname+i)=='/') ||
  3778.               ((*(filname+i)>=':')&&(*(filname+i)<='?')) ||
  3779.               ((*(filname+i)>='[')&&(*(filname+i)<=']')) ||
  3780.               (*(filname+i)=='|') ||
  3781.               (*(filname+i)>~~ 0x07e)
  3782.             )   *(filname+i)='_';
  3783.         }
  3784.     strcat(filname, ".res");
  3785.  
  3786.     if((fh=(fopen(filname, "w")))==NULL) return 0;
  3787.  
  3788.     co=lin_search_db(0, recs_in_db-1, lp,    \
  3789.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  3790.  
  3791.     /* find 286 baseline */
  3792.     i286off=lin_search_db(0, recs_in_db-1, lp,    \
  3793.         offset_in_struc(db_rec,basenum), INTCODE, 2);
  3794.  
  3795.     /* find 386 baseline */
  3796.     i386off=lin_search_db(0, recs_in_db-1, lp,    \
  3797.         offset_in_struc(db_rec,basenum), INTCODE, 3);
  3798.  
  3799.     /* calculate indices */
  3800.     calc_indexes (lp, co, i286off, i386off);
  3801.  
  3802.     if(machine_config.proc_type>286)
  3803.         fprintf(fh, "%d,", 3);
  3804.     else
  3805.         fprintf(fh, "%d,", 2);
  3806.  
  3807.     /* seperate vendor from product */
  3808.     strcpy(vendorname,machname);
  3809.  
  3810.     for(i=0;i<strlen(vendorname);i++){
  3811.         if (*(vendorname+i)==' '){
  3812.             *(vendorname+i)=0;
  3813.             break;
  3814.             }
  3815.         }
  3816.  
  3817.     productname=vendorname+i+1;
  3818.  
  3819.     fprintf(fh, "\"%s\",", vendorname);
  3820.     fprintf(fh, "\"%s\",", productname);
  3821.     fprintf(fh, "%-6f,", vf(co, sieveres));
  3822.     fprintf(fh, "%-6f,", vf(co, sortres));
  3823.     fprintf(fh, "%-6f,", vf(co, imathres));
  3824.     fprintf(fh, "%-6f,", vf(co, movbres));
  3825.     fprintf(fh, "%-6f,", vf(co, movwores));
  3826.     fprintf(fh, "%-6f,", vf(co, movweres));
  3827.     fprintf(fh, "%-6f,", vf(co, movdores));
  3828.     fprintf(fh, "%-6f,", vf(co, movderes));
  3829.     fprintf(fh, "%-6f,", vf(co, fourbangres));
  3830.     fprintf(fh, "%-6f,", vf(co, forres));
  3831.     fprintf(fh, "%-6f,", vf(co, fiorres));
  3832.     fprintf(fh, "%-6f,", vf(co, fiowres));
  3833.     fprintf(fh, "%-6f,", vf(co, tpres));
  3834.     fprintf(fh, "%-6f,", vf(co, seekres));
  3835.     fprintf(fh, "%-6f,", vf(co, txposres));
  3836.     fprintf(fh, "%-6f,", vf(co, txscrollres));
  3837.     fprintf(fh, "%-6f,", vf(co, graphres));
  3838.     fprintf(fh, "%-6f,", vf(co, cpuat));
  3839.     fprintf(fh, "%-6f,", vf(co, fpuat));
  3840.     fprintf(fh, "%-6f,", vf(co, diskat));
  3841.     fprintf(fh, "%-6f,", vf(co, videoat));
  3842.     fprintf(fh, "%-6f,", vf(co, cpu386));
  3843.     fprintf(fh, "%-6f,", vf(co, fpu386));
  3844.     fprintf(fh, "%-6f,", vf(co, disk386));
  3845.     fprintf(fh, "%-6f", vf(co, video386));
  3846.  
  3847.     fclose(fh);
  3848.  
  3849.     return 1;
  3850. }
  3851.  
  3852.