[comp.windows.ms.programmer] Windows and Interrupts

kevin@msa3b.UUCP (Kevin P. Kleinfelter) (12/05/90)

I'd like to generate an arbitrary interrupt from within a Windows
program.  Under non-Windows C, I'd just load up a struct with
values for the registers and make an "int86" call.  However,
the Windows doc for DOS3Call and NetBIOSCall imply that IF this
currently works, it may not work in the future.  To quote from DOS3Call's
doc:

   An application can use this function instead of a directly
   coded DOS 21H interrupt.  The DOS3Call function execute somewhat 
   faster than the equivalent DOS21H...

And from NetBIOSCall

   An application should call this function instead of directly
   issuing a NETBIOS 5CH interrupt to preserve compatibiloity
   with future Microsoft products.

I have an XXXXX.SYS driver, which my application communicates
with via an interrupt vector. This works just fine under plain
DOS.  Although I don't mind reworking the .SYS driver, I'd like
to come up with a driver that I could access from BOTH plain DOS
and Windows programs.

Any suggestions or pointers?
   
-- 
Kevin Kleinfelter @ Dun and Bradstreet Software, Inc (404) 239-2347
{emory,gatech}!nanovx!msa3b!kevin

Soon to become {emory,gatech}!nanovx!dbses0!kevin  (But not yet!)

richardh@hpopd.HP.COM (Richard Hancock) (12/07/90)

Two things you need to be aware of :-

  i)  you'll need to convert virtual addresses to real addresses if you want
      to support either protect mode (Standard/Enhanced);

  ii) you may need to supply a Virtual Device Driver if you want to support
      Enhanced mode.

There's a Windows 3.0 DDK (Device Driver Developer Kit).

Hopefully someone who's written a Windows 3.0 compatible device driver will
post their recommendations - my knowledge is second-hand.

Richard.

rommel@lan.informatik.tu-muenchen.dbp.de (Kai-Uwe Rommel) (12/07/90)

In article <1459@msa3b.UUCP> kevin@msa3b.UUCP (Kevin P. Kleinfelter) writes:
>I have an XXXXX.SYS driver, which my application communicates
>with via an interrupt vector. This works just fine under plain
>DOS.  Although I don't mind reworking the .SYS driver, I'd like
>to come up with a driver that I could access from BOTH plain DOS
>and Windows programs.

>Any suggestions or pointers?

Use INT 2F for communication between (Windows) programs and any TSR or
device driver that handles that interrupt. I use it and it is safe to
use. Be shure that you write your TSR/dev.driver in a way that it passes
calls that it cannot handle to the previous INT 2F address. See DOS
tech. ref. for details of AX register contents.

You can only pass data in registers when calling INT 2F in protected
mode from within a windows program, not addresses as they become invalid
because the machine is switched to real mode before the INT 2F handler
is called by Windows. You can use memory allocated with GlobalDosAlloc()
to communicate with larger amounts of data to the TSR/driver.

Kai Uwe Rommel

--
/* Kai Uwe Rommel
 * Munich
 * rommel@lan.informatik.tu-muenchen.dbp.de
 */

mojo@netcom.UUCP (Morris Jones) (12/09/90)

Kevin,

I have several scanner drivers that receive communications via an arbitrary
interrupt, and I've had no problems communicating with them via Windows
enhanced mode.  I use the int86 and int86x() functions.  But there are some
gotchas:

If you need to pass a memory buffer to your driver, the Windows program
must use GlobalDosAlloc() to get some memory that your device driver can
access.  Put the data there.  GlobalDosAlloc() gives you both a selector
and a segment address for the same area in memory.

If you pass an address to your device driver using a segment register,
i.e., ES:DX or whatever, then put the SELECTOR address in ES, because
Windows will convert it to the segment address when you make the call.
Or so it appears.  (I don't believe this is documented, it just works.)
If you pass the address in one of the GP registers, best use the SEGMENT
address because I don't think it'll be touched.

If you are doing multiple indirect addressing, that is, passing your
device driver a pointer to a pointer to more memory, be certain that
your second pointer is a SEGMENT address, not the selector, since of
course your device driver will be called in real mode.

During the course of discovering these things, I created functions to
emulate int86x() that called the DPMI function which performs a real mode
interrupt.  Interestingly I found that there were occasions where my
DPMI function would not work, but a call to int86x() from the library
would.  Go figure.

As has been said other places here, DPMI is clearly not _fully_
implemented.  Just enough to tease you into using it sometimes.   :)

Mojo
Caere Corp.

-- 
mojo@netcom.UUCP          Site Coordinating Instructor, San Jose South
Morris "Mojo" Jones       Skilled Motorcycling And Rider Training (S.M.A.R.T.)
Campbell, CA              800-675-5559 ... 800-CC-RIDER ...  408-423-2212
AA4KB @ N6LDL.#NOCAL.CA.USA.NA / aa4kb.ampr.org / netcom!mojo@apple.com