home *** CD-ROM | disk | FTP | other *** search
- /*
- * ATDISK -- PC Tech Journal AT Hard Disk Performance Test
- *
- * Version 1.00
- * Last modified 05/23/86
- * Copyright (c) 1986, PC Tech Journal
- * Program by: Paul Pierce, Ted Forgeron, Steven Armbrust
- *
- * Uses BIOS INT 13H to measure low-level performance.
- * Uses DOS INT 21H to measure high-level performance.
- */
-
- #include "dos.h"
-
- /* System clock tick rate in ticks/second */
- #define TICK_RATE 18.20648
-
- /* Number of trials for each test */
- #define TRIALS 1000
-
- struct diskparam {
- int sectors;
- int heads;
- int cylinders;
- int drives;
- } diskparam[10];
-
- char buffer[50 * 512];
-
- /* Number of files for DOS file I/O test */
- #define FILES 10
- /* Size of each file for DOS file I/O test */
- #define FILESIZE 20000
- /* Size of each read/write request for DOS file I/O test */
- #define FILEBUF 2000
-
- char filename[] = "C:ATDISK.~~0";
-
- unsigned long tick();
- unsigned rand();
-
- double drand()
- {
-
- return (double)rand() / 32767;
- }
-
- #define READ_SECTORS 2
- #define GET_PARAM 8
- #define SEEK 12
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- register i, j, k;
- unsigned long start;
- unsigned long total;
- unsigned trials;
- int f;
-
- trials = TRIALS;
-
- /*
- * Get the disk drive parameters for each hard disk
- * in the system.
- */
-
- disk_io(GET_PARAM, 0x80, &diskparam[0], 0, 0, 0, 0);
- for (i = 1; i < diskparam[0].drives; i++) {
- disk_io(GET_PARAM, 0x80 + i, &diskparam[i],
- 0, 0, 0, 0);
- }
-
- /*
- * Display the disk characteristics.
- */
-
- printf("\nATDISK -- PC Tech Journal AT Hard Disk ");
- printf("Performance Test");
- printf("\nVersion 1.00, Copyright (c) 1986 PC Tech ");
- printf("Journal");
- printf("\n\nHARD DISK CHARACTERISTICS\n");
- printf("Drive Sectors Heads Cylinders Total ");
- printf("space\n");
- for (i = 0; i < diskparam[0].drives; i++) {
- total = diskparam[i].sectors * diskparam[i].heads;
- total *= diskparam[i].cylinders;
- total *= 512;
- printf("%3d %5d %5d %5d %10lu\n",
- i,
- diskparam[i].sectors,
- diskparam[i].heads,
- diskparam[i].cylinders,
- total);
- }
-
- printf("\nBIOS TEST OF DISK HARDWARE PERFORMANCE\n");
-
- /*
- * Seek back and forth between tracks 0 and 1.
- */
-
- for (i = 0; i < diskparam[0].drives; i++) {
- disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0, 0);
- start = tick();
- for (j = 0; j < trials/2; j++) {
- disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0,
- 1);
- disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0,
- 0);
- }
- total = tick() - start;
- printf("Drive %d track-track seek time: %4.1f ms",
- i, (double)total / ((double)trials) *
- 1000.0 / TICK_RATE);
- printf("\n");
- }
-
- /*
- * Seek to random tracks.
- */
-
- for (i = 0; i < diskparam[0].drives; i++) {
- disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0, 0);
- start = tick();
- for (j = 0; j < trials; j++) {
- disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0,
- (short)(drand()*
- (diskparam[i].cylinders - 1)));
- }
- total = tick() - start;
- printf("Drive %d average seek time: %4.1f ms\n",
- i, (double)total / ((double)trials) *
- 1000.0 / TICK_RATE);
- }
-
- /*
- * Measure transfer rate by repeatedly reading sectors
- */
-
- for (i = 0; i < diskparam[0].drives; i++) {
- disk_io(READ_SECTORS, 0x80 + i, buffer, 1, 0, 0,
- 0);
- start = tick();
- for (j = 0; j < trials; j++) {
- disk_io(READ_SECTORS, 0x80 + i, buffer,
- diskparam[i].sectors, 0, 0, 0);
- }
- total = tick() - start;
- printf("Drive %d effective transfer rate: ", i);
- printf("%6.1f Kbytes/second\n",
- (((double)diskparam[i].sectors)*512.0) *
- (double)trials / ((double)total) /
- 1024 * TICK_RATE);
- }
-
- /*
- * This section indicates overall system disk performance
- * by using DOS calls to manipulate files. It is only
- * executed if the -d command line switch is used since
- * the test writes to disk.
- */
-
- if (argc == 1) {
- printf("\nType \"atdisk -d\" to run the DOS ");
- printf("TEST OF DISK SYSTEM PERFORMANCE.\n");
- printf("This test creates, writes, reads and ");
- printf("deletes ten files named \n");
- printf("atdisk.~~0 through atdisk.~~9.\n");
- }
- if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'd'){
- printf("\nDOS TEST OF DISK SYSTEM PERFORMANCE\n");
- printf("This test creates, writes, reads and ");
- printf("deletes ten 20,000 byte files.\n");
- printf("Best results are achieved with blank, ");
- printf("freshly-formatted disks.\n");
- for (k = 0; k < diskparam[0].drives; k++) {
- filename[0] = 'C' + k;
- start = tick();
-
- /*
- * First create each file, write to it,
- * and close it.
- */
-
- for (i = 0; i < FILES; i++) {
- filename[11] = '0' + i;
- f = dos_create(filename, 0);
- for (j = 0; j < FILESIZE/FILEBUF;
- j++) {
- dos_write(f, buffer,
- FILEBUF);
- }
- dos_close(f);
- }
-
- /*
- * Now reopen each file, read it, and
- * then delete it.
- */
-
- for (i = 0; i < FILES; i++) {
- filename[11] = '0' + i;
- f = dos_open(filename, 0);
- for (j = 0; j < FILESIZE/FILEBUF;
- j++) {
- dos_read(f, buffer,
- FILEBUF);
- }
- dos_close(f);
- dos_delete(filename);
- }
-
- total = tick() - start;
- printf("Drive %c:",'C' + k);
- printf("%6.1f seconds\n",
- ((double)total) / TICK_RATE);
- }
- }
- }
-
- /*
- * DOS file calls
- *
- * Each of these routines sets up the regs structure as
- * specified in the DOS technical reference and then
- * calls DOS using the intdos() function.
- */
-
-
- /*
- * DOS call 3C - create file
- */
-
- int
- dos_create(file, attribute)
- char *file;
- int attribute;
- {
- struct REGS regs;
-
- regs.x.dx =(int)file;
- regs.h.ah = 0x3C;
- regs.x.cx = attribute;
- intdos(®s, ®s);
- if (regs.x.cflag) {
- printf("DOS error %d in create\n",
- regs.x.ax);
- exit(1);
- }
- return regs.x.ax;
- }
-
- /*
- * DOS call 3D - open file
- */
-
- int
- dos_open(file, mode)
- char *file;
- int mode;
- {
- struct REGS regs;
-
- regs.x.dx = (int)file;
- regs.h.ah = 0x3D;
- regs.h.al = mode;
- intdos(®s, ®s);
- if (regs.x.cflag) {
- printf("DOS error %d in open\n",
- regs.x.ax);
- exit(1);
- }
- return regs.x.ax;
- }
-
- /*
- * DOS call 3E - close file
- */
-
- dos_close(handle)
- int handle;
- {
- struct REGS regs;
-
- regs.x.bx = handle;
- regs.h.ah = 0x3E;
- intdos(®s, ®s);
- if (regs.x.cflag) {
- printf("DOS error %d in close\n",
- regs.x.ax);
- exit(1);
- }
- }
-
- /*
- * DOS call 3F - read file
- */
-
- int
- dos_read(handle, buffer, count)
- int handle;
- char *buffer;
- int count;
- {
- struct REGS regs;
-
- regs.x.bx = handle;
- regs.x.cx = count;
- regs.x.dx = (int)buffer;
- regs.h.ah = 0x3F;
- intdos(®s, ®s);
- if (regs.x.cflag) {
- printf("DOS error %d in read\n",
- regs.x.ax);
- exit(1);
- }
- return regs.x.ax;
- }
-
- /*
- * DOS call 40 - write file
- */
-
- int
- dos_write(handle, buffer, count)
- int handle;
- char *buffer;
- int count;
- {
- struct REGS regs;
-
- regs.x.bx = handle;
- regs.x.cx = count;
- regs.x.dx = (int)buffer;
- regs.h.ah = 0x40;
- intdos(®s, ®s);
- if (regs.x.cflag) {
- printf("DOS error %d in write\n",
- regs.x.ax);
- exit(1);
- }
- return regs.x.ax;
- }
-
- /*
- * DOS call 41 - delete file
- */
-
- dos_delete(file)
- char *file;
- {
- struct REGS regs;
-
- regs.x.dx = (int)file;
- regs.h.ah = 0x41;
- intdos(®s, ®s);
- if (regs.x.cflag) {
- printf("DOS error %d in delete\n",
- regs.x.ax);
- exit(1);
- }
- }