[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
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
programming.
Under real-mode we know how CPU generates the 20-bit physical address from
a
pair of 16-bit segment:offset registers provided by the application.
However
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
into
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
w/in
16MB boundary. How does the CPU know where the descriptor table is
located?
What i'm doing is PCI IDE BusMastering which is similar to ISA DMA
programming.
Thus, i need to program couple locations in the PCI BusMastering chip
device
with physical memory addresses (32-bit value) of few memory locations i
have
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
to
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
block?
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
obtain
my physical memory address. It seems both farmalloc() and GlobalLock()
return
offset portion of pointer to zero, thus i believe i can just take the
24-bit
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,
-gshin
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
message
malloc() will not produce offset of pointer to zero but farmalloc()
will.
Thus farmalloc() seems to normalize the return pointer as a HUGE type.
Very strange. If anyone can offer some insight to this i would
appreciate
it.
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!!!