Category : System Diagnostics for your computer
Archive   : PREFORM.ZIP
Filename : ATDISK.C
Output of file : ATDISK.C contained in archive : PREFORM.ZIP
* ATDISK -- PC Tech Journal AT Hard Disk Performance Test
*
* Version 1.01
* Originally written 05/17/86
* Last modified 10/30/86
* Changes:
* 1. Fixed problem with REGS declared as struct
* instead of union.
*
* Copyright (c) 1986, Ziff Communications Company
* Program by: Ted Forgeron, Paul Pierce
*
* 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.01, Copyright (c) 1986 Ziff ");
printf("Communications Co.");
printf("\nWritten by Ted Forgeron and Paul Pierce");
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;
{
union 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;
{
union 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;
{
union 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;
{
union 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;
{
union 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;
{
union 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);
}
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/