#include 
#include 
#include 
#define ESC 0x1b
#define BSPACE 0x08
const unsigned long far * const dosTime =
 (const unsigned long far * const)MK_FP( 0x40, 0x6C );
class Timer
{
public:
 Timer();
 void start();
 void stop();
 void reset();
 int status();
 double time();
 static double resolution();
private:
 static unsigned adjust;
 static unsigned calibrate();
 int running;
 struct TIME
		 {
		 unsigned long dosCount;
		 unsigned timerCount;
		 };
 TIME startTime;
 double time_;
};
inline double Timer::time()
{
 return time_/1.E6;
}
inline double Timer::resolution()
{
 return 839/1.E9;
}
unsigned Timer::adjust = calibrate();
Timer::Timer() : time_(0), running(0)
{
}
void Timer::start()
{
 if( !running )
		 {
		 outportb( 0x43, 0x34 );
		 asm jmp __1;
 __1:
		 outportb( 0x40, 0 );
		 asm jmp __2;
 __2:
		 outportb( 0x40, 0 );
		 startTime.dosCount = *dosTime;
		 startTime.timerCount = 0;
		 running = 1;
		 }
}
void Timer::stop()
{
 outportb( 0x43, 0 );
 unsigned char temp = inportb( 0x40 );
 TIME stopTime;
 stopTime.timerCount = (inportb( 0x40 ) << 8) + temp;
 stopTime.dosCount = *dosTime;
 TIME elapsedTime;
 elapsedTime.dosCount = stopTime.dosCount - startTime.dosCount;
 elapsedTime.timerCount = -( stopTime.timerCount - adjust );
 const double fudge = 83810.0/100000.0;
 time_ += ((elapsedTime.dosCount << 16) +
elapsedTime.timerCount)*fudge;
 running = 0;
}
void Timer::reset()
{
 time_ = 0;
 if( running )
		 start();
}
unsigned Timer::calibrate()
{
 adjust = 0;
 unsigned long sum = 0;
 Timer w;
 for( int i = 0; i < 100; i++ )
		 {
		 w.start();
		 w.stop();
		 sum += w.time();
		 w.reset();
		 }
 return (unsigned)((sum+5)/100);
}
void main()
{
 clrscr();
 Timer t;
 char text[1000];
 int i = 0, space_count = 0, letter_count = 0;
 float duration;
 printf("
	 PROGRAM TO TEST TYPING SPEED
");
 printf("Hit any key to start timer...
");
 if(getch())
 {
 printf("Your time has started. Start typing. Hit Esc when done.
");
 t.start();
 }
 while(1)
 {
 text[i] = getche();
 letter_count++;
 if(text[i] == ' ')
 space_count++;
 if(text[i] == '
')
 printf("
");
 if(text[i] == BSPACE)
 printf(" "); // to erase previous character instead of cursoring
over
 if(text[i] == ESC)
 {
 printf(" ");
 // to eliminate a special character that is printed for Esc
 // A Backspace followed by Space erases previous character.
 break;
 }
 }
 t.stop();
 duration = t.time();
 printf("
Your typing speed is : 
");
 printf("%6.2f characters per minute
",60*letter_count/duration);
 printf("%6.2f words per minute (Actual)
",60*space_count/duration);
 printf("%6.2f words per minute (Average)",60*letter_count/duration/5);
 getch();
}