Date: Fri, 30 Sep 1994 17:27:58 -0400 (EDT) From: Edwin Phillips To: "Victor K. Chu" Cc: DJGPP mailing list Subject: Re: accuracy of clock() On Fri, 30 Sep 1994, Victor K. Chu wrote: > Dear Sir, > > Please do help me to find the original post regarding timer16() and > time32(), if it does not cause too much trouble. Besides, could you > give me a more precise direction about which "archives of list" that > I should be looking for. I am not familar with those stuff. > > Thank you ver much. > > Victor Chu > Here's a repost of the two high resolution timer related messages. I use the C ones and they seem to work ok. :) Ed /****************************************************************************/ /* Ed Phillips flaregun AT strauss DOT udel DOT edu University of Delaware */ /* Jr Systems Programmer (302) 831-6082 IT/Network and Systems Services */ /****************************************************************************/ >From: cnc AT netcom8 DOT netcom DOT com (Christopher Christensen) >Date: Fri, 28 Jan 1994 12:14:05 PST >In-Reply-To: Thomas Sams "How to measure time better than 1/10000 sec?" (Jan 28, 3:22pm) >X-Mailer: Mail User's Shell (7.2.5 10/14/92) >To: Thomas Sams >Subject: Re: How to measure time better than 1/10000 sec? >Cc: djgpp AT sun DOT soe DOT clarkson DOT edu >Status: O >X-Status: > >>Is it possible to measure time to better than, say, 1/10000 sec ? >>Does one have to turn off the 18.2 Hz interrupts from the machine >>to do so? >>How? >> >>Thanks in advance >> Thomas Sams. > >You can read the timer register directly. The following code should work >assuming that the timer hasn't been reprogrammed to interrupt at more than >18.2 Hz. The timer runs at 1193180 Hz (65536 times faster than the 18.2 >Hz timer tick). If you have problems with this code, let me know and I will >try to fix it. > >------------------------------------------------------------ >/* short timer16() -- return 16-bit timer value */ >/* timer resolution is 0.8381 microseconds (1193180 Hz clock) */ >/* rolls over 18.2 times per second */ > .align 2 >.globl _timer16 >_timer16: > cli > movb $0xc2,%al # read back cmd (status+count) > outb %al,$0x43 > .byte 0xeb,0 # jmp delay > inb $0x40,%al # get status (msb=out pin) > movb %al,%cl > .byte 0xeb,0 # jmp delay > inb $0x40,%al # get LSB > movb %al,%ah > .byte 0xeb,0 # jmp delay > inb $0x40,%al # get MSB > sti > xchgb %ah,%al > orw %ax,%ax > jz _timer16 # zero is problematic > shlb $1,%cl # carry=out status > rcrw $1,%ax > negw %ax > ret > > >/* unsigned int timer32() -- return 32-bit timer value */ >/* returns a timer with 0.8381 microsecond resolution that rolls over > about once an hour */ > .align 2 >.globl _timer32 >_timer32: > call __go32_conventional_mem_selector > movw %ax,%gs > xorl %eax,%eax > movl %gs:0x046c,%edx # read timer tick count in dos memory > call _timer16 > cmpl %gs:0x046c,%edx # has timer advanced? > je Ldone4 > > testb $0x80,%ah # if msbit==0 inc %edx > jnz Ldone4 > incl %edx >Ldone4: > shll $16,%edx > orl %edx,%eax > ret >------------------------------------------------------------ > > >-- >---------------------------------------------------------------------- >: Christopher : Huntington Beach California, USA : >: Christensen : email: cnc AT netcom DOT com : >---------------------------------------------------------------------- > >From: kunst AT prl DOT philips DOT nl >Message-Id: <9403211550 DOT AA15246 AT hpas5 DOT 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) >In-Reply-To: <27256 DOT johnson AT cdsmn> from "Erik Johnson" at Mar 21, 94 07:34:12 am >Mime-Version: 1.0 >Content-Type: text/plain; charset=US-ASCII >Content-Transfer-Encoding: 7bit >Content-Length: 2501 >Status: O >X-Status: > > >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 /* enable(), disable() */ >#include /* 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) ; >} >