{***********************************************************************}
{									}
{ UNIT_INT  Intervention code						}
{									}
{ This unit implements the POWER TOOLS PLUS Intevention support 	}
{ services.  These routines provide the capability to schedule a Turbo	}
{ Pascal procedure to execute at specified intervals, time events or	}
{ when "hot keys" are pressed.						}
{									}
{									}
{  _SignalKeyDef Intervention code keyboard signals	     (type)	}
{  _Signalkey	Hot key specification			     (type)	}
{  _SignalTimeDef							}
{		Intervention code timer signals 	     (type)	}
{  _SignalTime	Timer signal specification		     (type)	}
{  _Signal	Intervention procedure signal parameter      (type)	}
{  _IntVect	Structure of intervention vectors	     (type)	}
{  _IntCtrl	Intervention code control block 	     (type)	}
{  _IntCtrlPtr	Pointer to intervention code control block   (type)	}
{									}
{  _IntCtrlAddr Address of intervention code control block   (variable) }
{									}
{ __InsInt	Install an intervention code procedure			}
{ __IsInsInt	Check for the presence of an intervention procedure	}
{ __ResetInt	Disable an intervention procedure and reestablish	}
{		all interrupt vectors.					}
{									}
{ Version 4.00	(C)Copyright Blaise Computing Inc.  1987		}
{_______________________________________________________________________}

unit Unit_Int;

interface
  uses DOS,			       { Turbo Pascal DOS unit		}
       Unit_Sup,		       { POWER TOOLS PLUS Support unit	}
       Unit_Isr;		       { POWER TOOLS PLUS ISR unit	}

  type
    _SignalKeyDef =		       { Intervention keyboard signals	}
		     ( _NoKeyRequest,  { No keyboard request pending	}
		       _Service,       { Service requested		}
		       _Sleep,	       { Put intervention code to sleep }
		       _Wake);	       { Awaken intervention procedure	}

    _SignalKey	   = record	       { Specifies a "hot key"		}
		       _HotKeySeq : _KeySeq;
		       _Action	  : _SignalKeyDef;
		       _Reserved  : byte
		     end;

    _SignalTimeDef =		       { Intervention timer signals	}
		     ( _NoTimeRequest, { No timer request pending	}
		       _Interval,      { Action taken at intervals	}
		       _Event);        { Action taken at a moment	}

    _SignalTime    = record	       { Specifies a timer request	}
		       _Ticks  : longint;
		       _Action : _SignalTimeDef
		     end;

    { Intervention procedures are declared with a single variable	}
    { parameter of type _Signal.  The paremeter is used to record	}
    { the signal which caused control to be passed to the intervention	}

    _Signal	   = record
		       _KeyAction   : _SignalKeyDef;
		       _HotKey	    : _KeySeq;
		       _TimeAction  : _SignalTimeDef;
		       _TimeIndex   : integer;
		       _ClockTime   : longint
		     end;

    { The intervention control block is used by the intervention	}
    { filters and scheduler to control access to the intervention code. }
    { Space for it is allocated in the code segment and is initialized	}
    { by __InsInt ("Install an intervention procedure").  It is made	}
    { public so it can be accessed by the intervention procedure for	}
    { primarily debugging purposes.  Its address is exported as a	}
    { variable. 							}

    _IntVect = record			    { Interrupt vectors used	}
		 _TimerPtr     : pointer;   { $08 - Timer Tick		}
		 _KeyBdPtr     : pointer;   { $09 - Keystroke		}
		 _COM2Ptr      : pointer;   { $0B - COM2 service	}
		 _COM1Ptr      : pointer;   { $0C - COM1 service	}
		 _DiskPtr      : pointer;   { $13 - BIOS disk services	}
		 _KeyIOPtr     : pointer;   { $16 - Keyboard I/O	}
		 _BreakPtr     : pointer;   { $1B - Ctrl/Break handler	}
		 _DOSPtr       : pointer;   { $21 - DOS functions	}
		 _IdlePtr      : pointer    { $28 - DOS idle		}
	       end;

    _IntCtrl = record			    { Intervention control block}
		 _IntSignature : _Signature;	 { Signature		}
		 _IntIdent     : _IdentStr;	 { Code indentification }
		 _IntPSP       : word;	    { PSP of the code		}
		 _IntVectors   : _IntVect;  { Interrupt vectors 	}
		 _IntInstalled : boolean;   { Already installed 	}
		 _IntDOSNeed   : boolean;   { Need DOS services 	}
		 _IntDKeyNeed  : boolean;   { Need DOS function 1 - 12	}
		 _IntKeySize   : byte;	    { Size of hot key table	}
		 _IntKeyTable  : pointer;   { Hot key table pointer	}
		 _IntKeyEvent  : _SignalKey;{ Found hot key, if any	}
		 _IntWait      : boolean;   { 21 or 28 filter cycling	}
		 _IntReadyKey  : byte;	    { ReadyKey function number	}
		 _IntGetKey    : byte;	    { GetKey function number	}
		 _IntRequest   : boolean;   { Intervention request made }
		 _IntSleep     : boolean;   { Intervention code asleep	}
		 _IntTimerBusy : boolean;   { Timer filter busy 	}
		 _IntKeyBdBusy : boolean;   { Keystroke filter busy	}
		 _IntCOM2Busy  : boolean;   { COM2 ISR is in use	}
		 _IntCOM1Busy  : boolean;   { COM1 ISR is in use	}
		 _IntDiskBusy  : boolean;   { BIOS disk filter busy	}
		 _IntKeyIOBusy : boolean;   { BIOS keyboard I/O busy	}
		 _IntIdleBusy  : boolean;   { DOS Idle filter busy	}
		 _IntInIdle    : boolean;   { In the DOS Idle filter	}
		 _IntCtrlBreak : boolean;   { Ctrl/Break or C pressed	}
		 _IntSchedPtr  : pointer;   { Address of ISR block for	}
					    { the intervention scheduler}
		 _IntInDOSPtr  : ^byte;     { Address of DOS in use flag}
		 _IntInCritPtr : ^byte;     { Address of critical error }
					    { in use flag.		}
		 _IntCurID     : word	    { Current process ID	}
	       end;
    _IntCtrlPtr  = ^_IntCtrl;

  var
    _IntCtrlAddr : _IntCtrlPtr; 	    { Control block address	}

  procedure __InsInt(IntAddress : pointer;
		      StackSize : word;
	     UsesDOS,UsesDOSKey : boolean;
		    KeyTablePtr : pointer;
		   KeyTableSize : byte;
		   TimeTablePtr : pointer;
		  TimeTableSize : byte;
		       IntIdent : _IdentStr;
		  var ErrorCode : word);
  function  __IsInsInt(      Ident : _IdentStr;
		       var Vectors : _IntVect;
			 var PSPPtr,
			    EnvPtr : pointer) : boolean;
  function  __ResetInt(Ident : _IdentStr) : word;

implementation

  { The file reticisr.obj contains the object code for __RetICIsr, which}
  { returns the address of the intervention code control block.  This	}
  { also contains allocated space for the control block (in the code	}
  { segment), and all the intervention code filters.  The filters are	}
  { far procedures declared public so that __IntIsr can install them in }
  { the appropriate interrupt vectors.					}

  {$L reticint.obj}
  function  __RetICInt : _IntCtrlPtr; external;
  procedure TimerFilter; external;     { Internal intervention code	}
  procedure KeybdFilter; external;     { filters.			}
  procedure COM2Filter;  external;
  procedure COM1Filter;  external;
  procedure DiskFilter;  external;
  procedure KeyIOFilter; external;
  procedure BreakIsr;	 external;
  procedure DOSFilter;	 external;
  procedure IdleFilter;  external;

  {$I insint.imp  }		       { Install intervention procedure }
  {$I isinsint.imp}		       { Check for intervention presence}
  {$I resetint.imp}		       { Reset intervention filters	}

  begin {Initialization}

    _IntCtrlAddr := __RetICInt	       { Return the location of the	}
				       { intervention code control block}
  end.	{Initialization}
