From: kunst AT 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) 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) ; }