delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/03/21/11:29:38

From: kunst AT prl DOT philips DOT nl
Subject: Re: Timers (again) and also MIDI
To: johnson AT cdsmn (Erik Johnson)
Date: Mon, 21 Mar 1994 16:50:47 +0100 (MET)
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu (DJGPP users list)

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 -


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