[comp.windows.ms.programmer] connecting Win30

mcdonald@aries.scs.uiuc.edu (Doug McDonald) (04/20/91)

I want to use Windows 3.0 (386 enhanced mode) to talk to a device
(an ADC convertor) that requires interrupts. I got this to work
just fine by writing a DOS character device driver .sys file, and
sending commands to it with ordinary DOS writes and getting data
with ordinary DOS reads. But this appears to only transfer ONE byte at 
a time. Its inefficient.


So I tried using the DOS IOCTL calls - which can transfer several bytes per
call. I used the MSC 5.1 intdos call. Works fine in real mode -
bombs in standard and 386 mode.


How does one do this? Tools I have: MSC5.1, the Windows 2.11 SDK, 
and assembler. I also run Qemm386.


Doug McDonald (mcdonald@aries.scs.uiuc.edu)

jjw@hpcndpc.CND.HP.COM (Jimmy Wright) (04/23/91)

>> I want to use Windows 3.0 (386 enhanced mode) to talk to a device
>> (an ADC convertor) that requires interrupts. I got this to work
>> just fine by writing a DOS character device driver .sys file, and
>> sending commands to it with ordinary DOS writes and getting data
>> with ordinary DOS reads. But this appears to only transfer ONE byte at 
>> a time. Its inefficient.

>> So I tried using the DOS IOCTL calls - which can transfer several bytes per
>> call. I used the MSC 5.1 intdos call. Works fine in real mode -
>> bombs in standard and 386 mode.

	Are you making the DOS calls from a Windows Application?
	If you are then your problem is your passing addresses that address
	extended memory( i.e. Protected Mode ) to DOS which can only address
	memory below 1MB (i.e. Real Mode).

	For Standard Mode a piece of software called DOSX.EXE (its a
	Dos Extender) is suppose to copy the buffers to real mode addresses
	and pass the Real Mode address to DOS.  Then on the way back from
	DOS it will copy the Real Mode buffer back to the original Protected
	mode buffer and deallocate the Real Mode buffer.  The problem is
	that DOSX.EXE doesn't properly handle the IOCTL commands AX=4402,
	or AX=4403 correctly.  This has been confirmed by Microsoft.  The
	only work-around is to pass Protected Mode addresses that address
	memory below 1MB.  This can be done from a Windows Application by
	calling GlobalDosAlloc() to allocate memory below 1MB.

	DOSX.EXE is suppose to do this buffer copying for all DOS
	commands that are passed buffers from the user's space.  So there
	could be other commands that DOSX.EXE screws up on.  The DOSX.EXE
	also handles ROM BIOS calls that point to the users's address
	space.

	You should also be aware if the buffer you pass down through the
	IOCTL call also contains pointers to your applications address
	space then you will have problems.  The DOSX.EXE cannot translate
	pointers embedded in your buffer, since your buffer could have
	any format that you desire.  You will have to explicitly handle
	embedded pointers yourself via the GlobalDosAlloc() call mentioned
	above.

	In Enhanced mode a virtual device driver called DOSMGR (its built
	into the WIN386.EXE kernel file) does the buffer translation.
	I personally haven't seen any problems in its use.  I believe I
	tested the IOCTL commands and they worked correctly.  Again you
	would have to worry about pointers (if any) you have embedded in
	the buffer your passing to DOS.  You can try the GlobalDosAlloc()
	call for Enhanced mode but like I said the DOSMGR seems to do
	a much better job of buffer translation than the DOSX.EXE module
	does for Standard mode.

>> How does one do this? Tools I have: MSC5.1, the Windows 2.11 SDK, 
>> and assembler. I also run Qemm386.

>> Doug McDonald (mcdonald@aries.scs.uiuc.edu)

	JJ

mcdonald@aries.scs.uiuc.edu (Doug McDonald) (04/25/91)

In article <1991Apr19.195538.23441@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
>I want to use Windows 3.0 (386 enhanced mode) to talk to a device
>(an ADC convertor) that requires interrupts. I got this to work
>just fine by writing a DOS character device driver .sys file, and
>sending commands to it with ordinary DOS writes and getting data
>with ordinary DOS reads. But this appears to only transfer ONE byte at 
>a time. Its inefficient.
>
>
>So I tried using the DOS IOCTL calls - which can transfer several bytes per
>call. I used the MSC 5.1 intdos call. Works fine in real mode -
>bombs in standard and 386 mode.
>
>
>How does one do this? Tools I have: MSC5.1, the Windows 2.11 SDK, 
>and assembler. I also run Qemm386.
>
>
>Doug McDonald (mcdonald@aries.scs.uiuc.edu)


Thanks for the help, folks. Yes, it can be done. You just have to do it right:
open the file with the MSC "open" call, do the IOCTL with the MSC "intdos"
call, then close with MSC close. The handle generated by "open" works
with the direct DOS call. 

Some combination of using "int86" instead of "intdos" and trying to use
"intdos" to call in 44h to do the open caused the bomb. Sigh.

This method of writing your own character mode driver and communicating
this way appears to work fine and be efficient. (Even so-called
character mode devices can happily pass data blocks using this method.) 
A near panacea for connecting Windows 3.0 to things like data collection
devices.


Doug McDonald