Program ScnDsign;
{to design screens for other programs}

(*
                    Note : this is version 2.01
  This program requires that the Help.scn and Var.scn files be on the current
  disk drive when the program is run. The instructions for running the program
  are contained in the Readme file which should have been included with this
  program. This program is distributed under the Freeware concept. You are
  free to make and distribute copies as you wish. If the program proves useful
  to you, contributions to the author will be appreciated. The suggested
  contribution is $25.00. Thanks for making the Freeware concept work.
  To print out the Readme file, just type "type Readme > prn" at the DOS
  prompt.(Don't include the quotation marks). Use of this program will
  generate a pascal file which will call up the screen you design and will
  then call for the varible entries on the screen. You will need the
  General.inc file when compiling the pascal file which is generated by the
  ScnDsign program. Be sure to type the Readme file before using the program.

                   Iddo L. Enochs
                   403 Cherokee Dr.
                   Mc Comb, MS 39648
*)

Type
    TotScn          = Array[1..25,1..80,1..2] of Byte;
    TotAttributes   = Array[1..2000] of Byte;
    StoreCharacter  = array[1..2] of byte;
    FileName        = String[14];
    TypeVar         = (None,Int,Rl,Strn,Bol);
    ScnVar = Record
               VarName   : string[10];
               VarType   : TypeVar;
               VarRow    : integer;
               VarCol    : integer;
               VarLgth   : integer;
               VarMarker : byte;
             end;
    AnyString = String[10];
    ScnLine             = array[1..160] of byte;
Var
    VideoCode                     : integer absolute $0040:$0049;
    Symbol                        : StoreCharacter;
    MonoScn                       : TotScn Absolute $B000:0000;
    ColorScn                      : TotScn Absolute $B800:0000;
    ScnImage2,HelpScn,WorkScn,VarScn
                                  : TotScn;
    ScnAttributes                 : TotAttributes;
    Ch1,Ch2,ch                    : Char;
    AttributeSeg                  : integer;
    AttributeOfs                  : integer;
    Row,Col,Pos,Count             : Integer;
    InsertOn,OK,VarDefined        : Boolean;
    ImageFile                     : file of Byte;
    ScnFile                       : text;
    bt,bt1,bt2,ByteValue,NextChar : byte;
    ByteCounter,WordValue         : integer;
    Lngth,Attr                    : byte;
    Dummy                         : integer;
    NameOfScreen                  : FileName;
    VarFileName                   : FileName;
    TypeOfVar                     : TypeVar;
    VarNum                        : integer;
    AscMarker                     : integer;
    VarTable                      : file of ScnVar;
    ScnVars                       : array[1..80] of ScnVar;
    StartCol,EndCol               : integer;
    LastScnLine                   : ScnLine;
    StayOnRow                     : boolean;
    IsBWcard                      : boolean;
    Monitor                       : ^TotScn;
Label
    Jump,Skip;

{----------------------------------------------------------}

Procedure CheckVideo(var BWcard : boolean);
type
  result = record
   AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Integer;
           end;
var
  res : result;
begin
  intr($11,res);  {this is the equipment check interrupt}
  res.AX := res.AX and 48; {this turns off all but bit 4 and 5}
    {if bit 4 and 5 are set(48) then B&W card is installed}
  if res.AX = 48 then BWcard := true else BWcard := false;
end;

{----------------------------------------------------------}

Procedure InitMonoSPFX;
{Find the location of the attribute byte by changing the video
 attribute, then checking for differences}
{My thanks to Dr. R. L. Wulffson of Santa Ana, Calif. for this procedure}
Const
   MaxOffset = $0900;

Var
   A         : integer;
   Found     : boolean;
   Attribute : byte;

{----------------------------------------------}

Procedure FindAttribute;

Begin
  Repeat
   LowVideo;
   Attribute := Mem[AttributeSeg:AttributeOfs];
   NormVideo;
   If Mem[AttributeSeg:AttributeOfs] <> Attribute
     then Found := True
     else AttributeOfs := Succ(AttributeOfs)
  until Found or (AttributeOfs > MaxOffset);
end;

{----------------------------------------------}

Begin {InitMonoSPFX}
   Found := false;
   AttributeSeg := DSeg;
   AttributeOfs := 0;
   FindAttribute;
   If Not Found
     Then
       Begin
         AttributeSeg := CSeg;
         AttributeOfs := 0;
         FindAttribute;
       end;
end; {InitMonoSPFX}

{-----------------------------------------------}

Procedure Reverse;

Begin
   Mem[AttributeSeg:AttributeOfs] :=  $70;
end;

{-------------------------------}

Procedure Blink;

Begin
   Mem[AttributeSeg:AttributeOfs] := $87;
end;

{----------------------------------}

Procedure UnBlink;

Begin
   Mem[AttributeSeg:AttributeOfs] := Mem[AttributeSeg:AttributeOfs] and $7F;
end;

{----------------------------------}

Procedure UnderLine;

Begin
   Mem[AttributeSeg:AttributeOfs] := Mem[AttributeSeg:AttributeOfs] and $88;
   Mem[AttributeSeg:AttributeOfs] := Mem[AttributeSeg:AttributeOfs] or $01;
end;

{----------------------------------}

Procedure HiInt;

Begin
   Mem[AttributeSeg:AttributeOfs] := $0F;
end;

{-----------------------------------}

Procedure LoInt;

Begin
   Mem[AttributeSeg:AttributeOfs] := Mem[AttributeSeg:AttributeOfs] and $F7;
end;

{------------------------------------}

Procedure Normal;

Begin
   Mem[AttributeSeg:AttributeOfs] :=  $07;
end;

{----------------------------------------------------------}

Procedure OpenInFile(AnyFile:FileName);

Begin
     Assign(ImageFile,AnyFile);
     {$I-} Reset(ImageFile) {$I+};
     OK := (IOresult = 0);
     if not OK then
        begin
           Reverse;
           Writeln;
           ClrEol;
           Writeln('Cannot find file  ',AnyFile);
           ClrEol;
           Writeln('Retry to locate file');
           ClrEol;
           Writeln('Press any key to continue');
           while not keypressed do;
           Normal;
        end;
end;

{---------------------------------------------------}

Procedure BigCursor;
Type
  Result = Record
             AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer;
           end;
Var
  Res : Result;
Begin
  Res.AX :=  $0100;
  Res.CX := $070C;
  Intr($10,Res);

end;

{--------------------------------------------------------}

Procedure SmallCursor;
Type
  Result = Record
             AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer;
           end;
Var
  Res : Result;
Begin
  Res.AX :=  $0100;
  Res.CX := $0B0C;
  Intr($10,Res);

end;

{----------------------------------------------------------------}

Procedure MovScnPos;
Begin
  Col := Col + 1;
  if (Col > 80) and (Row < 25) then
     begin
        Col := 1;
        if Row < 25 then Row := Row + 1;
     end;
end;

{----------------------------------------------------------------}

Procedure MoveBlock;

Var
    UpRow,LoRow,LeftCol,RightCol    : integer;
    BytesToMove,kount,AttrCount     : integer;
    Symbol                          : StoreCharacter;

{-------------------------------------------------------------}

Procedure MoveBlockCursor;

Begin
    repeat
       repeat read(kbd,ch1) until ch1 = chr(27);
       read(kbd,ch2);
       case ord(ch2) of
              27 :begin {escape twice}
                     Move(Monitor^,ScnImage2,4000);
                     Move(HelpScn,Monitor^,4000);
                     While not keypressed do;
                     Move(ScnImage2,Monitor^,4000);
                  end;
              80 :begin   {down arrow}
                      if Row < 25 then Row := Row + 1;
                      GotoXY(Col,Row);
                  end;
              72 :begin   {up arrow}
                      if Row > 01 then Row := Row - 1;
                      GotoXY(Col,Row);
                  end;
              77 :begin   {right arrow}
                      if Col < 80 then Col := Col + 1;
                      GotoXY(Col,Row);
                  end;
              75 :begin   {left arrow}
                      if Col > 01 then Col := Col - 1;
                      GotoXY(Col,Row);
                  end;
       end;
    until ord(ch2) = 59;
end;{MoveBlockCursor}

{------------------------------------------------------------------}

Begin  {MoveBlock}
    Move(Monitor^[25,1,1],Symbol,2);
    {move the character and attribute at the lower left corner of
     the screen into temporary storage}
    GotoXY(1,25);
    Blink;
    Write('B');
    Normal;
    ScnImage2 := Monitor^;
    Reverse;
    GotoXY(2,25);ClrEol;
    Write('Move Cursor to upper left corner of block ',
    'to be moved and press F1');
    GotoXY(Col,Row);
    while not keypressed do;
    Monitor^ := ScnImage2;
    MoveBlockCursor;
    UpRow := WhereY; LeftCol := WhereX;
    GotoXY(2,25);
    ClrEol;
    Write('Move Cursor to lower right corner of block ',
    'to be moved and press F1');
    GotoXY(Col,Row);
    While not keypressed do;
    Monitor^ := ScnImage2;{restore original screen}
    MoveBlockCursor;
    LoRow := WhereY; RightCol := WhereX;
    {now, store the attributes in the block and
     change the attributes in the block to Reverse}
    AttrCount := 1; {start storing in position one of attribute array}
    For count := UpRow to LoRow do
      For kount := LeftCol to RightCol do
        begin
          ScnAttributes[AttrCount] := Monitor^[count,kount,2];
          Monitor^[count,kount,2] := $70;
          AttrCount := AttrCount + 1;
        end;
    ScnImage2 := Monitor^;
    GotoXY(2,24);ClrEol;
    Write('Use the arrow keys to move the block');
    GotoXY(2,25);ClrEol;
    Write('Press F10 to go back to the main part of the program');
    While not keypressed do;
    Monitor^ := Scnimage2;
    BytesToMove := (RightCol - LeftCol+1) * 2;
    repeat
       repeat read(kbd,ch1) until ch1 = chr(27);
       read(kbd,ch2);
       case ord(ch2) of
           27 :begin {escape twice}
                  Move(Monitor^,ScnImage2,4000);
                  Move(HelpScn,Monitor^,4000);
                  While not keypressed do;
                  Move(ScnImage2,Monitor^,4000);
               end;
           75 :if LeftCol > 1 then   {left arrow}
                 begin
                   for count := UpRow  to LoRow do
                   begin
                      Move(Monitor^[count,LeftCol,1],
                        Monitor^[count,LeftCol-1,1],
                        BytesToMove);
                      Monitor^[count,RightCol,1] := 032;{space}
                      Monitor^[count,RightCol,2] := $07;{normal}
                   end;
                   LeftCol := LeftCol - 1;
                   RightCol := RightCol -1;
                 end;
           77 :if RightCol < 80 then   {right arrow}
                 begin
                   for count := UpRow  to LoRow do
                   begin
                      Move(Monitor^[count,LeftCol,1],
                        Monitor^[count,LeftCol+1,1],
                        BytesToMove);
                      Monitor^[count,LeftCol,1] := 032;{space}
                      Monitor^[count,LeftCol,2] := $07;{normal attribute}
                   end;
                   LeftCol := LeftCol + 1;
                   RightCol := RightCol +1;
                 end;
           72 : if UpRow > 1 then {up arrow}
                 begin
                   for count := UpRow to LoRow do
                      begin
                        Move(Monitor^[count,LeftCol,1],
                        Monitor^[count-1,LeftCol,1],BytesToMove);
                      end;
                    for count := LeftCol to RightCol do
                      begin
                        Monitor^[LoRow,count,1] := 32;
                        Monitor^[LoRow,count,2] := $07;
                      end;
                    UpRow := UpRow - 1;
                    LoRow := LoRow - 1;
                 end;
           80 : if LoRow < 25 then {down arrow}
                 begin
                   for count := LoRow downto UpRow do
                      begin
                        Move(Monitor^[count,LeftCol,1],
                        Monitor^[count+1,LeftCol,1],BytesToMove);
                      end;
                    for count := LeftCol to RightCol do
                      begin
                        Monitor^[UpRow,count,1] := 32;
                        Monitor^[UpRow,count,2] := $07;
                      end;
                    UpRow := UpRow + 1;
                    LoRow := LoRow + 1;
                 end;

       end;
    until ord(ch2) = 68;
    {now restore origonal attributes}
    AttrCount := 1;
    For count := UpRow to LoRow do
      For kount := LeftCol to RightCol do
        begin
          Monitor^[count,kount,2] := ScnAttributes[AttrCount];
          AttrCount := AttrCount + 1;
        end;
    ScnImage2 := Monitor^;
    GotoXY(1,25);
    Write('You are now returning to the main part of the program');
    Delay(3000);
    Monitor^ := ScnImage2;
    ch2 := ' ';
    Move(Symbol,Monitor^[25,1,1],2);
    {restore the original character to the lower left corner of scren}
    Normal;
end;

{-----------------------------------------------------------------}

Procedure SaveScnImage;
Var
    Row,Col               : integer;
    NumOfChars            : byte;
    NextChar,LastChar     : byte;
    IsRepeatChar          : boolean;
    AttrSymbol,CharSymbol : byte;
Begin
    GotoXY(1,25);
    AttrSymbol := $FF;
    CharSymbol := $00;
    ScnImage2 := Monitor^;{save screen}
    ClrScr;
    Reverse;
    GotoXY(10,10);
    ClrEol;
    Write('Enter Name of Screen file');
    GotoXY(10,11);
    ClrEol;
    Write('Include the drive designation if different from current drive');
    GotoXY(10,12);
    ClrEol;
    Write('Do not include an extension since the extensions will be added');
    GotoXY(10,13);
    ClrEol;
    Write('File Name:  ');
    Read(NameOfScreen);
    Assign(ImageFile,NameOfScreen + '.scn');
    ReWrite(ImageFile);
    {This part will read the attributes on the screen and write
     them to the file}
    Monitor^ := ScnImage2;  {recover the Screen}
    LastChar := Monitor^[1,1,1];{set so no change from LastChar to
                                 NextChar on first loop}
    Attr := 07;{start with normal attribute}
    NumOfChars := 0;
    Write(ImageFile,AttrSymbol,Monitor^[01,01,2]);{first byte of file is
                               an attribute byte}
    For Row := 1 to  25 do
      For Col := 1 to 80 do
       begin

         NextChar := Monitor^[Row,Col,1];
         If (NextChar = LastChar) and (Monitor^[Row,Col,2] = Attr)
           then NumOfChars := NumOfChars + 1
           else begin
                  if NumOfChars > 3 then
                  write(ImageFile,CharSymbol,NumOfChars,LastChar)
                  else for count := 1 to NumOfChars do
                  write(ImageFile,LastChar);
                  NumOfChars := 1;
                  LastChar := NextChar;
                end;


         If NumOfChars = 255 then{255 is the maximun number that
                                   can be stored in a byte}
           begin
             write(ImageFile,CharSymbol,NumOfChars,LastChar);
             NumOfChars := 0;
           end;

         If Monitor^[Row,Col,2] <> Attr then
           begin
             Write(ImageFile,AttrSymbol,Monitor^[Row,Col,2]);
             {write $FF and the attribute to file each time it changes}
           end;

         Attr := Monitor^[Row,Col,2];{this is the new attribute}
       end;
    {if the repeat cycle was in effect, we need to flush the buffer}
       if NumOfChars > 3 then
       write(ImageFile,CharSymbol,NumOfChars,LastChar)
       else for count := 1 to NumOfChars do
            write(ImageFile,LastChar);
    Close(ImageFile);
    GotoXY(1,25);
    Reverse;
    Write('The Screen ',NameOfScreen,' has been saved');
    Delay(3000);
    Normal;
    Monitor^ := ScnImage2;
end;

{------------------------------------------------------------------}

Procedure GenerateScnCode;

Type
   OneLine  = String[80];
   LineImage = array[1..160] of char;
   Attributes = array[1..25,1..80] of char;
Var

   ScnLines             : array[1..25] of OneLine;
   count,kount,k,X,Y    : integer;
   Image                : LineImage;
   StartCount,StopCount : integer;
   NumOfChars           : integer;
   ch                   : char;
   AnyLine              : OneLine;
   Attr                 : Attributes;
   LastAttrib           : byte;
   NumOfVars            : integer;
   TypeEntry            : String[13];
   SaveRow,SaveCol      : integer;


{-------------------------------------------------------------------}

Procedure ChangeAttribute;
Begin
   case Monitor^[count,k,2] of
      $F0:writeln(ScnFile,'     ReverseBlink;');
      $87:writeln(ScnFile,'     Blink;');
      $70:writeln(ScnFile,'     Reverse;');
      $0F:writeln(ScnFile,'     HiInt;');
      $07:writeln(ScnFile,'     Normal;');
      else  writeln(ScnFile,'     Normal;');
   end;
end;

{-------------------------------------------------------------------}

Begin  {GenerateScnCode}
  ScnImage2 := Monitor^;{save Screen}
  Assign(ScnFile,NameOfScreen + '.pas');
  ReWrite(ScnFile);
  Writeln(ScnFile,'Program ',NameOfScreen,';');
  Writeln(ScnFile,'{$I General.inc}');
  if VarDefined then Writeln(ScnFile,'Var');
  for TypeofVar := Int to Bol do
    begin
      NumOfVars := 0;
      write(ScnFile,'   ');{indent before listing variables}
      for count := 1 to 80 do
        begin
          with ScnVars[count] do
            if (VarType = TypeOfVar) and (VarName <> '') then
              begin
                if NumOfVars > 0 then write(ScnFile,',');
                if (NumOfVars > 0) and (NumOfVars mod 4 = 0) then
                Write(ScnFile,#13,#10,'   ');
                Write(ScnFile,VarName:10);
                NumOfVars := NumOfVars + 1;
              end;
        end;
      if NumOfVars > 0 then
        begin
          Case TypeOfVar of
            Int : writeln(ScnFile,'   : integer;');
            Rl  : writeln(ScnFile,'   : real;');
            Strn: writeln(ScnFile,'   : AnyString;');
            Bol : writeln(ScnFile,'   : boolean;');
          end;
        end;
    end;
  Write(ScnFile,#13,#10,'Begin',#13,#10);
  Writeln(ScnFile);
  writeln(ScnFile,'     InitMonoSPFX;');
  Writeln(ScnFile,'     ClrScr;');
  Writeln(ScnFile,'     Normal;');
  For count := 1 to 80 do
    begin
      with ScnVars[count] do
        begin
          if VarName <> '' then
              Case VarType of
                Int : Writeln(ScnFile,'     ',VarName,' := 0;');
                Rl  : Writeln(ScnFile,'     ',VarName,' := 0;');
                Strn: Writeln(ScnFile,'     ',VarName,' := ','''','''',';');
                {no need to initialize boolean variables}
              end;
        end;
    end;

   LastAttrib := ord(Monitor^[1,1,2]);{set LastAttrib to the attribute of
                                  the upper left corner of screen}
   count := 1; k := 1; ChangeAttribute;{check to see if first screen
                                        attribute is other than normal}
   for count := 1 to 25 do
     begin
       kount := 0;
       repeat
           kount := kount + 1;
       until (ord(Monitor^[count,kount,1]) <> 32) or (kount >= 80);
       if kount < 80 then
         begin
           StartCount := kount;
           X := kount;
           Y := count;
           kount := 81;
           repeat
             kount := kount - 1;
           until (ord(Monitor^[count,kount,1]) <> 32) or (kount <= StartCount);
           StopCount := kount;
           Writeln(ScnFile,'     GotoXY(',X,',',Y,');');
           Write(ScnFile,'     Write(','''');
           NumOfChars := 0;
           for k:= StartCount to StopCount do
              begin
                NumOfChars := NumOfChars + 1;
                if NumOfChars = 50 then
                  begin
                    writeln(ScnFile,'''',',');
                    write(ScnFile,'       ','''');
                    NumOfChars := 0;
                  end;
                if ord(Monitor^[count,k,2]) <> LastAttrib then
                   begin
                     writeln(ScnFile,'''',');');
                     ChangeAttribute;
                     Write(ScnFile,'     Write(','''');
                     LastAttrib := ord(Monitor^[count,k,2]);
                     NumOfChars := 0;
                   end;
                if (Monitor^[count,k,1]) = 39 then write(ScnFile,'''',
                    ',','''','''','''','''',',','''')
                {if single quote, then write four quotes to program file}
                else write(ScnFile,chr(Monitor^[count,k,1]));
              end;
           Writeln(ScnFile,'''',');');
         end;
     end;


  For count := 1 to 80 do
    begin
      with ScnVars[count] do
        begin
          if VarName <> '' then
            begin
              Writeln(ScnFile,'     GotoXY(',VarCol,',',VarRow,');');
              Case VarType of
                Int : Writeln(ScnFile,'     Write(',VarName,':',VarLgth,
                        ');');
                Rl  : Writeln(ScnFile,'     Write(',VarName,':',VarLgth,
                        ':2);');
                Strn: Writeln(ScnFile,'     Write(',VarName,':',VarLgth,
                        ');');
              end;
            end;
        end;
    end;
  For count := 1 to 80 do
    begin
      with ScnVars[count] do
        begin
          if VarName <> '' then
            begin
              Case VarType of
                Int : TypeEntry := 'Integer_Entry';
                Rl  : TypeEntry := 'Real_Entry';
                Strn: TypeEntry := 'String_Entry';
                Bol : TypeEntry := 'Bol_Entry';
              end;{case}
              Case VarType of
                Int,Strn : begin
                              Writeln(ScnFile,'     GotoXY(',
                                      VarCol,',',VarRow,');');
                              Writeln(ScnFile,'     ',TypeEntry,
                                      '(',VarName,',', VarLgth,');');
                           end;
                Rl       : begin
                              Writeln(ScnFile,'     GotoXY(',
                                      VarCol,',',VarRow,');');
                              Writeln(ScnFile,'     ',TypeEntry,
                                      '(',VarName,',', VarLgth,',2);');
                           end;
                Bol : begin
                        Writeln(ScnFile,'     GotoXY(',VarCol,',',VarRow,');');
                        Writeln(ScnFile,'     ',TypeEntry,'(',VarName,');');
                      end;
              end;{case}
            end;
        end;
    end;
  Write(ScnFile,'end.');
  close(ScnFile);
end;

{------------------------------------------------------------------}

Procedure SetAttribute;
Var
   choice     : integer;


{------------------------------------------}

Procedure WriteMenu;
Begin
       Normal;
       GotoXY(20,10);Write('1. Normal Video');
       GotoXY(20,11);Write('2. Reverse Video');
       GotoXY(20,12);Write('3. Blinking Video');
       GotoXY(20,13);Write('4. Reverse Blinking Video');
       GotoXY(20,14);Write('5. High-intensity Video');
       GotoXY(20,15);Write('6. Return to Program');
       GotoXY(20,16);Write('Enter Selection');
end;

{---------------------------------}

Begin {SetAttribute}
       Move(Monitor^,ScnImage2,4000);
       ClrScr;
       WriteMenu;
       Repeat
           begin
             GotoXY(40,16);
             Repeat read(choice) until choice in[1..6];
           end;
         Case choice of
            1:begin
                Attr :=  $07;
                WriteMenu;
                HiInt;
                GotoXY(20,10);Write('1. Normal Video');
                Normal;
              end;
            2:begin
                Attr :=  $70;
                WriteMenu;
                HiInt;
                GotoXY(20,11);Write('2. Reverse Video');
                Normal;
              end;
            3:begin
                Attr :=  $87;
                WriteMenu;
                HiInt;
                GotoXY(20,12);Write('3. Blinking Video');
                Normal;
              end;
            4:begin
                Attr :=  $F0;
                WriteMenu;
                HiInt;
                GotoXY(20,13);Write('4. Reverse Blinking Video');
                Normal;
              end;
            5:begin
                Attr :=  $0F;
                WriteMenu;
                HiInt;
                GotoXY(20,14);Write('5. High-intensity Video');
                Normal;
              end;
         end;{case}
       until choice = 6;

       Move(ScnImage2,Monitor^,4000);
end;

{------------------------------------------------------------------}

Procedure CenterLine;
Var
   IsSpace           : boolean;
   NumOfSpaces       : integer;
   WhereCharStarts   : integer;
   NumOfBytestoMove  : integer;
   SpacesToFirstChar : integer;
Begin
   Count := 1;
   NumOfSpaces := 0;
   Repeat
     if Monitor^[Row,count,1] = 32 then
        begin
          IsSpace := true;
          NumOfSpaces := NumOfSpaces + 1;
        end
        else
          begin
            IsSpace := false;
            WhereCharStarts := Count;
         end;
     Count := Count + 1;
   until (IsSpace = false) or (Count = 81);

   Count := 80;
   If NumOfSpaces < 80 then
   Repeat
     if Monitor^[Row,count,1] = 32 then
        begin
          IsSpace := true;
          NumOfSpaces := NumOfSpaces + 1;
        end
        else IsSpace := false;
     Count := Count - 1;
   until (IsSpace = false) or (Count = 0);
   SpacesToFirstChar := NumOfSpaces div 2;
   NumOfBytesToMove := (80 - NumOfSpaces) * 2;
   Move(Monitor^[Row,WhereCharStarts,1],
       Monitor^[Row,(SpacesToFirstChar + 1),1],NumOfBytesToMove);
   {now fill in spaces before and after the new position of the string}
   for count := 1 to SpacesToFirstChar do
     Monitor^[Row,count,1] := 32;
   for count := 80 downto (80 + SpacesToFirstChar - NumOfSpaces + 1) do
     Monitor^[Row,count,1] := 32;

end;

{------------------------------------------------------------------}

Procedure IncrementScnPos;
begin
  Col := Col + 1;
  if Col > 80 then
    begin
      Row := Row +1;
      Col := 1;
    end;
end;

{------------------------------------------------------------------}

Procedure ReadScnFile(ScnName:FileName;var WhereToPutScn:TotScn);

Var
   Attr,bt,ByteValue,NextChar : byte;
Label
   Hop;
Begin
   Attr := 7;{normal attribute}
   Row:= 1;Col := 1;{Start writing to screen at upper
                                 left corner}

   OpenInFile(ScnName);
   If not OK then goto Hop;
   Reset(ImageFile);
   While not eof(ImageFile) do

    begin
      read(ImageFile,bt);
      case bt of
         $FF  :begin
                 Read(ImageFile,Attr);
               end;
         $00  :begin
                 Read(ImageFile,ByteValue);{number of times next ASC11 value
                                           is to be repeated}
                 Read(ImageFile,NextChar);
                 for count := 1 to ByteValue do
                   begin
                     WhereToPutScn[Row,Col,1] := NextChar;
                     WhereToPutScn[Row,Col,2] := Attr;
                     IncrementScnPos;
                   end;
               end
               else begin
                      WhereToPutScn[Row,Col,1] := bt;
                      WhereToPutScn[Row,Col,2] := Attr;
                      IncrementScnPos;
                    end;
      end;
    end;
   Close(ImageFile);
   Hop:
end;

{------------------------------------------------------------------}

Procedure Var_Entry(var Var_In:AnyString;VType:TypeVar;Max:Integer);

Const
   IntSet    : set of char = [#8,#13,#27,#48..#57];
   RealSet   : set of char = [#8,#13,#27,#46,#48..#57];
   StringSet : set of char = [#8,#13,#27,#32..#126];
Var
   Pos,count,Row,Col                      : integer;
   Answ                                   : AnyString;
   AnySet                                 : Set of char;
Begin

     Ch1 := ' ';
     Ch2 := ' ';
     Answ:='';
     col:=WhereX;row:=WhereY;
     Pos:=0;
     Case VType of
       Int :AnySet := IntSet;
       Rl  :AnySet := RealSet;
       Strn:AnySet := StringSet;
     end;
     Repeat
        Repeat read(kbd,Ch1) until Ch1 in AnySet;
        if Ch1=#27  then read(kbd,Ch2);
           {check to see if it is two character code}
           {if so then read the second character}
        case Ch1 of
           ^H:if pos>0 then
                   begin
                     write(^H,' ',^H);
                     delete(Answ,pos,1);
                     pos:=pos-1;
                     Var_In := Answ;
                   end;
            #32..#126:begin
                       if pos=0 then
                          begin
                            for count:=1 to max do write(chr(32));
                            for count:=1 to max do write(^H);
                          end;
                       if pos<max then
                          begin
                            pos:=pos+1;
                            write(Ch1);
                            Answ:=Answ+Ch1;
                            Var_In := Answ;
                          end
                          else write(^G);
                     end;
        end;
     until (Ch1 = #13) or (Ch2 in[#27,#59..#68,#71,#72,#75,#77,#79,
                                  #80,#82,#83,#90]);
     {
      #27           Escape         #79   End
      #59 thru #69  F1..F10        #80   Dn. arr.
      #71           Home           #82   Insert
      #72           Up arr.        #83   Delete
      #75           L. arr.        #90   Shift F7
      #77           R. arr.
     }
     GotoXY(col,row);Normal;
     For count:= 1 to max do write(chr(32));
     GotoXY(col,row);
     Write(VAr_In);
end;

{------------------------------------------------------------------}


Procedure MoveCursor;

Begin    {MoveCursor}

 Col := WhereX;
 Row := WhereY;
 Repeat
    Repeat Read(kbd,Ch1) until Ch1 = ^[;
    if Ch1 = ^[ then Read(kbd,Ch2);
          Case Ch2 of
            'P'    :if not StayOnRow then
                    begin   {down arrow}
                      if Row < 25 then Row := Row + 1;
                      GotoXY(Col,Row);
                    end;
            'H'    :if not StayOnRow then
                    begin   {up arrow}
                      if Row > 01 then Row := Row - 1;
                      GotoXY(Col,Row);
                    end;
            'M'     :begin   {right arrow}
                      if (Col < 80) then Col := Col + 1;
                      GotoXY(Col,Row);
                     end;
            'K'     :begin
                       Col := Col - 1;
                       GotoXY(Col,Row);
                     end;
         end;
  until Ch2 = #59;
  Col := WhereX;
  Row := WhereY;
end;

{---------------------------------------------------------------}

Procedure PlaceMarkers;
Var
   kount : integer;
Begin
   for count := 1 to 80 do
     if (ScnVars[count].VarName <> '') and (count <> VarNum) then
     {dont place marker for current variable or if no variable entry}
       begin
         with ScnVars[count] do
           begin
             for kount := VarCol to VarCol + VarLgth - 1 do
               begin
                 Monitor^[VarRow,kount,1] := VarMarker;
                 Monitor^[VarRow,kount,2] := $70;
               end;
           end;
       end;
end;

{---------------------------------------------------------------}

Procedure PlaceVariable;
Var
   SaveRow,SaveCol    : integer;
Begin {PlaceVariable}
   StayOnRow := false; { free to move about}
   SaveRow := Row; {this is where we want the cursor to}
   SaveCol := Col; {return to when it returns to the variable table}
   Move(Monitor^,ScnImage2,4000);{save the variable table}
   Move(WorkScn,Monitor^,4000);{now display the input screen}
   PlaceMarkers;
   Move(Monitor^[25,1,1],LastScnLine,160);{store line 25 of input screen}
   GotoXY(1,25);
   Reverse;ClrEol;
   Write('Position Cursor and press F1 to indicate starting position',
   ' of the variable');
   Normal;
   If VarNum > 1 then {goto the point the last variable was positioned}
      begin
        with ScnVars[VarNum - 1] do GotoXY(VarCol + VarLgth,VarRow);
      end;
   While not keypressed do;
   Move(LastScnLine,Monitor^[25,1,1],160);{restore line 25 of screen}
   Repeat MoveCursor until (Ch2 = #59);
   {move cursor until F1 is pressed}
   With ScnVars[VarNum] do
     begin
       VarRow := Row;
       VarCol := Col;
     end;
   Monitor^[Row,Col,2] := $70;
   Monitor^[Row,Col,1] := ScnVars[VarNum].VarMarker;
   Move(Monitor^[25,1,1],LastScnLine,160);{store line 25 of screen}
   GotoXY(1,25);
   Reverse;ClrEol;
   Write('Position Cursor and press F1 to indicate ending position',
   ' of the variable');
   With ScnVars[VarNum] do GotoXY(VarCol,VarRow);
   While not keypressed do;
   Move(LastScnLine,Monitor^[25,1,1],160);{restore line 25 of screen}
   Normal;
   StayOnRow := true; { now stay on the same row }
   if ScnVars[VarNum].VarType <> Bol then Repeat MoveCursor until (Ch2 = #59)
    and (Col >= ScnVars[VarNum].VarCol);
    {if VarType is not boolean then move cursor until F1 is pressed
       and the cursor  position is at or to the right of first F1}
   ScnVars[VarNum].Varlgth := Col - ScnVars[VarNum].VarCol + 1;
   For count := ScnVars[VarNum].VarCol to ScnVars[VarNum].VarCol +
           ScnVars[VarNum].VarLgth - 1 do
     begin
       Monitor^[Row,count,1] := ScnVars[VarNum].VarMarker;
       Monitor^[Row,count,2] := $70;
     end;
   While not keypressed do;
   Move(ScnImage2,Monitor^,4000);{and return the variable table}
   Row := SaveRow;{prepare for the cursor to return to the same}
   Col := SaveCol;{spot on the variable table}
   Normal;
end;

{-------------------------------------------------------------------}

Procedure SaveVarTable;

Var
  SaveRow,SaveCol  : integer;

Begin
  SaveRow := Row;
  SaveCol := Col;

  if VarDefined then
    begin
        {now write variable information to the VarTable file}
        Assign(VarTable,NameOfScreen + '.tbl');
        Rewrite(VarTable);
        for count := 1 to 80 do write(VarTable,ScnVars[count]);
        close(VarTable);
    end;

end;

{---------------------------------------------------------------------}

Procedure DeleteVariable;
Var
   DeleteRow,DeleteVariable : integer;
Begin
   for count := VarNum to 79 do
     begin
       ScnVars[count].VarName := ScnVars[count + 1].VarName;
       ScnVars[count].VarType := ScnVars[count + 1].VarType;
       ScnVars[count].VarRow := ScnVars[count + 1].VarRow;
       ScnVars[count].VarCol := ScnVars[count + 1].VarCol;
       ScnVars[count].VarLgth := ScnVars[count + 1].VarLgth;
     end;
   with ScnVars[80] do
     begin  {now change  variable #80 values to nil values}
       VarName := '';
       VarType := None;
       VarRow := 1;
       VarCol := 1;
       VarLgth := 1;
     end;
   DeleteRow := Row;DeleteVariable := VarNum;
   for count := DeleteRow to 24 do
     begin {now place variables on screen}
       GotoXY(2,DeleteRow);
       Write(DeleteVariable :2);
       GotoXY(5,DeleteRow);
       Write(chr(32):10);
       GotoXY(5,DeleteRow);
       Write(ScnVars[DeleteVariable].VarName);
       GotoXY(17,DeleteRow);
       Case ScnVars[DeleteVariable].VarType of
          Int :Write('I');
          Rl  :Write('R');
          Strn:Write('S');
          None:Write(' ');
       end;
       GotoXY(22,DeleteRow);
       DeleteRow := DeleteRow + 1;
       DeleteVariable := DeleteVariable + 1;
     end;
     GotoXY(2,Row);
end;

{----------------------------------------------------------------------}


Procedure MoveUp;

     begin
       case Row of
           4..24:begin
                   Row := Row - 1;
                   VarNum := VarNum - 1;
                 end;
               3:if VarNum > 1 then
                   begin
                     VarNum := VarNum - 1;
                     for count := 1 to  22 do
                       begin
                         GotoXY(2,Row);
                         Write(VarNum :2);
                         GotoXY(5,Row);
                         Write(chr(32):10);
                         GotoXY(5,Row);
                         Write(ScnVars[VarNum].VarName);
                         GotoXY(17,Row);
                         Case ScnVars[VarNum].VarType of
                           Int :Write('I');
                           Rl  :Write('R');
                           Strn:Write('S');
                           None:Write(' ');
                         end;
                         GotoXY(22,Row);
                         Row := Row + 1;
                         VarNum := VarNum +1;
                       end;
                     Row := Row - 22;
                     VarNum := VarNum - 22;
                   end;
       end;{case}

     end;

{---------------------------------------------------------------------}

Procedure MoveDown;
Begin
    case Row of
        3..23:begin
                Row := Row + 1;
                VarNum := VarNum + 1;
              end;
           24:if VarNum < 80 then
              begin
                GotoXY(2,24);
                Write(chr(32):2);
                GotoXY(5,24);
                Write(chr(32):10);
                GotoXY(17,24);
                Write(' ');
                GotoXY(22,24);
                Write(' ');
                VarNum := VarNum - 20;
                Row := Row - 21;
                for count := 1 to  22 do
                   begin
                     GotoXY(2,Row);
                     Write(VarNum :2);
                     GotoXY(5,Row);
                     Write(chr(32):10);
                     GotoXY(5,Row);
                     Write(ScnVars[VarNum].VarName);
                     GotoXY(17,Row);
                     Case ScnVars[VarNum].VarType of
                         Int : Write('I');
                         Rl  : Write('R');
                         Strn: Write('S');
                         None: Write(' ');
                      end;
                      GotoXY(22,Row);
                      Row := Row + 1;
                      VarNum := VarNum +1;
                   end;
                Row := Row - 1;
                VarNum := VarNum - 1;
              end;
    end; {case}
end;

{--------------------------------------------------------------------}

Procedure DisplayVariables;

Begin
   for count := 1 to  22 do
      begin
        GotoXY(2,Row);
        Write(VarNum :2);
        GotoXY(5,Row);
        Write(chr(32):10);
        GotoXY(5,Row);
        Write(ScnVars[VarNum].VarName);
        GotoXY(17,Row);
        Case ScnVars[VarNum].VarType of
            Int : Write('I');
            Rl  : Write('R');
            Strn: Write('S');
            None: Write(' ');
        end;
        GotoXY(22,Row);
        Row := Row + 1;
        VarNum := VarNum +1;
      end;
   Row := Row - 22;
   VarNum := VarNum - 22;
   GotoXY(Col,Row);
end;

{--------------------------------------------------------------------}

Procedure ReadVarTable;
Var
   SaveRow,SaveCol    : integer;
Label
   skip;
Begin
   Move(Monitor^,ScnImage2,4000);{save the variable table}
   ClrScr;
   GotoXY(1,10);Reverse;ClrEol;
   Writeln('Reading a new Variable table will overwrite the present table');
   ClrEol;
   Write('Do you wish to proceed?    ');
   Repeat read(kbd,ch) until UpCase(ch) in['Y','N'];
   If UpCase(ch) = 'N' then
     begin
       Normal;
       Monitor^ := ScnImage2;
       goto skip;
     end;
   Writeln;ClrEol;
   Writeln('Enter the Variable table file name without the extension');
   ClrEol;
   Write('File Name :  ');
   Read(VarFileName);
   Normal;
   Assign(VarTable,VarFileName + '.tbl');
   {$I-} Reset(VarTable) {$I+};
   OK := (IOresult = 0);
   if not OK then
      begin
         Reverse;
         Writeln;
         ClrEol;
         Writeln('Cannot find file  ',VarFileName);
         ClrEol;
         Writeln('Retry to locate file');
         ClrEol;
         Writeln('Press any key to continue');
         while not keypressed do;
         Normal;
         Monitor^ := ScnImage2;
         goto skip;
      end;
   For count := 1 to 80 do Read(VarTable,ScnVars[count]);
   close(VarTable);
   Move(ScnImage2,Monitor^,4000);
   Col :=2; Row := 3;
   VarNum := 1;
   DisplayVariables;
   skip:
end;

{---------------------------------------------------------------------}

Procedure InsertVariable;
Var
   InsertRow,InsertVariable : integer;
Begin {change variable 80 to insert point to next lower variable}
   for count := 80 downto (VarNum + 1) do
     begin
       ScnVars[count].VarName := ScnVars[count - 1].VarName;
       ScnVars[count].VarType := ScnVars[count - 1].VarType;
       ScnVars[count].VarRow := ScnVars[count - 1].VarRow;
       ScnVars[count].VarCol := ScnVars[count - 1].VarCol;
       ScnVars[count].VarLgth := ScnVars[count - 1].VarLgth;
     end;
   with ScnVars[VarNum] do
     begin  {now change insert variable values to nil values}
       VarName := '';
       VarType := None;
       VarRow := 1;
       VarCol := 1;
       VarLgth := 1;
     end;
   InsertRow := Row;InsertVariable := VarNum;
   for count := InsertRow to 24 do
     begin {now place variables on screen}
       GotoXY(2,InsertRow);
       Write(InsertVariable :2);
       GotoXY(5,InsertRow);
       Write(chr(32):10);
       GotoXY(5,InsertRow);
       Write(ScnVars[InsertVariable].VarName);
       GotoXY(17,InsertRow);
       Case ScnVars[InsertVariable].VarType of
          Int :Write('I');
          Rl  :Write('R');
          Strn:Write('S');
          None:Write(' ');
       end;
       InsertRow := InsertRow + 1;
       InsertVariable := InsertVariable + 1;
     end;
   GotoXY(2,Row);
end;

{-------------------------------------------------------------------}

Procedure DisPlayWkScn;
Var
   SaveRow,SaveCol : integer;
Begin
   SaveRow := Row;
   SaveCol := Col; {this is where we want the cursor to}
                   {return to when it returns to the variable table}
   Move(Monitor^,ScnImage2,4000);{save the variable table}
   Move(WorkScn,Monitor^,4000);{now display the input screen}
   PlaceMarkers;
   While not keypressed do;
   Move(ScnImage2,Monitor^,4000);
             {and return the variable table}
   Row := SaveRow;
             {prepare for the cursor to return to the same}
   Col := SaveCol;{spot on the variable table}
end;

{--------------------------------------------------------------------}

Procedure DefineVariables;
Var
  SaveRow,SaveCol : integer;

Begin
  VarDefined := true;{indicate that variables have been defined}
  Normal;
  Move(Monitor^,WorkScn,4000);{save the input screen}
  Move(VarScn,Monitor^,4000);

  Col :=2; Row := 3;
  VarNum := 1;
  DisplayVariables;
  Repeat
    GotoXY(2,Row);
    Write(VarNum:2);
    GotoXY(5,Row);
    Var_Entry(ScnVars[VarNum].VarName,Strn,10);
    case Ch1 of
      #27: Case Ch2 of  {escape character}
              #72: MoveUp;{up arrow}
              #80: MoveDown;{down arrow}
              #61: DeleteVariable;
              #60: InsertVariable;
              #63: ReadVarTable;
              #62: DisPlayWkScn;

           end;{case}
           else  {if Var_Entry is not one of allowed control characters
                  and the VarName <> '', then continue}
           begin
            if ScnVars[VarNum].VarName <> '' then
              begin
                GotoXY(17,Row);
                Repeat read(kbd,ch) until UpCase(ch) in ['I','R','S','B'];
                Write(UpCase(ch));
                Case UpCase(ch) of
                  'I' :ScnVars[VarNum].VarType := Int;
                  'R' :ScnVars[VarNum].VarType := Rl;
                  'S' :ScnVars[VarNum].VarType := Strn;
                  'B' :ScnVars[VarNum].VarType := Bol;
                end;
                PlaceVariable;   {position the variable on the data screen}
              end;
            MoveDown;
           end;
    end;

  until Ch2 = #68;  {F10}
  Ch2 := ' ';
  Move(WorkScn,Monitor^,4000);
end;

{-------------------------------------------------------------------}

Procedure SaveToFile;
Begin
  SaveScnImage; {save the screen in a file with extension of .scn}
  GenerateScnCode; {generate pascal scource code with ext. of .pas}
  SaveVarTable; {save variable table in a file with ext. of .tbl}
end;

{-------------------------------------------------------------------}

Begin
  CheckVideo(IsBWcard);
  if IsBWcard then Monitor := Addr(MonoScn) else Monitor :=
      Addr(ColorScn);
  VarDefined := false;{indicate that variables have not been defined}
  LowVideo;
  ClrScr;
  InitMonoSPFX; {find Attribute segment and offset}
  AscMarker := 49;{start out with numeral one as the marker}
  For count := 1 to 80 do    {initialize variable table}
     begin
       with ScnVars[count] do
         begin
           VarName := '';
           VarType := None;
           VarRow := 1;
           VarCol := 1;
           VarLgth := 1;
           VarMarker := AscMarker;
         end;
       AscMarker := AscMarker + 1;
       If AscMarker = 58 then AscMarker := 48;
         {when we get to nine start over at zero}
     end;

  GotoXY(10,10);
  Write('Now reading the Help Screen file from disk');
  ReadScnFile('Help.scn',HelpScn);
  GotoXY(10,10);ClrEol;
  Write('Now reading the Variable Screen file from disk');
  ReadScnFile('Var.scn',VarScn);
  ClrScr;
  GotoXY(10,10);
  Write('Remember to press  Escape key twice  for help');
  GotoXY(10,11);
  Write('Press any key to continue');
  While not keypressed do;
  LowVideo;
  ClrScr;
  NameOfScreen := '';
  InsertOn := false;
  Col := 1;Row := 1;
  GotoXY(Col,Row);
  Attr := $07;
    Repeat
        ch2 :=' ';
        Repeat read(kbd,Ch1) until Ch1 in[#8,#13,#27,#32..#254];
        {#8 = backspace, #13 = Enter,#27 = Escape,#32..#126 = ASCII chars}
        if Ch1 = #27 then       {check to see if it is two character code}
            read(kbd,ch2);      {read the second character}
        Col := WhereX;Row := WhereY;
        case Ch1 of
           #8  :if col > 0 then write(^H,' ',^H);   {backspace}

           #13 :begin {carriage return}
                  write(^M);
                  if Row < 25 then write(^J);
                  {if not on last row, write line feed}
                end;
           #32..#254: begin  {ASII characters}
                       if Col <= 80 then
                          begin
                            if InsertOn then
                              begin
                                For count := 79 downto Col do
                                  begin
                                     Monitor^[Row,Count + 1,1]
                                     := Monitor^[Row,Count,1];
                                     Monitor^[Row,Count + 1,2]
                                     := Monitor^[Row,Count,2];
                                  end;
                              end;
                            Monitor^[Row,Col,1] := Ord(Ch1);
                            Monitor^[Row,Col,2] := Attr;
                            MovScnPos;
                            GotoXY(Col,Row);
                          end;
                      end;
           #27 :case Ch2 of    {extended scan key codes}
                 #27 : begin {escape twice}
                         ScnImage2 := Monitor^;
                         Monitor^ := HelpScn;
                         While not keypressed do;
                         Read(kbd,ch);
                         Monitor^ := ScnImage2;
                       end;
                 #80 : begin   {down arrow}
                         if Row < 25 then Row := Row + 1;
                         GotoXY(Col,Row);
                       end;
                 #72 : begin   {up arrow}
                         if Row > 01 then Row := Row - 1;
                         GotoXY(Col,Row);
                       end;
                 #77 : begin   {right arrow}
                         if Col < 80 then Col := Col + 1;
                         GotoXY(Col,Row);
                       end;
                 #75 : begin   {left arrow}
                         if Col > 01 then Col := Col - 1;
                         GotoXY(Col,Row);
                       end;
                 #71 : GotoXY(1,Row);  {Home key}
                 #79 : begin           {End key}
                         Col := 80;
                         While (Monitor^[Row,Col,1] = 32) and
                          (Col > 1) do Col := Col - 1;
                         if Col = 1 then Col := 80;
                         GotoXY(Col,Row);
                       end;
                 #83 : begin    {delete key}
                         for count := Col to 79 do
                           begin
                             Monitor^[Row,Count,1] :=
                             Monitor^[Row,Count + 1,1];
                             Monitor^[Row,Count,2] :=
                             Monitor^[Row,Count + 1,2];
                           end;
                           Monitor^[Row,80,1] := 32;
                             {set last position on line to space}
                       end;
                 #82 : Begin;    {insert key}
                         Col := WhereX;Row := WhereY;
                         InsertOn := not InsertOn;
                         if InsertOn then BigCursor
                         else SmallCursor;
                         Write;
                       end;
                 #60 : begin  {insert line}
                         Move(Monitor^[Row,1,1],Monitor^[Row+1,1,1],
                             ((25-Row)*160));
                         for count := 1 to 80 do
                           begin
                             Monitor^[Row,count,1] := 32;
                             Monitor^[Row,count,2] := 7;
                         end;
                       end;
                 #64 : SaveToFile;
                 #66 : DefineVariables;
                 #61 : begin  {delete line}
                         Move(Monitor^[Row+1,1,1],Monitor^[Row,1,1],
                          (25-Row)*160);
                         for count := 1 to 80 do
                           begin
                             Monitor^[25,count,1] := 32;
                             Monitor^[25,count,2] := 7;
                           end;
                       end;
                 #59 : CenterLine;
                 #62 : begin
                         SetAttribute;
                         GotoXY(Col,Row);
                       end;
                 #63 : begin  {display a screen from a disk file}
                         ScnImage2 := Monitor^;
                         Window(10,8,70,17);
                         Reverse;
                         ClrScr;
                         Writeln('Displaying a Screen ',
                                 'will overwrite the present screen');
                         Write('Are you sure you want to proceed ?(Y/N)  ');
                         Repeat read(kbd,ch) until UpCase(ch) in['Y','N'];
                         if UpCase(ch) = 'N' then
                           begin
                             Monitor^ := ScnImage2;
                             Normal;
                             Goto Jump;
                           end;
                         Writeln;
                         Writeln('Enter Name of Screen to Display without',
                           ' the extension    ');
                         Writeln('The extension will added automatically');
                         Write('File Name :  ');
                         Read(NameOfScreen);
                         Normal;
                         ReadScnFile(NameOfScreen + '.scn',Monitor^);
                         if not OK then Monitor^ := ScnImage2;
                           {if file does not exist then
                            restore the former screen image}
                         Jump:
                         Window(1,1,80,25);
                       end;
                 #65 : if Col < 80 then {F7 key}
                                 {duplicates character to the right}
                         begin
                           Monitor^[Row,Col + 1,1] := Monitor^[Row,Col,1];
                           Monitor^[Row,Col + 1,2] := Monitor^[Row,Col,2];
                           Col := Col + 1;
                           GotoXY(Col,Row);
                         end;
                 #90 : if Row < 25 then {Shift F7 key}
                                 {duplicates character downward}
                         begin
                           Monitor^[Row + 1,Col,1] := Monitor^[Row,Col,1];
                           Monitor^[Row + 1,Col,2] := Monitor^[Row,Col,2];
                           Row := Row + 1;
                           GotoXY(Col,Row);
                         end;
                 #67 : MoveBlock;     {F9 key}
                end; {case}
        end;{case}
    until ord(ch2)=68;{F10}
    ScnImage2 := Monitor^;
    GotoXY(1,24);
    Reverse;
    ClrEol;
    Writeln('You are about to exit the program. Do you wish');
    ClrEol;
    Write('to define the variables for this screen?  ');
    Normal;
    Repeat Read(kbd,ch) until UpCase(ch) in['Y','N'];
    Monitor^ := ScnImage2;
    if UpCase(ch) = 'Y' then DefineVariables;
    ScnImage2 := Monitor^;
    GotoXY(1,24);
    Reverse;
    ClrEol;
    Writeln('You are about to exit the program. Do you wish');
    ClrEol;
    Write('to save this screen on disk?  ');
    Normal;
    Repeat Read(kbd,ch) until UpCase(ch) in['Y','N'];
    Monitor^ := ScnImage2;
    if UpCase(ch) = 'Y' then SaveToFile;
end.
