home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
mschrt3.arj
/
SEEKTEST.C
< prev
next >
Wrap
Text File
|
1990-07-24
|
19KB
|
430 lines
/*---------------------------------------------------------------------------
| Program SEEKTEST.C |
| |
| This program demonstrates the use of MSCHRT in timing seek performance |
| of a PC based hard disk drive. The method used will determine the total|
| seek time of the device which includes actual disk seek, controller |
| overhead, and ROM BIOS overhead. This is a "real world" measurement |
| of disk performance under actual usage conditions. |
| |
| This program uses both inline generic timers and BIOS interrupt |
| timers to measure disk performance. |
| |
| (c)1989 Ryle Design, P.O. Box 22, Mt. Pleasant, Michigan 48804 |
| |
| V3.00 Microsoft C Shareware Evaluation Version |
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <process.h>
#include "pchrt.h"
union REGS inregs,outregs;
long unsigned seek1, seek2, hits1, hits2, seek3, hits3;
void disk_err(int istat)
/*---------------------------------------------------------------------------
| This procedure outputs a description of an INT 13h error status, and |
| halts program exection. |
| |
| Globals referenced: none |
| |
| Arguments: (int) istat - status returned from INT 13h in AX if carry |
| flag set. |
| |
| Returns : void |
---------------------------------------------------------------------------*/
{
switch (istat)
{
case 0x00 : return; /* no error */
case 0x01 : printf("Disk error: Invalid command\n");
break;
case 0x02 : printf("Disk error: Address mark not found\n");
break;
case 0x03 : printf("Disk error: Disk is write-protected\n");
break;
case 0x04 : printf("Disk error: Requested sector not found\n");
break;
case 0x05 : printf("Disk error: Reset failed\n");
break;
case 0x06 : printf("Disk error: Floppy disk removed\n");
break;
case 0x07 : printf("Disk error: Bad parameter table\n");
break;
case 0x08 : printf("Disk error: DMA overrun\n");
break;
case 0x09 : printf("Disk error: DMA crossed 64KB boundary\n");
break;
case 0x0A : printf("Disk error: Bad sector flag set\n");
break;
case 0x0B : printf("Disk error: Bad track flag set\n");
break;
case 0x0C : printf("Disk error: Requested media type not found\n");
break;
case 0x0D : printf("Disk error: Invalid number of sectors on format\n");
break;
case 0x0E : printf("Disk error: Control data address mark detected\n");
break;
case 0x0F : printf("Disk error: DMA arbitration level out of range\n");
break;
case 0x10 : printf("Disk error: Uncorrectable CRC or ECC data error\n");
break;
case 0x11 : printf("Disk warning: ECC corrected data error\n");
return;
case 0x20 : printf("Disk error: Controller failed\n");
break;
case 0x40 : printf("Disk error: Seek failed\n");
break;
case 0x80 : printf("Disk error: Disk has timed out\n");
break;
case 0xAA : printf("Disk error: Drive not ready\n");
break;
case 0xBB : printf("Disk error: Error is undefined\n");
break;
case 0xCC : printf("Disk error: Write fault\n");
break;
case 0xE0 : printf("Disk error: Status register error\n");
break;
case 0xFF : printf("Disk error: Sense operation failed\n");
break;
default : printf("Unknown INT 13 return status %d\n",istat);
break;
}
exit(1);
} /* disk_err */
void test_disk(char disk)
/*---------------------------------------------------------------------------
| This function, which contains the actual disk test routines, does the |
| following: |
| 1. Seeks the test disk to track 0. |
| 2. Times 100 calls to seek to track 0. Since the heads are already |
| on track 0, they will not move, and a estimate of the software |
| overhead for each seek call can be made. |
| 3. Times single track seeks to all cylinders (0-1,1-2,2-3,3-4,etc). |
| This provides a measurement of single track seek time. |
| 4. Seeks from track 0 to all tracks (0-1,0-2,0-3,0-4,etc). This |
| provides average seek time for the entire disk. |
| 5. The results are reported. |
| |
| int86() is used to call the ROM BIOS. There is some software |
| overhead incurred using this method. |
| |
| Generic inline timers are used to measure disk performance. |
| |
| Globals referenced: inregs, outregs. |
| |
| Arguments: (char) disk - physical disk # - add to 0x80 for BIOS call. |
| |
| Returns : void |
---------------------------------------------------------------------------*/
{
int maxhead,maxcyl,indx;
unsigned long seek1,seek2,seek3,hits1,hits2,hits3;
inregs.h.dl = 0x80 + disk; /* get disk config */
inregs.h.ah = 0x08;
int86(0x13,&inregs,&outregs);
if (outregs.x.cflag != 0) disk_err(outregs.h.ah);
maxhead = outregs.h.dh; /* move bits to get */
maxcyl = ((outregs.h.cl & 0xC0) << 2) + outregs.h.ch; /* heads & tracks */
printf("\nPhysical drive %d shows %d cylinders, %d heads\n\n",disk,maxcyl+1,maxhead+1);
printf("Starting single track seek test ...\n");
inregs.h.ah = 0x0C; /* seek command */
inregs.h.ch = 0x00; /* track 0 */
inregs.h.cl = 0x01; /* XTs need sector bit set, or no seek */
inregs.h.dh = 0; /* head 0 */
inregs.h.dl = 0x80 + disk; /* disk # */
int86(0x13,&inregs,&outregs); /* seek to track 0 */
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on error */
for (indx=0; indx<100; indx++) /* seek to 0 100 times to get ave overhead */
{
t_entry(2);
int86(0x13,&inregs,&outregs);
t_exit(2);
}
for (indx=1; indx<=maxcyl; indx++) /* from zero, single track seek to end of disk */
{
inregs.h.ch = indx & 0x00FF; /* mask track bits and stuff in cl & ch */
inregs.h.cl = ((indx & 0x0300) >> 2) + 1; /* cl sector bit 1 for XTs */
t_entry(0);
int86(0x13,&inregs,&outregs); /* seek */
t_exit(0);
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on error */
if ((indx % 100) == 0) printf("%d ",indx); /* echo to user our progress */
}
printf("\nSeeking to all tracks ...\n");
inregs.h.ch = 0x00; /* back to track 0 for next test */
inregs.h.cl = 0x01; /* sector bit for XTs */
int86(0x13,&inregs,&outregs); /* seek */
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on errors */
for (indx=1; indx<=maxcyl; indx++) /* from track 0, seek to all tracks */
{
inregs.h.ch = indx & 0x00FF; /* mask tracks bits and stuff in cl & ch */
inregs.h.cl = ((indx & 0x0300) >> 2) + 1; /* cl sector bit 1 for XTs */
t_entry(1);
int86(0x13,&inregs,&outregs); /* seek */
t_exit(1);
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on errors */
if ((indx % 100) == 0) printf("%d ",indx); /* echo to user our progress */
inregs.h.ch = 0x00; /* go back to track 0 for next seek */
inregs.h.cl = 0x01;
int86(0x13,&inregs,&outregs);
if (outregs.x.cflag != 0) disk_err(outregs.h.ah);
}
t_ask_timer(0,&hits1,&seek1); /* query timers */
t_ask_timer(1,&hits2,&seek2);
t_ask_timer(2,&hits3,&seek3);
printf("\n\nTest of physical disk %d complete.\n",disk);
printf("Average single track seek ............. %7.3f milliseconds\n",((seek1/hits1)/1000.0) );
printf("Average seek to all tracks ............ %7.3f milliseconds\n",((seek2/hits2)/1000.0) );
printf("Estimated software overhead per seek .. %7.3f milliseconds\n\n",((seek3/hits3)/1000.0) );
t_reset(0); /* reset all timers */
t_reset(1);
t_reset(2);
} /* test_disk */
void test_disk_bios(char disk)
/*---------------------------------------------------------------------------
| This function, which contains the actual disk test routines, does the |
| following: |
| 1. Seeks the test disk to track 0. |
| 2. Times 100 calls to seek to track 0. Since the heads are already |
| on track 0, they will not move, and a estimate of the software |
| overhead for each seek call can be made. |
| 3. Times single track seeks to all cylinders (0-1,1-2,2-3,3-4,etc). |
| This provides a measurement of single track seek time. |
| 4. Seeks from track 0 to all tracks (0-1,0-2,0-3,0-4,etc). This |
| provides average seek time for the entire disk. |
| 5. The results are reported. |
| |
| int86() is used to call the ROM BIOS. There is some software |
| overhead incurred using this method. |
| |
| BIOS interrupt timers are used to measure disk performance. |
| |
| Globals referenced: inregs, outregs. |
| |
| Arguments: (char) disk - physical disk # - add to 0x80 for BIOS call. |
| |
| Returns : void |
---------------------------------------------------------------------------*/
{
int maxhead,maxcyl,indx;
unsigned long seek1,seek2,seek3,hits1,hits2,hits3;
t_bios_start(DISK);
inregs.h.dl = 0x80 + disk; /* get disk config */
inregs.h.ah = 0x08;
int86(0x13,&inregs,&outregs);
if (outregs.x.cflag != 0) disk_err(outregs.h.ah);
maxhead = outregs.h.dh; /* move bits to get */
maxcyl = ((outregs.h.cl & 0xC0) << 2) + outregs.h.ch; /* heads & tracks */
printf("\nPhysical drive %d shows %d cylinders, %d heads\n\n",disk,maxcyl+1,maxhead+1);
printf("Starting single track seek test ...\n");
inregs.h.ah = 0x0C; /* seek command */
inregs.h.ch = 0x00; /* track 0 */
inregs.h.cl = 0x01; /* XTs need sector bit set, or no seek */
inregs.h.dh = 0; /* head 0 */
inregs.h.dl = 0x80 + disk; /* disk # */
int86(0x13,&inregs,&outregs); /* seek to track 0 */
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on error */
for (indx=0; indx<100; indx++) /* seek to 0 100 times to get ave overhead */
int86(0x13,&inregs,&outregs);
t_bios_ask(DISK,0x0C,&hits1,&seek1);
t_bios_reset(DISK,0x0C);
for (indx=1; indx<=maxcyl; indx++) /* from zero, single track seek to end of disk */
{
inregs.h.ch = indx & 0x00FF; /* mask track bits and stuff in cl & ch */
inregs.h.cl = ((indx & 0x0300) >> 2) + 1; /* cl sector bit 1 for XTs */
int86(0x13,&inregs,&outregs); /* seek */
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on error */
if ((indx % 100) == 0) printf("%d ",indx); /* echo to user our progress */
}
t_bios_ask(DISK,0x0C,&hits2,&seek2);
printf("\nSeeking to all tracks ...\n");
inregs.h.ch = 0x00; /* back to track 0 for next test */
inregs.h.cl = 0x01; /* sector bit for XTs */
int86(0x13,&inregs,&outregs); /* seek */
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on errors */
t_bios_reset(DISK,0x0C);
for (indx=1; indx<=maxcyl; indx++) /* from track 0, seek to all tracks */
{
inregs.h.ch = indx & 0x00FF; /* mask tracks bits and stuff in cl & ch */
inregs.h.cl = ((indx & 0x0300) >> 2) + 1; /* cl sector bit 1 for XTs */
int86(0x13,&inregs,&outregs); /* seek */
if (outregs.x.cflag != 0) disk_err(outregs.h.ah); /* stop on errors */
if ((indx % 100) == 0) printf("%d ",indx); /* echo to user our progress */
inregs.h.ch = 0x00; /* go back to track 0 for next seek */
inregs.h.cl = 0x01;
int86(0x13,&inregs,&outregs);
if (outregs.x.cflag != 0) disk_err(outregs.h.ah);
}
t_bios_ask(DISK,0x0C,&hits3,&seek3);
printf("\n\nTest of physical disk %d complete.\n",disk);
printf("Average single track seek ............. %7.3f milliseconds\n",((seek2/hits2)/1000.0) );
printf("Average seek to all tracks ............ %7.3f milliseconds\n",((seek3/hits3)/1000.0) );
printf("Estimated software overhead per seek .. %7.3f milliseconds\n\n",((seek1/hits1)/1000.0) );
t_bios_stop();
} /* test_disk_bios */
void main(void)
{
int indx;
int numdisk;
char atom;
t_start(); /* start MSCHRT */
printf("SeekTest MSCHRT V3 Demonstration Series\n");
printf("(c)1989 Ryle Design, P.O. Box 22, Mt. Pleasant, Michigan 48804\n\n");
printf("Checking equipment ... ");
inregs.h.ah = 0x08;
inregs.h.dl = 0x80;
int86(0x13,&inregs,&outregs); /* get available physical disks */
if (outregs.x.cflag != 0)
{
printf("There are no hard disks on this system!\n\n"); /* exit on error */
printf("SeekTest complete\n");
exit(0);
}
numdisk = outregs.h.dl; /* DL has total disks on controller */
printf("%d physical hard disk(s) found\n\n",numdisk);
printf("*** WARNING -- Do not proceed unless the test disk is backed up!\n\n"); /* A word of advice ... */
do
{
for (indx=0; indx<numdisk; indx++)
{
printf("%d ... Test disk %d\n",indx,indx);
}
printf("%d ... Exit SeekTest\n",numdisk);
do
{
printf("Select disk or exit (0-%d) >> ",numdisk);
atom = getche();
atom -= '0';
printf("\n");
}
while ( (atom <0) || (atom > numdisk) );
if (atom == numdisk)
{
t_stop(); /* shut down MSCHRT before exit */
printf("\nSeekTest complete");
exit(0);
}
do
{
printf("\nUse inline or BIOS interrupt timers?\n");
printf("0 ... Use inline timers\n");
printf("1 ... Use BIOS interrupt timers\n");
printf("Select 0 or 1 >> ");
indx = getche();
indx -= '0';
}
while ( (indx > 1) || (indx < 0) );
if (indx == 0)
test_disk(atom);
else
test_disk_bios(atom);
}
while (atom != numdisk);
} /* main */