[comp.windows.ms.programmer] Accessing data between 640K and 1M from Windows.

wilcox@wucs1.wustl.edu (Don Wilcox) (06/06/91)

A question...

I am attempting to write a Windows 3.0 program which interfaces with a part-
icularly ill-behaved I/O card.  It acquires binary data (about 230K worth) from
an external device, and then writes this data into memory starting at 0xb00000.
A stand-alone program which the designers sent to me then reads the data into
the standard DOS address space using INT 15H, service 87H, which enters pro-
tected mode and make a block transfer.

The card designers had intended to use this in a standard 286 running DOS until
the end of time, and were not concerned about other cards.  My task, whether I
choose to accept or not, is to get this data into a Windows program where it
can be manipulated.

I have been able to get the standalone program to run in a DOS window (using
386Enh mode), but naturally the block transfer using int 15H will not work from
a normal Windows program (just to be sure, I checked).  My question is this:
what is the "best" way for me to get access to this data.  I have considered
having a DOS application much like the standalone which simply places the data
into a buffer which my Windows program allocated using the GlobalDOSAlloc()
service.  Here I am left with wondering if the address which is returned can
be used by a standalone DOS programming running under Windows.  If so, any
pointers on how to send this address to a DOS program?  Even better would be
to be able to access the data at 0xb00000 from Windows itself, but I can find
nothing about this in either the SDK or the DDK.  If anyone out there has any
experience with this, I would be very grateful for pointers.  I'll even buy
lunch for you if you are ever in St. Louis.

Thanks,

Don

Don Wilcox                         | "Hear, O Israel, the Lord your God, the
Washington University in St. Louis |     Lord is One."
email: wilcox@cs.wustl.edu         |

Norbert_Unterberg@p4.f36.n245.z2.fidonet.org (Norbert Unterberg) (06/12/91)

 > I am attempting to write a Windows 3.0 program which interfaces with a
 > part-
 > icularly ill-behaved I/O card.  It acquires binary data (about 230K
 > worth) from
 > an external device, and then writes this data into memory starting at
 > 0xb00000.

Use the DPMI. The DPMI (Dos Protected Mode Interface) is an API that provides 
the neccessary functions to "reach" your ill-behaved I/O card from protected 
mode (that is Windows in standard or enhanced mode). You can get a free copy of 
the specification from Intel.

There is another way to reach the address space between A0000 and FFFFF. 
Windows (or the SDK) as a set of built in selectors called __A000H, __B000H, 
__B800H, __C000H etc. Microsoft sais thar they are only accessible from 
assembly language (they are constant values in the library, not variables!), 
but with a little trick they can be used from within C. To read data from your 
i/o card at address 0xb0000h, use the following code:

      .
      .
      extern WORD _B000H;
      LPBYTE lpMyCard;

      lpMyCard = (LPSTR)MAKELONG(0, (NPSTR)&_B000H);

This declares the identifier _B000H as an external word. The linker resolves 
the reference in a way that the address (offset) of thar identifier has the 
value __B000H which is the selector. The MAKELONG statement genereates a far 
pointer from that value. This pointer can be used like any other far pointer to 
access the i/o card. But it is only valid in the area between B000:0 and 
B000:FFFF. For the next segment you must repeat the step with _C000H and so on.

Sorry, I've just seen thar your address is 0xB00000 and not 0xB0000. Then the 
only way is using the DPMI. But this post may be interesting to some other 
reader, so I don't delete the text... 
Norbert