Board index » delphi » Using EGAVGA.BGI - How to program the screensaver - scrnsavr.pas (0/1)

Using EGAVGA.BGI - How to program the screensaver - scrnsavr.pas (0/1)

Hi,

I've written a program that uses the EGAVGA.BGI file, it's a small
book-keeping program. Unfortunately, my screen saver uses a
320x200x256 colours mode. The screen saver loads fine, when I press a
key it exits fine, this works 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 I use assembler to determine what my current video state I'm in I
do the following -

mov ah,0fh
int 10h

this returns the following info
  Columns : 50
  Mode : 12
  Page : 00

This is the video status of my program I'm running, I want the screen
saver to work so that when I press a key it retuns to this mode, with
the correct data on the screen

 

Re:Using EGAVGA.BGI - How to program the screensaver - scrnsavr.pas (0/1)


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.

Other Threads