Date: Sun, 4 Jan 1998 14:29:05 -0800 (PST) Message-Id: <199801042229.OAA26976@adit.ap.net> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" To: =?iso-8859-1?Q?=22S=E9rgio_Vale_e_Pace=22?= , djgpp AT delorie DOT com From: Nate Eldredge Subject: Re: dos_ds Content-Transfer-Encoding: 8bit Precedence: bulk At 03:41 1/4/1998 -0200, Sérgio Vale e Pace wrote: >Somebody out there can tell-me how exactly dos_ds is defined and how it >works? `_dos_ds' (note leading underscore) is a selector which can be used to access conventional memory (as with `movedata'). It is actually a macro which expands to the ridiculously long name of a field in an info structure. > >I took a look on the DJGPP sources but seems like dos_ds uses the fat DS >method, >is that correct? Currently, it's similar to that. Its limit is set to -1 when it is allocated. However, it has been realized that this will not work on systems like Windows NT. The limit will be changed to something more reasonable in the next version, or so I understand. > >And another thing, can somebody tell-me how exactly fat DS works, I >already understand what I need to do to use it, bu I don't understand >why do this make it work, and how to calculate a real memory pointer >using fat DS. What see in the mail-archives for screen access look >pretty strange for me. The 386 has a 4GB address space. However, each segment has a base address within that, and a limit, above which access is disallowed. Each program sees itself running starting at virtual address zero. The Fat DS trick sets the limit of the DS segment to -1, or 0xFFFFFFFF in two's complement arithmetic. This means that the DS segment wraps all the way around the 4GB address space and any memory can be accessed relative to it. Since your program normally dereferences pointers relative to DS, you can now access any memory. Since the base of DS does not change, all your program's pointers can stay where they are. But conventional memory, for instance, will seem to be at some huge address. This is where the _djgpp_conventional_base (I think that's what it's called) variable comes in. Since the base of DS *can* change somewhat when sbrk() is called, this variable stores where conventional memory currently apprears to be. By adding some real-mode linear address to this, you can make a pointer to anywhere in conventional memory you want. The real-mode style segment/offset translation is not automatic, so you have to calculate it yourself: linear_address = (segment << 4) + offset; The canonical example is video memory, which in real mode is considered to be at 0xA000:0000. This translates to a linear address of 0xA0000, which one can add to _djgpp_conventional_base and write video memory quite nicely. Of course you must be careful doing this, because overwriting DOS or other important things living in conventional memory is depressingly easy with Fat DS on. Nate Eldredge eldredge AT ap DOT net