Mail Archives: djgpp/1994/03/21/11:29:38
Erik Johnson writes:
>
> I need a little help getting a high resolution timer working under DJGPP.
[stuff deleted]
Some weeks ago, Christopher Christensen (cnc AT netcom DOT com) posted his
timer16() and timer32() routines to this list.
I translated these routines from GAS assembler to C, because I wanted
to use the same source code with Turbo C (and other C compilers).
You can use these routines for high accuracy timing, e.g. Delay().
The timer resolution (unit) is 0.8381 micro-seconds (1193180 Hz clock).
Regards,
.^^^^^^^^ _____________________________________
| | / Pieter Kunst (P.J.) \
| _ _| / Philips Research Laboratories, \
.--(o)(o) / Building WY3, Prof. Holstlaan 4, \
|@ _) / 5656 AA Eindhoven, The Netherlands. |
| ,___| / e-mail: kunst AT prl DOT philips DOT nl /
| / \_______________________________________________/
/____\
==============================================================================
/*
* File: hrtimer.c
*
* From: Christopher Christensen (cnc AT netcom DOT com)
* Huntington Beach California, USA.
*
* Timer resolution (unit) is 0.8381 usec (1193180 Hz clock).
* NB: timer16() rolls over 18.2 times per second.
* timer32() rolls over once per hour.
*
* Overhead of timer16() is about 7.5 units ( 6 usec) on 486DX2/66 PC.
* Overhead of timer32() is about 13.5 units (12 usec) on 486DX2/66 PC.
*/
#include <dos.h> /* enable(), disable() */
#include <math.h> /* floor() */
typedef unsigned short WORD;
typedef unsigned long DWORD;
static WORD dosgetword (DWORD addr)
{
WORD value;
dosmemget (addr, sizeof(WORD), &value);
return value;
}
WORD timer16 (void)
{
BYTE ah, al;
WORD ax, cx;
do {
disable ();
outportb (0x43, 0xC2);
cx = (inportb (0x40)<<8) & 0x8000;
al = inportb (0x40);
ah = inportb (0x40);
enable ();
ax = (ah<<8)+al;
} while (ax == 0); /* zero is problematic */
return (WORD) (- (short) (cx | (ax>>1)));
}
DWORD timer32 (void)
{
DWORD tick = dosgetword (0x46C);
DWORD t16 = timer16();
if ((DWORD) dosgetword (0x46C) != tick) /* tick count has advanced... */
{
if ((t16 & 0x8000) == 0) tick++; /* MSB zero ? */
}
return (tick<<16)+t16;
}
void Delay (double msec) /* milli-seconds, can be less than 1 */
{
DWORD t = timer32();
DWORD dt = (DWORD) floor (0.5 + msec*1193.18);
t += dt;
while (timer32() < t) ;
}
- Raw text -