From: Neil Goldberg Newsgroups: comp.os.msdos.djgpp Subject: Re: 0xA000 plot pixels questions in 13h mode Date: Thu, 5 Aug 1999 16:27:24 +0100 Organization: The MITRE Corporation Lines: 126 Message-ID: References: <3 DOT 0 DOT 1 DOT 32 DOT 19990717221010 DOT 00698cd8 AT apiitkl DOT edu DOT my> <3 DOT 0 DOT 1 DOT 32 DOT 19990718134517 DOT 006a72c8 AT apiitkl DOT edu DOT my> NNTP-Posting-Host: mm58842-pc.mitre.org Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Trace: top.mitre.org 933884732 24156 128.29.96.60 (5 Aug 1999 20:25:32 GMT) X-Complaints-To: usenet AT news DOT mitre DOT org NNTP-Posting-Date: 5 Aug 1999 20:25:32 GMT In-Reply-To: <3.0.1.32.19990718134517.006a72c8@apiitkl.edu.my> X-X-Sender: ngoldber AT mailsrv2 DOT mitre DOT org To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On Sun, 18 Jul 1999, Mark wrote: > > - Can this _dos_ds looked at as some kind of 'portal with guardsmen' that > allow 0 to 1 MB addresses? > > - If so ... Are all _farnspokeb(), _farnspokel(), _farnspeekw() etc. codes > using that same 'portal' defined once(?) in a porgram with > _farsetsel(_dos_ds)? > > - Can I just use the same _dos_ds with all my _farpokeb() accesses to those > addresses? Or does _my_ds come in here somewhere? > > - And what does the DS mean in _dos_ds? _dos_ds is a selector pointing to the first megabyte of linear memory (The one typically used by real-mode DOS programs, and the place where 0xA0000 is). This selector is provided because many protected mode programs want to use that memory without having to go to the trouble of allocating it, etc.; since it is always available to programs compiled with real-mode compilers. Users of DJGPP say: "THATS NOT FAIR. I DON'T WANT TO GO THROUGH ALL THAT S**T!" So DJ Delorie say okidoke, here ya go: _dos_ds. Yes, _dos_ds is good for all _far* accesses. What I usually do is assign it to a local variable... it's a function call that can be avoided. And DS means data segment... in real mode, your DS in any program where you have chosen a memory model with a seperate data segment is always 0 > >> - Why are there so many functions that look like they are far or near types > >> ? The compiler is 32bit and in the FAQ stated that DJGPP doesn't even > >> recognise the far and near types ?!?! > > > >Some compilers allow you to specify near and far as part of the pointer, > >like `char far *p'. GCC (DJGPP's compiler) doesn't-- all pointers are > >effectively near. These functions are provided to let you access memory > >outside your segment anyway. > > I don't realy get this. Where will my pointers become far or remain near? > If I were to declare: > int i[100], *ptr; > ptr=i; > Is this within my program's segment or is it going to be far? > If far, ... what would be near? > And if I were to declare: > unsigned char *double_buffer > double_buffer = (unsigned char *)malloc(320*200); > This 'double_buffer' is far, right? > If there are any differences between the '*ptr' and the 'double_buffer', > what are they? Okay, here's the DJGPP pointer skinny: In the old skool real mode programs, to get outside your silly 16-bit segment, you had to declare a far * type pointer... to get access to 0xA000 for example. That makes the pointer 32-bit, 16-bit segment, 16-bit offset. Right? In DJGPP, all pointers you declare are 32-bit pointers, but in protected mode, these pointers are near. Why near? Because you still have only access to the memory pointed at by DS when the program is launched. (That is what near means). For safety reasons, protected mode selectors (like your DS) have a cap on which memory addresses can be referenced, and 0xA0000 is out of range. To get at it, you need a far pointer. For compatibility with DJGPP and UNIX oriented gcc, there is no such thing as a far pointer. In environments like UNIX, not being able to break out of your memory space is a good idea. DJ Delorie spake: This will not do! DOS users need a way to get out of near mode." So he added some far* functions to do the dirty, incompatible work. These pointers are 48-bit, 16-bit selector (like _dos_ds, for example) and a 32-bit offset. This allows you to BREAK OUT and access stuff pointed at by those other segment selectors. So no, int i[100], i[140342342], and *ptr are all near. You can actually allocate arrays as big as you can imagine (well, until the DPMI server complains). But to get out of the pen, you need those far* functions that insert the Intel PC only code. Note: Don't get cocky with far* functions. you can cause lots of General Protect Faults if you aren't prudent with making sure your selectors are valid and you're not accessing memory outside their limits. Case in point: memory at the _dos_ds selector DOES NOT wrap around if your offset is past 0xFFFF. That's when your program goes down. Finally, if you're really slick, you can try this trick. Instead of using _far pokey functions, you can use the __djgpp_nearptr_enable() hack. What does it do? It changes the segment limit of your normal DS (which all your near pointers use) to 2 ^ 32, meaning all memory is accessible by any near pointer... Be careful, ALL memory is now under your control and you can easily bring down Windows or DOS or whatever you're in if you're not careful. To get access say to 0xA0000 with a regular 'ol array... #include "dpmi.h" //dpmi_int, to get into video mode 0x13. #include "sys/nearptr.h" //nearptr stuff, and __djgpp_conventional_base void main (void) { __djgpp_nearptr_enable(); //YOWZERS! WHAT A DAREDEVIL! char * videobuffer = 0xA0000 + __djgpp_conventional_base; __dpmi_int(0x13); for(int i = 0; i < 64000; i++) videobuffer[i] = i; //Make a silly pattern __djgpp_nearptr_disable(); //Dont forget to clean up. } That should fill your screen with some stupid colors. But look! No far pointers! _djgpp_conventional_base is a constant that makes the pointer point to the "real zero" of your memory. Add any constant, and the pointer is pointing to where you really want it to be. 0xA0000 is where your VGA screenbuffer is... and so with that you can do whatever. This is my favorite way of getting at low DOS memory, or VESA linear framebuffers. Just remember though, be careful. Don't be alarmed if a program you write with this trick causes your system to reboot. Educating PC hackers.... moogla