{***********************************************************************}
{									}
{ __MoveScn   Move data directly to or from the screen			}
{									}
{ procedure __MoveScn(X1,Y1,X2,Y2 : byte; BufferPtr : pointer;		}
{					   ToScreen : boolean); 	}
{									}
{	      X1,Y1	Upper left corner of the area to be accessed.	}
{			X1 is the column and Y1 is the row number.	}
{	      X2,Y2	Lower right corner of access area, X2 is the	}
{			column number and Y2 is the row number. 	}
{	      BufferPtr Pointer to the buffer which holds the data to	}
{			be placed on the screen, or in which the data	}
{			is returned.  The data must be formatted as	}
{			alternate bytes of character followed by the	}
{			attribute byte. 				}
{	      ToScreen	If TRUE, the data pointed to by BufferPtr is	}
{			moved to the physical screen; otherwise data	}
{			from the screen access area is moved into the	}
{			data buffer.					}
{									}
{ Description __MoveScn directly accesses the video buffer to transfer	}
{	      data to and from the physical screen using the procedure	}
{	      __SpeedScn.  The window management routines which display }
{	      and remove windows use __MoveScn. 			}
{									}
{	      That portion of the screen defined by the coordinates	}
{	      (X1,Y1) and (X2,Y2) is accessed.	If ToScreen is TRUE,	}
{	      data is moved from the buffer to the screen area; other-	}
{	      wise, data is moved from the screen to the buffer. When	}
{	      accessing the screen, if the color/graphics adapter is	}
{	      used, data is moved in during horizontal retrace by	}
{	      specifying the "Wait" parameter to __SpeedScn to be TRUE	}
{	      so that no interference (snow) is seen.  Note that the	}
{	      data buffer need not be a screen image, but the data is	}
{	      returned in character, attribute sequence, and it must	}
{	      be formatted that way if data is moved to the screen.	}
{	      The current display page is accessed, and data is not	}
{	      written beyond the bounds of the page limit.  Therefore,	}
{	      if coordinates are specified that are not within the page }
{	      limit, the data is truncated upon output. 		}
{									}
{ Version     4.00 (C)Copyright Blaise Computing Inc. 1987		}
{_______________________________________________________________________}

procedure __MoveScn(X1,Y1,X2,Y2 : byte; BufferPtr : pointer;
					 ToScreen : boolean);

  var
    BufPtr	: _ScnImagePtr absolute BufferPtr;
    ScnPtr	: _ScnImagePtr;
    PageLength	: word absolute _BIOSSEG:$004C;
    Offset	: word; 	       { Offset into video buffer	}
    Width	: word; 	       { Width, in pairs, of each line	}
    Delta	: word; 	       { Increment between data lines	}
    Lines	: word; 	       { Number of lines to access	}
    Wait	: boolean;
    I,J,K	: word;

  begin {__MoveScn}

    if ((_CurMode > 3) and (_CurMode <> 7)) then
       Exit;			       { Leave if not in text mode	}

    { Force the coordinates to be within the page size limits.		}

    if (X1 < 1) then
       X1 := 1
    else if (X1 > _CurColumns) then
       X1 := _CurColumns;
    if (Y1 < 1) then
       Y1 := 1
    else if (Y1 > _CurRows) then
       Y1 := _CurRows;
    if (X2 < X1) then
       X2 := X1
    else if (X2 > _CurColumns) then
       X2 := _CurColumns;
    if (Y2 < Y1) then
       Y2 := Y1
    else if (Y2 > _CurRows) then
       Y2 := _CurRows;

    { Now compute the constants associated with the access area so that }
    { the video buffer can be correctly accessed.			}

    OffSet := ((Y1 - 1) * _CurColumns) + X1;
    Width  := X2 - X1 + 1;
    Delta  := _CurColumns - X2 + X1 - 1;
    Lines  := Y2 - Y1 + 1;
    if (_CurDisplayPage <> 0) then     { Offset into the correct page	}
       ScnPtr := Ptr(_VectorAddr(_ScnLoc)._Seg,
		     _VectorAddr(_ScnLoc)._Ofs +
					 (PageLength * _CurDisplayPage))
    else
       ScnPtr := _ScnLoc;

    Wait := (_CurDevice = _ColorAdapter);

    J := Offset;
    K := 1;
    for I := 1 to Lines do
      begin
	if (ToScreen) then
	   __SpeedScn(@BufPtr^[K],@ScnPtr^[J],Width,2,0,Wait)
	else
	   __SpeedScn(@ScnPtr^[J],@BufPtr^[K],Width,3,0,Wait);
	Inc(J,Width + Delta);
	Inc(K,Width);
      end

  end;	{__MoveScn}
