Board index » delphi » Two funny things under DPMI

Two funny things under DPMI

Just noticed this:

The test to see if SMARTDRV is installed doesnt work under DPMI.

The call just doesnt seem to happen, the registers come back with
their original values.

The same call works fine in real mode.

----

Another thing-- if you do a DOS EXEC call with DPMI running, the
called program doesnt get any environment.  I have tried passing NIL,
or a good environment selector, or a good environment real segment
value.  Also tried putting the environment in the lower 640K, where
DOS could see it.

 None of them seem to work with DPMI.  Works every
time in real mode.  I suspect the DPMI server is not mapping the
environment pointer correctly, or at all.

Can anyone confirm these problems, or suggest a fix?

Thanks.

-----------------------------------------------------------------------
George R. Gonzalez                        g...@boombox.micro.umn.edu
Sr. Sys. Programmer                       University of Minnesota

 

Re:Two funny things under DPMI


Quote
George Gonzalez wrote:
> Just noticed this:

> The test to see if SMARTDRV is installed doesnt work under DPMI.

> The call just doesnt seem to happen, the registers come back with
> their original values.

> The same call works fine in real mode.

When a real mode interrupt returns information in registers or uses
pointers, you can't call the interrupt directly.  You need to use the
DPMI server.

Here's how I do it.  First, you need a record type to pass to the DPMI
server.  The one I use:

type
  PRealModeRegs = ^TRealModeRegs;
  TRealModeRegs = record
    case integer of
      0 : (edi, esi, ebp, rsvd, ebx, edx, ecx, eax : longint);
      1 : (di, dih, si, sih, bp, bph, rs, rsh,
           bx, bxh, dx, dxh, cx, cxh, ax, axh,
           Flags, es, ds, fs, gs, ip, cs, sp, ss : word);
      2 : (dill, dilh, dihl, dihh, sill, silh, sihl, sihh,
           bpll, bplh, bphl, bphh, rsll, rslh, rshl, rshh,
           bl, bh, bxhl, bxhh, dl, dh, dxhl, dxhh,
           cl, ch, cxhl, cxhh, al, ah, axhl, axhh : byte);
    end;

Create a variable of this type, fill out the registers you need, then
pass it to this procedure:

function realint (vect : byte; var RMregs : TRealModeRegs) : word;
assembler;

{
 Used by the ROM-character related code to call the real-mode BIOS.
 Returns the error code reported by the DPMI server (0 means no error).

Quote
}

asm
  mov   ax,0300h        {function 0300h = simulate real mode
interrupt      }
  xor   bx,bx           {BH should be
cleared                               }
  mov   bl,[vect]       {set the interrupt vector to
call                   }
  xor   cx,cx           {do not transfer any data from RM stack -> PM
stack }
  les   di,[RMregs]     {get pointer to pseudoregister
structure            }
  int   31h             {call DPMI
server                                   }
end;

If you need to call an interrupt that requires a pointer, you usually
need to allocate memory using the GlobalDOSAlloc() function in the
WinAPI unit.

Quote
> ----

> Another thing-- if you do a DOS EXEC call with DPMI running, the
> called program doesnt get any environment.  I have tried passing NIL,
> or a good environment selector, or a good environment real segment
> value.  Also tried putting the environment in the lower 640K, where
> DOS could see it.

I'm not sure what you mean by this.  Perhaps what I mention above has to
do with the solution.

Quote
> Can anyone confirm these problems, or suggest a fix?

> Thanks.

> -----------------------------------------------------------------------
> George R. Gonzalez                        g...@boombox.micro.umn.edu
> Sr. Sys. Programmer                       University of Minnesota

--
Scott Earnest        | We now return you to our regularly |
set...@ix.netcom.com | scheduled chaos and mayhem. . . .  |

Other Threads