/*
    Disktest -- test the speed of reading and writing floppy
    Copyright (C) 1989  by Robert Fischer

	This program costs no money; you can redistribute it and/or modify it
	under the terms of the Lynxware General License as published by Robert
	Fischer; either version 1, or (at your option) any later version. 

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    Lynxware General License for more details.

    You should have received a copy of the Lynxware General License
    along with this program; if not, write to the author.

    To contact the author, call or write:
        Robert Fischer
        80 Killdeer Road
        Hamden, CT    06517
        (203) 288-9599
		E-mail: fischer-robert@cs.yale.edu
*/


/* This is meant to compile under Mark Williams C */
/* For other C compilers, the GEMDOS and BIOS macros may need to be changed.. */
/* ================= Pulled from my Include files ================== */
typedef unsigned long LONG;

#define HZ_200          *( (LONG *)0x4BAL )

#define Cconin()        gemdos(0x1)
#define Cconout(a)      gemdos(0x2,a)
#define Cnecin()        gemdos(0x8)
#define Cconws(a)       gemdos(0x9,a)
#define Super(a)        gemdos(0x20,(LONG)(a))
#define Getbpb(a)       bios(7,a)
#define Rwabs(a,b,c,d,e)    bios(4,a,(LONG)b,c,d,e)
#	define B_READ 0
#	define B_WRITE 1
#	define B_READ_NOCHANGE 2
#	define B_WRITE_NOCHANGE 3
#	define FLOP_A 0
#	define FLOP_B 1

extern char *lmalloc();

/* ========================== Start of code ======================== */
#define STARTSEC 27
#define NUM_TRACKS 20	/* Number of tracks per trial */
#define NUM_TRIALS 10	/* Number of trials to do */
char *buf;

/* ------------------------------------------------------- */
long clock()
{
LONG usp;
long ret;
	usp = Super(0);
	ret = HZ_200;
	Super(usp);
	return ret;
}
/* ------------------------------------------------------- */
insert_disk(sides)
int sides;
{
	printf("Insert your junk %d-sided, 9-sector floppy in drive A\n",
		sides);
	Cnecin();
	Getbpb(FLOP_A);
}
/* ------------------------------------------------------- */
int test_disk(rowr, sides)
int rowr;		/* 1 for write, 0 for read */
int sides;
{
long start_time;
int elapsed;
	Rwabs(B_READ, buf, 2, STARTSEC - 9, FLOP_A);	/* Start motor going */
	start_time = clock();
	Rwabs(rowr, buf, NUM_TRACKS * 9 * sides, STARTSEC, FLOP_A);	/* Do the timed read */
	elapsed = clock() - start_time;
	return elapsed;
}
/* ------------------------------------------------------- */
run_trial(rorw, sides)
int rorw;		/* 1 for write, 0 for read */
int sides;
{
long total;
int tpt;	/* Time per track */
int i;
	/* Test the disk */
	for (total = 0, i = 0; i < NUM_TRIALS; i++) {
		total += test_disk(rorw, sides);
	}
	tpt = (total / (NUM_TRACKS * NUM_TRIALS));
	printf("%cS %s: %d ms/track avg.\n",
		(sides == 1 ? 'S' : 'D'),
		(rorw == B_READ ? " Read" : "Write"),
		tpt * 5);
}
/* ------------------------------------------------------- */
main()
{
int c;
int sides;
	buf = lmalloc((long)NUM_TRACKS * 9L * 512L);

    Cconws("\033EDisktest -- test the speed of reading and writing floppy disks.\r\n");
    Cconws("Copyright \275 1989  by Robert Fischer\r\n");
	Cconws("Disktest comes with ABSOLUTELY NO WARRANTY.\r\n"
	"This program is Lynxware and is subject to the terms of the Lynxware\r\n"
	"General License; either version 1, or (at your option) any later version.\r\n\n"
	);

    Cconws("To use Disktest, you need a formatted junk 9-sector single or\r\n");
    Cconws("double-sided floppy disk, and a few minutes.  DISKTEST WILL DESTROY\r\n");
    Cconws("THE DATA ON THE DISK YOU INSERT!  If you wish to continue, press 'C'.\r\n");
    Cconws("Any other key will exit. ");

	c = Cconin() & 0xFF;
	if (c != 'c' && c != 'C') exit(0);

    Cconws("\r\nHow many sides does your disk have? ");
	c = Cconin() & 0xFF;
	sides = (c == '2' ? 2 : 1);
	Cconws("\r\n");

	insert_disk(sides);

	Cconws("Are you sure you want to continue with Disktest and destroy ALL THE\r\n");
	Cconws("DATA in drive A? ");
	c = Cconin() & 0xFF;
	Cconws("\r\n\r\n");
	if (c != 'y' && c != 'Y') exit(0);

	run_trial(B_READ, sides);
	run_trial(B_WRITE, sides);

	Cconws("Press any key to return to the Desktop.\r\n");
	Cnecin();
}
/* ------------------------------------------------------- */
