Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!src.honeywell.com!msi.umn.edu!math.fu-berlin.de!unido!rwthinf!slcdec!hippo!f1.n6000.z2.fidonet.org!p4.f36.n245.z2.fidonet.org!Norbert_Unterberg From: Norbert_Unterberg@p4.f36.n245.z2.fidonet.org (Norbert Unterberg) Newsgroups: comp.windows.ms.programmer Subject: Windows3/TSR interface HELP Message-ID: <1485449533@p4.f36.n245.z2.fidonet.org> Date: 17 May 91 10:00:00 GMT References: <6362@p1.f6.n242.z2.fidonet.org> Reply-To: Norbert_Unterberg%p4.f36.n245.z2@hippo.dfv.rwth-aachen.de (Norbert Unterberg) Organization: Point of SoftStream, Dortmund, Germany Lines: 68 Comment-To: Dave_Lockwood@f1.n6000.z2.fidonet.org (Dave Lockwood) > I'm trying to write a Windows 3 application which needs to interface to a > DOS TSR which communicates via an interrupt. Everything works fine in real > mode, but I get UAEs and reboots in both standard and 386 enhanced mode. > > The code segment that's causing the trouble: > [...] > hBuffer = GlobalAlloc(GHND,512L); > lpBuffer = GlobalLock(hBuffer); > InRegs.x.di = FP_OFF(lpBuffer); > SegRegs.es = FP_SEG(lpBuffer); > > int86x(0x7f,&InRegs,&OutRegs,&SegRegs); > > I've done a lot of RTFM-ing, but to no avail (at least, the problem > isn't > solved). I didn't write the TSR, so it's difficult to get changes done > there (I don't have the source). You obviously have read the wrong manual. Ever heard of the DPMI (Dos Protected Mode Interface)? That should solve your problems. The protected mode you must watch out for a lot of things you can ignore in real mode. Here are some of the differences: - In protected mode the processor can access more than 1MB of memory. In real mode only the 1st MByte can be reached by the processor. So if you GlobalAlloc some memory in protected mode, that memory can be anywhere, very likely somewhere above 1 MB. Hence your TSR (in real mode) can _not_ reach that memory. - In proteted mode all segment `addresses' are no longer `adresses'. All values stored in segment registers are selectors. A selector is an index in a (local or global) descriptor table (LDT/GDT), which contains the linear addresses for the segments. So a selector only identifies a segment. That si similar to the Windows memory handle. The segment can float in memory, but the selector remains valid, as long as the segment address is updated in the descriptor table. - The protected mode has its own interrupt table, which is not identical with the real mode interrupt table. So calling a (real mode) TSR from protected mode must fail, because the protected mode interrupt vector does not point to the TSR. Because these restrictions make it (nearly) impossible for a protected mode application to communicate with a real mode programm, some people from Borland, Microsoft, Intel, Lotus, Phar Lap etc. came together and developed the DPMI specification. DPMI stands for Dos Protected Mode Interface and is an API for protected mode programs that allows it to do several (dirty) things and tricks otherwise not possible in PM. A copy of that specification can freely(!) be orderd by Intel, Santa Clara. This DPMI has all the functions you need to call yout TSR. Fist you must allocate the memory you need in the real mode addressable 1 MB region. That is done with function `Allocate DOS Memory Block'. The result is a selector AND the segment address of the memory block. Then you fill in the required register values for the TSR into a data area called `real mode call structur'. When calling the real mode program, all registers will be loaded from this structure. Then you can call yout TSR via the DPMI fuction `Simulate Real Mode Interrupt'. The TSR will (hopefully) do its job and fill the memory with the expected values. And don't forget to free the DOS memory block, if it is no longer needed. Hope I could give you some clues... Norbert, Dortmund, FRG