www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2002/09/19/08:07:20

Message-ID: <BDD73AE8AEE3EF438E07420C2600E9F65C9150@qtiexch0.qgraph.com>
From: "Sisco, Michael" <mdsisco AT qtiworld DOT com>
To: "'Eli Zaretskii'" <eliz AT is DOT elta DOT co DOT il>
Cc: "Djgpp (E-mail)" <djgpp AT delorie DOT com>
Subject: RE: Fw: uclock() within an interrupt handler
Date: Thu, 19 Sep 2002 07:08:13 -0500
MIME-Version: 1.0
X-Mailer: Internet Mail Service (5.5.2656.59)
Reply-To: djgpp AT delorie DOT com

> On Fri, 13 Sep 2002, Sisco, Michael wrote:
>
> > Has anyone ever tried calling uclock() from inside an interrupt handler?
>
> As you will see from the sources, uclock issues an Int 2Fh call, which 
> might not be a good idea in an interrupt handler.  I'd suggest to take 
> that call out of the code and see if that helps.

I specifically checked the source for uclock() and I found no such interrupt

being issued. Am I missing something?

// From uclock.c
uclock_t
uclock(void)
{
  static uclock_t base = 0;
  static unsigned long last_tics = 0;
  unsigned char lsb, msb;
  unsigned long tics, otics;
  uclock_t rv;

  if (uclock_bss != __bss_count)
  {
    int e = errno;

    /* switch the timer to mode 2 (rate generator) */
    /* rather than mode 3 (square wave), which doesn't count linearly. */

    outportb(0x43, 0x34);
    outportb(0x40, 0xff);
    outportb(0x40, 0xff);

    base = 0;
    last_tics = 0;
    uclock_bss = __bss_count;

    /* It seems like Windows 9X virtualization of the timer device
       delays the actual execution of the above command until the
       next timer tick.  Or maybe it only consults the actual device
       once per tick.  In any case, the values returned during the
       first 55 msec after the timer was reprogrammed still look as
       if the timer worked in mode 3.  So we simply wait for one clock
       tick when we run on Windows.  */
    _farsetsel(_dos_ds);
    otics = _farnspeekl(0x46c);
    do {
      errno = 0;
      __dpmi_yield();   /* will set errno to ENOSYS on plain DOS */
    } while (errno == 0 && _farnspeekl(0x46c) == otics);
    errno = e;
  }

  /* Make sure the numbers we get are consistent */
  do {
    otics = _farpeekl(_dos_ds, 0x46c);
    outportb(0x43, 0x00);
    lsb = inportb(0x40);
    msb = inportb(0x40);
    tics = _farpeekl(_dos_ds, 0x46c);
  } while (otics != tics);

  /* calculate absolute time */
  msb ^= 0xff;
  lsb ^= 0xff;
  rv = ((uclock_t)tics << 16) | (msb << 8) | lsb;

  if (base == 0L)
    base = rv;

  if (last_tics > tics) /* midnight happened */
    base -= 0x1800b00000LL;

  last_tics = tics;

  /* return relative time */
  return rv - base;
}

- Raw text -


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