{***********************************************************************}
{									}
{ UNIT_SCN    Screen Handling Functions 				}
{									}
{ This unit implements the POWER TOOLS PLUS screen handling routines	}
{ These routines provide the capability to sense and control the in-	}
{ stalled video hardware.  Routines are provided for both direct and	}
{ for BIOS-level access to the screen buffer.				}
{									}
{  _BLACK	Black color attribute			     (constant) }
{  _BLUE	Blue color attribute			     (constant) }
{  _GREEN	Green color attribute			     (constant) }
{  _CYAN	Cyan color attribute			     (constant) }
{  _RED 	Red color attribute			     (constant) }
{  _MAGENTA	Magenta color attribute 		     (constant) }
{  _BROWN	Brown color attribute			     (constant) }
{  _LIGHTGRAY	Light gray color attribute		     (constant) }
{  _BLINK	Blinking foreground			     (constant) }
{  _INTENSITY	High intensity foreground		     (constant) }
{									}
{  _UNKNOWN	Adapter undetermined			     (constant) }
{  _ABSENT	No adapter installed			     (constant) }
{  _MONO	Monochrome type adapter 		     (constant) }
{  _COLOR	Color type adapter			     (constant) }
{									}
{  _CHONLY_SCN	Write characters only using __FastScn	     (constant) }
{  _USEATTR_SCN Use specified attributes using __FastScn     (constant) }
{  _CHATTR_SCN	Characters and attributes using __FastScn    (constant) }
{  _ATTRONLY_SCN					     (constant) }
{		Write attributes only using __FastScn			}
{									}
{  _CHNOMOVE_SCN					     (constant) }
{		Characters only and cursor does not move		}
{  _CHMOVE_SCN	Characters only and cursor is repositioned   (constant) }
{  _CHATTNOMOVE_SCN					     (constant) }
{		Characters and attributes and cursor does not move	}
{  _CHATTMOVE_SCN					     (constant) }
{		Characters and attributes and cursor is repositioned	}
{									}
{  _ScnPos	Screen element, character and attribute      (type)	}
{  _ScnImage	Full screen array of _ScnPos		     (type)	}
{  _ScnImagePtr Pointer to a screen buffer		     (type)	}
{									}
{  _MonitorType Type of monitor attached to an adapter	     (type)	}
{  _CursorType	Cursor appearance			     (type)	}
{									}
{  _ScnLoc	Location of screen adapter memory	     (variable) }
{  _CurMonitor	Monitor attached to _CurDevice		     (variable) }
{									}
{  _CurColumns	Number of screen columns		     (variable) }
{  _CurRows	Number of screen rows			     (variable) }
{  _CurMode	Current video display mode		     (variable) }
{  _CurDevice	Current device (_MONO or _COLOR)	     (variable) }
{  _MaxDisplayPage							}
{		Maximum display page number		     (variable) }
{  _CurDisplayPage							}
{		Current video display page		     (variable) }
{  _CurActivePage							}
{		Current video active page		     (variable) }
{									}
{  _MonoAdapter Monochrome adapter			     (variable) }
{  _ColorAdapter							}
{		Color/graphics adapter			     (variable) }
{  _EgaAdapter	EGA adapter				     (variable) }
{  _HercAdapter Hercules Mono Graphics card		     (variable) }
{  _VgaAdapter	PS/2 Video Graphics Array		     (variable) }
{  _McgaAdapter PS/2 Model 30 adapter			     (variable) }
{									}
{ __EquipScn	Determine adapters attached and video modes supported	}
{ __RetDvScn	Return the current video setting			}
{ __NewDvScn	Select and reset a display adapter			}
{ __ChgDvScn	Change the video device 				}
{ __BordScn	Set the border color					}
{ __BlinkScn	Alter the meaning of bit 7 of the attribute byte	}
{ __DisPgScn	Set the current display page				}
{ __ActPgScn	Set the active display page				}
{ __SpeedScn	Access video memory directly				}
{ __FastScn	Write to the screen directly				}
{ __WrAttScn	Write copies of an attribute only to to screen		}
{ __MoveScn	Access a block of video memory				}
{ __IsEmScn	Return the status of cursor emulation (EGA and VGA)	}
{ __EmOffScn	Turn off cursor emulation (EGA and VGA) 		}
{ __IsCurScn	Return the status of the cursor 			}
{ __COffScn	Turn the cursor on or off				}
{ __CSizeScn	Set the cursor size					}
{ __CSetScn	Choose cursor appearance				}
{ __GotoScn	Position the cursor					}
{ __WhereScn	Return the cursor position and size			}
{ __VertScn	Vertically scroll lines of text 			}
{ __ClearScn	Clear the screen					}
{ __HorzScn	Horizontally scroll columns of text			}
{ __AttrScn	Display characters and attributes			}
{ __RCharScn	Read a character and attribute from the screen		}
{ __WCharScn	Write copies of a character				}
{ __ReadScn	Read a string from the screen				}
{ __WriteScn	Write a string to the screen				}
{ __BoxScn	Display a box on the screen				}
{ __DebugScn	Export Unit_Scn implementation global variables 	}
{									}
{ Version 4.00	(C)Copyright Blaise Computing Inc. 1987 		}
{_______________________________________________________________________}

unit Unit_Scn;

interface
  uses DOS,			       { Turbo Pascal DOS unit		}
       Unit_Sup;		       { POWER TOOLS PLUS support unit	}

  const
    _BLACK	  = 0;		       { Foreground attribute values	}
    _BLUE	  = 1;
    _GREEN	  = 2;
    _CYAN	  = 3;
    _RED	  = 4;
    _MAGENTA	  = 5;
    _BROWN	  = 6;
    _LIGHTGRAY	  = 7;
    _BLINK	  = 8;		       { Foreground blink		}
    _INTENSITY	  = 8;		       { Foreground high intensity	}

    _UNKNOWN	  = $FF;
    _ABSENT	  = 0;		       { No adapter installed		}
    _MONO	  = 1;		       { Monochrome type adapter	}
    _COLOR	  = 2;		       { Color type adapter		}

    { Methods for accessing the video adapter memory directly.	These	}
    { are values for the Mode parameter to __FastScn.			}

    _CHONLY_SCN   = 0;		       { Write characters only		}
    _USEATTR_SCN  = 1;		       { Use specified attributes	}
    _CHATTR_SCN   = 2;		       { Characters and attributes	}
    _ATTRONLY_SCN = 3;		       { Write attributes only		}

    { Methods for accessing the video using __WriteScn and __ReadScn.	}

    _CHNOMOVE_SCN    = 0;	       { Chars only; cursor not moved	}
    _CHMOVE_SCN      = 1;	       { Chars only; cursor repositioned}
    _CHATTNOMOVE_SCN = 2;	       { Char and attr; cursor not moved}
    _CHATTMOVE_SCN   = 3;	       { Char and attr; cursor moved	}

  type
    _ScnPos	 = record	       { Screen element record is a	}
		     _Ch    : char;    { character followed by the	}
		     _Attr  : byte;    { attribute byte.		}
		   end;

    _ScnImage	 = array[1..4000] of _ScnPos;
    _ScnImagePtr = ^_ScnImage;

    _MonitorType = (_NoMonitor,
		    _MonoMonitor,      { Monochrome monitor		}
		    _ColorMonitor,     { Color monitor (composite also) }
		    _EnhancedMonitor,  { EGA rnhanced color monitor	}
		    _AnMonoMonitor,    { PS/2 analog monochrome monitor }
		    _AnColorMonitor);  { PS/2 analog color monitor	}

    _CursorType  = (_CBottom,	       { Standard double line at bottom }
		    _CTop,	       { Two scan lines at top of box	}
		    _CBlock,	       { All scan lines: blinking box	}
		    _CLowBlock,        { Lower half of the box		}
		    _CHighBlock,       { Upper half of the box		}
		    _CDash,	       { Middle two scan lines		}
		    _COff,	       { Cursor is invisible		}
		    _COn);	       { Cursor is visible		}


  var
    _ScnLoc	    : _ScnImagePtr;    { Screen adapter memory location }
    _CurColumns     : byte;	       { Number of screen columns	}
    _CurRows	    : byte;	       { Number of screen rows		}
    _CurMode	    : byte;	       { Current video display mode	}
    _CurDevice	    : byte;	       { _MONO or _COLOR device 	}
    _CurMonitor     : _MonitorType;    { Monitor attached to _CurDevice }
    _MaxDisplayPage : byte;	       { Maximum display page number	}
    _CurDisplayPage : byte;	       { Current video display page	}
    _CurActivePage  : byte;	       { Current video active page	}
    _MonoAdapter    : byte;	       { Monochrome adapter		}
    _ColorAdapter   : byte;	       { Color/graphics adapter 	}
    _EgaAdapter     : byte;	       { EGA adapter			}
    _HercAdapter    : byte;	       { Hercules Mono Graphics card	}
    _VgaAdapter     : byte;	       { PS/2 Video Graphics Array	}
    _McgaAdapter    : byte;	       { PS/2 Model 30 adapter		}

  procedure __EquipScn;
  function  __RetDvScn(var Mode,Cols,Rows,
			   ActivePage,DisplayPage : byte) : byte;
  procedure __NewDvScn(ScnMode,Rows : byte; var ErrorCode : word);
  procedure __ChgDvScn( Device : byte; var ErrorCode : word);
  procedure __BordScn (  Color : byte);
  procedure __BlinkScn(BlinkOn : boolean);
  procedure __DisPgScn(DisplayPage : byte);
  procedure __ActPgScn( ActivePage : byte);
  procedure __SpeedScn(SourcePtr,TargetPtr : pointer;
		       Count,Option,Attribute : word;
					 Wait : boolean);
  procedure __FastScn(X,Y : byte; BufferPtr : pointer;
				    NoChars : word;
			     Fore,Back,Mode : byte);
  procedure __WrAttScn(X,Y : byte; Count : word;
			       Fore,Back : byte);
  procedure __MoveScn (X1,Y1,X2,Y2 : byte; BufferPtr : pointer;
					    ToScreen : boolean);
  function  __IsEmScn  : boolean;
  procedure __EmOffScn(EmulationOff : boolean);
  function  __IsCurScn : boolean;
  procedure __COffScn (CursorOff : boolean);
  procedure __CSizeScn(Top,Bottom : byte);
  procedure __CSetScn (Ctype : _CursorType);
  procedure __GotoScn (X,Y : byte);
  procedure __WhereScn(var X,Y,TopScan,BotScan : byte);
  procedure __VertScn (X1,Y1,X2,Y2,NumRows,Fore,Back : byte;
						  Up : boolean);
  procedure __ClearScn(Fore,Back : byte);
  procedure __HorzScn (X1,Y1,X2,Y2,NumCols,Fore,Back : byte;
						Left : boolean);
  procedure __AttrScn (DisplayCh : char; Count : word; Fore,Back : byte);
  function  __RCharScn(var Fore,Back : byte) : char;
  procedure __WCharScn(DisplayCh : char; Count : word);
  procedure __ReadScn (X,Y : byte; BufferPtr : pointer;
				     NoChars : word;
					Mode : byte);
  procedure __WriteScn(X,Y : byte; BufferPtr : pointer;
				     NoChars : word;
			      Fore,Back,Mode : byte);
  procedure __BoxScn  (X1,Y1,X2,Y2,BoxType,Fore,Back : byte);

implementation

  type

    VParmBlock_  = record	       { VGA parameter block for PS/2	}
		     VSFIOff_  : word; { Offset of information block	}
		     VSFISeg_  : word; { Segment of information block	}
		     VMode_    : byte; { Video mode			}
		     VCols_    : word; { Columns on screen		}
		     VRlen_    : word; { Length of regen buffer 	}
		     VLocn_    : word; { Starting address in regen	}
		     VCsrRowCol_ : array[0 ..7] of word;   { Cursor po- }
				       { sition for 8 pages, row, col	}
		     VCsrType_ : word; { Cursor start/end value 	}
		     VActPage_ : byte; { Active display page		}
		     VCRTCntlAddr_ : word;   { CRT controller address	}
		     V3x8_     : byte; { Setting of 3x8 register	}
		     V3x9_     : byte; { Setting of 3x9 register	}
		     VRows_    : byte; { Rows on screen (char. lines)	}
		     VCharHeight_ : word;   { Scan lines / character	}
		     VActCombo_: byte; { Display combo code--active	}
		     VAltCombo_: byte; { Display combo code--alternate	}
		     VColors_  : word; { Colors supported/current mode	}
		     VPages_   : byte; { Display pages/current mode	}
		     VScanLines_ : byte; { Scan lines/current mode:	}
					 { 0 = 200, 1 = 350, 2 = 400,	}
					 { 3 = 480			}
		     VPrimBlock_ : byte; { Primary character block:	}
					 { 0 = Block 0, 1 = Block 1	}
					 { ..255 = Block 255		}
		     VSecBlock_  : byte; { Secondary character block	}
		     VMisc_	 : byte; { Miscellaneous state info	}
		     VReserved1_ : array[1 ..3] of byte;
		     VMemory_	 : byte; { video memory available:	}
					 { 0,1,2,3 = 64,128,192,256Kb	}
		     VSaveState_ : byte; { Save pointer state--bits 7	}
					 { and 6 reserved		}
					 { 5=1 : DCC extension active	}
					 { 4=1 : Palette override	}
					 { 3=1 : Graphics font override }
					 { 2=1 : Alpha font override	}
					 { 1=1 : Dynamic save area	}
					 { 0=1 : 512 character set	}
		     VReserved2_ : array[1..13] of byte
		   end;
    ScnVideo_	 = record		   { Video adapter control info }
		     CurPage_  : word;	   { Copy of _CurDisplayPage	}
		     Video_    : array[1..30] of byte;	   { PC/XT area }
		     EGAReset_ : word;	   { EGA information area	}
		     EGAArea_  : array[1..5] of byte;
		     EGAPtr_   : pointer;  { pointer to EGA variables	}
		     EGAState_ : byte;	   { EGA status byte		}
		   end;
    ScnStat_	 = array[1..2] of ^ScnVideo_;

    VideoModes_  = set of 0..19;
    LegalRows_	 = set of 25..50;
    SaveArray_	 = array[1..2] of boolean;

  var
    ScnState_	      : ScnStat_;      { BIOS Video save information	}
    StateSaved_       : SaveArray_;    { Video information saved?	}
    AvailColorModes_  : VideoModes_;   { Modes available on color device}
    AvailMonoModes_   : VideoModes_;   { Modes available on mono device }
    AvailColorRows_   : LegalRows_;    { Rows available on color device }
    AvailMonoRows_    : LegalRows_;    { Rows available on mono device	}
    DualDisplay_      : boolean;       { Two adapters present		}
    EgaMonitor_       : _MonitorType;  { Monitor attached: EGA		}
    AnalogMonitor_    : _MonitorType;  { Monitor attached: VGA/MCGA	}
    EgaMemory_	      : word;	       { 64, 128, 192, or 256 (K)	}
    MaxScanLine_      : byte;	       { Current character set size	}

  {$L isherc.obj}		       { Detect Hercules adpater	}
  function IsHerc : boolean;  external;
  {$I equipscn.imp}
  {$I vinfoscn.imp}		       { Return VGA information block	}
  {$I retdvscn.imp}
  {$I savescn.imp }		       { Used by __NewDvScn and __ChgScn}
  {$I newdvscn.imp}
  {$I chgdvscn.imp}
  {$I bordscn.imp }
  {$I blinkscn.imp}
  {$I dispgscn.imp}
  {$I actpgscn.imp}
  {$L speedscn.obj}		       { Direct video object code	}
  procedure __SpeedScn; external;
  {$I fastscn.imp }
  {$I wrattscn.imp}
  {$I movescn.imp }
  {$I isemscn.imp }
  {$I emoffscn.imp}
  {$I iscurscn.imp}
  {$I coffscn.imp }
  {$I csizescn.imp}
  {$I csetscn.imp }
  {$I gotoscn.imp }
  {$I wherescn.imp}
  {$I vertscn.imp }
  {$I clearscn.imp}
  {$I horzscn.imp }
  {$I attrscn.imp }
  {$I rcharscn.imp}
  {$I wcharscn.imp}
  {$I readscn.imp }
  {$I writescn.imp}
  {$I boxscn.imp  }

  begin {Initialization}

    _CurDisplayPage := 0;
    StateSaved_[1]  := FALSE;	       { Have not saved BIOS info yet	}
    StateSaved_[2]  := FALSE;

    { __EquipScn and __RetDvScn determine the video equipment instal-	}
    { led and initialize the exported variables that describe the	}
    { current video state.						}

    __EquipScn;
    _CurDevice := __RetDvScn(_CurMode,_CurColumns,_CurRows,
					  _CurActivePage,_CurDisplayPage)

  end. {Initialization}
