From: sandmann AT clio DOT rice DOT edu (Charles Sandmann) Message-Id: <10212071847.AA13093@clio.rice.edu> Subject: Re: XP delay() again - potential solution To: djgpp-workers AT delorie DOT com Date: Sat, 7 Dec 2002 12:47:48 -0600 (CST) In-Reply-To: <001a01c29db4$6ee30100$0100a8c0@p4> from "Andrew Cottrell" at Dec 07, 2002 04:49:08 PM X-Mailer: ELM [version 2.5 PL2] Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > This was discussed a while ago and I cannot remember if there was a solution > proposed, except one I worked on. Below is a modified delay.c that works on > XP. It does have some problems in that it is only accuate to approx 27 > milliseconds as the TOD tick is updated every 54.9 millisends and I do a > manual rounding check in the code in order to try to make the delay a bit > more accurate. I also worked on something similar - my WIP from last year is attached at the bottom. I was trying to get more accuracy, but due to the unsync between the counter and tick rollover, I think there were bugs I hadn't fixed in the stuff below (it didn't work?). I also tried to call the int15 call and checked for success, just in case they fixed it some day. Yours looks fine, and I think we ought to get it into the library for the next release. Maybe document the accuracy issue. Maybe do some yields in the busy loop. Thanks for working on this, I'm just completely swamped. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #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); if(r.x.flags & 1) { unsigned char lsb, msb, omsb; int msbcount = msec * 4661; /* Actually 1193180/256 */ outportb(0x43, 0x34); /* Program as counter */ outportb(0x40, 0xff); outportb(0x40, 0xff); outportb(0x43, 0x00); lsb = inportb(0x40); omsb = inportb(0x40) ^ 0xff; do { /* printf("msbcount %d\n",msbcount); */ outportb(0x43, 0x00); lsb = inportb(0x40); msb = inportb(0x40) ^ 0xff; if(msb >= omsb) { msbcount -= (unsigned)msb - (unsigned)omsb; } else { msbcount -= (unsigned)msb + 256 - (unsigned)omsb; } omsb = msb; } while (msbcount > 0); printf("int 15 failed!\n"); return; } msec -= msec_this; } } int main(int argc, char **argv) { int i; i = atoi(argv[1]); if(i) delay(i); return 0; }