Date: Wed, 01 Sep 1999 09:11:29 -0500 From: Eric Rudd Subject: Re: Nearptr putpixel method? To: Eli Zaretskii Cc: djgpp AT delorie DOT com Message-id: <37CD3410.A9D2C9B7@cyberoptics.com> Organization: CyberOptics MIME-version: 1.0 X-Mailer: Mozilla 4.08 [en] (Win95; U) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit References: Reply-To: djgpp AT delorie DOT com Eli Zaretskii wrote: > On Tue, 31 Aug 1999, Eric Rudd wrote: > > > If one is using a linear frame buffer (usually located high in 32-bit memory > > space), one other option is to write a modified __djgpp_nearptr_enable() that > > opens the segment limit just wide enough to include the video card address. I was a little careless in my wording; of course, the segment limit must include the last byte in video memory. > > This at least prevents a stray pointer from wrapping and accessing DOS memory. > > Thus, a buggy program may crash, but at least it's unlikely to bring down DOS. > > I have been using this technique for several years now (both under DOS and > > under Win95), and have yet to have a problem with it. > > Care to post some minimal code that demonstrates this? It could be a > valuable addition to the FAQ. For comparison purposes, here is an excerpt from the file "nearptr.c" in the official distribution: int __djgpp_nearptr_enable(void) { if(!__dpmi_set_segment_limit(_my_ds(), 0xffffffffU)) { if(__dpmi_get_segment_limit(_my_ds()) != 0xffffffffU) return 0; /* We set it but DPMI ignored/truncated it */ __dpmi_set_segment_limit(__djgpp_ds_alias, 0xffffffffU); __dpmi_set_segment_limit(_my_cs(), 0xffffffffU); _crt0_startup_flags |= _CRT0_FLAG_NEARPTR; return 1; } return 0; } ...and here is my simple modification: int var_nearptr_enable(unsigned long limit) { if(!__dpmi_set_segment_limit(_my_ds(), limit)) { if(__dpmi_get_segment_limit(_my_ds()) != limit) return 0; /* We set it but DPMI ignored/truncated it */ __dpmi_set_segment_limit(__djgpp_ds_alias, limit); __dpmi_set_segment_limit(_my_cs(), limit); _crt0_startup_flags |= _CRT0_FLAG_NEARPTR; return 1; } return 0; } Here are some code fragments that illustrate how to use var_nearptr_enable() to set the segment limit appropriately: unsigned long LFBaddress; /* Physical address of linear frame buffer */ if (LFBaddress < __djgpp_base_address) { /* LFB is located below __djgpp_base_address -- must allow wrap. */ var_nearptr_enable(0xFFFFFFFF); } else { /* LFB is located above __djgpp_base_address -- open up segment limit just enough to include video memory, but still trap stray pointers that try to access DOS memory. */ unsigned long curlim, reqlim; curlim = __dpmi_get_segment_limit(_my_ds()); /* VideoMemorySize is the maximum size of the video memory space. Either query the video card, or put in something big, such as 16 MB. */ reqlim = LFBaddress - __djgpp_base_address + VideoMemorySize; /* If current segment limit is big enough, leave it alone. */ if (reqlim > curlim) var_nearptr_enable(reqlim); } I have omitted the rest of the code, since it is based on Charles Sandmann's vbe.zip code. -Eric Rudd