Hi,
I've written a program that uses the EGAVGA.BGI file, it's a small
book-keeping program. My screen saver uses a 320x200x256 colour plasma
display.
The screen saver loads fine, when I press a key it exits fine and
restores the screen fine IF i'm running it with a 80x25 text mode
I've attached my screensaver code, how do I get it to work so that the
screen is restored into the original mode when using my program that
uses a 640x480x16 colours mode.
I press a key it exits fine, but it displays a blank screen, and the
size of the cursor is the same size as that of one running in 320x200.
..
..
..
unit Scrnsavr;
{$F+}
interface
uses Dos,Crt;
function NumRows: byte; {Returns number of rows in current
screen}
function ColorAdaptor: boolean; {TRUE if color video card installed}
procedure SetTimeOut(T: integer); {Delay(seconds) before activation}
procedure DispMsg(VideoMode: byte);
(************************************)
implementation
type
VideoArray = array[1..2000] of word; {buffer to save video screen}
VAR
FT :ARRAY [0..511] OF BYTE;
SINT :ARRAY [0..255] OF BYTE;
I1,A,B,D,C,OD,COLOR :BYTE;
X,Y,K,I :WORD;
VideoMode: byte;
Timer: word;
Waiting: boolean;
OldInt15, {Keyboard interrupt}
OldInt1C, {Timer interrupt}
OldInt23, {Cntl-C/Cntl-Break handler}
ExitSave: pointer;
Position, Cursor: integer; {save and restore cursor positions}
VideoSave: VideoArray;
VideoMem: ^VideoArray;
TimeOut: integer;
procedure JumpToPriorIsr(p: pointer);
inline($5b/$58/$87/$5e/$0e/$87/$46/$10/$89/$ec/$5d/$07/$1f/
$5f/$5e/$5a/$59/$cb);
function ColorAdaptor: boolean; assembler;
asm
int 11 {BIOS call - get equipment list}
and al,$0010 {mask off all but bit 4}
xor al,$0010 {flip bit 4 - return val is in al}
end;
function NumRows: byte; assembler; {returns number of displayable
rows}
asm
mov ax,$40
mov es,ax
mov ax,$84
mov di,ax
mov al,[es:di] {byte at [$40:$84] is number of rows in
display}
end;
procedure HideCursor; assembler;
asm
mov ah,$03
xor bh,bh
int $10 {video interrupt}
mov Position,dx {save cursor position}
mov Cursor,cx {and type}
mov ah,$01
mov ch,$20
int $10 {video interrupt - hide cursor}
end;
procedure RestoreCursor; assembler;
asm
mov ah,$02
xor bh,bh
mov dx,Position {get old position}
int $10 {video interrupt - restore cursor position}
mov cx,Cursor {get old cursor type}
mov ah,$01
int $10 {video interrupt - restore cursor type}
end;
procedure RestoreScreen;
begin
asm
mov ah,$00
mov al, VideoMode
int $10
end;
VideoMem^ := VideoSave; {Copy saved image back onto video memory}
RestoreCursor;
end;
procedure SaveScreen;
begin
VideoSave := VideoMem^; {Copy video memory to array}
HideCursor;
end;
procedure DispMsg(VideoMode: byte);
begin
ASM
MOV AX,0013H; INT 10H;
mov dx,3d4h
mov al,9
out dx,al
inc dx
in al,dx
and al,0e0h
add al,3
out dx,al
END;
PORT [$3C8]:=0;
FOR I:=0 TO 255 DO
BEGIN
PORT [$3C9]:=I DIV 4;
PORT [$3C9]:=I DIV 5;
PORT [$3C9]:=I DIV 6
END;
FOR I:=0 TO 511 DO FT [I]:=ROUND (64+63*SIN (I/40.74));
FOR I:=0 TO 255 DO SINT [I]:=ROUND (128+127*SIN (I/40.74));
REPEAT
INC (I1);
DEC (C,2);
INC (OD,1);
D:=OD;
FOR Y:=0 TO 100 DO
BEGIN
K:=Y*320+Y AND 1;
K:=K-(I1 AND 1)*320;
INC (D,2);
A:=SINT [(C+Y) AND 255];
B:=SINT [(D) AND 255];
FOR X:=0 TO 159 DO
BEGIN
COLOR:=FT [A+B]+FT [Y+B];
MEM [$A000:K]:=COLOR;
INC (A,1+COLOR SHR 7);
INC (B,2); INC (K,2);
END;
END;
UNTIL PORT [$60]<128;
end;
procedure NewInt15(Flags,CS,IP,AX,BX,CX,DX,
SI,DI,DS,ES,BP:WORD); interrupt; {keyboard handler}
begin
Timer:=0; {Reset timer}
if Waiting then {Screen saver activated?}
begin
RestoreScreen; {Restore saved screen image}
Waiting:= FALSE; {De-activate screen saver}
Flags:=(Flags and $FFFE); {Tell BIOS to ignore current
keystroke}
end
else
JumpToPriorISR(OldInt15); {call original int 15}
end;
procedure NewInt1C; interrupt; {timer interrupt}
begin
Inc(Timer); {Increment timer}
if Timer>TimeOut then {No key hit for TimeOut seconds?}
begin
Waiting := TRUE; {Activate screen saver}
SaveScreen; {Save image of video memory}
DispMsg(VideoMode); {Display your own
message}
Timer := 0; {Reset timer}
end;
JumpToPriorISR(OldInt1C); {Chain to old timer interrupt}
end;
procedure ResetIntVectors; {Restores Intrrupt vectors to orig.
values}
begin
SetIntVec($15,OldInt15);
SetIntVec($1C,OldInt1C);
SetIntVec($23,OldInt23);
end;
procedure NewInt23; interrupt; {Called to handle cntl-c/brk}
begin
ResetIntVectors; {Restore old interrupt vectors}
JumpToPriorISR(OldInt23); {Chain to original int 23h}
end;
procedure MyExit; far; {exit code for unit}
begin
ResetIntVectors; {Restore old interrupt vectors}
ExitProc:=ExitSave; {Restore old exit code}
end;
procedure SetVideoAddress; {Returns pointer to text video
memory}
begin
if ColorAdaptor then
VideoMem := ptr($B000,$0000)
else
VideoMem := ptr($B800,$0000);
end;
procedure SetTimeOut(T: integer); {Set delay(seconds) before
activation}
begin
TimeOut:=Round(T*18.2);
end;
{Initialize unit}
begin
asm
mov ah, 0fh
int 10h
mov VideoMode, al
end;
SetVideoAddress; {Set up address for video memory}
Waiting := FALSE; {Screen saver initially OFF}
Timer := 0; {Reset timer}
ExitSave := ExitProc; {Save old exit routine}
ExitProc := @MyExit; {Install own exit routine}
{Install user defined int vectors}
GetIntVec($15,OldInt15); {Keyboard handler}
SetIntVec($15,@NewInt15);
GetIntVec($1c,OldInt1C); {Timer int}
SetIntVec($1c,@NewInt1C);
GetIntVec($23,OldInt23); {Cntl-C/Brk handler}
SetIntVec($23,@NewInt23);
SetTimeOut(20);
end.