Date: Sun, 4 Jan 1998 15:23:56 -0500 (EST) Message-Id: <199801042023.PAA12044@delorie.com> From: DJ Delorie To: space AT gold DOT com DOT br CC: djgpp AT delorie DOT com In-reply-to: <34AFC9B1.2678D80C@gold.com.br> (space@gold.com.br) Subject: Re: dos_ds Precedence: bulk > Somebody out there can tell-me how exactly dos_ds is defined and how > it works? dos_ds is a segment with a zero base and an appropriate limit, so when you use it, you get the DOS memory instead of your program's memory. > I took a look on the DJGPP sources but seems like dos_ds uses the > fat DS method, is that correct? Perhaps it did, but it shouldn't. In the next release, the DOS segment will only be 1M+64K long (0x110000 bytes), because that's all DPMI lets you use anyway. If you need to access physical memory above that, you need to ask DPMI to map the physical memory into the logical memory space and tell you where it put it, and then use other DPMI calls to create a segment that refers to it (farptr) or locate it in your memory space (nearptr). > 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 supports 4Gb of logical address space. Your program occupies a tiny fraction of it. Normally, you segments are only big enough to cover your tiny fraction, to protect the rest of memory from your program. With a "fat" DS, the size of your segment is grown to 4Gb, so that *all* of the 386's logical address space is available to you. If you know where your segment starts (logically), you can use that to calculate what pointers end up pointing to specific logical addresses. For example, If you wanted to access a device at physical address 0x15000000, you'd first ask DPMI to map it into the 386's logical address space. Let's say it ends up at 0x98000000. Now, your memory is mapped somewhere too (this is the __djgpp_base_address variable, but you can ask DPMI for this also), let's say it's at 0x23000000. Since virtual address 0x0 is the start of your segment (0x23000000), if you want to get to 0x98000000 you'd have to subtract pointers: char *foo = 0x98000000 - 0x23000000; or char *foo = 0x98000000 - __djgpp_base_address; Now, let's say you want to point to something in conventional memory, like the VGA (0x000a0000). First, you have to figure out where conventional memory *is*. This is easy; it's at logical address zero! char *dos_mem = 0 - 0x23000000; Note that this is what __djgpp_conventional_base is. To find the VGA, add 0x000a0000 to that: char *vga_mem = 0 - 0x23000000 + 0xa0000; or char *vga_mem = __djgpp_conventional_base + 0xa0000; The thing you have to remember is that DPMI may *move* your program's memory (the 0x23000000 changes) whenever you call malloc(). The two variables noted above are automatically changed whenever needed, but you have to recompute any pointers you're keeping that point outside of your own program space. The manual page for __djgpp_nearptr_enable covers most of this information.