From: mauch AT uni-duisburg DOT de (Michael Mauch) Newsgroups: comp.os.msdos.djgpp Subject: Re: testing uclock() Date: Tue, 29 Apr 1997 15:41:55 +0200 Organization: Home, sweet home (via Gesamthochschule Duisburg) Lines: 128 Distribution: world Message-ID: <3364e262.1961163@news.uni-duisburg.de> References: NNTP-Posting-Host: ppp103.uni-duisburg.de Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk On Sun, 27 Apr 1997 08:52:06 GMT, Eli Zaretskii wrote: > > On Sat, 26 Apr 1997, Michael Mauch wrote: > > > Then the program works like it should - on plain MS-DOS 7 in virtual x86 > > mode. The first call to uclock() returns 0 and the other values are > > always from 4 to 7 on my Pentium 75. > > > > However in a DOS window of Win95, I also get negative values sometimes > > (i.e. not in each run, and only one of the hundred numbers). > > That's because `uclock' reprograms the system timer chip, and > Windows 95 has a nasty habit of resetting it to the default mode > every now and then. When the timer works in its default mode, > you get negative values. Oh, that's the problem then. Doesn't this mean that we can't use uclock() in a Win95 DOS window, because we don't know what mode that default mode is? On the other hand: isn't it possible that this default mode is just the same as the one set by the first call to uclock()? The difference between two consecutive calls to uclock() remains the same, even after that single negative difference. I removed the first three outportb() calls from the uclock source code, and now I don't get any negative differences anymore. So maybe Win95 resets the mode only when it feels that somebody else fiddled around with the timer chip? Looking through Ralf Brown's Interrupt List, I also found a DOS (16 bit mode in DOS window) function that returns the "clock tick time in 840ns units since Windows was started". It's a VxD API call to the Virtual Timer Device of MS-Windows/Win95 - I don't know if this kind of functions work under NT. I append a little test program that works under Win95 (hopefully it's not too long for this newsgroup/list). It has to be compiled with a 16 bit compiler (I used BC++ 4.52), because API call is a 16 bit function. I have no clue how to translate this to DJGPP, maybe someone else is able to do that. Regards... Michael /* Compile with "bcc -v -3 -B vtd.c" */ #include #include typedef unsigned long uclock_t; /* Alas, Borland C has no 64-bit integers, so forget about the upper 32 bits for now. */ uclock_t wuclock(void) { static struct { unsigned short lo,hi; } VTD; /* address of the Virtual Timer Device API entry point */ static int GotEntryPoint; static uclock_t rv,base; if(!GotEntryPoint) { asm{ pushad mov ax,0x1684 mov bx,0x0005 xor di,di mov es,di int 0x2F mov word ptr VTD.lo,di mov word ptr VTD.hi,es popad } base = 0; GotEntryPoint = 1; } if(VTD.hi | VTD.lo) /* if(NULL != *(void far*)VTD) */ { static unsigned long TicksLow,TicksHigh; asm{ /* 0100h get current clock tick time Return: EDX:EAX = clock tick time in 840ns units since Windows was started */ push edx push eax mov ax,0x0100 call dword ptr [VTD] mov dword ptr TicksLow,eax mov dword ptr TicksHigh,edx pop eax pop edx } rv = TicksLow; /* !!! throwing away the upper 32 bit for now */ if(!base) base = rv; return rv - base; } return (uclock_t)(-1); /* error: VTD API not available */ } #define MAXDT 10000 int main(int argc,char* argv[]) { uclock_t t0; static uclock_t dt[MAXDT]; size_t i; printf( "%d\n", (int) (t0 = wuclock()) ); /* first call resets clock to 0 */ for (i=0; i