/*** *** pmon code *** *** This code has been borrowed. ***/ /*** *** Include files ***/ #include #include #include #include #include #include #include "pragmas.h" #include "pinewood.h" /* * From orstcs!rutgers!shelby!agate!ucbvax!ucsd!swrinde!cs.utexas.edu!uunet!sugar!sms Sun Mar 18 22:14:10 PST 1990 * Article 1373 of alt.msdos.programmer: * Path: orstcs!rutgers!shelby!agate!ucbvax!ucsd!swrinde!cs.utexas.edu!uunet!sugar!sms * From: sms@sugar.hackercorp.com (Stanley M. Sutton) * Newsgroups: alt.msdos.programmer * Subject: Microsecond timer for IBM PC Compatibles * Message-ID: <5397@sugar.hackercorp.com> * Date: 17 Mar 90 08:14:55 GMT * Reply-To: sms@sugar.hackercorp.com (Stanley M. Sutton) * Distribution: alt * Organization: Sugar Land Unix - Houston * Lines: 149 * * Here is a public domain set of routines for timing events to * the resolution of the PC clock. It is very consistent accross both * 8088s, 80286s, and 80386s. The routine is compilable with TurboC. * This is very short, so I'm posting to alt.msdos.programmers * and alt.sources. */ #pragma inline #define OUT outportb #define IN inportb #define DIS disable #define ENB enable static unsigned long far *_Dos_time = MK_FP(0x40, 0x6C); static unsigned int Pmon_ovhead = 0xFFFF; void get_time(US_TIME *us_time) { DIS(); OUT(0x43, 0); us_time->tick = *_Dos_time; us_time->timer = IN(0x40); #ifdef __TURBOC__ asm jmp $+2; #endif us_time->timer += ((unsigned int)(IN(0x40)) << 8); ENB(); /* A quick hack to check the timer if the time is close to roll-over */ if (us_time->timer < 1000) { DIS(); OUT(0x43, 0); us_time->tick = *_Dos_time; us_time->timer = IN(0x40); #ifdef __TURBOC__ asm jmp $+2; #endif us_time->timer += ((unsigned int)(IN(0x40)) << 8); ENB(); } } unsigned long delta_us(US_TIME *s_time, US_TIME *e_time) { if (Pmon_ovhead == 0xFFFF) calib_pmon(); return ((((e_time->tick - s_time->tick) << 16) + s_time->timer - e_time->timer - Pmon_ovhead) * 84 / 100); } void calib_pmon(void) { US_TIME e_time; US_TIME s_time; OUT(0x43, 0x34); #ifdef __TURBOC__ asm jmp $+2; #endif OUT(0x40, 0); #ifdef __TURBOC__ asm jmp $+2; #endif OUT(0x40, 0); get_time(&s_time); get_time(&e_time); Pmon_ovhead = (unsigned int) ((e_time.tick - s_time.tick) << 16) + s_time.timer - e_time.timer; }