[Back to MEMORY SWAG index]  [Back to Main SWAG index]  [Original]

{
 SM> I have a bit of a problem with pascal 7 protected mode,
 SM> I have a TSR (assembly) that does my comms work for me.
 SM> I use intr(regs) with various settings to the registers to collect
 SM> data from the TSR. However when in protected mode my TSR seems
 SM> to be unavailable.

 SM> Do I need to switch to real mode from the app.
 SM> (if so how, I can't find it in the manual).

Yes. This is not documented in the manual, though.

 SM> Do I need to modify my TSR.
 SM> I presume not because I'm sure that the mouse drivers can be got
 SM> to work.

The problem is that interrupt calls in protected mode use
protected mode interrupt handlers. RTM.EXE converts protected
mode interrupts to real mode ones, for 'known' interrupts
(ie INT $21, some functions of INT $10, INT $33 (mouse)...)

What you need is to call the DPMI function that lets you issue
a real mode interrupt. What follows should help you (let me know
if it's not clear enough;-))
}

{ DPMI tools }

{$X+,G+}

{$IfNDef DPMI}
     You don't need that.
{$EndIf}

Unit MinDPMI;

Interface

Type TRealModeRegs =
     Record
          Case Integer Of
          0: ( EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint;
               Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word);
          1: ( DI,DIH, SI, SIH, BP, BPH, XX, XXH: Word;
               Case Integer of
                 0: (BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word);
                 1: (BL, BH, BLH, BHH, DL, DH, DLH, DHH,
                     CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte));
     End;

     TLowMemoryBlock     =
     Record
          ProtectedPtr   : Pointer;
          RealSegment    : Word;
          Size           : Word;
     End;

Procedure ClearRegs(Var RealRegs : TRealModeRegs);

Function RealModeInt(    IntNo          : Byte;
                         Var RealRegs   : TRealModeRegs) : Boolean;
{ IMPORTANT notes :
     - If SS and SP in RealRegs are set to 0, the DPMI server provides
       a 30 bytes stack. If not, the specified stack is used.    }

Procedure AllocateLowMem(Var Pt : TLowMemoryBlock; Size : Word);
Procedure FreeLowMem(Var Pt : TLowMemoryBlock);

Procedure SetProtectedIntVec(No : Byte; p : Pointer);
Procedure GetProtectedIntVec(No : Byte; Var p : Pointer);

Implementation

Uses WinAPI;

Type TDouble   =
     Record
          Lo, Hi    : Word;
     End;

Procedure ClearRegs;
Begin
     FillChar(RealRegs, SizeOf(RealRegs), 0);
End;

Function RealModeInt(    IntNo          : Byte;
                         Var RealRegs   : TRealModeRegs) : Boolean;
Assembler;
Asm
     Mov  AX, $0300
     Mov  BL, IntNo
     XOr  BH, BH
     XOr  CX, CX
     LES  DI, RealRegs
     Int  $31
     Mov  AX, 0               { Not XOr }
     JNC  @Ok
     Inc  AX
@Ok:
     Or   AX, AX
End;

Procedure AllocateLowMem;
Var  Adr  : LongInt;
Begin
     Adr:=GlobalDOSAlloc(Size);
     If Adr=0 Then Size:=0;
     Pt.ProtectedPtr:=Ptr(TDouble(Adr).Lo, 0);
     Pt.RealSegment:=TDouble(Adr).Hi;
     Pt.Size:=Size;
End;

Procedure FreeLowMem;
Begin
     GlobalDOSFree(Seg(Pt.ProtectedPtr^));
     FillChar(Pt, SizeOf(Pt), 0);           { Fills with NIL }
End;

Procedure SetProtectedIntVec(No : Byte; p : Pointer); Assembler;
Asm
     Mov  AX, $0205
     Mov  BL, No
     Mov  CX, TDouble[p].Hi        { Selector }
     Mov  DX, TDouble[p].Lo        { Offset }
     Int  $31
End;

Procedure GetProtectedIntVec(No : Byte; Var p : Pointer); Assembler;
Asm
     Mov  AX, $0204
     Mov  BL, No
     Int  $31
     LES  DI, p
     { Mov  ES:[DI], DX }
     { Mov  ES:[DI+2], CX }
     Mov  TDouble[ES:DI].Lo, DX
     Mov  TDouble[ES:DI].Hi, CX
End;

End.

[Back to MEMORY SWAG index]  [Back to Main SWAG index]  [Original]