Mail Archives: djgpp/1998/01/31/20:21:09

From: Kris Heidenstrom <kheidens AT clear DOT net DOT nz>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: High speed timing
Date: Sun, 01 Feb 1998 14:14:46 +1300
Organization: CLEAR Net,
Lines: 77
Message-ID: <>
References: <34D11CA2 DOT 79CD AT bellsouth DOT net>
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Lester "Ringo" Davis wrote:

> What is the best way to get a time value between events. I'm getting
> ready to interface a sonar system to a pc and need to measure time of
> flight of the sonar. I don't want to use a simple counter. I'm sure
> there is a function that does what I need, any ideas?

There may be a function in the library - check the libc reference.

As a general answer, you can read the 8254 programmable interval
timer (PIT).  It counts at 1.19318166666... MHz (resolution is
about 0.838 microseconds).  It has three channels.  You can use
channel 0 or channel 2.  There are also other timing methods you
can use, though this is probably the best for your application.
Some simple initialisation is needed as some motherboards (mostly
older ones) operate timer channel 0 in mode 3 and it needs to be
in mode 2.  Channel 2 is used to generate speaker audio, so if
you use it for timing, make sure you can't ever generate a beep
(may require special handling of the keyboard buffer, as the BIOS
generates a beep when the buffer gets full).

Running code in a tight loop, it is possible to time any period
to within a few microseconds using this technique.  How accurate
do you need to be?

As in any real-time application, you have to be aware of interrupts
and their overhead.  The timer tick interrupt, int 8, occurs every
time timer channel 0 wraps around, i.e. every 65536*0.838 us which
is every 54.9254 ms or 18.2065 times per second.  The BIOS int 8
handler doesn't do too much, but TSRs often hook the interrupt or
int 1Ch which is called by the BIOS int 8 handler, and TSRs are
often poorly written.  The nett effect is a gap in execution every
time a timer tick occurs.

Interrupts are also generated by keypresses and releases, and by
mouse clicks and movements.  All of these interrupts will cause a
gap in execution.  If you are using an interrupt yourself to start
and stop your timing, acceptance of your interrupt could be delayed
by these interrupts (the timer tick has the highest priority).

With DJGPP (or any protected mode program), there is also the
overhead of one or more mode switches.  The normal handlers for
hardware interrupts like the timer tick, keyboard, mouse etc
are real-mode ones, so if the CPU is in protected mode when the
interrupt occurs, two mode switches are required.  If you use
interrupts yourself, more mode switches could be needed.

Depending on what other requirements you have for your program,
you could consider disabling all interrupt sources during the
timing process.

I wrote a large document on timing and related stuff, it covers
all the things I've mentioned here and a lot of other things
that you might find useful if you want to 'cover all the bases'
in your programming.  The URL is:

Unfortunately, it is written for real-mode only (all the code is
16-bit real-mode, written for Borland C and TASM).  I will update
it for DJGPP one day :-)  You will need lots of extra information
on low-level programming under DJGPP.  There are pointers in the
excellent DJGPP FAQ under topics like 'writing interrupt handlers',
'accessing hardware directly' and 'inline assembly'.

One other idea - look at the Allegro package, it is designed for
game programming etc but I'm sure it will have timing stuff,
which may be self-contained.

Please feel free to email me if you think I can help with anything.

This reply sent to Ringo via email and to the newsgroup.

Kris Heidenstrom        Electronic designer, programmer, bass player
kheidens AT clear DOT net DOT nz

- Raw text -

  webmaster     delorie software   privacy  
  Copyright 2019   by DJ Delorie     Updated Jul 2019