[comp.windows.ms.programmer] Extended memory access ...

hansh@idca.tds.PHILIPS.nl (Hans Helmonds) (12/19/90)

With MS-Windows running in Standard or Enhanced mode I have a problem
accessing an IO board from a windows program.

The board occupies 1 Mb in extended memory at D0000 (i.e. 13-14 Mb). 
                                              ===== 
I try to read and write data from conventional memory to the board
using Int 15H, function 87H (Move extended memory block). This
function returns 0 (Ok) if the program runs in Real mode, but returns
2 (exception interrupt error) if it runs in Standard or Enhanced mode.

Who can give me a hint about the easiest way to tackle this problem?

Thanks,

   Hans Helmonds  |  hansh@idca.tds.PHILIPS.nl  |  Tel +31 55 432161
      Philips     |  Apeldoorn, the Netherlands |  Fax +31 55 433488
 

davidds@microsoft.UUCP (David D'SOUZA) (01/03/91)

In article <1327@ssp18.idca.tds.philips.nl> hansh@idca.tds.PHILIPS.nl (Hans Helmonds) writes:
>
>With MS-Windows running in Standard or Enhanced mode I have a problem
>accessing an IO board from a windows program.
>
>The board occupies 1 Mb in extended memory at D0000 (i.e. 13-14 Mb). 
>                                              ===== 
>I try to read and write data from conventional memory to the board
>using Int 15H, function 87H (Move extended memory block). This
>function returns 0 (Ok) if the program runs in Real mode, but returns
>2 (exception interrupt error) if it runs in Standard or Enhanced mode.

Er, I believe Move extended memory block is something you should only
call from real mode.  If you call it from protected mode (ie. standard
or enhanced mode), you just get blown off and an error message is
returned.

Since this may be of interest to others, I will post this reply...

For Standard and Enhanced modes, you need to cons up a selector to the
PHYSICAL (remember that virtual memory in enhanced mode) memory
address.  Now, you ask, how the hell do I do that?

Well, after praying to the DPMI demi-gods, you will need to look at the
dpmi spec and check out section 16. Physical Address Mapping, page 83. 
With this function, you will specify a PHYSICAL address (D0000:0000)
and it will give you the LINEAR address for this memory location. 
(Works in both Standard and Enhanced modes but especially important for
Enhanced mode!)

Now you need to get a selector. Use the Kernel function (documented in
SDK)  AllocSelector(NULL).  This returns a selector which has a bogus
limit and base so now let's fix that...

To set the selector base, use the (undocumented in the SDK but documented 
in the DDK) kernel function 
void FAR PASCAL SetSelectorBase(WORD selector, DWORD selBase)

Use the return value from the above DPMI call and the selector from
AllocSelector.

To set the selector limit, use the (undocumented in the SDK but documented 
in the DDK) kernel function, 
void SetSelectorLimit(WORD selector, DWORD selLimit)

Amazing huh?

Hope this helps and I hope you have the DPMI spec. BTW: The
SetSelectorLimit/Base functions map to DPMI calls also.


-- Dave

PS: This is really device driver sort of stuff and belongs in a DLL 
instead of an app so that you can easily replace/isolate the OS
specific portions of your code.

PPS: Use of these functions is only encouraged in drivers ie. hardware specific
and OS dependent things. It is very stupid to use them in an app since not
all environments will support them.