[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]