home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / BYTE24.ZIP / BENCHFAC.C < prev    next >
Text File  |  1993-04-14  |  97KB  |  3,870 lines

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