home *** CD-ROM | disk | FTP | other *** search
- /*«PL1»*/
- /*
- ** Low-level Benchmarks for 80x86 machines.
- ** BYTE Magazine
- ** Apr. 1990
- **
- ** This module contains the high level source for the BYTE benchmarks
- ** Routines called from this module may be found in BENCHSUBS.ASM.
- **
- */
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <dos.h>
- #include <mem.h>
- #include <math.h>
- #include <float.h>
- #include "benchdef.h"
- #include "win.h"
-
- /* Typedefs */
- typedef struct {
- unsigned int maxhead; /* Max head number */
- unsigned int maxcyl; /* Max cylinder number */
- unsigned int sectspertrack; /* Sectors per track */
- } harddiskspecs;
-
- /* external globals */
- extern unsigned long ll_filelen();
- extern volatile struct mcfig machine_config;
- extern int tdef[14];
- extern int oldlen;
-
- /* window prototypes (winsubs.asm)*/
- extern int chattr (win_handle *, int, int, int, int, int, int);
- extern int winputch (win_handle *, int, int, char);
- extern void clearscreen (void);
-
- /* misc prototypes (miscsubs.asm) */
- extern void click(void);
-
- /*local prototypes */
- char *gfname(int);
- long randwc(long);
- long randnum(long);
- double timetodouble( unsigned int *);
- void adjust_bar(win_handle*, int, int);
-
- /****************************
- * sieve *
- *****************************
- ** The (in)famous sieve of Eratosthenes.
- ** Call with:
- ** sieve (winptr,dotime,acttime,iters)
- ** Where:
- ** winptr= handle of window upon which to draw slidey-bar; null means don't
- ** dotime = # of seconds for the system to execute the sieve
- ** Returns:
- ** acttime[3] = pointer to a 3-element array
- ** acttime[0] = # of microseconds actually elapsed
- ** acttime[1] = # of milliseconds actually elapsed
- ** acttime[2] = # of seconds actually elapsed
- ** iters = number of iterations performed in acttime
- */
- sieve(winptr,dotime,acttime,iters)
- win_handle *winptr; /* current window */
- unsigned int dotime; /* Seconds to execute */
- unsigned int acttime[3]; /* Actual elapsed time */
- unsigned int *iters; /* # of iterations performed */
- {
- unsigned int mysegptr; /* Place to hold pointer for segment */
- unsigned int mytime[3]; /* Local for time accumulation */
-
- /* Clear # of iterations and actual time */
- *iters=0;
- acttime[0]=acttime[1]=acttime[2]=0;
-
- /* Get a segment for the array */
- if(allocmem(SIEVESIZE/16+1,&mysegptr)!=-1)
- return; /* Allocation failed */
-
- /* Loop and execute */
- do {
- start_timer();
- /*
- ** NOTE: If you want to see how many primes the do_sieve() function
- ** finds, simply examine its return value. We don't do that here.
- */
- do_sieve(mysegptr,SIEVESIZE);
-
- stop_timer(mytime);
-
- /* Accumulate elapsed time into total time */
- accumtime(mytime,acttime);
-
- *iters+=1; /* Increment iterations */
-
- if(winptr!=NULL)
- adjust_bar(winptr, acttime[2], dotime); /* slide the bar */
-
- } while(acttime[2]<dotime);
-
- /* Free the array segment */
- freemem(mysegptr);
-
- }
-
- /****************************
- * sort *
- *****************************
- ** The Sort benchmark (new and improved!)
- ** Call with:
- ** sort(winptr,dotime,acttime,iters)
- ** Where:
- ** winptr= handle of window upon which to draw slidey-bar; null means don't
- ** dotime = # of seconds to perform the sort
- ** Returns:
- ** acttime[3] = pointer to a 3-element array
- ** acttime[0]=# of microseconds elapsed
- ** acttime[1]=# of milliseconds elapsed
- ** acttime[3]=# of seconds elapsed
- ** iters = # of iterations completed
- **
- ** NOTE: Here, a SINGLE iteration is considered to be 1 pass
- ** of the quick sort and 1 pass of the shell sort.
- */
- sort(winptr, dotime,acttime,iters)
- win_handle *winptr; /* current window */
- unsigned int dotime; /* Time to do iterations */
- unsigned int acttime[3]; /* Actual elapsed time */
- unsigned int *iters; /* # of iterations */
- {
- unsigned int mysegptr; /* Pointer to array segment */
- unsigned int mytime[3]; /* Local for elapsed time */
- unsigned int rarrayseg; /* Pointer to random array */
-
- /* Clear iterations and actual time */
- *iters=0;
- acttime[0]=acttime[1]=acttime[2]=0;
-
- /* Allocate memory segments for the arrays */
- if(allocmem(SORTSIZE/8+1,&mysegptr)!=-1)
- return; /* Return if failure */
- if(allocmem(SORTSIZE/8+1,&rarrayseg)!=-1)
- { freemem(mysegptr);
- return; /* Return if failure */
- }
-
- /* Restart the random number generator */
- randnum(1L);
-
- /* Fill up the random array */
- rload_int_seg(rarrayseg,SORTSIZE,32767);
-
- do {
-
- /* Copy random array into local */
- segcopy(mysegptr,rarrayseg,SORTSIZE+SORTSIZE);
-
- start_timer();
-
- /* Do a quicksort */
- do_qsort(mysegptr,0,SORTSIZE);
-
- stop_timer(mytime);
- accumtime(mytime,acttime);
-
- /* Fill the array again */
- segcopy(mysegptr,rarrayseg,SORTSIZE+SORTSIZE);
-
- start_timer();
-
- /* Do a shellsort */
- do_shell(mysegptr,SORTSIZE);
-
- stop_timer(mytime);
- accumtime(mytime,acttime);
-
- *iters+=1; /* Increment iterations counter */
-
- if(winptr!=NULL)
- adjust_bar(winptr, acttime[2], dotime); /* slide the bar */
-
- } while(acttime[2]<dotime);
-
- /* Free the memory segments */
- freemem(rarrayseg);
- freemem(mysegptr);
-
- }
-
- /****************************
- * movetest *
- *****************************
- ** Executes the string move benchmarks.
- ** Call with:
- ** dotime = max # of seconds for each test
- ** nk = # of K bytes to move
- ** Returns:
- ** acttime[5][3] = Matrix of results. First index picks:
- ** 0=byte-wide
- ** 1=word-wide, odd address
- ** 2=word-wide, even address
- ** 3=dword-wide, odd address
- ** 4=dword-wide, even address
- ** The last two are filled only if is386!=0.
- ** Second index picks 0=micr, 1=milli, 2=seconds.
- ** iters[5] = # of iterations for each test.
- */
- movetest(winptr, dotime,nk,acttime,iters)
- win_handle *winptr; /* current window */
- unsigned int dotime; /* Time to run each test */
- unsigned int nk; /* K bytes to move */
- unsigned int acttime[5][3]; /* Actual elapsed time */
- unsigned int iters[5]; /* Iterations for each test */
- {
- unsigned int ssegptr; /* Source segment */
- unsigned int dsegptr; /* Destination segment */
- unsigned int i,j; /* Index variables */
- unsigned int totloops; /* processor dependent number of loops */
-
- /* Clear out the results arrays */
- for(i=0;i<5;i++)
- { iters[i]=0;
- for(j=0;j<3;j++)
- acttime[i][j]=0;
- }
-
- /* Allocate source and destination segments */
- if(allocmem(nk*64+1,&ssegptr)!=-1) return;
- if(allocmem(nk*64+1,&dsegptr)!=-1)
- { freemem(ssegptr);
- return;
- }
-
- /* Loop through the tests */
-
- /* Can we do 386 stuff? */
- totloops=(machine_config.proc_type>286)? 5:3;
-
- for(i=0; i<totloops; ++i)
- {
- moveloop(i,ssegptr,dsegptr,nk,dotime,acttime,iters);
-
- if(winptr!=NULL)
- adjust_bar(winptr, i+1, totloops); /* slide the bar */
-
- }
-
- /* Free up segments */
- freemem(dsegptr);
- freemem(ssegptr);
-
- return;
- }
-
- /****************************
- * moveloop *
- *****************************
- * Inner loop of movetest
- * i selects which test:
- * 0 = byte wide
- * 1 = word wide odd boundary
- * 2 = word wide even boundary
- * 3 = double word wide odd boundary
- * 4 = double word wide even boundary
- */
-
- moveloop(i,seg1,seg2,nk,dotime,acttime,iters)
- unsigned int i; /* Which test to perform */
- unsigned int seg1; /* Segment 1 (source) */
- unsigned int seg2; /* Segment 2 (destination) */
- unsigned int nk; /* Number of K bytes */
- unsigned int dotime; /* Max seconds to do */
- unsigned int acttime[5][3]; /* Actual elapsed time */
- unsigned int iters[5]; /* Iterations */
- {
- unsigned int nb; /* Number of bytes to move */
- unsigned int nw; /* Number of words to move */
- unsigned int nd; /* Number of doublewords to move */
- unsigned int soff; /* Source offset */
- unsigned int doff; /* Destination offset */
- unsigned int myactime[3]; /* Local for accumulating time */
- unsigned int eltime[3]; /* Local for elapsed time per iteration */
-
- /* Clear accumulators */
- myactime[0]=myactime[1]=myactime[2]=0;
-
- /* Set bytes, words, and doublewords */
- nb=nk*1024; /* Calc number of bytes */
- nw=nb>>1; /* Calc number of words */
- nd=nw>>1; /* Calc number of dwords */
-
- /* Set even/odd boundary */
- soff=doff=0;
- if((i&1)!=0) soff=doff=1;
-
- do {
- /* The i variable tells us which test to perform */
- switch(i) {
-
- case 0: /* Byte wide */
- start_timer();
- do_bmove(seg1,soff,seg2,doff,nb);
- stop_timer(eltime);
- break;
-
- case 1: /* Word wide odd */
- case 2: /* Word wide even */
- start_timer();
- do_wmove(seg1,soff,seg2,doff,nw);
- stop_timer(eltime);
- break;
-
- case 3: /* Dword wide odd */
- case 4: /* Dword wide even */
- start_timer();
- do_dmove(seg1,soff,seg2,doff,nd);
- stop_timer(eltime);
- break;
-
- default:
- break;
-
- } /* End of switch */
-
- accumtime(eltime,myactime);
- iters[i]++;
- } while(myactime[2]<dotime);
-
- acttime[i][0]=myactime[0]; acttime[i][1]=myactime[1];
- acttime[i][2]=myactime[2];
- return;
- }
-
- /****************************
- * ifourbang *
- *****************************
- ** Integer math tests.
- ** Note, n indicates the number of times each 4 operations
- ** (add, subtract, multiply, and divide) are performed.
- ** Maximum is 8192.
- */
- ifourbang(winptr, dotime, n, acttime,iters)
- win_handle *winptr; /* current window handlke */
- unsigned int dotime; /* Seconds to perform operations */
- unsigned int n; /* number of operations */
- unsigned int acttime[3]; /* Actual elapsed time */
- unsigned int *iters; /* Iterations completed */
- {
- unsigned int i; /* Index */
- unsigned int rn; /* Random number */
- unsigned int mysegptr; /* Pointer to working segment */
- unsigned int huge *isegptr; /* Actual pointer to rands */
- unsigned int mytime[3]; /* Local for elapsed time */
-
-
- /* Clear iterations and actual time */
- *iters=0;
- acttime[0]=acttime[1]=acttime[2]=0;
-
- /* Allocate memory segments for the arrays */
- if(allocmem(n/2,&mysegptr)!=-1)
- return; /* Return if failure */
-
- /* Build the random array */
- isegptr=MK_FP(mysegptr,0);
- i=0;
- do {
- if(i==0) *(isegptr+i)=2;
- else *(isegptr+i)=*(isegptr+i-1)+1;
- ++i;
- *(isegptr+i)=*(isegptr+i-1)-1; ++i;
- *(isegptr+i)=*(isegptr+i-1)+2; ++i;
- *(isegptr+i)=*(isegptr+i-1)-1; ++i;
- } while(i<(n*4));
-
- do {
- start_timer();
-
- do_ifourbang(mysegptr,n);
-
- stop_timer(mytime);
- accumtime(mytime,acttime);
- *iters+=1;
-
- if(winptr!=NULL)
- adjust_bar(winptr, acttime[2], dotime); /* slide the bar */
-
- }while(acttime[2]<dotime);
-
- /* Free memory segments */
- freemem(mysegptr);
- }
-
- /****************************
- * ffourbang *
- *****************************
- ** Floating-point version of ifourbang.
- */
- ffourbang(winptr,dotime,acttime,iters)
- win_handle *winptr; /* current window handle */
- unsigned int dotime; /* # of seconds to do the test */
- unsigned int acttime[3]; /* Actual elapsed time */
- unsigned int *iters; /* # of iterations */
- {
- unsigned int mytime[3]; /* Local for elapsed time */
-
- /* Clear iterations and actual time */
- *iters=0;
- acttime[0]=acttime[1]=acttime[2]=0;
-
- do {
- start_timer();
- do_fourbang(FFITERS);
- stop_timer(mytime);
- accumtime(mytime,acttime);
- *iters+=1;
-
- if(winptr!=NULL)
- adjust_bar(winptr, acttime[2], dotime); /* slide the bar */
-
- } while(acttime[2]<dotime);
- }
-
- /****************************
- * fourier *
- *****************************
- ** Calculates fourier coefficients for a square wave.
- */
- fourier(winptr, dotime,acttime,iters)
- win_handle *winptr; /* current window handle */
- unsigned int dotime; /* Time to do test */
- unsigned int acttime[3]; /* Actual elapsed time */
- unsigned int *iters; /* Iterations */
- {
- double coeffs[NCOEFFS*2]; /* Coefficients array */
- unsigned int mytime[3]; /* Local time */
-
- /* Clear iterations and actual time */
- *iters=0;
- acttime[0]=acttime[1]=acttime[2]=0;
-
- do{
- start_timer();
- square_fourier(NCOEFFS,coeffs);
- stop_timer(mytime);
- accumtime(mytime,acttime);
- *iters+=1;
-
- if(winptr!=NULL)
- adjust_bar(winptr, acttime[2], dotime); /* slide the bar */
-
- } while(acttime[2]<dotime);
- }
-
- /****************************
- * textbench *
- *****************************
- ** Random text display benchmark (cursor positioning)
- ** This routine tests appropriate modes.
- */
- textbench(dotime,n,avgips)
- unsigned int dotime; /* # of seconds to do the test */
- unsigned int n; /* # of characters to display */
- double *avgips; /* average iterations per second */
-
- {
- /* Maximum column # */
- unsigned int acttime[3][3]; /* Actual elapsed time */
- unsigned int iters[3]; /* Iterations */
- unsigned int cmax[3]={80,80,80};
- unsigned int modes[3]={2,3,7};
- unsigned int nummodes;
- unsigned int vpage; /* Video page segment */
- unsigned int rcseg; /* Row/column segment number */
- unsigned int attseg; /* Attributes segment */
- int i,j; /* Indices */
- unsigned char far *attsegptr; /* Far pointer to attribute seg */
- unsigned int mytime[3]; /* Local for elapsed time */
-
- /* just for looks */
- clearscreen();
- printf("Preparing text benchmarks ...");
-
- /* set modes according to type */
-
- switch(machine_config.graphics_type){
- case MDA:
- case HERC:
- nummodes=1;
- modes[0]=7;
- break;
- case CGA:
- nummodes=2;
- break;
- case EGAM:
- case EGAC:
- case VGA:
- nummodes=3;
- break;
- }
-
- /* Clear all the accumulators */
- for(i=0;i<3;i++)
- { iters[i]=0;
- for(j=0;j<3;j++)
- acttime[i][j]=0;
- }
- /* Allocate the row/column and attributes segments */
- if(allocmem(n/8+1,&rcseg)!=-1)
- return;
- if(allocmem(n/16+1,&attseg)!=-1)
- { freemem(rcseg);
- return;
- }
-
- /* Restart the random number generator */
- randnum(1L);
-
- /* Fill the attributes segment */
- attsegptr=MK_FP(attseg,0);
- for(i=0;i<n;i++)
- *(attsegptr+i)=(unsigned char)randwc(256L);
-
-
- /* Loop through the tests */
- clearscreen();
- for(i=0;i<nummodes;i++)
- { textbloop(dotime,n,mytime,&iters[i],modes[i],cmax[i],rcseg,attseg);
- acttime[i][0]=mytime[0];
- acttime[i][1]=mytime[1];
- acttime[i][2]=mytime[2];
- }
-
- /* Clean up after yourself */
- freemem(attseg);
- freemem(rcseg);
-
- /* calculate avgips */
-
- *avgips=0;
- for(i=0;i<nummodes;i++){
- *(avgips)+=((double)iters[i])/timetodouble(acttime[i]);
- }
- *avgips/=nummodes;
-
- return;
- }
-
- /****************************
- * textbloop *
- *****************************
- ** Inner loop for the random text benchmark.
- */
- textbloop(dotime,n,acttime,iters,vmode,cmax,rcseg,attseg)
- unsigned int dotime; /* Max seconds to execute */
- unsigned int n; /* Number of entries */
- unsigned int acttime[3]; /* Actual time */
- unsigned int *iters; /* Iterations */
- unsigned int vmode; /* Graphics mode */
- unsigned int cmax; /* Column max */
- unsigned int rcseg; /* Row/column segment */
- unsigned int attseg; /* Attributes segment */
- {
- unsigned int vpage; /* Video page segment */
- unsigned int far *rcsptr; /* Pointer to row/col segment */
- unsigned int eltime[3]; /* Holding for elapsed time */
- unsigned int i; /* Index */
- unsigned int myvmode; /* Saved video mode */
-
- /* just for looks */
- printf("Running random text benchmark ...");
-
- /* Build far pointer */
- rcsptr=MK_FP(rcseg,0);
-
- /* Fill up the row/column segment */
- for(i=0;i<n;i++)
- { *(rcsptr+i)=(unsigned int)(abs((randwc(25L)<<8))+
- abs(randwc((long)cmax)));
- }
-
- /* Determine the video page segment */
- vpage=0;
-
- /* Get the current video mode and save it */
- myvmode=gvmode();
-
- /* Put the system in the proper video mode */
- svmode(vmode);
-
- /* Clear accumulators */
- *iters=0;
- acttime[0]=acttime[1]=acttime[2]=0;
-
- /* Do the benchmark */
- do {
- start_timer();
- random_text(rcseg,attseg,n,vpage);
- stop_timer(eltime);
- accumtime(eltime,acttime);
- *iters+=1; /* Bump iterations */
- svmode(vmode); /* Clear the screen */
- } while(acttime[2]<dotime);
-
- /* Return the system to original mode */
- svmode(myvmode);
-
- return;
- }
-
- /****************************
- * tscroll *
- *****************************
- * Text scrolling benchmark
- */
- tscroll(dotime,n,avgips)
- unsigned int dotime; /* # of seconds to do each test */
- unsigned int n; /* # of characters to display */
- double *avgips; /* average iterations for modes */
- {
- /* Maximum column # */
- unsigned int acttime[3][3]; /* Actual elapsed time */
- unsigned int iters[3]; /* Iterations */
- unsigned int cmax[3]={80,80,80};
- unsigned int modes[3]={2,3,7};
- unsigned int nummodes;
- unsigned int rcseg; /* Row/column/attr segment */
- unsigned int i,j; /* Indices */
- unsigned int mytime[3];
-
- /* set modes according to type */
-
- switch(machine_config.graphics_type){
- case MDA:
- case HERC:
- nummodes=1;
- modes[0]=7;
- break;
- case CGA:
- nummodes=2;
- break;
- case EGAM:
- case EGAC:
- case VGA:
- nummodes=3;
- break;
- }
-
- /* Clear all the accumulators */
- for(i=0;i<3;i++)
- { iters[i]=0;
- for(j=0;j<3;j++)
- acttime[i][j]=0;
- }
-
- /* Allocate memory for the row/column,attribute segments */
- if(allocmem(n*3/8+1,&rcseg)!=-1) return;
-
- /* Restart the random number generator */
- randnum(1L);
-
- /* Loop through the tests */
- for(i=0;i<nummodes;i++)
- {
- scrolloop(dotime,n,mytime,&iters[i],modes[i],cmax[i],rcseg);
- acttime[i][0]=mytime[0];
- acttime[i][1]=mytime[1];
- acttime[i][2]=mytime[2];
- }
-
- /* Clean up after yourself */
- freemem(rcseg);
-
- /* calculate avgips */
-
- *avgips=0;
- for(i=0;i<nummodes;i++){
- *avgips+=(double)iters[i]/timetodouble(acttime[i]);
- }
- *avgips/=nummodes;
-
- return;
- }
-
- /****************************
- * scrolloop *
- *****************************
- * Inner loop for the text scroll benchmark.
- */
- scrolloop(dotime,n,acttime,iters,vmode,cmax,rcseg)
- unsigned int dotime; /* Max seconds to execute */
- unsigned int n; /* Size of rcseg array */
- unsigned int acttime[3]; /* Actual elapsed time */
- unsigned int *iters; /* Iterations completed */
- unsigned int vmode; /* Video mode */
- unsigned int cmax; /* Column max */
- unsigned int rcseg; /* Row/column/attribute segment */
- {
- unsigned int vpage; /* Video page */
- unsigned int far *rcsptr; /* Pointer to row/column segment */
- unsigned int eltime[3]; /* Local for elapsed time */
- unsigned int i,j; /* Indices */
- unsigned int myvmode; /* Local for current video mode */
- unsigned int ulr,ulc,lrr,lrc; /* Corner coordinates for window */
-
- /* just for looks */
- printf("Running scroll benchmark ...");
-
- /* Build the row/column/attributes array */
- rcsptr=MK_FP(rcseg,0);
- for(i=0;i<n;i++)
- {
- j=3*i;
- ulr=(unsigned int)abs(randwc(24L));
- ulc=(unsigned int)abs(randwc((long)(cmax-1)));
- lrr=ulr+(unsigned int)abs(randwc(24L-(long)ulr));
- lrc=ulc+(unsigned int)abs(randwc((long)(cmax-ulc-1)));
- *(rcsptr+j)=(ulr<<8)+ulc;
- *(rcsptr+j+1)=(lrr<<8)+lrc;
- lrc=(unsigned int)abs(randwc(256L)); /* Attributes */
- ulc=(unsigned int)abs(randwc((long)(lrr-ulr+1)));
- *(rcsptr+j+2)=(lrc<<8)+ulc;
- }
-
- /* Set video page */
- vpage=0;
-
- /* Get the current video mode */
- myvmode=gvmode();
-
- /* Put the system in the proper video mode */
- svmode(vmode);
-
- /* Clear the accumulators */
- *iters=0;
- acttime[0]=acttime[1]=acttime[2]=0;
-
- /* Do the benchmark */
- do {
- start_timer();
- scroll_text(rcseg,n>>1,vpage);
- stop_timer(eltime);
- svmode(vmode); /* Clear display */
- *iters+=1; /* Bump iterations */
- accumtime(eltime,acttime);
- } while(acttime[2]<dotime);
-
- /* Return system to original mode */
- svmode(myvmode);
-
- return;
- }
-
- /****************************
- * graph_bench *
- *****************************
- ** Do the graphics filled-circle benchmark.
- ** The results array is a 2-dimensional array that has the following
- ** format:
- ** results[i][j] i -> picks a group
- ** j -> picks member of group.
- ** Each group is 5 elements big.
- ** results[i][0] = mode
- ** results[i][1]= # iterations completed
- ** results[i][2]= microseconds elapsed
- ** results[i][3]= milliseconds elapsed
- ** retuslt[i][4]= seconds elapsed
- */
- graph_bench(dotime, avgips)
- unsigned int dotime; /* Max seconds for each test */
- double *avgips;
- {
- unsigned int results[11][5]; /* Results array */
- int i,j; /* Indices */
- int gatype; /* Graphics adaptor type */
- int mvector[11]; /* Mode vector */
- int nmodes; /* Number of modes in vector */
- int cx,cy; /* Center of circle */
- int color; /* Foreground color */
- unsigned int esseg; /* Graphics segment */
- unsigned int floodseg; /* Segment for flood routine */
- unsigned int acttime[3]; /* Time accumulator */
- unsigned int eltime[3]; /* Elapsed time per loop */
- unsigned int iters; /* Iterations */
- int mymode; /* Storage for current mode */
- union REGS myregs;
- struct SREGS mysregs;
-
- /* Clear results array */
- for(i=0;i<11;i++)
- for(j=0;j<5;j++)
- results[i][j]=0;
-
- /* Allocate memory for the flood segment (16K should be more
- ** than enough) */
- if(allocmem(1024,&floodseg)!=-1) return;
-
- /* Determine what type of graphics adaptor we've got. */
- if((gatype=machine_config.graphics_type)==0) {
- *avgips=0;
- return;
- }
-
- /* Load up the modes vector */
- build_mvector(gatype,&nmodes,mvector);
- if(nmodes==0){
- *avgips=0;
- return;
- }
-
- /* Loop through each of the modes in the vector */
- for(i=0;i<nmodes;i++)
- {
- mymode=gvmode(); /* Get current mode */
- acttime[0]=acttime[1]=acttime[2]=0; /* Clear acc. time */
- iters=0;
- setup_circle(mvector[i],&cx,&cy,&color,&esseg);
- do {
- svmode(mvector[i]);
- /* If graphics mode 4, set pallette */
- if(mvector[i]==4)
- {
- myregs.h.ah=0x0B;
- myregs.x.bx=257;
- intdosx(&myregs,&myregs,&mysregs);
- }
-
- start_timer();
- circle_fill(cx,cy,color,mvector[i],floodseg,esseg);
- stop_timer(eltime);
- accumtime(eltime,acttime);
- iters++;
- } while(acttime[2]<dotime);
- svmode(mymode); /* Restore mode */
-
- /* Put results into results array */
- results[i][0]=mvector[i]; /* Mode */
- results[i][1]=iters; /* Iterations */
- results[i][2]=acttime[0]; /* Microseconds */
- results[i][3]=acttime[1]; /* Milliseconds */
- results[i][4]=acttime[2]; /* Seconds */
- }
-
- /* All done, release the flood segment */
- freemem(floodseg);
-
- /* calculate avgips */
-
- *avgips=0;
- for(i=0;i<nmodes;i++){
- *avgips+=(double)results[i][1]/timetodouble(&results[i][2]);
- }
- *avgips/=nmodes;
-
- return;
- }
-
- /****************************
- * circle_fill *
- *****************************
- * Performs the circle fill algorithm.
- */
- circle_fill(cx,cy,color,mode,floodseg,esseg)
- int cx,cy; /* Coordinates of center */
- int color; /* Foreground color */
- int mode; /* Graphics mode */
- unsigned int floodseg; /* Segment for flood stack */
- unsigned int esseg; /* Grahics segment */
- {
- int radius; /* Circle radius */
- int i; /* Index */
-
- radius=8; /* Starting radius */
-
- /* Draw an initial circle */
- draw_circle(cx,cy,radius,color,mode,esseg);
-
- /* Draw and fill the rest */
- for(i=0;i<NUMCIRC;++i) {
- radius+=8;
- draw_circle(cx,cy,radius,color,mode,esseg);
- do_flood(cx+radius-4,cy,color,mode,floodseg,esseg);
- }
- return;
- }
-
- /****************************
- * setup_circle *
- *****************************
- * Setup variables needed to draw a circle.
- */
- setup_circle(mode,cx,cy,color,esseg)
- int mode; /* Grahics mode */
- int *cx,*cy; /* Center of circle (returned) */
- int *color; /* Color (returned) */
- unsigned int *esseg; /* ES segment for drawing (returned) */
- {
-
- switch(mode) {
-
- case 4:
- case 5: *cx=160;
- *cy=100;
- *color=3;
- *esseg=0xB800;
- return;
- case 6: *cx=320;
- *cy=100;
- *color=1;
- *esseg=0xB800;
- return;
- case 13:
- *cx=160;
- *cy=100;
- *color=7;
- *esseg=0xA000;
- return;
- case 14:
- *cx=320;
- *cy=100;
- *color=15;
- *esseg=0xA000;
- return;
- case 15:
- *cx=320;
- *cy=175;
- *color=1;
- *esseg=0xA000;
- return;
- case 16:
- *cx=320;
- *cy=175;
- *color=3;
- *esseg=0xA000;
- return;
- case 17:
- case 18:
- *cx=320;
- *cy=240;
- *color= (mode==17) ? 1 : 15;
- *esseg=0xA000;
- return;
- case 19:
- *cx=160;
- *cy=100;
- *color=15;
- *esseg=0xA000;
- return;
- case 255:
- *cx=360;
- *cy=174;
- *color=1;
- *esseg=0xB000;
- return;
- }
- }
-
- /****************************
- * build_mvector *
- *****************************
- ** Builds a mode vector.
- ** Pass in a graphics adaptor type, this routine returns a vector
- ** of video modes that the adaptor can support.
- */
- build_mvector(gatype,n,vector)
- int gatype; /* Graphics adaptor type */
- int *n; /* Returned length of vector */
- int vector[]; /* Vector of supported modes */
- {
- int i; /* Index */
-
- switch(gatype) {
- case 0: /* NO graphics adaptor! */
- *n=0;
- return;
-
- case 1: /* VGA */
- vector[0]=4; vector[1]=5; vector[2]=6;
- vector[3]=13; vector[4]=14; vector[5]=15;
- vector[6]=16; vector[7]=17;vector[8]=18;
- vector[9]=19;
- *n=10;
- return;
-
- case 2: /* EGA enhanced */
- vector[0]=4; vector[1]=5; vector[2]=6;
- vector[3]=13; vector[4]=14;
- vector[5]=16;
- *n=6;
- return;
-
- case 3: /* CGA */
- vector[0]=4; vector[1]=5; vector[2]=6;
- *n=3;
- return;
-
- case 4: /* EGA monochrome */
- vector[0]=6; vector[1]=15;
- *n=2;
- return;
-
- case 5: /* Hercules */
- vector[0]=255;
- *n=1;
- return;
-
- case 6: /* MDA */
- default:
- *n=0;
- return;
- }
- }
-
- /****************************
- * do_fileio *
- *****************************
- * Performs the file i/o benchmark.
- */
- do_fileio(winptr,dotime,rbytes,wbytes,accrtime,accwtime,maxbytes)
- win_handle *winptr; /* current window */
- unsigned int dotime; /* User-selected time */
- unsigned long *rbytes; /* Total bytes read */
- unsigned long *wbytes; /* Total bytes written */
- unsigned int accrtime[3]; /* Accumulated read time */
- unsigned int accwtime[3]; /* Accumulated write time */
- unsigned long maxbytes; /* Maximum bytes avail */
- {
- unsigned int buffseg; /* Buffer segment for reading/writing */
- unsigned int i; /* Index */
- char huge *buffptr; /* Pointer to buffer */
- unsigned long mymax; /* My accumulated maximum */
-
- /* Clear all the results */
- *rbytes=0L;
- *wbytes=0L;
- accrtime[0]=accrtime[1]=accrtime[2]=0;
- accwtime[0]=accwtime[1]=accwtime[2]=0;
-
- /* Allocate a buffer segment (if you can) */
- if(allocmem(2500+1,&buffseg)!=-1) return;
- buffptr=(char huge *) MK_FP(buffseg,0);
-
- /* Fill up the memory segment */
- for(i=0;i<40000;i++)
- *buffptr++='A';
-
- /* Initialize maximum */
- mymax=0L;
-
- /* Create the files */
- for (i=0;i<20;i++)
- kreate(i,buffseg,&mymax);
-
- /* Extend them */
- for(i=0;i<20;i++)
- appnd(i,buffseg,&mymax);
-
- randnum(1L);
-
- /* Do random i/o */
- random_fio(winptr,dotime,buffseg,rbytes,wbytes,accrtime,accwtime,
- maxbytes,&mymax);
-
- /* Clean up after yourself */
- freemem(buffseg);
- for(i=0;i<20;i++)
- remove(gfname(i));
-
- return;
- }
-
- /****************************
- * kreate *
- *****************************
- * Create file n. Write the assigned number of bytes to
- * the file and close it. Accumulate the number of bytes
- * written and the aggregate time.
- */
- kreate(n,buffseg,mymax)
- int n; /* File number */
- unsigned int buffseg; /* Pointer to buffer segment */
- unsigned long *mymax; /* Bytes written */
- {
- int fh; /* File handle */
- unsigned int nb; /* # of bytes to write */
- unsigned int wvector[20]={4000,1000,500,2800,2500,
- 1400,8000,8800,300,21111,
- 2000,6000,200,48800,1300,
- 9870,3000,2816,8660,127};
-
- /* Open the file */
- fh=ll_create(gfname(n));
- nb=wvector[n]; /* Number of bytes to write */
- ll_seekwrite(fh,0L,0,buffseg,nb); /* Do the write */
- *mymax+=(unsigned long)nb; /* Accumulate bytes written */
- ll_close(fh); /* Close the file */
- return;
- }
-
- /****************************
- * appnd *
- *****************************
- * This routine opens file n and appends the appropriate number of
- * bytes.
- */
- appnd(n,buffseg,mymax)
- int n; /* File number */
- unsigned int buffseg; /* Buffer segment */
- unsigned long *mymax; /* Total bytes written */
- {
- int fh; /* File handle */
- unsigned int nb; /* Number of bytes */
- unsigned int wvector[20]={1200,2030,31111,3400,9099,
- 2075,7000,400,2200,2700,
- 2360,1495,5960,3430,70,
- 3600,8900,1233,4000,1000};
-
- fh=ll_open(gfname(n)); /* Open the file */
- nb=wvector[n]; /* Number of bytes to write */
- ll_seekwrite(fh,0L,2,buffseg,nb); /* Do the write */
- *mymax+=(unsigned long)nb; /* Accumulate bytes written */
- ll_close(fh); /* Close the file */
- return;
- }
-
- /****************************
- * random_fio *
- *****************************
- * This is the random i/o portion of the file i/o benchmark.
- * The routine randomly selects, reads, and writes the 20
- * files. The system continues the testing until the aggregate
- * time (read and write) exceed the selected time (dotime)
- */
- random_fio(winptr, dotime,buffseg,rbytes,wbytes,accrtime,accwtime,
- maxbytes,mymax)
- win_handle *winptr; /* current window */
- unsigned int dotime; /* User selected time */
- unsigned int buffseg; /* Read/write buffer segment */
- unsigned long *wbytes; /* Total bytes written */
- unsigned long *rbytes; /* Total bytes read */
- unsigned int accwtime[3]; /* Total write-time */
- unsigned int accrtime[3]; /* Total read-time */
- unsigned long maxbytes; /* Max space avail. */
- unsigned long *mymax;
- {
- int fh; /* File handle */
- unsigned long offset; /* Byte offset */
- unsigned long flen; /* File length */
- unsigned int eltime[3]; /* Elapsed time */
- unsigned int nb; /* Number of bytes */
- int n; /* File number */
- int i; /* Loop index */
- unsigned long avg; /* Avg. bytes read per loop */
-
- do {
- avg=0L; /* Clear averaging var. */
-
- /* For each pass, do 3 reads and 1 write */
- for(i=0;i<3;i++)
- {
- n=(int)abs(randwc(20L));
- fh=ll_open(gfname(n));
- flen=ll_filelen(fh); /* Get file length */
- offset=abs(randwc(flen)); /* Get random offset */
- flen=flen-offset;
- if(flen==0L) ++flen;
- nb=(flen>32000L) ? 32000 : (unsigned int)flen;
- nb=(unsigned int)abs(randwc((unsigned long)nb));
- start_timer(); /* Start timing */
- ll_seekread(fh,offset,0,buffseg,nb);
- stop_timer(eltime);
- accumtime(eltime,accrtime);
- *rbytes+=(unsigned long)nb;
- avg+=(unsigned long)nb;
- ll_close(fh);
- }
-
- n=(int)abs(randwc(20L)); /* No resonance */
- n=(int)abs(randwc(20L)); /* Pick file */
- fh=ll_open(gfname(n));
- flen=ll_filelen(fh); /* Get file length */
- offset=abs(randwc(flen)); /* Get random offset */
- nb=(unsigned int)(avg/3L);
- if((offset+(unsigned long)nb)>flen)
- { *mymax+=((offset+(unsigned long)nb)-flen);
- if(*mymax>maxbytes) return;
- }
- start_timer(); /* Start timing */
- ll_seekwrite(fh,offset,0,buffseg,nb); /* Do the write */
- stop_timer(eltime); /* Done timing */
- accumtime(eltime,accwtime);
- *wbytes+=(unsigned long)nb;
- ll_close(fh);
-
- if(winptr!=NULL)
- adjust_bar(winptr, accrtime[2]+accwtime[2], dotime); /* bar */
-
- } while(accrtime[2]+accwtime[2]<dotime);
- return;
-
- }
-
- /****************************
- * gfname *
- *****************************
- ** For file i/o routines. Pass this guy and integer between
- ** 0 and 19 and he returns a pointer to a null-terminated string
- ** holding the file's name.
- */
- char *gfname(n)
- int n; /* Selection number */
- {
- static char fname[20]; /* File name buffer */
-
- /* Build the name */
- strcpy(fname,"BYTEDAT.");
- itoa(n,fname+8,10);
-
- return(fname);
- }
-
- /****************************
- * ll_diskseek *
- *****************************
- ** Low level disk seek benchmark (hard disks)
- ** NOTE: This test requires that the throughput test be already
- ** run so that bytes per second is available.
- */
- ll_diskseek(drive,bytespersec,seektime)
- unsigned int drive; /* Drive number (0=1st hard disk) */
- double bytespersec; /* Bytes per sec from throughput test */
- double *seektime; /* Avg seek time */
- {
- unsigned int buffseg; /* Buffer segment */
- harddiskspecs myhdisk; /* Hard disk specs */
- unsigned int mytime[3]; /* Local for elapsed time */
- unsigned int i; /* Index */
- double divisor;
- double transtime;
- double thistime;
-
-
- /* Allocate memory segments for the arrays */
- if(allocmem(512/16+1,&buffseg)!=-1)
- return;
-
- /* Determine the drive's maximum cylinder number */
- if(get_hdinfo(drive+0x80,&myhdisk)==0)
- { freemem(buffseg);
- return;
- }
- divisor=(long)myhdisk.maxcyl*(long)(myhdisk.maxcyl-1);
- transtime=(double)512.0/bytespersec;
- drive +=0x80; /* Hard disk */
- for(i=1;i<myhdisk.maxcyl;i++)
- { hd_1seek(drive,0,buffseg); /* Seek to 0 */
- start_timer();
- hd_1seek(drive,i,buffseg); /* Seek distance=i */
- stop_timer(mytime);
- thistime=timetodouble(mytime); /* Get time */
- thistime-=transtime; /* Subtract transfer time */
- thistime=thistime*((double)(myhdisk.maxcyl-i)/(double)divisor);
- *(seektime)+=thistime+thistime; /* Times 2 */
- }
-
- /* Free memory segments */
- freemem(buffseg);
-
- return;
- }
-
- /****************************
- * ll_hdthru *
- *****************************
- ** Low level hard disk read throughput.
- */
- ll_hdthru(drive,n,bpersec)
- unsigned int drive; /* Drive to test */
- unsigned int n; /* # of iterations to test */
- double *bpersec; /* Bytes per second transfer */
- {
- unsigned int cysecarrseg; /* Cylinder/array segment */
- unsigned int buffseg; /* Buffer segment */
- harddiskspecs myhdisk; /* Hard disk specs */
- unsigned int far *cysecptr; /* Far pointer to cyl/sect array */
- unsigned int eltime[3]; /* Local for elapsed time */
- unsigned int seektime1[3];
- unsigned int seektime2[3];
- unsigned int cyl; /* Cylinder */
- unsigned int sect; /* Sector */
- unsigned long totbytes; /* Total bytes */
- unsigned int i; /* Index */
-
- /* Clear return value */
- *bpersec=0.0;
-
- /* Determine the configuration of the hard disk */
- if(get_hdinfo(drive+0x80,&myhdisk)==0)
- return;
-
- /* Build the cylinder/sector and # of sectors arrays */
- if(allocmem(n/4+1,&cysecarrseg)!=-1)
- return;
- cysecptr=MK_FP(cysecarrseg,0); /* Make a pointer */
- if(allocmem((myhdisk.sectspertrack*512)/16+1,&buffseg)!=-1)
- { freemem(cysecarrseg);
- return;
- }
-
- /* Build arrays for first test */
- randnum(1L);
- i=0;
- totbytes=0L;
- do {
- cyl=abs((int)randwc((unsigned long)myhdisk.maxcyl));
- sect=abs((int)randwc((unsigned long)myhdisk.sectspertrack))+1;
- *(cysecptr+i)=(sect&0x3f)+((cyl&255)<<8)+((cyl&0x300)>>2);
- ++i;
- *(cysecptr+i)=myhdisk.sectspertrack-sect+1;
- totbytes+=(unsigned long)*(cysecptr+i);
- } while(++i<((n*2)-1));
-
- totbytes=(totbytes-(unsigned long)n)*512L; /* FIX!!! */
-
- /* Do first test */
- seektime1[0]=seektime1[1]=seektime1[2]=0;
- start_timer();
- i=hd_rread(drive+0x80,cysecarrseg,buffseg,n);
- stop_timer(eltime);
- if(i!=0) printf("Whoops at %d\n",i);
- accumtime(eltime,seektime1);
-
- /* Fix up array for second test */
- for(i=0;i<n;i++)
- *(cysecptr+2*i+1)=1;
-
- /* Do second test */
- seektime2[0]=seektime2[1]=seektime2[2]=0;
- start_timer();
- i=hd_rread(drive+0x80,cysecarrseg,buffseg,n);
- stop_timer(eltime);
- if(i!=0) printf("2Whoops at %d\n",i);
- accumtime(eltime,seektime2);
-
- /* Calculate bytes per second */
- *bpersec=(double)totbytes/(timetodouble(seektime1)-timetodouble(seektime2));
-
- /* Close it up */
- freemem(cysecarrseg);
- freemem(buffseg);
-
- return;
- }
-
- /****************************
- * get_hdinfo *
- *****************************
- ** Return hard disk information.
- ** Call with:
- ** drive = hard disk number (0x80 is first drive, 0x81 is second)
- ** Returns:
- ** hdinf structure filled with disk information
- ** return value is number of drives connected to first
- ** controller
- */
- int get_hdinfo(drive,hdinf)
- unsigned int drive; /* Drive to get information on */
- harddiskspecs *hdinf; /* Structure of hard disk info */
- {
-
- union REGS inregs, outregs; /* For talking to the BIOS */
-
- /* Make the call to INT 13H */
- inregs.h.ah=8;
- inregs.h.dl=drive;
- int86(0x13,&inregs,&outregs);
-
- /* Pass back results */
- hdinf->maxhead=outregs.h.dh;
- hdinf->maxcyl=outregs.h.ch + ((outregs.h.cl & 0xC0)<<2);
- hdinf->sectspertrack=outregs.h.cl & 0x3F;
-
- /* Return number of attached drives */
- return((int)outregs.h.dl);
- }
-
- /****************************
- * segcopy *
- *****************************
- * Given two segments, copies n bytes from source to
- * destination.
- */
- segcopy(destin,source,n)
- unsigned int destin; /* Destination segment */
- unsigned int source; /* Source segment */
- unsigned int n; /* Number of bytes */
- {
- char huge *dptr;
- char huge *sptr;
-
- /* Make some far pointers */
- dptr=MK_FP(destin,0);
- sptr=MK_FP(source,0);
-
- do {
- *dptr++=*sptr++;
- } while(--n);
-
- }
-
- /****************************
- * rload_int_seg *
- *****************************
- ** Load a segment with random integers.
- ** Call with:
- ** rload_int_seg(segptr,n,max)
- ** Where:
- ** segptr = unsigned integer holding the segment
- ** n = number of elements to load the array
- ** max = maximum value (must be unsigned)
- */
- rload_int_seg(segptr,n,max)
- unsigned int segptr;
- unsigned int n;
- int max;
- {
- int huge *mysegptr; /* For coercion */
- unsigned int i; /* Index */
-
- /* Set up my pointer */
- mysegptr=MK_FP(segptr,0);
-
- /* Loop and load the array */
- for(i=0;i<n;i++)
- *mysegptr++=(int)randwc((long)max);
- }
-
- /****************************
- * accumtime() *
- *****************************
- ** Accumulate elapsed time.
- ** Call with:
- ** accumtime(eltime,tottime)
- ** Where:
- ** eltime[3] = array of elapsed time to be added to
- ** tottime
- ** Returns:
- ** tottime[3] = total time
- */
- accumtime(eltime,tottime)
- unsigned int eltime[3]; /* Elapsed time */
- unsigned int tottime[3]; /* Total time */
- {
-
- /* Add in microseconds */
- tottime[0]+=eltime[0];
-
- /* Handle overflow */
- if(tottime[0]>=1000)
- { tottime[0]-=1000;
- tottime[1]+=1;
- }
-
- /* Add in milliseconds */
- tottime[1]+=eltime[1];
-
- /* Handle overflow */
- if(tottime[1]>=1000)
- { tottime[1]-=1000;
- tottime[2]+=1;
- }
-
- /* Add in seconds */
- tottime[2]+=eltime[2];
- }
-
- /****************************
- * randwc() *
- *****************************
- ** Returns random modulo num.
- */
- long randwc(num)
- long num;
- {
- return(randnum(0L)%num);
- }
-
- /****************************
- * randnum() *
- *****************************
- ** Second order linear congruential generator.
- ** Constants suggested by J. G. Skellam.
- ** If val==0, returns next member of sequence.
- ** val!=0, restart generator.
- */
- long randnum(lngval)
- long lngval;
- {
- register long interm;
- static long randw[2] = { 13L , 117L };
-
- if (lngval!=0L)
- { randw[0]=13L; randw[1]=117L; }
-
- interm=(randw[0]*254754L+randw[1]*529562L)%999563L;
- randw[1]=randw[0];
- randw[0]=interm;
- return(interm);
- }
-
- /****************************
- * timetodouble *
- *****************************
- * Convert a time array micro, milli, seconds to a floating-point
- * double value.
- */
- double timetodouble(histime)
- unsigned int histime[3];
- {
- double temp; /* Local for holding time */
-
- temp=(double)histime[0]; /* Microseconds */
- temp=temp/1000.0;
- temp+=(double)histime[1]; /* Milliseconds */
- temp=temp/1000.0;
- temp+=(double)histime[2]; /* Seconds */
-
- return(temp);
- }
-
- void adjust_bar(win_handle *winptr, int curr, int tot)
- /****************************
- ** adjust_bar *
- *****************************
- **
- **
- ** Colors the sliding bar graph
- */
- {
- double curlen;
- int i;
-
- curlen = ((double)curr/tot)*20;
-
- curlen=(curlen>20) ? 20: curlen;
-
- for(i=oldlen;i< (int) curlen;i++){
- winputch(winptr, 39+i, 23, 0xb2);
- if (tdef[13])
- click();
- }
-
- chattr(winptr, 39, 23, (int) curlen, 1, WHITE, RED);
-
- oldlen=curlen;
- return;
- }