home *** CD-ROM | disk | FTP | other *** search
- {$A+,B-,D+,E+,F-,I+,L+,N+,O-,R-,S-,V-}
- Unit PopUp;
-
- Interface
-
- Uses Dos,Crt;
-
- Const
- RightShift = $0100; { right shift key }
- LeftShift = $0200; { left shift key }
- Control = $0400; { control key }
- ALT = $0800; { ALT key }
-
- Function Installed(OurID : Byte) : Byte;
-
- Procedure StayResident(OurID : Byte;Vector,HaltPtr : Pointer;PopKey : Word);
-
- Procedure ReleaseEnvironment; { releases the environment memory }
-
- Implementation
-
- Var
- ProgramVector : Pointer; { address of popup program }
- HaltVector : Pointer; { address of exit routine }
- oldDTA : Pointer; { interrupted DTA }
- OurDTA : Pointer; { our DTA }
- PrevBreak : Boolean; { previous BREAK status }
- EnvReleased : Boolean;
-
- Procedure ReleaseBlock(Segment : Word);
-
- { Given a segment, releases the memory. }
-
- InLine($07/ { pop es }
- $B4/$49/ { mov ah,49h }
- $CD/$21); { int 21h }
-
- Procedure ReleaseEnvironment;
-
- { Releases the memory of the environment segment. }
-
- Begin
- If Not EnvReleased Then
- Begin
- ReleaseBlock(MemW[PrefixSeg:$002C]); { free the enviornment }
- EnvReleased := True;
- End;
- End;
-
- Function GetBreakStatus : Boolean;
-
- InLine($B8/$00/$33/ { mov ax,3300h }
- $CD/$21/ { int 21h }
- $88/$D0); { mov al,dl }
-
- Procedure SetBreakStatus(Status : Boolean);
-
- InLine($5A/ { pop dx }
- $B8/$01/$33/ { mov ax,3301h }
- $CD/$21); { int 21h }
-
- Function GetDTAVec : Pointer;
-
- { returns the segment:offset of the DTA }
-
- InLine($B4/$2F/ { mov ah,2Fh }
- $CD/$21/ { int 21h }
- $89/$D8/ { mov ax,bx }
- $8C/$C2); { mov dx,es }
-
- Procedure SetDTAVec(DTA : Pointer);
-
- { sets the segment:offset of the DTA }
-
- InLine($8C/$D8/ { mov ax,ds }
- $5A/ { pop dx }
- $1F/ { pop ds }
- $50/ { push ax }
- $B4/$1A/ { mov ah,1Ah }
- $CD/$21/ { int 21h }
- $1F); { pop ds }
-
- Procedure EntryInit;
-
- Begin
- PrevBreak := GetBreakStatus; { save the BREAK status flag }
- SetBreakStatus(False); { turn of BREAK }
- OldDTA := GetDTAVec; { get the current DTA address }
- SetDTAVec(OurDTA); { set it to our own address }
- SwapVectors; { install our interrupt vectors }
- End;
-
- Procedure EntryExit;
-
- Begin
- SwapVectors; { restore the interrupt vectors }
- SetDTAVec(OldDTA); { restore the DTA address }
- SetBreakStatus(PrevBreak); { restore the original BREAKing status }
- End;
-
- Procedure ReleaseProgram; Interrupt;
-
- { Releases the program's memory. We call this when unhooking the program. }
-
- Begin
- If HaltVector <> Nil Then
- Begin
- EntryInit;
- InLine($FF/$1E/>HaltVector);
- EntryExit;
- End;
- ReleaseBlock(PrefixSeg);
- ReleaseEnvironment;
- End;
-
- Procedure CriticalHandler; External; {$L crit.obj}
- { internal routine - don't ever call direct }
-
- Procedure CallPopUp; Interrupt;
-
- { set some interrupt vectors and run the popup progams }
- { restore the interrupt vectors when done }
-
- Begin
- EntryInit;
- InLine($FF/$1E/>ProgramVector); { call the user's procedure }
- EntryExit;
- End;
-
- Function Installed(OurID : Byte) : Byte; External;
-
- Procedure InitializePopUp(OurID : Byte;PopKey : Word); External;
- { sets interrupt vectors }
- {$L popup.obj}
-
- Procedure StayResident(OurID : Byte;Vector,HaltPtr : Pointer;PopKey : Word);
-
- { saves some info and Terminated and Stays Resident }
-
- Begin
- OurDTA := GetDTAVec; { save our DTA address }
- SetIntVec($23,@CriticalHandler); { install our critical error handler }
- SwapVectors; { restore all the vectors, save ours }
- ProgramVector := Vector; { save the user program address }
- HaltVector := HaltPtr; { Our exit routine }
- InitializePopUp(OurID,PopKey); { install our interrupt vectors }
- Keep(0); { terminate and stay resident }
- End;
-
- Begin
- CheckBreak := False; { ignore the control break key }
- EnvReleased := False; { environment not yet released }
- End.