Message-ID: <004101c29f53$919af9f0$0100a8c0@p4> From: "Andrew Cottrell" To: References: <10212071847 DOT AA13093 AT clio DOT rice DOT edu> <004401c29e90$dc1ccf30$0100a8c0 AT p4> Subject: Re: XP delay() again - potential solution Date: Mon, 9 Dec 2002 18:20:48 +1100 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1123 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1123 Reply-To: djgpp-workers AT delorie DOT com Try # 2:- I haev hopefully incorporated all of the feedback from everyone in this attempt. *** \djgppcvs\src\libc\dos\dos\delay.c Tue Mar 21 18:35:38 1995 --- src\libc\dos\dos\delay.c Mon Dec 9 18:08:16 2002 *************** *** 1,10 **** --- 1,16 ---- + /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ + #include #include + + #define tick_per_day (24*60*60*10000/182) + void delay(unsigned msec) { __dpmi_regs r; + while (msec) { unsigned usec; *************** *** 16,21 **** --- 22,66 ---- r.x.cx = usec>>16; r.x.dx = usec & 0xffff; __dpmi_int(0x15, &r); + if ((r.x.flags & 1) || (r.h.ah == 0x83)) + { + /* INT 15 FAILED, so fall back to the Time Of Day Tick */ + unsigned long start_tick; + unsigned long end_tick; + + r.h.ah = 0x00; + __dpmi_int(0x1A, &r); + + start_tick = (r.x.cx << 16) + (r.x.dx & 0xffff); + end_tick = (msec*182)/10000 + start_tick; + + if ((msec%10000/182) > (5000/182)) /* Manual round ticks */ + { + end_tick++; + } + if (end_tick > tick_per_day) /* Tick time past midnight */ + { + /* check for midnight */ + while (r.h.al == 0) + { + r.h.ah = 0x00; + __dpmi_int(0x1A, &r); + __dpmi_yield(); + } + end_tick = end_tick - tick_per_day; + } + + while (((r.x.cx << 16) + (r.x.dx & 0xffff)) <= end_tick) + { + r.h.ah = 0x00; + __dpmi_int(0x1A, &r); + __dpmi_yield(); + } + msec = 0; /* waited the required time */ + } + else + { msec -= msec_this; } } + } *** \djgppcvs\src\libc\dos\dos\delay.txh Mon Sep 6 22:39:32 1999 --- src\libc\dos\dos\delay.txh Mon Dec 9 18:16:48 2002 *************** *** 13,22 **** It uses the @code{int 15h} delay function to relinquish the CPU to other programs that might need it. ! Some operating systems that emulate DOS, such as OS/2 and Windows/NT, ! hang the DOS session when the @key{Pause} key is pressed during the call ! to @code{delay}. Plain DOS and Windows 3.X and 9X are known to not have ! this bug. @subheading Return Value --- 13,35 ---- It uses the @code{int 15h} delay function to relinquish the CPU to other programs that might need it. ! Some operating systems that emulate DOS, such as OS/2, Windows/NT, Windows 2000 ! and Windows XP hang the DOS session when the @key{Pause} key is pressed during ! the call to @code{delay}. Plain DOS and Windows 3.X and 9X are known to ! not have this bug. On Windows 2000 and XP to exit the pause press any key. ! ! Some operating systems, such as Windows 2000 and XP which do not support ! @code{int 15h}. @code{int 1ah} is used instead on these operating ! systems. This method has lower accuracy in the delay length. ! ! Windows 2000 and XP delay resolution is 54.9 millisecond. Under Windows ! 2000 and XP the delay function uses the Time Of Day Tick which occurs ! 18.2 times per second. This limits the accuracy of the delay to around ! 27 milliseconds on Windows 2000 and XP. On Windows 2000 and XP the Programable ! Interval Timer works and is a source of higher resolution than delay ! currently uses. Unfortunately PIT and Time Of Day tic does not appear ! to be coordinated. ! @subheading Return Value