www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/12/04/01:57:59

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: <MPG.12b2640e2b0657f09896d4@news.cso.uiuc.edu>
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?

- Raw text -


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