home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
lan
/
spy
/
source
/
screen.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-10-02
|
6KB
|
176 lines
{$A+,B-,D-,E-,F+,I-,L-,N-,O-,R-,S-,V+}
Unit Screen;
{
Screen supports fast, adapter independent movement of data to and from page
zero of a text-mode screen.
Author: Edwin T. Floyd [76067,747]
9 Adams Park Court
Columbus, GA 31909
404-322-0076 (home)
404-576-3305 (work)
Thanks to Jeff Dunteman and Brian Foley who pioneered much of the code for
these routines.
This unit is contributed to the public domain.
}
Interface
Type
AdapterType = (None, MDA, CGA, EGAMono, EGAColor, VGAMono, VGAColor,
MCGAMono, MCGAColor, HercMono, HercPlus, HercInColor);
FontSize = (Font8, Font14, Font16);
ScreenSaveHeader =
{ Format of data area used by SaveScreenArea and RestoreScreenArea }
Record
Cursor : Word; { CursorPosition }
RowCol1 : Word; { Upper-left corner }
RowCol2 : Word; { Lower-right corner }
Mode : Byte; { Video mode }
Compressed : Boolean; { True if screen area is compressed }
Size : Word; { Size of data area that follows }
{ The header is followed by screen data }
End;
Var
ScreenOfs : Word; { *Offset of video buffer }
ScreenSeg : Word; { *Segment of video buffer }
DesqViewVersion : Word; { *0 if DesqView not active }
ScreenCols : Byte; { *Number of columns on screen }
ScreenRows : Byte; { *Number of rows on screen }
ScreenAdapterType : AdapterType; { *Adapter type }
ScreenVideoMode : Byte; { *Video mode }
ScreenFontSize : FontSize; { *Font size }
BiosVideoMode : Byte Absolute $0040:$0049; { Video Mode byte in Bios data }
CheckSnow : Boolean; { If True, wait for retrace on CGA }
DirectVideo : Boolean; { If False, use BIOS }
{
Fields marked with "*" are set by GetBiosInfo. In a TSR, if
ScreenVideoMode <> BiosVideoMode, you should GetBiosInfo again.
}
Procedure GetBiosInfo;
{ Get information on current video adapter }
Procedure FillWord(Var Dest; Count, Value : Word);
{ Like FillChar, only with words (faster than FillChar) }
Function CursorPosition : Word;
{ Returns current cursor position on page 0. Hi=Row, Lo=Col base 1. }
Procedure SetCursorPosition(RowCol : Word);
{ Sets cursor position }
Procedure PutWord(RowCol, Value : Word);
{ Write a word (Hi=Attribute, Lo=Character) to screen at indicated position }
Procedure PutWords(Var Source; RowCol, Count : Word);
{ Copy words to screen beginning at indicated position up to end of row }
Procedure GetWords(Var Dest; RowCol, Count : Word);
{ Copy words from screen beginning at indicated position up to end of row }
Function ScreenAreaSize(X1, Y1, X2, Y2 : Byte) : Word;
{ Returns the number of bytes required by SaveScreenArea. }
Procedure SaveScreenArea(Var Dest; X1, Y1, X2, Y2 : Byte);
{ Save a rectangular area of screen. Coordinates set 1 defines upper-left
corner, 2 defines lower right corner, top row: X1=1, left col: Y1=1.
Save area format is described by ScreenSaveHeader above. }
Procedure RestoreScreenArea(Var Source);
{ Restore a previously saved rectangular area of screen }
Implementation
Type
ScreenSaveArea = Record
Header : ScreenSaveHeader;
Data : Array[0..30000] Of Word;
End;
Procedure GetBiosInfo;
External;
Procedure FillWord(Var Dest; Count, Value : Word);
External;
Function CursorPosition : Word;
External;
Procedure SetCursorPosition(RowCol : Word);
External;
Procedure PutWord(RowCol, Value : Word);
External;
Procedure PutWords(Var Source; RowCol, Count : Word);
External;
Procedure GetWords(Var Dest; RowCol, Count : Word);
External;
{$L SCREEN.OBJ }
Function ScreenAreaSize(X1, Y1, X2, Y2 : Byte) : Word;
Begin
If X2 > ScreenCols Then X2 := ScreenCols;
If Y2 > ScreenRows Then Y2 := ScreenRows;
If (X1 > X2) Or (Y1 > Y2) Then ScreenAreaSize := SizeOf(ScreenSaveHeader)
Else ScreenAreaSize := SizeOf(ScreenSaveHeader)
+ Succ(X2-X1) * Succ(Y2-Y1) * 2;
End;
Procedure SaveScreenArea(Var Dest; X1, Y1, X2, Y2 : Byte);
Var
SaveArea : ScreenSaveArea Absolute Dest;
LenPerRow, RowCount, i, j : Word;
Begin
If X2 > ScreenCols Then X2 := ScreenCols;
If Y2 > ScreenRows Then Y2 := ScreenRows;
If X1 > X2 Then LenPerRow := 0 Else LenPerRow := Succ(X2-X1);
If Y1 > Y2 Then RowCount := 0 Else RowCount := Succ(Y2-Y1);
With SaveArea, Header Do Begin
Cursor := CursorPosition;
RowCol1 := Y1 Shl 8 + X1;
RowCol2 := Y2 Shl 8 + X2;
Mode := ScreenVideoMode;
Compressed := False;
Size := LenPerRow * RowCount * 2;
If Size > 0 Then Begin
j := 0;
For i := Y1 To Y2 Do Begin
GetWords(Data[j], i Shl 8 + X1, LenPerRow);
Inc(j, LenPerRow);
End;
If Not DirectVideo Then SetCursorPosition(Cursor);
End;
End;
End;
Procedure RestoreScreenArea(Var Source);
Var
SaveArea : ScreenSaveArea Absolute Source;
LenPerRow, X1, Y1, Y2, i, j : Word;
Begin
With SaveArea, Header Do Begin
If Size > 0 Then Begin
X1 := Lo(RowCol1);
Y1 := Hi(RowCol1);
Y2 := Hi(RowCol2);
LenPerRow := Succ(Lo(RowCol2) - X1);
j := 0;
For i := Y1 To Y2 Do Begin
PutWords(Data[j], i Shl 8 + X1, LenPerRow);
Inc(j, LenPerRow);
End;
End;
SetCursorPosition(Cursor);
End;
End;
Begin
DirectVideo := True;
GetBiosInfo;
CheckSnow := (ScreenAdapterType = CGA) And (ScreenSeg = $B800);
End.