From: Maurice Lombardi Newsgroups: comp.os.msdos.djgpp Subject: Re: Bug in Delay Date: Thu, 29 Mar 2001 11:24:50 +0200 Organization: Universite Joseph Fourier - Grenoble 1 Lines: 100 Message-ID: <3AC2FF62.2090203@ujf-grenoble.fr> References: <3AB7D646 DOT 16A658BC AT multimania DOT com> <3AB8CE13 DOT 2030802 AT ujf-grenoble DOT fr> <3ABAAB9E DOT 948D44B9 AT multimania DOT com> <1C47F554 DOT 20010329065831 DOT FOO-195F DOT frank AT g-n-u DOT de> NNTP-Posting-Host: knautie.ujf-grenoble.fr Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Trace: amazone.ujf-grenoble.fr 985857767 71218 152.77.252.196 (29 Mar 2001 09:22:47 GMT) X-Complaints-To: abus AT ujf-grenoble DOT fr NNTP-Posting-Date: 29 Mar 2001 09:22:47 GMT Cc: gpc AT gnu DOT de User-Agent: Mozilla/5.0 (Windows; U; Win98; fr-FR; m18) Gecko/20010131 Netscape6/6.01 X-Accept-Language: fr,it,en To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Frank Heckenbach wrote: > This should make it possible to fix/work-around the problem in > CRT... > > What I'm wondering is, if DJGPP's libc contains a delay() function > which does handle short delays well (and even seems to use > microseconds internally AFAICS), why doesn't its usleep() function > do the same thing? > > Are there any issues with the interrupt call used in delay() (that I > probably should be aware of when using it in CRT), or what is the > reason? Anyone knows? From the libc sources (in djlsr203.zip) usleep() uses the 55ms timer ticks while delay() uses the 0x1586 BIOS interrupt described as Category: BIOS INT 15 - BIOS - WAIT (AT,PS) AH = 86h CX:DX = interval in microseconds Return: CF clear if successful (wait interval elapsed) CF set on error or AH=83h wait already in progress AH = status (see #00496) Note: the resolution of the wait period is 977 microseconds on many systems because many BIOSes use the 1/1024 second fast interrupt from the AT real-time clock chip which is available on INT 70; because newer BIOSes may have much more precise timers available, it is not possible to use this function accurately for very short delays unless the precise behavior of the BIOS is known (or found through testing) SeeAlso: AH=41h,AH=83h,INT 1A/AX=FF01h,INT 70 Duno why the difference. I send a copy of this message to c.o.m.djgpp: somebody should know there. For reference: The code in usleep.c is #include #include #include unsigned int usleep(unsigned int _useconds) { clock_t cl_time; clock_t start_time = clock(); /* 977 * 1024 is about 1e6. The funny logic keeps the math from overflowing for large _useconds */ _useconds >>= 10; cl_time = _useconds * CLOCKS_PER_SEC / 977; while (1) { clock_t elapsed = clock() - start_time; if (elapsed >= cl_time) break; __dpmi_yield(); } return 0; } The code in delay.c is #include #include void delay(unsigned msec) { __dpmi_regs r; while (msec) { unsigned usec; unsigned msec_this = msec; if (msec_this > 4000) msec_this = 4000; usec = msec_this * 1000; r.h.ah = 0x86; r.x.cx = usec>>16; r.x.dx = usec & 0xffff; __dpmi_int(0x15, &r); msec -= msec_this; } } Hope this helps Maurice -- Maurice Lombardi Laboratoire de Spectrometrie Physique, Universite Joseph Fourier de Grenoble, BP87 38402 Saint Martin d'Heres Cedex FRANCE Tel: 33 (0)4 76 51 47 51 Fax: 33 (0)4 76 51 45 44 mailto:Maurice DOT Lombardi AT ujf-grenoble DOT fr