home *** CD-ROM | disk | FTP | other *** search
- {$R-,S-,I+,D+,T+,F-,V-,B-,N-,L+ }
- 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 ReadKey : Char;
-
- Function Installed(OurID : Byte) : Byte;
-
- Procedure StayResident(OurID : Byte;Vector : Pointer;PopKey : Word);
-
- Procedure ReleaseEnvironment; { releases the environment memory }
-
- Implementation
-
- Var
- ProgramVector : Pointer; { address of popup program }
- old23h : Pointer; { interrupted ^C handler }
- old24h : Pointer; { interrupted critical error handler }
- oldDTA : Pointer; { interrupted DTA }
- int23h : Pointer; { our ^C handler }
- int24h : Pointer; { our critical error handler }
- 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;
-
- Procedure ReleaseProgram; Interrupt;
-
- { Releases the program's memory. We call this when unhooking the program. }
-
- Begin
- ReleaseBlock(PrefixSeg);
- ReleaseEnvironment;
- End;
-
- 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 }
-
- 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 }
-
- Procedure CallPopUp; Interrupt;
-
- { set some interrupt vectors and run the popup progams }
- { restore the interrupt vectors when done }
-
- 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 }
- GetIntVec($23,old23h); { save the control-break interrupt }
- GetIntVec($24,old24h); { save the critical error interrupt }
- SetIntVec($23,int23h); { install our control-break interrupt }
- SetIntVec($24,int24h); { install our critical error interrupt }
- InLine($FF/$1E/>ProgramVector); { call the user's procedure }
- SetIntVec($23,old23h); { restore the control-break interrupt }
- SetIntVec($24,old24h); { restore the critical error interrupt }
- SetDTAVec(OldDTA); { restore the DTA address }
- SetBreakStatus(PrevBreak); { restore the original BREAKing status }
- End;
-
- Function ReadKey : Char;
-
- Begin
- Repeat
- InLine($CD/$28); { int 28h }
- Until Keypressed;
- ReadKey := crt.ReadKey;
- End;
-
- Function Installed(OurID : Byte) : Byte; External;
-
- Procedure InitializePopUp(OurID : Byte;PopKey : Word); External;
- { sets interrupt vectors }
- {$L tpop.obj}
-
- Procedure StayResident(OurID : Byte;Vector : Pointer;PopKey : Word);
-
- { saves some info and Terminated and Stays Resident }
-
- Begin
- OurDTA := GetDTAVec; { save our DTA address }
- GetIntVec($23,int23h); { save our control-break interrupt }
- GetIntVec($24,int24h); { save our critical error interrupt }
- ProgramVector := Vector; { save the user program address }
- 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.