From: locke AT mcs DOT net (Peter Johnson) Newsgroups: comp.os.msdos.djgpp Subject: NT4 DPMI BUG (303h, Allocate Real-Mode Callback)--ATTN: DJ Deloie, Shawn Hargreaves, Eli Zaretskii Date: Fri, 3 Dec 1999 23:35:13 -0600 Organization: BiLogic Productions Lines: 45 Message-ID: NNTP-Posting-Host: isr4186.urh.uiuc.edu X-Newsreader: MicroPlanet Gravity v2.12 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com I found this bug in NT4's DPMI provider by accident when writing some NASM code to allocate and use a real-mode callback. This bug is probably why some DJGPP programs crash with an illegal instruction error under NT if they allocate a real-mode callback for mouse or sound (and may be why Allegro contains an explicit NT check and doesn't install a real-mode callback if NT is present). The DPMI function call 303h, Allocate Real-Mode Callback is supposed to take the following parameters: (ref: http://www.delorie.com/djgpp/doc/dpmi/api/310303.html) DS:(E)SI = selector:offset of protected mode procedure to call ES:(E)DI = selector:offset of 32H-byte buffer for real mode register data structure to be used when calling callback routine. The function is supposed to take the full 32-bit offset for both ESI and EDI. The bug is that under NT, only the low 16 bits of EDI are processed--it either trashes or ignores the high 16 bits!! (ESI, interestingly and thankfully, is correctly processed). Thus, if the real mode register data structure is located at a greater than 64k offset within ES, the program will cause an illegal instruction error under NT! As the location of data variables in DJGPP is obviously not controllable at build time, I devised the following workaround that should probably be included in src/libc/dpmi/api/d0303.s: 1) Get a selector from DPMI (function 0000h) 2) Get the base address of the DS selector (DPMI function 0006h) 3) Set the base address of the selector allocated in 1) to the value found in 2) plus the offset of the registers variable (ARG2). 4) Set the limit of the selector allocated in 1) to 32h (the size of the dpmi registers structure). 5) Pass the created selector and offset 0 as ES:EDI to 303h Obviously, this selector should be saved somewhere so d0304.s can free it. I'm not very proficient in GAS assembly (I'm a NASM fan), but if no one else wants to I can write a patch for the library files. -- Peter Johnson locke AT mcs DOT net :Windows: Where do you want to go today? :Linux: Where do you want to go tomorrow? :FreeBSD: Are you guys coming or what?