{***********************************************************************}
{									}
{ UNIT_SUP General support unit 					}
{									}
{ This unit contains the POWER TOOLS PLUS  global constants and 	}
{ variables used by the other POWER TOOLS PLUS units.			}
{									}
{  _VIDEO	   BIOS video interrupt 		     (constant) }
{  _BSERVICE	   BIOS services			     (constant) }
{  _KEYBD	   BIOS keyboard interrupt		     (constant) }
{  _DOS 	   DOS function interrupt		     (constant) }
{  _PRINT	   DOS PRINT interface interrupt	     (constant) }
{  _BIOSSEG	   Segment of BIOS/DOS communication area    (constant) }
{									}
{  _PC		   PC identification			     (constant) }
{  _XT		   XT identification			     (constant) }
{  _PCjr	   PCjr identification			     (constant) }
{  _AT		   AT identification			     (constant) }
{  _XT2 	   XT/2 identification			     (constant) }
{  _PS2_M30	   PS/2 model 30 identication		     (constant) }
{  _CVT 	   Convertible identification		     (constant) }
{  _PS2_M80	   PS/2 model 80 identification 	     (constant) }
{									}
{  _VerCtrl	   Version and copyright notice 	     (type)	}
{  _VerCtrlPtr	   Pointer to version and copyright notice   (type)	}
{									}
{  _Processor	   CPU type				     (type)	}
{  _PCMachType	   Machine model name			     (type)	}
{									}
{  _KeySeq	   Keyboard character/scancode sequence      (type)	}
{  _KeyBoard	   Keyboard buffer including end pointers    (type)	}
{									}
{  _MemoryByte	   Maximal array of memory (bytes)	     (type)	}
{  _MemoryChar	   Maximal array of memory (characters)      (type)	}
{  _BytePtr	   Byte pointer 			     (type)	}
{  _Path	   DOS full path (string[67])		     (type)	}
{  _VectorAddr	   Offset and segment portions of pointer    (type)	}
{									}
{  _VerCtrlAddr    Address of version and copyright notice   (variable) }
{									}
{  _Ident	   Machine ID byte			     (variable) }
{  _PCModel	   PC model identification		     (variable) }
{  _PCSubModel	   PC submodel identification		     (variable) }
{  _PCMachine	   PC machine name			     (variable) }
{  _PCProcessor    Processor type			     (variable) }
{									}
{  _DOSMajorVer    DOS major version number		     (variable) }
{  _DOSMinorVer    DOS minor version number		     (variable) }
{  _EnvSeg	   Segment of the environment at startup     (variable) }
{  _ExtendedKbdBIOS							}
{		   Extended keyboard BIOS available	     (variable) }
{  _EnhancedKbd    Enhanced keyboard attached		     (variable) }
{									}
{ __2LongSup	   Construct a long from two words	     (macro)	}
{ __HiWrdSup	   Return the high word from a long integer  (macro)	}
{ __LoWrdSup	   Return the low word from a long integer   (macro)	}
{ __2WordSup	   Construct a word from two bytes	     (macro)	}
{ __2ByteSup	   Construct a byte from two nybbles	     (macro)	}
{ __HiNybSup	   Return the high nybble from a byte	     (macro)	}
{ __LoNybSup	   Return the low nybble from a byte	     (macro)	}
{ __Ptr2LSup	   Convert a pointer to a long integer. 		}
{ __NPtrSup	   Normalize a pointer					}
{									}
{ Version 4.01 (C)Copyright Blaise Computing Inc. 1988			}
{_______________________________________________________________________}


unit Unit_Sup;

interface
  uses DOS;			       { Turbo Pascal DOS unit		}

  const
    _VIDEO	= $10;		       { BIOS video interrupt		}
    _BSERVICE	= $15;		       { BIOS services			}
    _KEYBD	= $16;		       { BIOS keyboard interrupt	}
    _DOS	= $21;		       { DOS function interrupt 	}
    _PRINT	= $2F;		       { DOS PRINT interface interrupt	}
    _BIOSSEG	= $0040;	       { Segment of BIOS/DOS communica- }
				       { tion area.			}
				       { Equipment identification	}
    _PC 	= $FF;		       { PC identification		}
    _XT 	= $FE;		       { XT identification		}
    _PCjr	= $FD;		       { PCjr identification		}
    _AT 	= $FC;		       { AT identification		}
    _XT2	= $FB;		       { XT/2 identification		}
    _PS2_M30	= $FA;		       { PS/2 model 30 identication	}
    _CVT	= $F9;		       { Convertible identification	}
    _PS2_M80	= $F8;		       { PS/2 model 80 identification	}

  type
    _VerCtrl	= record		{ Version and copyright notice	}
		    _VerMinor	  : byte;
		    _VerMajor	  : byte;
		    _VerStr	  : string[12];
		    _VerCopyright : string[40]
		  end;
    _VerCtrlPtr = ^_VerCtrl;

    _Processor	= (_8088,_80C88,_8086,_80286,_80386);
    _PCMachType = (_mUnknown,_mPC,_mXT,_mPCjr,_mAT,_mAT3x9,
			    _mXT2,_mXT286,_mCVT,_mPS2_25,
			    _mPS2_30,_mPS2_50,_mPS2_60,_mPS2_80);

     { Keyboard buffer keystroke sequence is a character followed by a	}
     { psuedo scan code.  Keyboard buffer itself is a circular queue	}
     { with pointers to head and tail.					}

    _KeySeq	 = record
		     case boolean of
		       TRUE : (_Ch	 : char;
			       _ScanCode : byte);
		       FALSE: (_ChScan	 : word)
		   end;
    _KeyBoard	 = record
		     _BufferHead  : integer;
		     _BufferTail  : integer;
		     _KbBuffer	  : array[1..16] of _KeySeq
		   end;

    _MemoryByte = array[1..65534] of byte;
    _MemoryChar = array[1..65534] of char;
    _BytePtr	= ^byte;
    _Path	= string[67];	       { DOS full path			}
    _VectorAddr = record	       { Used to type cast pointers and }
		    _Ofs : word;       { access the offset and segment. }
		    _Seg : word
		  end;
  var
    _VerCtrlAddr   : _VerCtrlPtr;

    _Ident	   : byte absolute $FFFF:$000E; { Machine ID byte	}
    _PCModel	   : byte;	       { PC model identification	}
    _PCSubModel    : byte;	       { PC submodel identification for }
    _PCMachine	   : _PCMachType;      { PS/2 models 50 and 60. 	}
    _PCProcessor   : _Processor;       { Processor type 		}

    _DOSMajorVer   : byte;	       { DOS major version number	}
    _DOSMinorVer   : byte;	       { DOS minor version number	}
    _EnvSeg	   : word;	       { Segment address of the environ-}
				       { ment at start up.		}
    _ExtendedKbdBIOS : boolean;        { Extended Keyboard services?	}
    _EnhancedKbd     : boolean;        { Enhanced Keyboard attached?	}

  { The following inline macros are used to build long integers from	}
  { words (__2LongSup), words from bytes (__2WordSup), bytes from	}
  { nybbles (__2ByteSup), and to  extract the constituent words from	}
  { long integers (_HiWrdSup and __LoWrdSup), and nybbles from bytes	}
  { (__HiNybSup and __LoNybSup).					}

  function __2LongSup(HiWord,LoWord : word) : longint;
		     inline( $58		      { pop ax		}
			    /$5A);		      { pop dx		}

  function __HiWrdSup(IntValue : longint) : word;
		     inline( $58		      { pop ax		}
			    /$58);		      { pop ax		}

  function __LoWrdSup(IntValue : longint) : word;
		     inline( $58		      { pop ax		}
			    /$5A);		      { pop dx		}

  function __2WordSup(HiByte,LoByte : byte) : word;
		     inline( $58		      { pop ax		}
			    /$5A		      { pop dx		}
			    /$8A/$E2);		      { mov ah,dl	}

  function __2ByteSup(HiNybble,LoNybble : byte) : byte;
		     inline(
			     $5B		      { pop bx		}
			    /$58		      { pop ax		}
			    /$32/$E4		      { xor ah,ah	}
			    /$B1/$04		      { mov cl,4	}
			    /$D3/$E0		      { shl ax,cl	}
			    /$80/$E3/$0F	      { and bl,0Fh	}
			    /$0A/$C3);		      { or  al,bl	}

  function __HiNybSup(ByteValue : byte) : byte;
		     inline(
			     $58		      { pop ax		}
			    /$32/$E4		      { xor ah,ah	}
			    /$B1/$04		      { mov cl,4	}
			    /$D3/$E8);		      { shr ax,cl	}

  function __LoNybSup(ByteValue : byte) : byte;
		     inline(
			     $58		      { pop ax		}
			    /$25/$0F/$00);	      { and ax,000Fh	}

  function __NPtrSup (ThisPtr : pointer) : pointer;
  function __Ptr2LSup(ThisPtr : pointer) : longint;

implementation

  {$L rversup.obj }
  function  __RVerSup : _VerCtrlPtr; external;
  {$I nptrsup.imp }
  {$I ptr2lsup.imp}
  {$I initsup.imp }

  begin {Initialization}

    __InitSup

  end.	{Initialization}
