I don't know if this is the right forum to post this question, but I think it may be the one with the most knowledgable users. I'm going to explain what I'm trying to do and what I've discovered so far before I actually ask the questions.
I'm trying to write some programs in DOS that interact with PCI hardware. The PCI hardware, because it bypasses the CPU and controls the Address Bus directly, always requires a physical address for memory manipulation. Of course, when you're writing a program, you always use a logical or linear address for memory amnipulation. When you want to read/write something to/from the "shared" memory space, you have to know both the logical/linear address (for the "CPU side" to use) and the physical address (for the "PCI side" to use).
In real mode, of course, the linear and physical address are the same, so the conversion is trivial. In most modern situations, though, you're usually not in real mode even when at a DOS prompt. You're either in protected mode under VCPI (using "real DOS" and a memory manager like EMM386), or in protected mode under DPMI (with Windows or some other DPMI server).
Under DPMI, I cannot figure out a good way to perform the conversion between linear and physical addresses. DPMI has INT 31h, Function 0800h, which is supposed to convert a physical address to a linear address, but not all DPMI servers support it. There is no DPMI function at all that I can find to convert a linear address to a physical address. Also, at least under Windows, Paging always seems to be enabled so it's not possible to just assume that the linear address and physical address are the same.
I've figured out how to do the conversions under VCPI, but there are some "quirky" things going on that I don't understand. To convert a Segment:Offset (logical) address to a linear address, you just multiply the Segment by 16 and add the Offset. I've also seen it declared in several places that "If Paging is disabled in the CPU, the linear address and physical address are the same", or words to that effect. Under VCPI (at least from what I've seen), Paging is always disabled. So, theoretically, it should be trivial to convert a linear address anywhere in memory to a physical address under VCPI, but it doesn't work that way.
VCPI has a service (INT 67h, Function DE06h) that will convert an address in the first MB of memory to a physical address for you. If you do this, you will find that some of the addresses in upper memory (the space between 640K and 1MB) are not in physical memory where the statement "If Paging is disabled in the CPU, the linear address and physical address are the same" tells you they should be. So, either the statement is not true, or there's some "missing piece" that I don't understand. Under VPCI, from what I can tell, all addresses above 1MB are linear address = physical address.
So, basically, here are my questions:
1) Under DMPI how can I convert a linear address to a physical address and vice-versa? I would like to do this without switching to protected mode, but will if there's no other way.
2) What's going on under VCPI where some of the upper memory addresses do not map linearly to physical addresses, even when Paging is disabled in the CPU? I suspect VCPI might be using some sort of memory-access exception trap, but why would they even bother?
Thanks in advance for any help provided!