Message-ID: <37446E37.77180C1@enter.net> Date: Thu, 20 May 1999 16:19:03 -0400 From: Sean X-Mailer: Mozilla 4.51 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 Newsgroups: comp.os.msdos.djgpp Subject: Re: uclock trouble References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit NNTP-Posting-Host: 207.16.154.79 X-Original-NNTP-Posting-Host: 207.16.154.79 X-Trace: 20 May 1999 16:18:34 -0400, 207.16.154.79 Organization: Enter.Net Lines: 110 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Thanks a lot. :) No, it was more like 70000 uclocks :P cause it would count up to around 0x1200 then go down to 0x10000. I'm not converting hex in my head, but I think that's around 70000. What you said worked great, thanks again. Sean Eli Zaretskii wrote: > > On Sun, 16 May 1999, Sean wrote: > > > Each time I ran > > it, it would count for a while, then jump down to the same point, then > > count up and continue up through 0 normally, so the first thing I used > > uclock to time would be off by around 70000 uclocks, I think. > > 65536, to be exact ;-). > > This is a peculiarity of Windows 9X, or so it seems; thanks for paying > attention to it. Please try the version of `uclock' below and tell me > if it works okay; it seems to solve this problem in my machine. > > (If you want to know what do I think about the cause for the problem, > read the comments in the code below.) > > -------------------------------------------------------------------- > /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ > /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ > #include > #include > #include > #include > #include > #include > #include > > static int uclock_bss = -1; > > /* tics = about 18.2 * 65536 (1,192,755) > > actually, it's 0x1800b0 tics/day (FAQ) > / 24*60*60 sec/day > * 65536 utics/tic > = 1,193,180 utics/sec */ > > 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; > }