{***********************************************************************}
{									}
{ __NewDvScn  Select and reset a video display adapter			}
{									}
{ procedure __NewDvScn(ScnMode,Rows : byte; var ErrorCode : word);	}
{									}
{	      ScnMode	The video mode to set.	The possible values are }
{									}
{			Mode  Description				}
{			----  ----------------------------------------	}
{			  0   40 columns, black and white		}
{			  1   40 columns, color 			}
{			  2   80 columns, black and white		}
{			  3   80 columns, color 			}
{			  4   320 by 200 color (graphics)		}
{			  5   320 by 200 black and white (graphics)	}
{			  6   640 by 200 black and white (graphics)	}
{			  7   Monochrome				}
{			  8   160 by 200 color (PCjr only, low res)	}
{			  9   320 by 200 color (PCjr only, medium res)	}
{			 10   640 by 200 color (PCjr only, high res)	}
{			 13   320 by 200 color (EGA/VGA, medium res)	}
{			 14   640 by 200 color (EGA/VGA only, high res) }
{			 15   640 by 350 mono  (EGA/VGA only, high res) }
{			 16   640 by 350 color (EGA and Enhanced disp)	}
{					       (also VGA)		}
{			 17   640 by 480 color (VGA and MCGA)		}
{			 18   640 by 480 color (VGA only)		}
{			 19   320 by 200 color (VGA and MCGA)		}
{	      Rows	The maximum number of rows on the current	}
{			display device.  The only allowable values are	}
{			25, 30, 43 (EGA and VGA) and 50 (VGA only).	}
{	      ErrorCode Returned error status code.  The values are:	}
{			0 - Video adapter successfully reset		}
{			1 - Invalid number of rows specified		}
{			2 - Invalid screen mode specified		}
{			3 - No color device				}
{			4 - No monochrome device			}
{			5 - Cannot support more than 25 text lines.	}
{			    This error occurs if 30, 43 or 50 lines are }
{			    requested and either the installed hardware }
{			    does not support more than 25 lines, or the }
{			    requested video mode does not support more	}
{			    than 25 lines.				}
{			6 - Enhanced graphics mode not available. The	}
{			    EGA or VGA is not installed or enhanced	}
{			    display monitor is not installed.		}
{									}
{ Description This function selects and resets a video adapter and	}
{	      initializes 25, 43 or 50-line mode. If the adapter cannot }
{	      be set, either because the parameters are invalid, or the }
{	      hardware does not support the screen mode selection, no	}
{	      action is taken, and a nonzero error code returned.  If	}
{	      the mode is successfully set, then 0 is the returned	}
{	      code.  The following variables may be altered by		}
{	      calling __NewDvScn:					}
{									}
{	      _MaxDisplayPage	       Maximum display page number	}
{	      _CurDisplayPage	       Current video display page	}
{	      _CurActivePage	       Current video active page	}
{	      _CurColumns	       Current number of screen cols	}
{	      _CurRows		       Current number of screen rows	}
{	      _CurMode		       Current display mode		}
{	      _CurDevice	       _MONO or _COLOR			}
{	      _ScnLoc		       Address of video adapter memory	}
{	      StateSaved_	       Video information has been saved }
{	      ScnState_ 	       Video information for adapter	}
{	      MaxScanLine_	       Last scan line of a character	}
{									}
{ Version     4.00 (C)Copyright Blaise Computing Inc. 1987		}
{_______________________________________________________________________}

procedure __NewDvScn(ScnMode,Rows : byte; var ErrorCode : word);


  {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  { CheckParams  Check input parameters for valid request		}
  {_____________________________________________________________________}

  function CheckParams(CMode,CRows : byte) : word;

    var
      ErrCode : word;

    begin {CheckParams}

      { First check for completely out-of-range input parmeters.	}

      if ((CRows = 25) or (CRows = 30) or
				       (CRows = 43) or (CRows = 50)) then
	 ErrCode := 0
      else
	 ErrCode := 1;		       { Unknown row specification	}

      if ( ((CMode >= 0) and (CMode <= 10)) or
				 ((CMode >= 13) and (CMode <= 19)) ) then
	 ErrCode := 0
      else
	 ErrCode := 2;		       { Unknown mode specification	}

      if (ErrCode <> 0) then
	 begin
	   CheckParams := ErrCode;
	   Exit
	 end;

      { Check for legal rows and mode combinations.			}

      if ( ((CRows = 25) and
	      (((CMode >= 0) and (CMode <= 16)) or (CMode = 19))) or
	   ((CRows = 30) and ((CMode = 17) or (CMode = 18)))	  or
	   ((CRows = 43) and
	      (((CMode >= 0) and (CMode <= 3)) or
		(CMode = 7) or (CMode = 15) or (CMode = 16)))	  or
	   ((CRows = 50) and
	      (((CMode >= 0) and (CMode <= 3)) or (CMode = 7))) ) then
	 CheckParams := 0	       { Can support this combination	}
      else
	 begin
	   CheckParams := 5;	       { Not acceptable 		}
	   Exit
	 end;

      { Next check request against adapters installed.			}

      if (CMode in AvailColorModes_) then
	 if (CRows in AvailColorRows_) then
	    CheckParams := 0
	 else
	    CheckParams := 5
      else
	if (CMode in AvailMonoModes_) then
	   if (CRows in AvailMonoRows_) then
	      CheckParams := 0
	   else
	      CheckParams := 5
	else if ((CMode = 7) or (CMode = 15)) then
	   CheckParams := 4	       { No mono device available	}
	else if (CMode > 12) then      { EGA/VGA graphics not available }
	   CheckParams := 6
	else if (CMode > 7) then       { PCjr modes without a PCjr	}
	   CheckParams := 2
	else
	   CheckParams := 3	       { No Color device available	}

    end;  {CheckParams}

  var
    Device	: byte; 	       { Device type (_COLOR or _MONO)	}
    CurDevice	: byte; 	       { Current device type		}
    EquipFlag	: word absolute _BIOSSEG:$0010;     {Equipment flag	}
    VideoSet	: word; 	       { Video portion of Equipment flag}
    Mode	: byte;
    Cols,PRows	: byte;
    APage,DPage : byte;
    Reg 	: registers;

  begin {__NewDvScn}

    { First get default hardware setting if current adapter selected	}

    if (ScnMode = _UNKNOWN) then
      begin
	VideoSet := EquipFlag and $0030;
	case VideoSet of
	  $0010 : ScnMode := 3;
	  $0020 : ScnMode := 3;
	  $0030 : ScnMode := 7;
	end ;
      end;

    { Next check input parameters for a valid request, considering the	}
    { combinations possible with the installed hardware.		}

    ErrorCode := CheckParams(ScnMode,Rows);
    if (ErrorCode <> 0) then
	Exit;

    CurDevice := __RetDvScn(Mode,Cols,PRows,APage,DPage);

    { Now prepare to set BIOS equipment flag:				}

    case ScnMode of
      0..6: begin		       { These are the color modes	}
	      if (ScnMode <= 1) then
		 VideoSet := $0010
	      else
		 VideoSet := $0020;
	      Device := _COLOR
	    end;
	 7: begin		       { Monochrome mode		}
	      VideoSet := $0030;
	      Device   := _MONO
	    end;
	15: begin		       { EGA/VGA Monochrome graphics	}
	      VideoSet := $0030;
	      Device   := _MONO
	    end;
      13,14,16..19:
	    begin		       { EGA/VGA color/graphics modes	}
	      VideoSet := $0020;
	      Device   := _COLOR
	    end;
    end;  {case ScnMode}

    { Since a PS/2 machine with a VGA adapter (only) can alternately	}
    { become the _MONO and the _COLOR device we change it here. 	}

    if ((_VgaAdapter = _CurDevice) and (not DualDisplay_)) then
	_VgaAdapter := Device;

    { For VGA machines to do 43 line mode, set scan lines to 350, not	}
    { 400.  We default other text modes to 400 scan lines.  This func-	}
    { tion is ignored by the EGA BIOS, so it is called whenever 43-line }
    { mode is requested.						}

    if ( (Rows = 43) or
	    (((ScnMode >= 0) and (ScnMode <= 3)) or (ScnMode = 7)) ) then
       with Reg do
	 begin
	   AH := $12;		       { Alternate select function	}
	   BX := $0030; 	       { Select scan lines/alpha modes	}
	   if (Rows = 43) then
	      AL := $01 	       { Select 350 scan lines		}
	   else
	      AL := $02;	       { Select 400 scan lines		}
	   Intr(_VIDEO,Reg)
	 end;

    { Now actually initialize the video adapter and switch devices if	}
    { necessary.  This is done by setting the equipment flag and by	}
    { making a call to the BIOS to initialize the adapter.		}

    SaveVideo(CurDevice);	       { Save the video information and }
    EquipFlag := (EquipFlag and $FFCF) or VideoSet; { change devices.	}
    Reg.AX    := word(ScnMode);
    Intr(_VIDEO,Reg);		       { Reset the adapter.		}

    { If 43 or 50 lines are requested, install the character set and	}
    { the correct print screen routine. 				}

    if ((Rows = 43) or (Rows = 50)) then
       with Reg do
	 begin
	   _CurRows := Rows;
	   if ((ScnMode > 3) and (ScnMode <> 7)) then
	      begin		       { Graphics modes 		}
		AX := $1123;
		BX := $0003;
		Intr(_VIDEO,Reg)
	      end
	   else
	      begin		       { Text mode			}
		AX := $1112;
		BX := $0000;
		Intr(_VIDEO,Reg)
	      end;
	   AX := $1200; 	       { Install alternate print screen }
	   BX := $0020;
	   Intr(_VIDEO,Reg)
	 end
    else
       _CurRows := Rows;

    { Finally, set the global variables, _CurMode, the current screen	}
    { mode, the current device, _CurDevice, to _MONO or _COLOR, and	}
    { _ScnLoc, the pointer to the video adapter.  The current number	}
    { of columns, _CurColumns, current display page, _CurDisplayPage,	}
    { and current active page, _CurActivePage are also set.		}
    { Call __RetDvScn to accomplish all this:				}

    CurDevice := __RetDvScn(Mode,Cols,PRows,APage,DPage);

    _CurDisplayPage := 0;
    _CurActivePage  := 0;

    ErrorCode	    := 0

  end;	{__NewDvScn}
