[Back to NETWORK SWAG index]  [Back to Main SWAG index]  [Original]

 {
 Program Name : 10Peek.Pas
 Written By   : Anonymous
 E-Mail       : nothing
 Web Page     : nothing
 Program
 Compilation  : Turbo Pascal 5.0 or later

 Program Description :

  This program uses the 10NET network function call $14 of the $6F interrupt
  (GetRemoteMemory) provided by 10NET to access first the low memory of
  another node, to find out what video mode it is currently in, and then
  Video memory, to "peek" at their screen and duplicate it locally. It works
  for monochrome, CGA in text or graphics mode, and EGA or VGA in all but
  their highest resolution graphics.
       The parameters that the program expects on startup are as illustrated:

       10Peek <Nodename> [<delay>]

  where <Nodename> must be currently on the network and available to NetStat,
  and <delay> is an optional number of seconds to delay between refreshes of
  the screen. Whether a delay is selected or not, a refresh can be forced by
  pressing the spacebar.
     This program takes advantage of TURBO Pascal 5.5 graph procedures to put
  the local monitor into the proper mode.

   [In the case of high resolution VGA/EGA modes, apparently part of the
  detail of their screen images is not available in their directly accessible
  memory.]

  }

Program TenPeek;


  Uses CRT,DOS,Graph;
TYPE
    VGABuffer = Array[0..32767] of Byte;

CONST
   VGARemScreen : Array[0..3] of Word = ($A000,$A800,$B000,$B800);
   VRec : Array[0..3] of ^VGABuffer = (Ptr($A000,0000),Ptr($A800,0000),Ptr($B000,0000),Ptr($B800,0000));
TYPE
   RegRec= Registers;
   Buffer = Byte;
   VidRec = Record
             VMode : Byte;
             ColCount : Integer;
             ScreenPagelength : Word;
             ScreenLoc : Integer;
             CursorPos : Array[1..8] of Array[1..2] of Byte;
             CursorSize : Array[1..2] of Byte;
             DisplayPage : Byte;
             ControllerAddr : Integer;
             CRTMode : Byte;
             PalletteMask : Byte;
          end;
    ScreenBuffer = Array[0..65490] of Char;
    String12 = String[12];
    ScreenRec = Record
                 RNode : String12;
                 SBuffer : ScreenBuffer;
                 VidBuffer : VidRec;
                end;
VAR
   VGAHi : Boolean;
   CGAScreen : Array[0..4096] of Byte absolute $B800:0000;
   EGAVGAScreen : Array[0..41360] of Byte absolute $A000:0000;
   LocalScreenBuffer : Array[0..4096] of Byte;
   PageOffset,ErrCode : Word;
   VideoMode : Byte;
   GDriver,GMode : Integer;
   PauseCount : Word;
   Test,I,IV,VLength : Integer;
   VidBuffer : VidRec;
   SRec : ^ScreenRec;
   LocalScreen : ^ScreenBuffer;
   RemScreen : Word;
   OneKey : Char;
   LocalVideo : VidRec absolute 0000:$0449;
   Reps : Integer;
   Regs : RegRec;

Procedure Save;
Begin
   Move(LocalVideo,VidBuffer,30);
   Repeat until ((Port[$3DA] and 8)=8);
   Move(LocalScreen^,LocalScreenBuffer,4096);
End;

Procedure Restore;
Begin
   GDriver:=CGA;
   GMode:=0;
   Case VidBuffer.VMode of
   0..3 : TextMode(VidBuffer.VMode);
   4 : InitGraph(GDriver,GMode,'');
   5 : InitGraph(GDriver,GMode,'');
   6 : InitGraph(GDriver,GMode,'');
   end;
   LocalScreen:=@CGAScreen;
   Repeat until ((Port[$3DA] and 8)=8);
   Move(LocalScreenBuffer,LocalScreen^,4096);
   Move(VidBuffer.CursorPos,LocalVideo.CursorPos,18);
End;


Procedure GetRemoteMemory(VAR Node : String12; RSeg,ROfs : Word; VAR RLength : Integer;VAR LBuffer);
Begin
   With Regs do
    begin
       AX:=$1400;
       BX:=RSeg;
       CX:=RLength;
       SI:=ROfs;
       DS:=Seg(Node);
       DX:=Ofs(Node)+1;
       While (Length(Node)<12) do Node:=Node+' ';
       DI:=Ofs(LBuffer);
       Intr($6F,Regs);
       If (Flags and 1)>0
       then
        begin
           Writeln(^G,'Error reading remote memory...Halting');
           Halt;
        end;
       RLength:=CX;
    end;
End;

Procedure SetVideoMode;
Begin
   Case SRec^.VidBuffer.VMode of
   0..3,7 : Begin
               VGAHi:=False;
               If ((SRec^.VidBuffer.VMode=3) and (SRec^.VidBuffer.ScreenPageLength>4096))
               then
                begin
                   TextMode(CO80+Font8X8);
                   LocalScreen:=@CGAScreen;
                   RemScreen:=$B800;
                   Reps:=17;
                end
               else if SRec^.VidBuffer.VMode=7 then TextMode(BW80)
               else TextMode(SRec^.VidBuffer.VMode);
               LocalScreen:=@CGAScreen;
            End;
   4 : Begin
          VGAHi:=False;
          GMode:=0;
          GDriver:=CGA;
          LocalScreen:=@CGAScreen;
       End;
   6 : Begin
          VGAHi:=False;
          GMode:=4;
          GDriver:=CGA;
          LocalScreen:=@CGAScreen;
       End;
   14 : Begin
           VGAHi:=False;
           GMode:=0;
           GDriver:=EGA;
           LocalScreen:=@EGAVGAScreen;
        End;
   16 : Begin
           VGAHi:=True;
           GMode:=1;
           GDriver:=VGA;
           LocalScreen:=@EGAVGAScreen;
        End;
   18,19 : Begin
           VGAHi:=True;
           GMode:=2;
           GDriver:=VGA;
           LocalScreen:=@EGAVGAScreen;
        End;
   End;
   If SRec^.VidBuffer.VMode in [4,6,14,16,18,19]
   then
    begin
       InitGraph(GDriver,GMode,'');
       ErrCode:=GraphResult;
       If ErrCode=0 then VideoMode:=SRec^.VidBuffer.VMode;
    end
   else VideoMode:=SRec^.VidBuffer.VMode;
End;

Procedure VideoParms;
Begin
   VLength:=30;
   GetRemoteMemory(SRec^.RNode,0,$449,VLength,SRec^.VidBuffer);
   If VLength<>30 then Halt;
{   ClrScr;
   GotoXY(1,1);
   Writeln('Mode: ',SRec^.VidBuffer.VMode);
   Writeln('Columns: ',SRec^.VidBuffer.ColCount);
   Writeln('Bytes/Page: ',SRec^.VidBuffer.ScreenPageLength);
   Delay(300);
 }  If VideoMode<>SRec^.VidBuffer.VMode
   then SetVideoMode;
   Case SRec^.VidBuffer.VMode of
        0 : Begin
               Reps:=4;
               RemScreen:=$B800;
            End;
        1 : Begin
               Reps:=4;
               RemScreen:=$B800;
            End;
        2 : Begin
               Reps:=8;
               RemScreen:=$B800;
            End;
        3 : If not((SRec^.VidBuffer.VMode=3) and (SRec^.VidBuffer.ScreenPageLength>4096))
            then
             begin
               Reps:=8;
               RemScreen:=$B800;
             End;
        4 : Begin
               Reps:=34;
               RemScreen:=$B800;
            End;
        6 : Begin
               Reps:=34;
               RemScreen:=$B800;
            End;
        7 : Begin
               Reps:=34;
               RemScreen:=$B000;
            End;
        14 : Begin
               Reps:=34;
               RemScreen:=$A000;
             End;
        16 : Begin
                Reps:=69;
                RemScreen:=$A000;
             end;
        18,19 : Begin
                Reps:=69;
                RemScreen:=$A000;
             End;

        else
         begin
	    TextMode(CO80);
            ClrScr;
            Writeln('VideoMode= ',SRec^.VidBuffer.VMode);
            Halt;
         end;
   end;
  Move(SRec^.VidBuffer.CursorPos,LocalVideo.CursorPos,18);
end;

{Main}
Begin
   If ParamCount=0
   then
    begin
       Writeln(' Syntax : ');
       Writeln('             10Peek <Nodename>');
    end
   else
    begin
       New(SRec);
       VideoMode:=255;
       VGAHi:=False;
       LocalScreen:=@CGAScreen;
       ErrCode:=0;
       SRec^.RNode:=ParamStr(1);
       For I:=1 to Length(SRec^.RNode) do SRec^.RNode[I]:=Upcase(SRec^.RNode[I]);
       PauseCount:=0;
       If Paramcount<2 then Test:=0 else VAL(ParamStr(2),PauseCount,Test);
       If test<>0 then PauseCount:=0;
       PauseCount:=PauseCount*10;
       Save;
       VideoParms;
       Repeat
          OneKey:=#0;
          If (SRec^.VidBuffer.VMode in [0..3])
          then PageOffset:=Integer(SRec^.VidBuffer.DisplayPage)*SRec^.VidBuffer.ScreenPageLength
          else PageOffset:=0;
          If not VGAHi
          then
           begin
              for I:=0 to Reps do
               begin
                  VLength:=470;
                  GetRemoteMemory(SRec^.RNode,RemScreen,I*470+PageOffset,VLength,SRec^.SBuffer[I*470]);
               end;
              Repeat until ((Port[$3DA] and 8)=8);
              Move(SRec^.SBuffer[0],LocalScreen^,(Reps*470)+VLength);
           end
          else for IV:=0 to 3 do
           begin
              Delay(10);
              for I:=0 to Reps do
               begin
                  VLength:=470;
                  GetRemoteMemory(SRec^.RNode,RemScreen,I*470+PageOffset,VLength,SRec^.SBuffer[I*470]);
               end;
              Move(SRec^.SBuffer,VRec[IV]^,32767);
           end;
          Sound(6000);
          Delay(50);
          Nosound;
          Repeat
             If PauseCount<>0
             then
              begin
                 OneKey:=#32;
                 For I:=1 to PauseCount do if not keypressed
                  then delay(100) else
                   begin
                      I:=PauseCount;
                      OneKey:=Readkey;
                   end;
              end
             else OneKey:=Readkey;
             If not (Onekey in [#32,#27]) then Write(#7);
          Until OneKey in [#32,#27];
          If Onekey=#32 then Videoparms;
       Until OneKey=#27;
      Restore;
   end;
End.

[Back to NETWORK SWAG index]  [Back to Main SWAG index]  [Original]