home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / pxl214a / pxlinst.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-07-01  |  36.0 KB  |  1,090 lines

  1. {$R+}    {Range checking off}
  2. {$B-}    {Boolean complete evaluation off}
  3. {$S+}    {Stack checking on}
  4. {$I+}    {I/O checking on}
  5. {$N-}    {No numeric coprocessor}
  6. {$M 32768,16384,65536}
  7.  
  8. program PXLInst;                                                      {.CP33}
  9. {  Creates &/or updates PXLX.PRN data file of print control characters for  }
  10. {  use by PXL Pascal X-Ref lister version 2.11+                             }
  11. {                                                                           }
  12. {  Allows up to seven control characters for each of six actions:           }
  13. {                                                                           }
  14. {      (1) underlining on             (2) underlining off,                  }
  15. {      (3) Pica on, (Elite off)       (4) Elite on (Pica off),              }
  16. {                                                                           }
  17. {      (5) Printer setup string (sent before printing)                      }
  18. {      (6) Printer reset string (sent after printing                        }
  19. {                                                                           }
  20. {  plus 3 single bytes for:                                                 }
  21. {                                                                           }
  22. {      (7) page control (either by Char #12 or by line count).              }
  23. {      (8) width of page (number of columns) in "pica"                      }
  24. {      (9) width of page (number of columns) in "elite"                     }
  25. {                                                                           }
  26. {  String data is stored in string[InstLen], though the program thinks of   }
  27. {  them (as PXL does) as Bt (arrays of [0..7] Bt where [0] shows how many   }
  28. {  of the others are significant).                                          }
  29. {                                                                           }
  30. {  If PXL.PRN for older versions of PXL is found, user is warned, and can   }
  31. {  choose update & rebuild the old file to exit, preserving it.             }
  32. {                                                                           }
  33. {  Programmer: R. N. Wisan, 7/6,1985                                        }
  34. {  Converted for TP4 & extended for nine 7-character instructions: 1988     }
  35. {  Converted for TP5 & extended for 6 string plus 3 byte instructions: 1989 }
  36.  
  37. Uses
  38.   CRT,
  39.   DOS;
  40.  
  41. const
  42.    {Don't change the following without making all the}
  43.    {matching changes throughout the PXL source files.}
  44.    FileName        =  'PXL.PRN';
  45.    InstLen         =  7;           {Maximum length of any printer instruction}
  46.    DatStrLen       = (4 * InstLen) - 1;
  47.    PredDatStrLen   = DatStrLen - 1;
  48.    EoFileSize      = 72; {Bt}
  49.    PalaeoFileSize  = 28; {Bt}
  50.    NeoFileSize     = 51; {Bt}
  51.  
  52.    {Colors for the screen.  Set these as you like:                          }
  53.      Bright        = 14;  {15}    {Normal text will be Dim on Background.   }
  54.      Dim           =  7;   {7}    {Inverse text will be Background on Dim.  }
  55.      Background    =  1;          {Highlights will be Bright on Background. }
  56.                                   {Warnings will blink Bright on Background.}
  57. type
  58.    LineType        = string[79];
  59.    DatStrType      = string[DatStrLen];
  60.    Str48           = string[48];
  61.    Tpface          = (MrkB, MrkE, SetLg,SetSm,PreP,PostP,FF,LW,SW);
  62.    ByteLine        = array[0..InstLen] of byte;
  63.    DataType        = record
  64.                        Tp:  array[MrkB..PostP] of ByteLine;
  65.                        Bt:  array[FF..SW] of byte;
  66.                      end; {DataType}    {58 Bt}
  67.    NeoFileType     = File of DataType;
  68.    FoundType       = (Palaeo,Eo,Neo,Wrong,NoFile);
  69.  
  70. const
  71.    ByteSet: set of TpFace = [FF..SW];
  72.  
  73. var
  74.    I:           integer;
  75.    OrigAtt:     byte;
  76.    Ch:          char;
  77.    T:           TpFace;
  78.    Inst:        DataType;
  79.    NullLine,
  80.    Line:        DatStrType;
  81.    PalaeoFile,
  82.    Changed,
  83.    FFFlag,
  84.    GotFile,
  85.    Extended:    boolean;
  86.    Found:       FoundType;
  87.    TypeLabel:   array[MrkB..SW] of string[20];
  88.    TypeLine:    array[MrkB..SW] of byte;
  89.    FName,
  90.    BarLine,
  91.    HeadLine:    LineType;
  92.    CRet:        string[InstLen];
  93.  
  94. procedure Bip;                                                         {.CP5}
  95. begin
  96.    sound(1760); delay(10); sound(440); delay(30);
  97.    sound(1760); delay(15); nosound
  98. end;
  99.  
  100. procedure Blanklines (Top,Bot: byte);                                  {.CP9}
  101. var
  102.    Col,Row:   byte;
  103. begin
  104.    for Row := Top to Bot do begin
  105.       GotoXY(1,Row);
  106.       for Col := 1 to 79 do write(#32)
  107.    end {for Row}
  108. end; {Blanklines}
  109.  
  110. function StrgB(B,L: Byte): LineType;                                   {.CP7}
  111. var
  112.    S: LineType;
  113. begin
  114.    str(B:L,S);
  115.    StrgB := S
  116. end; {StrgB}
  117.  
  118. function StrgI(B,L: Integer): LineType;                                {.CP7}
  119.    var
  120.    S: LineType;
  121. begin
  122.    str(B:L,S);
  123.    StrgI := S
  124. end; {StrgB}
  125.  
  126. function CurrentAttribute: byte;                                      {.CP12}
  127. var
  128.    R:    Registers;
  129. begin
  130.    GotoXY(1,pred(WhereY));
  131.    with R do begin
  132.       AH := $08;
  133.       BH := 0;
  134.       Intr($10,R);
  135.       CurrentAttribute := AH
  136.    end {with R}
  137. end; {CurrentAttribute}
  138.  
  139. procedure PutItBack(Colr: byte);                                      {.CP15}
  140. {Alternative to RestoreScreen.  Uses Turbo color procedures. }
  141. {Scrolls up one line, but doesn't overwrite rest of screen.  }
  142. {Background & foreground (including intensity) are preserved.}
  143. {Blinking is turned off.}
  144. var
  145.    Fore,Back: byte;
  146. begin
  147.    Back := (Colr shl 1) shr 5;
  148.    Fore := Colr and 15;
  149.    TextColor(Fore);
  150.    TextBackground(Back);
  151.    GotoXY(1,25);
  152.    writeln
  153. end; {PutItBack}
  154.  
  155. procedure Center(S: LineType; Row: byte);                              {.CP9}
  156. var
  157.    B:    byte;
  158. begin
  159.    BlankLines(Row,Row);
  160.    GotoXY(1,Row);
  161.    for B := 1 to (40 - (length(S) div 2)) do write(#32);
  162.    write(S);
  163. end; {Center}
  164.  
  165. procedure VideoInv;                                                    {.CP5}
  166. begin
  167.    TextColor(Background);
  168.    TextBackGround(Dim)
  169. end; {VideoInv}
  170.  
  171. procedure VideoHi;
  172. begin                                                                  {.CP5}
  173.     TextColor(Bright);
  174.     TextBackGround(Background);
  175. end; {VideoHi}
  176.  
  177. procedure VideoNorm;                                                   {.CP5}
  178. begin
  179.    TextColor(Dim);
  180.    TextBackGround(Background)
  181. end; {VideoNorm}
  182.  
  183. function EnvironLine(LineStart: LineType): LineType;                  {.CP30}
  184. { Searches DOS Environment for line beginning with LineStart     }
  185. { Returns line with LineStart removed in EnvironLine if found.   }
  186. { Returns "NONE" if not found. }
  187. var
  188.    S:               LineType;
  189.    EnvAdd:          word;
  190.    B:               byte;
  191.    LineFound:       boolean;
  192. begin
  193.    EnvAdd := MemW[PrefixSeg:$2C];
  194.    LineFound := False;
  195.    for B := 1 to ord(LineStart[0]) do LineStart[B] := UpCase(LineStart[B]);
  196.    B := 0;
  197.    repeat
  198.       S := '';
  199.       while Mem[EnvAdd:B]<>0 do begin
  200.          S := S + UpCase(char(Mem[EnvAdd:B]));
  201.          B := succ(B)
  202.       end; {while}
  203.       if pos(LineStart,S)=1 then begin
  204.          delete(S,1,ord(LineStart[0]));
  205.          while S[1] in [' ','='] do delete(S,1,1);
  206.          EnvironLine := S;
  207.          LineFound := True
  208.       end; {if PATH}
  209.       B := succ(B)
  210.    until (S[0]=#0) or LineFound;
  211.    if not LineFound then EnvironLine := 'NONE'
  212. end; {EnvironLine}
  213.  
  214. function FindFile(var FName: LineType): boolean;                       {.CP9}
  215. {Takes File name.  Searches for file on default drive & along DOS PATH.  }
  216. {Reports success or failure in FindFile.                                 }
  217. {If file is found, returns openable FName with successful path prefixed. }
  218. var
  219.    Paths,
  220.    Try:       LineType;
  221.    F:         text;   {File type doesn't matter.  File only reset, not read.}
  222.    GotIt:     boolean;
  223.  
  224.    function Path(var P: LineType): LineType;                          {.CP15}
  225.    {Takes DOS PATH line and peels one path specifier from it.  }
  226.    {Returns specifier in Path, bobtailed DOS PATH line in P.   }
  227.    var
  228.       Chunk:     LineType;
  229.    begin
  230.       Chunk := '';
  231.       while (P[1]<>';') and (P[0]<>#0) do begin
  232.          Chunk := Chunk + P[1];
  233.          delete(P,1,1)
  234.       end; {while not ";"}
  235.       while (P[1]=';') and (P[0]<>#0) do delete(P,1,1);
  236.       if Chunk[ord(Chunk[0])]<>'\' then Chunk := Chunk + '\';
  237.       Path := Chunk
  238.    end; {Path}
  239.  
  240.    function Found(var F: text): boolean;                              {.CP14}
  241.    {Takes file variable, tries to open it.  Closes file if opened. }
  242.    {Reports success or failure in Found.                           }
  243.    begin
  244.       {$I-}
  245.       reset(F);
  246.       {$I+}
  247.       if IOresult=0 then begin
  248.          Found := True;
  249.          close(F);
  250.       end {if 0}
  251.       else
  252.          Found := False;
  253.    end; {Found}
  254.  
  255. begin {FindFile}                                                      {.CP23}
  256.    assign(F,FName);
  257.    if Found(F) then
  258.       GotIt := True
  259.    else begin                                          {Strip all path specs}
  260.       while (pos(':',FName)<>0) or (pos('\',FName)<>0) do
  261.          delete(FName,1,1);
  262.       Paths := EnvironLine('PATH');               {Get PATH from Environment}
  263.       if Paths='NONE' then begin
  264.          assign(F,FName);                     {if no PATH, try default drive}
  265.          GotIt := Found(F)
  266.       end {if NONE}
  267.       else begin                                     {else search along PATH}
  268.          repeat
  269.             Try :=  Path(Paths);
  270.             assign(F,Try + FName);
  271.             GotIt := Found(F)
  272.          until (Try='\') or GotIt;
  273.          if GotIt then FName := Try + FName
  274.       end {else found a PATH}
  275.    end; {else not on default drive}
  276.    FindFile := GotIt;
  277. end; {FindFile}
  278.  
  279. procedure ReadFile;                                                   {.CP22}
  280. var
  281.    Fb: file of byte;
  282.    F:  NeoFileType;
  283.    I:  integer;
  284.    B:  byte;
  285.  
  286.    function WhatWeGot: FoundType;
  287.    var
  288.       Len: longint;
  289.    begin
  290.       assign(Fb,FName);
  291.       reset(Fb);
  292.       Len := FileSize(Fb);
  293.       case Len of
  294.          PalaeoFileSize: WhatWeGot := Palaeo;
  295.          EoFileSize:     WhatWeGot := Eo;
  296.          NeoFileSize:    WhatWeGot := Neo;
  297.          else            WhatWeGot := Wrong;
  298.       end; {Case}
  299.       close(Fb);
  300.    end; {WhatWeGot}
  301.  
  302.    function WantOut(var Row:byte): boolean;                           {.CP14}
  303.    const
  304.       Col = 25;
  305.    var
  306.       Ch:  char;
  307.    begin;
  308.       Row := 2;
  309.       TextBackground(Background);
  310.       TextColor(Bright or 128);
  311.       Center('WARNING!',Row);
  312.       inc(Row);
  313.       VideoNorm;
  314.       Center('Printer file found is ' + FName,Row);
  315.       inc(Row,2);
  316.       if Found<>Wrong then begin                                      {.CP12}
  317.          Center('It''s an old file in the format used by versions of PXL',Row);
  318.          inc(Row);
  319.          if Found=Palaeo then
  320.             Center('earlier than 2.00.   If you update that file with this',Row)
  321.          else
  322.             Center('between 2.00 & 2.10. If you update that file with this',Row);
  323.          inc(Row);
  324.          Center('program, it will be converted to the current format, &',Row);
  325.          inc(Row);
  326.          Center('it will not be usable by older PXL''s.                 ',Row);
  327.       end {if not wrong}
  328.       else begin                                                       {.CP7}
  329.          Center('It isn''t a proper PXL printer file, and I have no idea',Row);
  330.          inc(Row);
  331.          Center('what it is. If you continue PXLINST now, the file will',Row);
  332.          inc(Row);
  333.          Center('be over-written.                                      ',Row);
  334.       end; {else wrong}
  335.       inc(Row,2);                                                    {.CP19}
  336.       Center('When looking for PXL.PRN, PXL searches through all the',Row);
  337.       inc(Row);
  338.       Center('directories on the path.  Therefore:                  ',Row);
  339.       inc(Row,2);
  340.       Center('To PRESERVE this file:                                ',Row);
  341.       inc(Row,2);
  342.       Center('            (1) Exit PXLINST now, and                 ',Row);
  343.       inc(Row);
  344.       Center('            (2) RENAME the file or                    ',Row);
  345.       inc(Row);
  346.       Center('                MOVE it to a directory OFF the path.  ',Row);
  347.       inc(Row,2);
  348.       Center('To CONVERT this file: Just continue with this program.',Row);
  349.       inc(Row,2);
  350.       GotoXY(Col,Row); write('To exit now, press <');
  351.       VideoHi; write('Esc'); VideoNorm; write('>');
  352.       inc(Row);
  353.       GotoXY(Col,Row); write('To continue, press any other key. ');
  354.       Ch := ReadKey;                                                  {.CP11}
  355.       if Ch=#27 then begin
  356.          WantOut := True;
  357.          write('<Esc>')
  358.       end {if Esc}
  359.       else begin
  360.          ClrScr;
  361.          WantOut := False
  362.       end; {else not #27}
  363.       inc(Row,2);
  364.    end; {WantOut}
  365.  
  366.    (*
  367.    Paleodata:
  368.       Tpface   = (MrkB, MrkE, SmallB,SmallE,CondB,CondE,FF);
  369.       ByteLine = array[0..3] of byte;
  370.       Bytes    = array [MrkB..FF] of ByteLine;
  371.    Eodata:
  372.       Tpface     = (MrkB, MrkE, SmallB,SmallE,CondB,CondE,PreP,PostP,FF);
  373.       ByteLine   = array[0..7] of byte;
  374.    *)
  375.    procedure ReadInOldFile;                                           {.CP10}
  376.    Type
  377.       OldTpface = (OldMrkB,OldMrkE,OldSmallB,OldSmallE,
  378.                  OldCondB,OldCondE,OldPreP,OldPostP,OldFF);
  379.       OldBLine  = array[0..7] of byte;
  380.    var
  381.       Len,B: byte;
  382.       T: OldTpface;
  383.       OInst: array[OldMrkB..OldFF] of OldBLine;
  384.       EliteIsCond: boolean;
  385.    begin                                                              {.CP20}
  386.       if Found=Eo
  387.          then Len := 7         {Eo files have 7-byte strings}
  388.          else Len := 3;        {Palaeo files have 3-byte strings}
  389.       for T := OldMrkB to OldFF do begin  {carefully empty Inst}
  390.          OInst[T,0] := 0;
  391.          fillchar(OInst[T,1],Len,$FF);
  392.       end; {for T}
  393.       assign(Fb,FName);
  394.       reset(Fb);
  395.       for T := OldMrkB to OldCondE do
  396.          for B := 0 to Len do
  397.             read(Fb,OInst[T,B]);
  398.       if Found=Eo then                   {2 extra instructions in Eo files}
  399.          for T := OldPreP to OldPostP do
  400.             for B := 0 to Len do
  401.                read(Fb,OInst[T,B]);
  402.       read(Fb,OInst[OldFF,0],OInst[OldFF,1]);
  403.       read(Fb,OInst[OldFF,0],OInst[OldFF,1]);  {just the first 2 bytes}
  404.       close(Fb);
  405.       EliteIsCond := True;                                            {.CP21}
  406.       for B := 0 to Len do
  407.          if OInst[OldSmallB,B]<>OInst[OldCondB,B] then EliteIsCond := False;
  408.       if OInst[OldFF,0]=1 then Inst.Bt[FF] := OInst[OldFF,1];
  409.       Move(OInst[OldMrkB],Inst.Tp[MrkB],succ(OInst[OldMrkB,0]));
  410.       Move(OInst[OldMrkE],Inst.Tp[MrkE],succ(OInst[OldMrkE,0]));
  411.       if Found=Eo then begin
  412.          Move(OInst[OldPreP],Inst.Tp[PreP],succ(OInst[OldPreP,0]));
  413.          Move(OInst[OldPostP],Inst.Tp[PostP],succ(OInst[OldPostP,0]));
  414.       end; {if Eo}
  415.       if OInst[OldSmallB,0]<>0 then begin
  416.          Move(OInst[OldSmallB],Inst.Tp[SetSm],succ(OInst[OldSmallB,0]));
  417.          Move(OInst[OldSmallE],Inst.Tp[SetLg],succ(OInst[OldSmallE,0]));
  418.       end {if OldSmall}
  419.       else if OInst[OldCondB,0]<>0 then begin
  420.          Move(OInst[OldCondB],Inst.Tp[SetSm],succ(OInst[OldCondB,0]));
  421.          Move(OInst[OldCondE],Inst.Tp[SetLg],succ(OInst[OldCondE,0]));
  422.          Inst.Bt[SW] := 131;
  423.       end; {else if OldCond}
  424.       if EliteIsCond then Inst.Bt[SW] := 131;
  425.    end; {ReadInOldFile}
  426.  
  427. begin {ReadFile}                                                     {.CP11}
  428.    FName := FileName;
  429.    if FindFile(Fname) then begin
  430.       GotFile := TRUE;
  431.       Found := WhatWeGot;
  432.       if Found=Neo then begin
  433.          assign(F,FName);
  434.          Reset(F);
  435.          read(F,Inst);  {Much neater this way, isn't it?}
  436.          close(F);
  437.       end {else neo style}
  438.       else begin                                                      {.CP20}
  439.          if WantOut(B) then begin
  440.             Center('Okay.  ' + FName + ' left as is.',B);
  441.             PutItBack(OrigAtt);
  442.             Halt;
  443.          end {if WantOut}
  444.          else begin
  445.             Inst.Bt[LW] := 79; {default}
  446.             Inst.Bt[SW] := 95; {assumption}
  447.             if Found in [Eo,Palaeo] then
  448.                ReadInOldFile
  449.          end {else doesn't want out}
  450.       end {if old file}
  451.    end {if found file}
  452.    else begin
  453.       Found := NoFile;
  454.       GotFile := FALSE;
  455.       GotoXY(1,23)
  456.    end; {else}
  457. end; {ReadFile}
  458.  
  459. function MadeFile: boolean;                                           {.CP17}
  460. var
  461.    F: NeoFileType;
  462. begin
  463.    if FName='' then FName := FileName;
  464.    assign(F,FName);
  465.    {$I-}
  466.    rewrite(F);
  467.    {$I+}
  468.    if IOResult=0 then begin
  469.       write(F,Inst);
  470.       close(F);
  471.       MadeFile := True;
  472.    end
  473.    else
  474.       MadeFile := False
  475. end; {MadeFile}
  476.  
  477. Function KbIn: char;                                                  {.CP13}
  478. var
  479.    C:              char;
  480. begin
  481.    C := ReadKey;
  482.    if C<>#0 then
  483.       Extended := False
  484.    else begin         {get extended code}
  485.       Extended := True;
  486.       C := ReadKey;
  487.    end; {else}
  488.    KbIn := C;
  489. end; {KbIn}
  490.  
  491. procedure Initialize;                                                 {.CP22}
  492. var
  493.    T:    TpFace;
  494.     K:    integer;
  495. begin
  496.    OrigAtt := CurrentAttribute;
  497.    CheckBreak := False;
  498.    Changed := False;
  499.    PalaeoFile := False;
  500.    VideoNorm;
  501.    ClrScr;
  502.    for T := MrkB to PostP do begin
  503.       Inst.Tp[T,0] := 0;
  504.       for K := 1 to InstLen do Inst.Tp[T,K] := $FF;
  505.    end; {for T}
  506.    Inst.Bt[FF] := 12;
  507.    Inst.Bt[LW] := 79;
  508.    Inst.Bt[SW] := 95;
  509.    FFFlag := True;
  510.    CRet := #17+#196+#217;
  511.    Found := NoFile;
  512. end; {Initialize}
  513.  
  514. procedure GetNewData;                                                 {.CP15}
  515. const
  516.    LeftCol  = 1;
  517.     BlankCol = 22;
  518.    DataCol  = 22;
  519.    FileCol  = 52;
  520.    InsCol    = 72;
  521.     InsRow    =  1;
  522.    MsgRow   = 19;
  523.    Numerals: set of char = ['0'..'9'];
  524.    Enterables: set of char = ['0'..'9','/',',',';',' '];
  525.    Enter: set of char = [#10,#13];
  526.    InsertStr:    array[False..True] of string[8] = ('Overtype','Insert  ');
  527. var
  528.     InsertOn:    boolean;
  529.  
  530.     procedure ParseLine(var Line: DatStrType; T: TpFace);               {.CP4}
  531.     var
  532.        J,X:    integer;
  533.        NBt: byte;
  534.  
  535.        function NextDigit: integer;                                    {.CP21}
  536.       {if finds no digit, returns -1}
  537.       var
  538.          Temp: DatStrType;
  539.          X,C:    integer;
  540.        begin {NextDigit}
  541.          NextDigit := -1;
  542.          while not (Line[1] in Numerals) and (Line<>'') do
  543.             delete(Line,1,1);
  544.          if Line<>'' then begin
  545.             Temp := '';
  546.             while (Line[1] in Numerals) and (Line<>'') do begin
  547.                Temp := Temp + Line[1];
  548.                delete(Line,1,1);
  549.             end; {while}
  550.             if Temp<>'' then begin
  551.                  val(Temp,X,C);
  552.                NextDigit := X mod 256;                  {force to byte-sized}
  553.             end {if Temp}
  554.          end {if Line}
  555.        end; {NextDigit}
  556.  
  557.     Begin {ParseLine}                                                  {.CP11}
  558.        if T in ByteSet then begin               {Accept only 1 byte for FF &c}
  559.          X := NextDigit;
  560.          if T=FF then begin
  561.             if X>-1
  562.                then Inst.Bt[T] := X
  563.                else Inst.Bt[T] := 66
  564.          end {if FF}
  565.          else if X>-1 then
  566.             Inst.Bt[T] := X
  567.       end {if ByteSet}
  568.        else begin                                                      {.CP12}
  569.          fillchar(Inst.Tp[T,1],InstLen,$FF);
  570.           Inst.Tp[T,0] := 0;
  571.          For J := 1 to InstLen do begin
  572.             X := NextDigit;
  573.             if X>-1 then Begin
  574.                inc(Inst.Tp[T,0]);
  575.                Inst.Tp[T,J] := X; {Force to a byte-size value}
  576.              end {if got a digit}
  577.          end {For J}
  578.       end {else not ByteSet}
  579.     end; {ParseLine}
  580.  
  581.     procedure MakeLabels;                                              {.CP25}
  582.     var
  583.        B:     byte;
  584.     begin
  585.        Headline := 'Instruction:         ';
  586.       BarLine :=  '───────────────────  ';
  587.        HeadLine := HeadLine + 'Present Data:';
  588.       BarLine :=  Barline +  '───────────────────────────   ';
  589.        for B := length(HeadLine) to FileCol-2 do
  590.          HeadLine := HeadLine + #32;
  591.        if not GotFile then
  592.          HeadLine := HeadLine + '─── No File ───'
  593.        else
  594.          HeadLine := HeadLine + 'In ' + FName + ':';
  595.       BarLine :=  Barline +  '───────────────────────────';
  596.        TypeLabel[MrkB]   := 'Underlined: start:'; TypeLine[MrkB]   :=  5;
  597.        TypeLabel[MrkE]   := '            stop:'; TypeLine[MrkE]   :=  6;
  598.        TypeLabel[SetLg]  := 'Start using Pica:'; TypeLine[SetLg]  :=  8;
  599.        TypeLabel[SetSm]  := 'Start using Elite:'; TypeLine[SetSm]  :=  9;
  600.        TypeLabel[PreP]   := 'Before printing: '; TypeLine[PreP]   := 11;
  601.        TypeLabel[PostP]  := 'After printing:  '; TypeLine[PostP]  := 12;
  602.        TypeLabel[FF]     := 'Page Control:    '; TypeLine[FF]     := 14;
  603.        TypeLabel[LW]     := 'Cols/Ln in Pica: '; TypeLine[LW]     := 15;
  604.        TypeLabel[SW]     := 'Cols/Ln in Elite:'; TypeLine[SW]     := 16;
  605.     end; {MakeLabels}
  606.  
  607.    function DataString(T: TpFace): DatStrType;                        {.CP18}
  608.     var
  609.        B:        byte;
  610.         S:    DatStrType;
  611.     begin
  612.       with Inst do begin
  613.          if T in ByteSet then
  614.             S := StrgB(Bt[T],1)
  615.          else begin
  616.             S := '';
  617.             for B := 1 to Tp[T,0] do begin
  618.                S := S + StrgI(Tp[T,B],3);
  619.                if B<Tp[T,0] then S := S + ' ';
  620.             end; {for B}
  621.          end; {else not ByteSet}
  622.       end; {with Inst}
  623.         DataString := S;
  624.     end; {DataString}
  625.  
  626.    procedure WriteString(T: TpFace);                            {.CP19}
  627.    var
  628.       K: integer;
  629.       S: DatStrType;
  630.    begin
  631.       with Inst do begin
  632.          if T in ByteSet then begin
  633.             if (T=FF) then begin
  634.                if Bt[T]=66 then
  635.                   S := '66 lines/page [Default]'
  636.                else if Bt[T]=12 then
  637.                   S := '12 [Form Feed]'
  638.                else
  639.                   S := StrgB(Bt[T],1) + ' lines/page';
  640.             end {if FF}
  641.             else
  642.                S := StrgB(Bt[T],1);
  643.          end {if ByteSet}
  644.          else if Tp[T,0]=0 then                                       {.CP10}
  645.             S := '[Nothing]'
  646.          else if Tp[T,0]>0 then
  647.             S := DataString(T)
  648.          else
  649.             S := '[Nothing]';
  650.       end; {with Inst}
  651.       for K := length(S) to PredDatStrLen do S := S + ' ';
  652.       write(S);
  653.    end; {WriteString}
  654.  
  655.    procedure WriteIns;                                                {.CP12}
  656.    var
  657.         X,Y: byte;
  658.     begin
  659.         X := WhereX; Y := WhereY;
  660.         InsertOn := not InsertOn;
  661.         GotoXY(InsCol,InsRow);
  662.       VideoHi;
  663.         write(InsertStr[InsertOn]);
  664.         VideoInv;
  665.       GotoXY(X,Y);
  666.     end; {WriteIns}
  667.  
  668.     procedure LayOut;                                                  {.CP18}
  669.    var
  670.       B: byte;
  671.  
  672.        procedure WriteHelpLine;
  673.        begin
  674.           write('Use ');
  675.           TextColor(Bright); write(#27);     VideoNorm; write(', ');
  676.           TextColor(Bright); write(#26);     VideoNorm; write(', ');
  677.           TextColor(Bright); write(#24);     VideoNorm; write(', ');
  678.           TextColor(Bright); write(#25);     VideoNorm; write(', ');
  679.           TextColor(Bright); write('Home');  VideoNorm; write(', ');
  680.           TextColor(Bright); write('End');   VideoNorm; write(', ');
  681.           TextColor(Bright); write('PgUp');  VideoNorm; write(', & ');
  682.           TextColor(Bright); write('PgDn');  VideoNorm; write(' to move, ');
  683.           TextColor(Bright); write('Ins');   VideoNorm; write(' & ');
  684.           TextColor(Bright); write('Del');   VideoNorm; write(' to edit.');
  685.        end; {WriteHelpLine}
  686.  
  687.     begin {LayOut}                                                     {.CP14}
  688.        Center('PXLINST (Set printer for PXL 2.11+)',1);
  689.        GotoXY(1,InsRow); write('<');
  690.        TextColor(Bright); write('Esc');
  691.       VideoNorm; write('> to quit');
  692.       GotoXY(InsCol - 9,InsRow);
  693.         write('Ins/Ovr: ');
  694.        GotoXY(1,3); write(HeadLine);
  695.       GotoXY(1,4);
  696.       for B := 1 to 78 do write(#196);
  697.       GotoXY(1,succ(TypeLine[MrkE])); write(BarLine);
  698.       GotoXY(1,succ(TypeLine[SetSm])); write(BarLine);
  699.       GotoXY(1,succ(TypeLine[PostP])); write(BarLine);
  700.       GotoXY(1,succ(TypeLine[SW]));
  701.       for B := 1 to 78 do write(#196);                                {.CP20}
  702.        for T := MrkB to SW do begin
  703.           GotoXY(LeftCol,TypeLine[T]);
  704.           write(TypeLabel[T]);
  705.           GotoXY(DataCol,TypeLine[T]);
  706.          WriteString(T);
  707.          if GotFile then begin
  708.              GotoXY(FileCol,TypeLine[T]);
  709.             if (Found=Neo) or
  710.                ((Found=Eo) and (T<LW)) or
  711.                ((Found=Palaeo) and (T<PreP))
  712.                   then WriteString(T)
  713.                   else write('   ----   ');
  714.           end {if GotFile}
  715.        end; {for T}
  716.         WriteIns;
  717.        GotoXY(8,25);
  718.         VideoNorm;
  719.        WriteHelpLine;
  720.     end; {Layout}
  721.  
  722.     procedure Message;                                                 {.CP17}
  723.    var
  724.       Row1,Row2,Row3,Row4: byte;
  725.    begin
  726.       Row1 := MsgRow; Row2 := succ(Row1);
  727.       Row3 := Row2 + 2; Row4 := succ(Row3);
  728.       if T in ByteSet then begin
  729.          if T=FF then begin
  730.             GotoXY(5,Row1);
  731.             write(' If Character #12 makes your printer feed out ',
  732.                'a fresh page, enter');
  733.             TextColor(Bright); write(' 12 '); VideoNorm;
  734.             GotoXY(5,Row2);
  735.             write('Otherwise, enter the ');
  736.             TextColor(Bright); write('number of lines you get on a page,');
  737.             VideoNorm; write(' (66 is common)');
  738.          end {if T=FF}
  739.          else begin                                                   {.CP22}
  740.             GotoXY(5,Row1);
  741.             write('    Enter the number of ');
  742.             TextColor(Bright);
  743.             write('columns ');
  744.             VideoNorm;
  745.             write('your printer puts on a line in ');
  746.             TextColor(Bright);
  747.             if T=LW
  748.                then write('Pica                ')
  749.                else write('Elite               ');
  750.             VideoNorm;
  751.             BlankLines(Row2,Row4);
  752.          end; {else LW or SW}
  753.           GotoXY(5,Row3);
  754.           write('      Type a number.  Then press <CR> (');
  755.             TextColor(Bright); write(CRet);
  756.             VideoNorm; write(') to enter it as data.   ');
  757.           if not FFFlag then BlankLines(Row4,Row4);
  758.           FFFlag := True;
  759.          BlankLines(Row4,Row4);
  760.       end {if in ByteSet}
  761.       else begin                                                      {.CP23}
  762.           if FFFlag then begin
  763.              GotoXY(5,Row1);
  764.              write('     Enter the ASCII numbers (');
  765.                TextColor(Bright); write('numbers');
  766.              VideoNorm; write(' not characters) of the print     ')
  767.           end; {if FFFlag}
  768.           GotoXY(5,Row2);
  769.           case T of
  770.              MrkB..MrkE,
  771.             PreP:  write('        ');
  772.             PostP: write('         ');
  773.             else   write(' ');
  774.           end; {case}
  775.          if (T=PreP) or (T=PostP) then
  776.             write('control symbols to ')
  777.          else
  778.              write('control symbols your printer needs to ');
  779.          if T=SetSm then
  780.             write('stop pica and ')
  781.          else if T=SetLg then
  782.             write('stop elite and ');
  783.           VideoHi;
  784.           case T of                                                    {.CP10}
  785.              MrkB:  write('start underlining.                  ');
  786.             MrkE:  write('stop underlining.                   ');
  787.              SetSm: write('start ELITE print.                  ');
  788.              SetLg: write('start PICA print.                   ');
  789.             PreP:  write('set up your printer before printing.          ');
  790.             PostP: write('reset your printer after printing.            ');
  791.           end; {case}
  792.           VideoNorm;                                                   {.CP12}
  793.           if FFFlag then begin
  794.              Center('    Enter up to '+ StrgB(InstLen,1)
  795.                     + ' numbers, separated by comma,'
  796.                + ' space, or slash (/).      ',Row3);
  797.              GotoXY(17,Row4);
  798.              write('Then press <CR> ('); TextColor(Bright); write(CRet);
  799.              VideoNorm; write(') to enter them as data.');
  800.              FFFlag := False
  801.           end; {if FFFlag}
  802.       end {else not FF}
  803.     end; {Message}
  804.  
  805.     procedure GoGetEm;                                                  {.CP5}
  806.  
  807.     var
  808.        EndOBlank,
  809.         Pt:             byte;
  810.        Quit:       boolean;
  811.  
  812.        procedure PrintCurrentLine;                                     {.CP13}
  813.       var
  814.          S: DatStrType;
  815.          K: integer;
  816.        begin
  817.             VideoInv;
  818.             GotoXY(DataCol,TypeLine[T]);
  819.          S := Line;
  820.          for K := 1 to DatStrLen do S := S + ' ';
  821.          write(S);
  822.              GotoXY(DataCol + pred(Pt),TypeLine[T]);
  823.             VideoNorm;
  824.        end;
  825.  
  826.          procedure SortExtent(B: char);                                  {.CP20}
  827.        begin
  828.           case B of
  829.             'M':    begin
  830.                             if Pt>=DatStrLen then
  831.                                 Bip
  832.                             else begin
  833.                                  inc(Pt);
  834.                                 PrintCurrentLine;
  835.                             end {else}
  836.                         end; {Right Arrow}
  837.                 'K':    begin
  838.                             if Pt<2 then
  839.                                 Bip
  840.                             else begin
  841.                                 dec(Pt);
  842.                                 PrintCurrentLine;
  843.                             end {else}
  844.                         end; {Left Arrow}
  845.                 'G':    begin                                               {.CP10}
  846.                             Pt := 1;
  847.                             PrintCurrentLine;
  848.                         end; {Home}
  849.                 'O':    begin
  850.                             Pt := length(Line);
  851.                      if Pt<DatStrLen then inc(Pt);
  852.                             PrintCurrentLine;
  853.                         end; {End}
  854.                 'H':     begin                                               {.CP12}
  855.                              GotoXY(DataCol,TypeLine[T]);
  856.                               VideoNorm;
  857.                      WriteString(T);
  858.                            if T=MrkB
  859.                              then T := SW
  860.                           else dec(T);
  861.                             Pt := 1;
  862.                             Line := DataString(T);
  863.                           Message;
  864.                             PrintCurrentLine;
  865.                       end; {Up Arrow}
  866.             'I':  begin                                               {.CP12}
  867.                             GotoXY(DataCol,TypeLine[T]);
  868.                             VideoNorm;
  869.                      WriteString(T);
  870.                             T := MrkB;
  871.                             Pt := 1;
  872.                             Line := DataString(T);
  873.                           Message;
  874.                             PrintCurrentLine;
  875.                         end;  {PgUp}
  876.               'P':  begin                                               {.CP12}
  877.                             GotoXY(DataCol,TypeLine[T]);
  878.                             VideoNorm;
  879.                             WriteString(T);
  880.                             if T=SW
  881.                              then T := MrkB
  882.                            else inc(T);
  883.                             Pt := 1;
  884.                             Line := DataString(T);
  885.                           Message;
  886.                             PrintCurrentLine;
  887.                         end; {Down Arrow}
  888.               'Q':    begin                                               {.CP11}
  889.                             GotoXY(DataCol,TypeLine[T]);
  890.                             VideoNorm;
  891.                             WriteString(T);
  892.                             T := FF;
  893.                             Pt := 1;
  894.                             Line := DataString(T);
  895.                           Message;
  896.                             PrintCurrentLine;
  897.                         end; {PgDn}
  898.             'R':    WriteIns;
  899.                 'S':    begin                                                {.CP8}
  900.                             delete(Line,Pt,1);
  901.                             Line := Line + ' ';
  902.                             PrintCurrentLine;
  903.                         end; {Delete}
  904.               else  Bip;
  905.            end; {case}
  906.         end; {SortExtent}
  907.  
  908.        procedure ReadLine(var Line:DatStrType);                         {.CP16}
  909.       var
  910.          K: integer;
  911.  
  912.             procedure BackSpace;
  913.             var
  914.                 B:    byte;
  915.           begin
  916.              if Pt>1 then begin
  917.                     dec(Pt);
  918.                 delete(Line,Pt,1);
  919.                     Line := Line + #32;
  920.                 PrintCurrentLine
  921.              end {if length}
  922.              else
  923.                 Bip
  924.           end; {BackSpace}
  925.  
  926.           procedure ProcCharacter;                                     {.CP16}
  927.           begin
  928.             while Pt>length(Line) do
  929.                Line := Line + #32;
  930.             if Pt=DatStrLen then
  931.                Line[Pt] := Ch
  932.              else if InsertOn=False then begin
  933.                   Line[Pt] := Ch;
  934.                     inc(Pt);
  935.                 end {if Overtype}
  936.                 else begin
  937.                 insert(Ch,Line,Pt);
  938.                     inc(Pt);
  939.                 end; {else Insert}
  940.                 PrintCurrentLine;
  941.           end; {ProcCharacter}
  942.  
  943.        begin {ReadLine}                                                {.CP21}
  944.             Pt := 1;
  945.           Ch := #0; Extended := False;
  946.           repeat
  947.              Ch := Kbin;
  948.                 if Extended then
  949.                     SortExtent(Ch)
  950.              else if Ch=#27 then
  951.                     Quit := True                                                {Escape}
  952.                 else if not (Ch in Enter) then begin
  953.                 if (Ch=#8) then begin   {Backspace}
  954.                         BackSpace;
  955.                     Extended := False
  956.                  end {if backspace}
  957.                     else if (Pt>DatStrLen) or not (Ch in Enterables) then
  958.                         Bip
  959.                     else
  960.                         ProcCharacter                                                 {Reg Char}
  961.             end {else if not CR}
  962.             until Quit or (Ch in Enter);
  963.        end; {ReadLine}
  964.  
  965.        procedure InitGoGetEm;                                           {.CP9}
  966.         var
  967.             K:    integer;
  968.         begin
  969.           EndOBlank := BlankCol + DatStrLen;
  970.             Quit := False;
  971.           T := MrkB;
  972.             Pt := 1
  973.        end; {InitGoGetEm}
  974.  
  975.     begin {GoGetEm}                                                    {.CP21}
  976.         InitGoGetEm;
  977.        while not Quit do begin
  978.           Message;
  979.          Line := DataString(T);
  980.             PrintCurrentLine;
  981.           ReadLine(Line);  {comes back with QUIT or Line to parse}
  982.          Pt := 1;
  983.           PrintCurrentLine;
  984.          if not Quit then begin
  985.              Changed := True;
  986.              ParseLine(Line,T);
  987.              PrintCurrentLine;
  988.                 GotoXY(DataCol,TypeLine[T]);
  989.                 VideoNorm; WriteString(T);
  990.              if T=SW
  991.                 then T := MrkB
  992.                 else inc(T);
  993.           end {if CR}
  994.        end; {while}
  995.     end; {GoGetEm}
  996.  
  997.    procedure InitGetNewData;
  998.     begin                                                               {.CP4}
  999.         InsertOn := False;
  1000.     end; {InitGetNewData}
  1001.  
  1002. begin {GetNewData}
  1003.     InitGetNewData;                                                     {.CP6}
  1004.    MakeLabels;
  1005.    LayOut;
  1006.    GoGetEm;
  1007. end; {GetNewData}
  1008.  
  1009. procedure SaveIt;                                                     {.CP16}
  1010. begin
  1011.    if MadeFile then begin
  1012.       BlankLines(22,25);
  1013.       if not GotFile then
  1014.          Center('Okay, new ' + FileName
  1015.                 + ' file created & data stored in it',22)
  1016.       else if Found<>Neo then
  1017.          Center('Okay, ' + FileName
  1018.                 + ' converted to new format & updated',22)
  1019.       else
  1020.          Center('Okay, data in ' + FileName + ' updated',22)
  1021.    end {if MadeFile}
  1022.    else
  1023.       Center('Bungled!  Couldn''t write to file.',22);
  1024. end; {SaveIt}
  1025.  
  1026. procedure QuitIt;                                                     {.CP10}
  1027. begin
  1028.    BlankLines(22,25);
  1029.    if GotFile then
  1030.       Center('Okay, new data are ignored.  '
  1031.               + FileName + ' is unchanged.',22)
  1032.    else
  1033.       Center('Okay, new data are ignored.  No PXLX.PRN created.',22)
  1034. end; {QuitIt}
  1035.  
  1036. procedure AskSave;                                                    {.CP21}
  1037. const
  1038.    Answers: set of char = ['Y','N'];
  1039.    Yesses: set of char = ['Y','y'];
  1040. var
  1041.    Ch:        char;
  1042. begin {AskSave}
  1043.    BlankLines(TypeLine[SW] + 2,25);
  1044.    if PalaeoFile then begin
  1045.       VideoHi;
  1046.       Center('Remember, this was an old style file.  If you update ',20);
  1047.       Center('it now, the file will be converted to the new format.',21);
  1048.       VideoNorm;
  1049.       Center('Do you want to update it? ',24);
  1050.    end {if PalaeoFile}
  1051.    else if GotFile then
  1052.       Center('Do you want ' + FileName
  1053.              + ' updated with this new data?  ',20)
  1054.    else
  1055.       Center('Do you want this data saved in ' + FileName + '?  ',20);
  1056.    repeat
  1057.       Ch := UpCase(ReadKey);                                          {.CP17}
  1058.       if not (Ch in Answers) then begin
  1059.          BlankLines(25,25);
  1060.          Bip;
  1061.          gotoXY(28,25);
  1062.          write('You must answer ');
  1063.          TextColor(Bright); write('Y');
  1064.          VideoNorm; write(' or ');
  1065.          TextColor(Bright); write('N');
  1066.          VideoNorm; write(':')
  1067.       end {if not answer}
  1068.       else
  1069.          write(Ch)
  1070.    until Ch in Answers;
  1071.    if Ch in Yesses then SaveIt else QuitIt
  1072. end; {AskSave}
  1073.  
  1074. procedure PartFriends;                                                 {.CP6}
  1075. begin
  1076.    BlankLines(TypeLine[FF] + 2,25);
  1077.    Center('Nothing changed; nothing saved.',21);
  1078.    Center('Nothing venture, nothing win.',22)
  1079. end; {PartFriends}
  1080.  
  1081. begin {install main}                                                   {.CP9}
  1082.    Initialize;
  1083.    ReadFile;
  1084.    GetNewData;
  1085.    if Changed
  1086.       then AskSave
  1087.       else PartFriends;
  1088.    PutItBack(OrigAtt);
  1089. end.
  1090.