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.