home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
ins_msc
/
imc9106
/
hrtimer2.c
< prev
next >
Wrap
Text File
|
1991-05-01
|
6KB
|
142 lines
/*********************************************************************
* HRTIMER2.C - This program uses the function HRTimer2() as shown in *
* Figure E of the article "Designing a high-resolution timer" in *
* the May 1991 issue of Inside Microsoft C. It demonstrates some *
* of the problems associated with this function. *
*********************************************************************/
#include <stdio.h> /* puts() */
#include <conio.h> /* outp(), inp(), kbhit() */
#include <dos.h> /* disable(), enable() */
#define MAX_LAG_CYCLES 64
#define COUNTS_PER_uSEC (double)1.19318
void HRMode2( void );
void HRMode3( void );
void InitHRTimer( void );
unsigned long HRTimer2( void );
unsigned long StartTicker; /* Holds starting ticker value at init */
/*********************************************************************
* HRMode2 - Switch counter 0 to mode 2 and load initial value 65536 *
*********************************************************************/
void HRMode2( void )
{
_disable(); /* Disable interrupts */
outp(0x43, 0x34); /* Counter 0, Mode 2, LSB/MSB */
outp(0x40, 0x00); /* Load low word of valu */
outp(0x40, 0x00); /* Load high word of value */
_enable(); /* Re-enable interrupts */
}
/*********************************************************************
* HRMode3 - Switch counter 0 to mode 3 and load initial value 65536 *
*********************************************************************/
void HRMode3( void )
{
_disable(); /* Disable interrupts */
outp(0x43, 0x36); /* Counter 0, Mode 3, LSB/MSB */
outp(0x40, 0x00); /* Load low word of value */
outp(0x40, 0x00); /* Load high word of value */
_enable(); /* Re-enable interrupts */
}
/*********************************************************************
* InitHRTimer - Get StartTicker value from master clock count. *
*********************************************************************/
void InitHRTimer( void )
{
unsigned int far * BiosTicker =
(unsigned int far *)0x0040006cL;
StartTicker = *BiosTicker;
}
/*********************************************************************
* HRTimer2 - as shown in Figure E. *
*********************************************************************/
unsigned long HRTimer2( void )
{
unsigned int far * BiosTicker =
(unsigned int far *)0x0040006cL;
union {
unsigned long l;
struct { unsigned int l, h; } i;
struct { unsigned char l, h; } c;
} A, B, Ticker;
_disable(); /* Turn off interrupts */
outp(0x43, 0x00); /* Latch PIT counter 0 */
A.c.l = inp(0x40); /* Read low byte of counter 0 */
A.c.h = inp(0x40); /* Read high byte of counter 0 */
Ticker.l = *BiosTicker; /* Get BIOS's master clock count */
_enable(); /* Turn interrupts back on */
A.i.l = 65535 - (--A.i.l); /* Normalize counter value */
B.i.l = A.i.l; /* Copy initial value to B.i.l */
while ( B.i.l < MAX_LAG_CYCLES ) /* If new cycle, wait a while */
{ /* to ensure MCC has been updated */
_disable(); /* Turn off interrupts */
outp(0x43, 0x00); /* Latch PIT counter 0 */
B.c.l = inp(0x40); /* Read low byte of counter 0 */
B.c.h = inp(0x40); /* Read high byte of counter 0 */
Ticker.l = *BiosTicker; /* Get BIOS's master clock count */
_enable(); /* Turn interrupts back on */
B.i.l = 65535 - (--B.i.l);/* Normalize counter value */
}
Ticker.l -= StartTicker; /* Subtract start ticker value */
A.i.h = Ticker.i.l; /* Move difference to A.i.h */
return( A.l );
}
/*********************************************************************
* main - Test loop for HRTimer2(). *
*********************************************************************/
void main( void )
{
unsigned long time1, time2;
unsigned long iterations=0;
unsigned long min=0xffff, max=0;
HRMode2();
InitHRTimer();
printf( "Testing 32k iterations of HRTimer2(). "
" Press any key to quit ... \n" );
while ( !kbhit() && iterations < 32768 )
{
time1 = HRTimer2();
time2 = HRTimer2();
++iterations;
if ( time2 < time1 )
puts( "HRTimer2 error" );
else
{
if ( time2 - time1 > max )
{
max = time2 - time1;
printf( "New max: %lu\n", max );
}
else if ( time2 - time1 < min )
{
min = time2 - time1;
printf( "New min: %lu\n", min );
}
}
}
if ( iterations >= 16384 )
printf( "HRTimer2 is accurate to approximately ± %f uSecs.\n",
(double)(max - min) / COUNTS_PER_uSEC / 2.0 );
else
puts( "Not enough iterations to estimate HRTimer2() accuracy" );
HRMode3();
}