{***********************************************************************}
{									}
{ __VertScn   Scroll text vertically within an area on the screen	}
{									}
{ procedure __VertScn(X1,Y1,X2,Y2,NumRows,Fore,Back : byte;		}
{						 Up : boolean); 	}
{									}
{	      X1,Y1	Upper left corner of window area, X1 is the	}
{			column number and Y1 is the row number. 	}
{	      X2,Y2	Lower right corner of window area, X2 is the	}
{			column number and Y2 is the row number. 	}
{	      NumRows	The number of rows to scroll within the window	}
{			area. To scroll the entire area, 0 is specifed. }
{	      Fore,Back The attributes used to fill the rows within the }
{			window area scrolled.				}
{	      Up	If TRUE, the area is scrolled up, otherwise it	}
{			is scrolled down.				}
{									}
{ Description This procedure scrolls text within a specified area on	}
{	      current display page. The vacant lines within the screen	}
{	      area are filled with the specified attributes.  Lines can }
{	      be scrolled up (so the vacant lines are at the bottom) or }
{	      down.  Only the current display page can be scrolled, and }
{	      if it is the same as the active display page, BIOS calls	}
{	      are used to do the scrolling.  If the display page is	}
{	      not the same as the active page, direct memory moves	}
{	      (__MoveScn) are used.					}
{									}
{	      Notice that __VertScn does not check the parameters to	}
{	      make sure they are reasonable.  It is the programmer's	}
{	      responsibility that the area coordinates be within the	}
{	      physical screen, but NumRows is forced to be less than	}
{	      the number of lines.   To scroll within the current	}
{	      window, the procedure __VertWin should be used.		}
{									}
{ Version     4.00 (C)Copyright Blaise Computing Inc.  1987		}
{_______________________________________________________________________}

procedure __VertScn(X1,Y1,X2,Y2,NumRows,Fore,Back : byte;
					       Up : boolean);
  var
    Attribute : byte;
    BufPtr    : Pointer;	       { Image to be scrolled		}
    FillPtr   : _ScnImagePtr;	       { Vacant lines image		}
    BufSize   : word;
    FillSize  : word;
    I	      : word;
    Reg       : registers;

  begin {__VertScn}

    Attribute := __2ByteSup(Back,Fore);
    if (NumRows >= (Y2 - Y1 + 1)) then
       NumRows := 0;		       { Scroll the entire window	}

    if (_CurActivePage = _CurDisplayPage) then
       with Reg do		       { Set up call to BIOS Video	}
	 begin			       { function 6 or 7.		}
	   if (Up) then 	       { Set the direction bytes	}
	      AH := 6		       { Scroll up			}
	   else
	      AH := 7;		       { Scroll down			}
	   AL := NumRows;
	   BH := Attribute;	       { BH = attribute byte		}
	   CH := Y1 - 1;	       { Row and column of upper left	}
	   CL := X1 - 1;	       { corner, and			}
	   DH := Y2 - 1;	       { row and column of lower right	}
	   DL := X2 - 1;	       { corner.			}
	   Intr(_VIDEO,Reg)
	 end
    else			       { Use direct memory moves	}
      if (NumRows = 0) then	       { Clear the "window"		}
	 begin
	   FillSize := (Y2 - Y1 + 1) * (X2 - X1 + 1);
	   GetMem(FillPtr,2 * FillSize);
	   for I := 1 to FillSize do
	     with FillPtr^[I] do
	       begin
		 _Ch   := #32;	       { Blank character with the	}
		 _Attr := Attribute    { specified attribute.		}
	       end;
	   __MoveScn(X1,Y1,X2,Y2,@FillPtr^,TRUE);
	   FreeMem(FillPtr,2 * FillSize)
	 end
      else
	 begin
	   BufSize  := (Y2 - Y1 + 1 - NumRows) * (X2 - X1 + 1);
	   FillSize := NumRows * (X2 - X1 + 1);
	   GetMem(BufPtr,2 * BufSize);
	   GetMem(FillPtr,2 * FillSize);
	   for I := 1 to FillSize do
	     with FillPtr^[I] do
	       begin
		 _Ch   := #32;	       { Blank character with the	}
		 _Attr := Attribute    { specified attribute.		}
	       end;
	   if (Up) then
	      begin		       { Scroll up NumRows lines	}
		__MoveScn(X1,Y1 + NumRows,X2,Y2,BufPtr,FALSE);
		__MoveScn(X1,Y1,X2,Y2 - NumRows,BufPtr,TRUE);
		__MoveScn(X1,Y2 - NumRows + 1,X2,Y2,@FillPtr^,TRUE)
	      end
	   else
	      begin		       { Scroll down NumRows lines	}
		__MoveScn(X1,Y1,X2,Y2 - NumRows,BufPtr,FALSE);
		__MoveScn(X1,Y1 + NumRows,X2,Y2,BufPtr,TRUE);
		__MoveScn(X1,Y1,X2,Y1 + NumRows - 1,@FillPtr^,TRUE)
	      end;
	   FreeMem(BufPtr,2 * BufSize);
	   FreeMem(FillPtr,2 * FillSize)
	 end

  end;	{__VertScn}
