www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/05/18/08:01:42

Date: Tue, 18 May 1999 14:59:12 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: djgpp-workers AT delorie DOT com
cc: Shawn Hargreaves <Shawn AT talula DOT demon DOT co DOT uk>
Subject: uclock on Windows 9X
Message-ID: <Pine.SUN.3.91.990518145337.24330G-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

Somebody reported enough details on c.o.m.d., so I looked into this.  It 
seems like Windows waits until the next timer tick before its virtualized 
timer device begins to behave according to the new mode.  The code below 
simply waits until then before returning to the caller, the first time 
uclock is called.  This seems to eliminate the problem of negative 
results during the first 55msec, at least on my Windows 95 machine.

Does anybody see any danger in waiting like this, on the first call 
only?  If not, I will check this in.

*** src/libc/pc_hw/timer/uclock.c~0	Mon May 17 09:34:50 1999
--- src/libc/pc_hw/timer/uclock.c	Mon May 17 09:47:20 1999
***************
*** 1,9 ****
--- 1,11 ----
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <time.h>
+ #include <errno.h>
  #include <pc.h>
  #include <libc/farptrgs.h>
  #include <go32.h>
+ #include <dpmi.h>
  #include <libc/bss.h>
  
  static int uclock_bss = -1;
*************** uclock(void)
*** 26,31 ****
--- 28,35 ----
  
    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. */
  
*************** uclock(void)
*** 36,41 ****
--- 40,60 ----
      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 */

- Raw text -


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