[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: PCI IDE BusMastering programming from a DPMI16 application

DMA under DPMI is quite complex due to the variety of implementations.

I don' thave the DPMI spec handy here, but basically, you need to take a 
user mode address (selector:offset), get the base 'linear' address of the
selector using the Get Segment Base function, add in the offset to get the
'Linear' address.  You then need to determine if the current implementation
DPMI is using 'paging', if this is the case, then the linear address must
'page locked', and each page translated via ??? (Oh shoot, I can't find it
the DPMI 0.9 spec I'm looking at...)

If you are writing DOS DMA applications under windows, you should use the
VDS (Virtual
DMA Services specification, obtainable from the microsoft knowlege base as
article PW0519.  This has a 'scatter lock' call which will do what
you want, and is supported both under windows 3.1 and 95.


From: 	George JS Shin
Sent: 	Saturday, July 06, 1996 7:02 PM
To: 	Mailing List Recipients
Subject: 	PCI IDE BusMastering programming from a DPMI16 application

Hello there,

I'm currently facing some problem producing a physical memory address under
DPMI16 programming.  I just migrated to DPMI16 from DOS real mode
Under real-mode we know how CPU generates the 20-bit physical address from
pair of 16-bit segment:offset registers provided by the application. 
under DPMI16 the segment registers are loaded with selector value into the
descriptor table and the CPU uses this 16-bit selector value as an index
a descriptor table, obtain 24-bit base address from there, add the 16-bit
offset and use the resulting 24-bit address to access the physical memory
16MB boundary.   How does the CPU know where the descriptor table is

What i'm doing is PCI IDE BusMastering which is similar to ISA DMA
Thus, i need to program couple locations in the PCI BusMastering chip
with physical memory addresses (32-bit value) of few memory locations i
allocated (including a 256KB of data buffer).  Thus the chip would then use
its 32-bit registers to access the pre-allocated physical memory addresses
do its job.

I'm using the Borland's PowerPack and doing DPMI16 application programming 
and trying to figure out how to turn the selector and offset values 
(all 16-bits each) of a memory pointer to a 32-bit PHYSICAL memory address.
I have used combination of farmalloc() (for size < 64KB) and 
GlobalAlloc()/GlobalLock() (for size > 64KB) to allocate buffers.  For 
GlobalAlloc(), i can see that it has allocated two selectors each being 
64KB data block contiguous.

Can the use of WINAPI GetSelectorBase() be used to first obtain (from the 
descriptor table entry) the 24-bit base address of the allocated buffer
Is this what GetSelectorBase() return as a DWORD value?  If so i should be
able to add the offset portion of the pointer to this base address and
my physical memory address.  It seems both farmalloc() and GlobalLock()
offset portion of pointer to zero, thus i believe i can just take the
address as my physical base memory address.

If anyone has come across this area and willing to share some thoughts i 
would appreciate it very much.

Thank you very much,


PS For anybody using Borland's PP and doing DPMI16, i have found that using

   malloc() instead of farmalloc() will generate compiler warning message
   "type mismatch to a FAR pointer".  I would think that malloc() under
   DPMI16 would be the same as farmalloc(), but besides this warning
   malloc() will not produce offset of pointer to zero but farmalloc()
   Thus farmalloc() seems to normalize the return pointer as a HUGE type.
   Very strange.  If anyone can offer some insight to this i would

PSS As a final note i would like to thank the PP documentation for its 
    discussion on DPMI16 programming especially on example using variable
    "__SegIncr".  This came really handy when doing segment arithmetic on
    selectors.  Thanks Borland!!!