www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/03/29/04:31:49

From: Maurice Lombardi <Maurice DOT Lombardi AT ujf-grenoble DOT fr>
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
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 <unistd.h>
#include <time.h>
#include <dpmi.h>

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 <dos.h>
#include <dpmi.h>

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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019