home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / pxl214a / pxlinit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-02-14  |  45.6 KB  |  1,242 lines

  1. {$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+}
  2. {$M 16384,0,655360}
  3. {$R-}    {Range checking off}                                          {.CP5}
  4. {$B-}    {Boolean complete evaluation off}
  5. {$S+}    {Stack checking on}
  6. {$I+}    {I/O checking on}
  7. {$N-}    {No numeric coprocessor}
  8.  
  9. Unit PXLINIT;
  10.  
  11. Interface
  12.  
  13. Uses
  14.   Crt,
  15.   Dos;
  16.  
  17. const                                                                 {.CP17}
  18.    TitleStr = ' PXL 2.14a Pascal X-Ref Lister';
  19.    CreditStr = 'R. N. Wisan  fecit  7/85-10/90';
  20.    PrnFileName = 'PXL.PRN';
  21.    StdLineWidth   = 150;
  22.    ScreenSize     = 2000;
  23.    Triggers: set of char = [#27,#3];
  24.    MaxResWords = 100;             {Enlarge if required}
  25.    NoIncFiles = 8;
  26.    InstLen    = 7;                {Maximum length of any printer instruction}
  27.    BoxT =  5;
  28.    BoxB = 21;
  29.    BoxL = 10;
  30.    BoxR = 70;
  31.    EoFileSize      = 72; {Bt}
  32.    PalaeoFileSize  = 28; {Bt}
  33.    NeoFileSize     = 51; {Bt}
  34.  
  35.  
  36. type                                                                  {.CP27}
  37.    ColType      =  record                    {These 3 make a scrn size array}
  38.                       case boolean of        {Addressed like BASIC'S screen }
  39.                          True:  (C,A: byte); {[Row,Col].C = char            }
  40.                          False: (I: word)    {[Row,Col].A = attribute       }
  41.                    end;                      {[Row,Col].I = both, but with  }
  42.    RowType      =  array[1..80] of ColType;  {   attribute in hi byte       }
  43.    ScrType      =  array[1..25] of RowType;  {   character in lo byte       }
  44.    ScrPtrType   =  ^ScrType;
  45.    MonitorType  =  (MDA,CGA,EGA);
  46. (*   LineType     =  string[StdLineWidth]; *)
  47.    CharSet      =  set of char;
  48.    CMD      = string[128]; {For command line}
  49.    Str40    = string[40];
  50.    Str20    = string[20];
  51.    ResWType = string[20]; {Must be large enough for longest reserved word}
  52.    ResWPtrType = ^ResType;
  53.    ResType     = Record
  54.                     R: ResWType;
  55.                     Next: ResWPtrType;
  56.                  end;
  57.    Str10    = string[10];
  58.    Str9     = string[9];
  59.    Str5     = string[5];
  60.    Str4     = string[4];
  61.    Str3     = string[3];
  62.    str2     = string[2];
  63.  
  64.    (*                                                                {.CP18}
  65.    Paleodata:
  66.       Tpface   = (MrkB, MrkE, SmallB,SmallE,CondB,CondE,FF);
  67.       ByteLine = array[0..3] of byte;
  68.       Bytes    = array [MrkB..FF] of ByteLine;
  69.    Eodata:
  70.       Tpface     = (MrkB, MrkE, SmallB,SmallE,CondB,CondE,PreP,PostP,FF);
  71.       ByteLine   = array[0..7] of byte;
  72.    *)
  73.    Tpface          = (MrkB, MrkE, SetLg,SetSm,PreP,PostP,FF,LW,SW);
  74.    ByteLine        = array[0..InstLen] of byte;
  75.    InsType         = string[InstLen];
  76.    PrnDataType     = record
  77.                        Tp:  array[MrkB..PostP] of ByteLine;
  78.                        Bt:  array[FF..SW] of byte;
  79.                      end; {PrnDataType}    {58 Bt}
  80.    NeoFileType     = File of PrnDataType;
  81.    FoundType       = (Palaeo,Eo,Neo,Wrong,NoFile);
  82.  
  83. const
  84.    ByteSet: set of TpFace = [FF..SW];
  85.  
  86. var                                                                   {.CP23}
  87.    CRTube:    ScrPtrType;  {Set to point at real screen buffer}
  88.    CRTAddr:   array[1..2] of word absolute CRTube;
  89.    Monitor:   MonitorType;
  90.    OrigAtt:   byte;
  91.    BlnkLn:    string;
  92.    Scr:                ScrType;
  93.    C:                  char;
  94.    MaxResLen,
  95.    Inside,
  96.    BottomMargin,
  97.    MaxLin,
  98.    NormalColor,
  99.    FrameColor,
  100.    Background,
  101.    Bright,Dim:         byte;
  102.    F,Lst:              text;
  103.    IFil:               array[1..NoIncFiles] of text;
  104.    IFileName:          array[1..NoIncFiles] of string;
  105.    IFN:                1..NoIncFiles;
  106.    QuitStrg,
  107.    PathSign,
  108.    FileName:           string;
  109.    Opening,Closing:    InsType;                                       {.CP26}
  110.    PrintDate,
  111.    FileDate:           Str20;
  112.    PrintTime,
  113.    FileTime:           Str10;
  114.    UserID:             string[25];
  115.    Number:             string[16];
  116.    Line:               string;
  117.    Day,I,LineNumber,
  118.      PageLineNumber,
  119.      Page,Year,NRes:  integer;
  120.    ScrSeg:             word;
  121.    GotPrnData,Plain,
  122.      MarkWCaps,
  123.      MarkWCR,
  124.      Vanilla,Turbo3,
  125.      PrePSent,
  126.      Mrk,XRef,
  127.      XRefOnly,Enough,
  128.      NumberLines,
  129.      InABatch,FFeed,
  130.      DataFiles:        boolean;
  131.    Inst:               PrnDataType;
  132.    T:                  TpFace;
  133.    Istring:            array[MrkB..PostP] of InsType absolute Inst;
  134.    Rsv:                array['A'..'Z'] of ResWPtrType;
  135.    OutputDevice:       Str40;
  136.    Command:            CMD;
  137.  
  138. procedure Bip;
  139. procedure Beep;
  140. procedure Bop;
  141. procedure ToScrn(var S: ScrType);
  142. procedure FromScrn(var S: ScrType);
  143. procedure FillWd(Segm,Offst,Num,Wd: word);
  144. procedure FillOdd(Segm,Offst,Num: integer; Bt: byte);
  145. procedure SkipMove(var From,Target; Num: word);
  146. procedure GetScreen;
  147. procedure WipeSlate(var S: ScrType; Clr: byte);
  148. procedure Rectangle(var S: ScrType; R1,C1,R2,C2,Att,Vert,Hor: byte);
  149. procedure WriteIt(var Scr: ScrType; Str: string; R,C,Color: byte);
  150. procedure WriteCRT(Str: string; Row,Col,Att: byte);
  151. procedure CenterCRT(S: string; Row,Attrib,Width: byte);
  152. procedure Center(var Scr: ScrType; Str: string; Line,Color,Width: byte);
  153. function CurrentAttribute: byte;
  154. procedure CursorOff; {invisible but present}
  155. procedure CursorOn;
  156. procedure RestoreScreen;
  157. procedure SetErrorLevel(Level: byte);
  158. procedure SetScrAtt(Att: byte);
  159.  
  160. function Intensified(A: byte): byte;
  161. function Dimmed(A: byte): byte;
  162. function BlackBackground(A: byte): boolean;
  163. function BlackForeground(A: byte): boolean;
  164. function BackgroundOf(A: byte): byte;
  165. function ForegroundOf(A: byte): byte;
  166. function CombinedAttributeOf(F,B: byte): byte;
  167.  
  168. function PadOrChop(L: string; Len: byte):string;
  169. procedure Replace(This,WithThat: string; var TheLine: string);
  170.  
  171. function StrgI(B,L: Integer): Str9;
  172. function Strip(L: string; NoNo: CharSet): string;
  173. (* function InCapitals(L: string): string; *)
  174. function InCapitals(S: string): string; { Assembler;}
  175.  
  176. function KbIn(var Extended: boolean): char;
  177. function EditTrm(N: byte): string;
  178.  
  179. function CurrentDriveAndDirectory: string;
  180.    {Returns full current drive:\directory}
  181.  
  182. function EnvironLine(LineStart: string): string;                      {.CP3}
  183.    {Searches DOS environment for line beginning with LineStart}
  184.    {If found, returned in EnvironLine.  If not returns "NONE"}
  185. function FindFile(var FName: string): boolean;                       {.CP4}
  186.    {Takes File name.  Searches for file on default drive & along DOS PATH. }
  187.    {Reports success or failure in FindFile.                                }
  188.    {If file is found, returns openable FName with successful path prefixed.}
  189. procedure CloseCarefully(var F: text);                                 {.CP4}
  190. {Closes text file whether open or not.  Closing open file in TP3 was harm-}
  191. {less, but TP4 birks at closing files which aren't open.  Unfortunately,  }
  192. {you need one of these for each file type.  This is for text files.       }
  193.  
  194. function Escape: boolean;                                              {.CP3}
  195. {  Empties the keyboard buffer & returns False if no trigger}
  196. {  Does not wait for a keypress}
  197.  
  198. procedure Blank(Top,Bot: integer);
  199. procedure ByeBye;
  200. procedure GetOutOfHere;
  201. procedure PXLRectangle;
  202. procedure CantCont(FilNam,Comment: string);
  203. procedure GetPrinterData;                                              {.CP3}
  204.   { If constant DataFiles is True, this procedure loads printer control }
  205.   { symbols from PrnFileName.  If it's false, they're set here.         }
  206. function DefaultDrive: char; {Returns letter of Default Drive}
  207. procedure FixUpFileName(Var FilNam: string);
  208. function Shortened(FileName: string): Str20;
  209.  
  210. {===========================================================================}
  211.  
  212. Implementation
  213.  
  214. procedure Bip;                                                         {.CP5}
  215. begin
  216.    sound(1760); delay(10); sound(440); delay(30);
  217.    sound(1760); delay(15); nosound
  218. end;
  219.  
  220. procedure Beep;                                                        {.CP4}
  221. {Starts the sound that BOP finishes}
  222. begin
  223.    sound(456);
  224. end; {Beep}
  225.  
  226. procedure Bop;                                                         {.CP4}
  227. begin
  228.    delay(100); nosound; delay(150); sound(362); delay(400); nosound;
  229. end; {Bop}
  230.  
  231. procedure ToScrn(var S: ScrType);                                     {.CP14}
  232. const
  233.    ScrnPort        = $3D8;           {for CGA board}
  234.    On              =  45;            {for ScrnPort}
  235.    Off             =   5;
  236. begin
  237.    if Monitor=CGA then begin
  238.       Port[ScrnPort] := Off;
  239.       CRTube^ := S;
  240.       Port[ScrnPort] := On
  241.    end {if CGA}
  242.    else
  243.       CRTube^ := S
  244. end; {ToScrn}
  245.  
  246. procedure FromScrn(var S: ScrType);                                   {.CP14}
  247. const
  248.    ScrnPort        = $3D8;           {for CGA board}
  249.    On              =  45;            {for ScrnPort}
  250.    Off             =   5;
  251. begin
  252.    if Monitor=CGA then begin
  253.       Port[ScrnPort] := Off;
  254.       S := CRTube^;
  255.       Port[ScrnPort] := On
  256.    end {if CGA}
  257.    else
  258.       S := CRTube^
  259. end; {FromScrn}
  260.  
  261. procedure FillWd(Segm,Offst,Num,Wd: word);                            {.CP18}
  262. { Like FillChar but fills with 2-byte integers.  Here declared:      }
  263. {      procedure FillWd(Segm,Offst,Num,Wd: integer)                  }
  264. { Can also be declared:                                              }
  265. {      procedure FillWd(var S; Num,Wd: integer)                      }
  266. begin
  267.    inline
  268.                   {FILLWD PROC NEAR                                  }
  269.                   {       INLINE                                     }
  270.    ($C4/$7E/$0A/  { <     les  di, 08H[bp] ; load di and ds at once  }
  271.                   {                                                  }
  272.    $8B/$4E/$08/   { <     MOV  CX,6[BP]    ; Num                     }
  273.    $8B/$46/$06/   { <     MOV  AX,4[BP]    ; Wd                      }
  274.                   {                                                  }
  275.    $FC/           {       cld              ;8088 ==> autoincrement   }
  276.    $F3/           {       rep              ;store CX copies of AX in }
  277.    $AB)           {       stosw            ; ES:[DI] (not DS:[DI])   }
  278. end; {FillWd}
  279.  
  280. procedure FillOdd(Segm,Offst,Num: integer; Bt: byte);                 {.CP21}
  281.    {Turbo Pascal INLINE procedure like FillChar but skips even bytes in }
  282.    {target.  Use it To write without coloring or color without writing. }
  283.    {Here declared:                                                      }
  284.    {   procedure FillOdd(Segm,Offst,Num: integer; Bt: byte);            }
  285.    {Can also be declared:                                               }
  286.    {   procedure FillWd(var V; Num, integer; Bt: byte);                 }
  287. begin                  {       INLINE                                   }
  288.    inline(             {FILLWD PROC NEAR                                }
  289.    $1E/                {       PUSH DS          ; Save DS               }
  290.    $8E/$5E/$0C/        {       MOV  DS,0AH[BP]  ; Segm                  }
  291.    $8B/$7E/$0A/        {       MOV  DI,8H[BP]   ; Offst                 }
  292.    $8B/$4E/$08/        {       MOV  CX,6H[BP]   ; Num                   }
  293.    $29/$C0/            {       SUB  AX,AX                               }
  294.    $8A/$46/$06/        {       MOV  AL,4H[BP]   ; Bt                    }
  295.    $88/$05/            {START  MOV  [DI],AL     ; Put Bt in target      }
  296.    $47/                {       INC  DI          ; Shift target          }
  297.    $47/                {       INC  DI          ;  twice                }
  298.    $E2/$FA/            {       LOOP START       ; Loop CX (Num) times   }
  299.    $1F)                {       POP  DS          ; Restore DS            }
  300. end; {FillOdd}         {       ENDP                                     }
  301.  
  302. procedure SkipMove(var From,Target; Num: word);                       {.CP27}
  303.   {Moves Num bytes from source to Target, skipping bytes in Target.     }
  304.   {Could write to screen w/o coloring. (Beware: can't handle overlap).  }
  305.   {Here declared:                                                       }
  306.   {   procedure SkipMove(var From,Target; Num: integer);                }
  307.   {Can also be declared:                                                }
  308.   {   procedure SkipMove(SegS,OffS,SegT,OffT,Num: integer);             }
  309. begin                   {                                               }
  310.    inline(              {       inline                                  }
  311.                         {FILLWD PROC NEAR                               }
  312.    $1E/                 {       push ds                                 }
  313.    $8E/$46/$0E/         {       mov  es,0ch[bp]  ;SegS                  }
  314.    $8B/$76/$0C/         {       mov  si,0ah[bp]  ;OffS                  }
  315.                         {                                               }
  316.    $8E/$5E/$0A/         {       MOV  DS,08H[BP]  ; SegT                 }
  317.    $8B/$7E/$08/         {       MOV  DI,06H[BP]  ; OffT                 }
  318.    $28/$ED/             {       sub  ch,ch                              }
  319.    $8A/$4E/$06/         {       MOV  CL,04h[BP]    ; Num in CX          }
  320.                         {                                               }
  321.    $26/$8A/$04/         {START  mov  al,es:[si]  ; Get byte from source }
  322.    $88/$05/             {       MOV  [DI],al     ; Put byte in target   }
  323.    $47/                 {       INC  DI          ; Shift target         }
  324.    $47/                 {       INC  DI          ;  twice               }
  325.    $46/                 {       inc  si          ; Shift source once    }
  326.    $E2/$F6/             {       LOOP START       ; Loop CX (Num) times  }
  327.    $1F)                 {       POP  DS          ; Restore DS           }
  328. end; {SkipMove}         {       ENDP                                    }
  329.  
  330. procedure GetScreen;                                                  {.CP13}
  331.  
  332.    function MonitorIsEGA: boolean;
  333.    var
  334.       R: Registers;
  335.    begin
  336.      with R do begin
  337.         AH := $12;
  338.         BX := $FF10;
  339.         intr($10,R);
  340.         MonitorIsEga := BH<>$FF
  341.      end {with}
  342.   end; {MonitorIsEGA}
  343.  
  344. begin                                                                 {.CP12}
  345.    if (Lo(LastMode)=7) then begin
  346.       CRTube := Ptr($B000,0000);
  347.       Monitor := MDA;
  348.    end {if mode 7}
  349.    else begin
  350.       CRTube := Ptr($B800,0000);
  351.       if MonitorIsEGA
  352.          then Monitor := EGA
  353.          else Monitor := CGA
  354.    end {else not 7}
  355. end; {GetScrn}
  356.  
  357. procedure WipeSlate;                                                   {.CP8}
  358. {Set attributes all to same color)}
  359. var
  360.    Filler:    integer;
  361. begin
  362.    Filler := (Clr shl 8) + $20;
  363.    FillWd(seg(S),ofs(S),2000,Filler);
  364. end; {WipeSlate}
  365.  
  366. procedure Rectangle(var S: ScrType; R1,C1,R2,C2,Att,Vert,Hor: byte);  {.CP11}
  367. {R1,C1 is row & col of upper left corner, R2,C2 is lower right       }
  368. {Vert is single or double vert char, Hor is single or 2ble horizontal}
  369. const
  370.    OK: set of byte = [1..2];
  371. type
  372.    Rchars = (Hr,Vr,UL,UR,LL,LR);
  373. var
  374.    Element: array[Hr..LR] of byte;
  375.    Row:     byte;
  376.    Filler:  integer;
  377. begin                                                                 {.CP20}
  378.    if not (Hor in OK) then Hor := 1;
  379.    if not (Vert in OK) then Vert := 1;
  380.    if Vert=1 then begin
  381.       Element[Vr] := 179;
  382.       if Hor=1 then begin
  383.          Element[Hr] := 196;       {V1 H1}
  384.          Element[UL] := 218;
  385.          Element[UR] := 191;
  386.          Element[LL] := 192;
  387.          Element[LR] := 217;
  388.       end {if Hor=1}
  389.       else if Hor=2 then begin    {V1 H2}
  390.          Element[Hr] := 205;
  391.          Element[UL] := 213;
  392.          Element[UR] := 184;
  393.          Element[LL] := 212;
  394.          Element[LR] := 190;
  395.        end {if Hor=2}
  396.    end {if V1}
  397.    else begin                                                         {.CP17}
  398.       Element[Vr] := 186;
  399.       if Hor=1 then begin
  400.          Element[Hr] := 196;       {V2 H1}
  401.          Element[UL] := 214;
  402.          Element[UR] := 183;
  403.          Element[LL] := 211;
  404.          Element[LR] := 189;
  405.       end {if Hor=1}
  406.       else if Hor=2 then begin    {V2 H2}
  407.          Element[Hr] := 205;
  408.          Element[UL] := 201;
  409.          Element[UR] := 187;
  410.          Element[LL] := 200;
  411.          Element[LR] := 188;
  412.        end {if Hor=2}
  413.    end; {else Ver=2}
  414.    Filler := Att shl 8 + Element[Hr];                                 {.CP4}
  415.    FillWd(seg(S[R1,C1].I),ofs(S[R1,C1].I),succ(C2-C1),Filler);
  416.    FillWd(seg(S[R2,C1].I),ofs(S[R2,C1].I),succ(C2-C1),Filler);
  417.    Filler := Att shl 8 + Element[Vr];
  418.    for Row := succ(R1) to pred(R2) do begin                           {.CP4}
  419.       S[Row,C1].I  := Filler;
  420.       S[Row,C2].I  := Filler
  421.    end; {for Row}
  422.    S[R1,C1].I  := Att shl 8 + Element[UL];                            {.CP5}
  423.    S[R2,C1].I  := Att shl 8 + Element[LL];
  424.    S[R1,C2].I  := Att shl 8 + Element[UR];
  425.    S[R2,C2].I  := Att shl 8 + Element[LR];
  426. end; {Rectangle}
  427.  
  428. procedure WriteIt(var Scr: ScrType; Str: string; R,C,Color: byte);   {.CP6}
  429. {R is row; C is column in which to start.}
  430. begin
  431.    FillWd(Seg(Scr[R,C]),Ofs(Scr[R,C]),length(Str),succ(Color shl 8));
  432.    SkipMove(Str[1],Scr[R,C],length(Str));
  433. end; {WriteIt}
  434.  
  435. procedure WriteCRT(Str: string; Row,Col,Att: byte);                  {.CP5}
  436.  { Writes characters quickly to the screen starting at Row, Col, }
  437.  { using attribute Att.  Detects presence of Text or CGA board.  }
  438.  { If it finds a CGA, chars are snuck in during vertical retrace }
  439.  { to avoid snow. }
  440. begin
  441.    inline(      {         INLINE ; CHASM's famous Turbo feature  }    {.CP29}
  442.                 {WRITECRT PROC FAR                               }
  443.    $1E/         {         PUSH DS                                }
  444.    $1E/         {         PUSH DS                                }
  445.    $8A/$46/$0A/ {         MOV  AL,08H[BP]     ; Row.             }
  446.    $FE/$C8/     {         DEC  AL             ; Make top Row 1   }
  447.    $B3/$50/     {         MOV  BL,80                             }
  448.    $F6/$E3/     {         MUL  BL                                }
  449.    $29/$DB/     {         SUB  BX,BX                             }
  450.    $8A/$5E/$08/ {         MOV  BL,06H[BP]     ; Col              }
  451.    $FE/$CB/     {         DEC  BL             ; Make 1st Col 1   }
  452.    $01/$D8/     {         ADD  AX,BX                             }
  453.    $01/$C0/     {         ADD  AX,AX                             }
  454.    $8B/$F8/     {         MOV  DI,AX                             }
  455.    $8A/$7E/$06/ {         MOV  BH,04H[BP] ; Attrib into BH       }
  456.    $8E/$46/$0E/ {         MOV  ES,0CH[BP] ; Str SEG -> ES        }
  457.    $8B/$76/$0C/ {         MOV  SI,0AH[BP] ; Str OFS -> SI        }
  458.    $29/$C9/     {         SUB  CX,CX ; Addr of Str now in ES:SI  }
  459.    $26/$8A/$0C/ {         MOV  CL,ES:[SI] ; Length of Str in CX  }
  460.    $29/$C0/     {         SUB  AX,AX   ; See if graphix or mono  }
  461.    $8E/$D8/     {         MOV  DS,AX                             }
  462.    $3E/$A0/$49/$04/ {     MOV  AL,DS:[449H]                      }
  463.    $1F/         {         POP  DS                                }
  464.    $20/$C9/     {         AND  CL,CL ; If length(Str)=0 then done}
  465.    $74/$26/     {         JZ   DONE                              }
  466.    $BA/$00/$B0/ {         MOV  DX,0B000H      ; For MONO         }
  467.    $8E/$DA/     {         MOV  DS,DX                             }
  468.    $2C/$07/     {         SUB  AL,7                              }
  469.    $74/$12/     {         JZ   GETCHAR                           }
  470.    $BA/$00/$B8/ {GRAPHICS MOV  DX,0B800H ; Load display mem      }     {.CP9}
  471.    $8E/$DA/     {         MOV  DS,DX   ;    into DS              }
  472.    $BA/$DA/$03/ {         MOV  DX,3DAH ; Status port CGA board   }
  473.    $EC/         {TESTLOW  IN   AL,DX   ; Await vert retr (Test 8)}
  474.    $A8/$08/     {         TEST AL,8    ; (This code found in     }
  475.    $75/$FB/     {         JNZ  TESTLOW ; Tech Ref Man BIOS listg)}
  476.    $EC/         {TESTHI   IN   AL,DX                             }
  477.    $A8/$08/     {         TEST AL,8                              }
  478.    $74/$FB/     {         JZ   TESTHI                            }
  479.  
  480.    $46/         {GETCHAR  INC  SI     ; Point at next char in Str}     {.CP8}
  481.    $26/$8A/$1C/ {         MOV  BL,ES:[SI] ; Get char into BL     }
  482.    $3E/$89/$1D/ {         MOV  DS:[DI],BX ; Write wd into target }
  483.    $47/         {         INC  DI         ; Shift aim            }
  484.    $47/         {         INC  DI         ;   by 2 bytes         }
  485.    $E2/$F5/     {         LOOP GETCHAR ; CX times (len of string)}
  486.    $1F)         {DONE     POP  DS                                }
  487. end; {WriteCRT} {         ENDP                                   }
  488.  
  489. procedure CenterCRT(S: string; Row,Attrib,Width: byte);              {.CP8}
  490. begin
  491.    if Width >0 then begin
  492.       BlnkLn[0] := char(Width);
  493.       WriteCRT(BlnkLn,Row,41-(length(BlnkLn) div 2),Attrib);
  494.    end; {if Width}
  495.    WriteCRT(S,Row,41-(length(S) div 2),Attrib)
  496. end;
  497.  
  498. procedure Center(var Scr: ScrType;                                    {.CP15}
  499.                      Str: string;
  500.                      Line,Color,Width: byte);
  501. var
  502.    StartCol:   byte;
  503.    Filler:     integer;
  504. begin
  505.    if Width>0 then begin
  506.       Filler := (Color shl 8) + $20;
  507.       StartCol := 41 - (Width div 2);
  508.       FillWd(seg(Scr),ofs(Scr[Line,StartCol]),Width,Filler);
  509.    end; {if Width}
  510.    StartCol := 41 - (length(Str) div 2);
  511.    WriteIt(Scr,Str,Line,StartCol,Color)
  512. end; {Center}
  513.  
  514. function CurrentAttribute;                                            {.CP12}
  515. var
  516.    R:    DOS.Registers;
  517. begin
  518.    GotoXY(1,pred(WhereY));
  519.    with R do begin
  520.       AH := $08;
  521.       BH := 0;
  522.       Intr($10,R);
  523.       CurrentAttribute := AH
  524.    end {with R}
  525. end; {CurrentAttribute}
  526.  
  527. procedure CursorOff;                                                   {.CP9}
  528. var
  529.    R:    Registers;
  530. begin
  531.    R.AH := 1;
  532.    R.CH := $20;
  533.    R.CL := 0;
  534.    intr($10,R)
  535. end; {CursorOff}
  536.  
  537. procedure CursorOn;                                                   {.CP21}
  538. var
  539.    R:    Registers;
  540. begin
  541.    with R do begin {Make standard 2-line cursor}
  542.       AH := 1;      {Make Cursor }
  543.       if Monitor=CGA then begin
  544.          CH := 6;   {top line 6}
  545.          CL := 7;   {bot line 7}
  546.       end {if CGA}
  547.       else if Monitor=EGA then begin
  548.          CH := 7;   {top line 7}
  549.          CL := 10;  {bot line 10}
  550.       end {else if EGA}
  551.       else begin
  552.          CH := 12;  {top 12}
  553.          CL := 13;  {bot 13}
  554.       end; {else MDA}
  555.    end; {with R}
  556.    Intr($10,R);    {BIOS Video service}
  557. end; {CursorOn}
  558.  
  559. procedure RestoreScreen;                                              {.CP19}
  560. { Put screen back politely (if A is the atribute found by CurrentAttribute  }
  561. { on entry).  Scrolls up one line to set color, but does not overwrite any- }
  562. { other part of the screen.  Makes standard 2-line DOS cursor, placed at    }
  563. { bottom of the screen.                                                     }
  564. var
  565.    Filler:    integer;
  566.    R:         Registers;
  567. begin
  568.    CursorOn;
  569.    GotoXY(1,24);
  570.    with R do begin {Scroll up one line at bottom of screen coloring   }
  571.       AX := $0601;    {BIOS Video Svc 6 in AH, 1 line to scroll in AL }
  572.       CX := $1700;    {Top row 23 in CH, Lft col 0 in CL }
  573.       DX := $184F;    {Bot row 24 in CH, Rt col 79 in CL }
  574.       BH := OrigAtt;        {Attribute in BH }
  575.    end; {with R}
  576.    Intr($10,R);    {BIOS Video service}
  577. end; {RestoreScreen}
  578.  
  579. procedure SetErrorLevel(Level: byte);                                 {.CP21}
  580. {Uses DOS function $4C to terminate, setting error level for DOS batch   }
  581. {file to read.  Checks for DOS 2 or higher --$4C would crash DOS 1.10-.  }
  582. {Since $4C also terminates program, handle like halt statement.  Be care-}
  583. {ful.  If run from Turbo, it will terminate Turbo.                       }
  584. var
  585.    Regs:      Registers;
  586. begin
  587.    RestoreScreen;
  588.    with Regs do begin
  589.       AH := $30;                                            {Get DOS version}
  590.       MsDos(Regs);                              {0 in AL if DOS 1.00 or 1.10}
  591.       if AL>0 then begin                {if DOS 2 or higher, set error level}
  592.          AL := Level;                                {--DOS 1 crashes on $4C}
  593.          AH := $4C;                           {Terminate setting error level}
  594.          MsDos(Regs)
  595.       end {if AL>0}
  596.       else
  597.          halt
  598.    end; {with Regs}
  599. end; {SetErrorLevel}
  600.  
  601. procedure SetScrAtt;                                                   {.CP5}
  602. {Set Turbo's internal variable}
  603. begin
  604.    TextAttr := Att;
  605. end; {SetScrAtt}
  606.  
  607. function Intensified;                                                  {.CP4}
  608. begin
  609.    Intensified := A or 8;
  610. end; {Intensified}
  611.  
  612. function Dimmed;                                                       {.CP4}
  613. begin
  614.    Dimmed := A and 247
  615. end; {Dimmed}
  616.  
  617. function BlackBackground;                                              {.CP4}
  618. begin
  619.    BlackBackground := (A and 112)=0
  620. end; {BlackBackground}
  621.  
  622. function BlackForeground;                                              {.CP4}
  623. begin
  624.    BlackForeground := (A and 7)=0
  625. end; {BlackForeground}
  626.  
  627. function BackgroundOf;                                                 {.CP4}
  628. begin
  629.    BackgroundOf := (A and 112) shr 4
  630. end; {BackgroundOf}
  631.  
  632. function ForegroundOf;                                                 {.CP5}
  633. {including intensity}
  634. begin
  635.    ForegroundOf := A and 15
  636. end; {ForegroundOf}
  637.  
  638. function CombinedAttributeOf;                                          {.CP5}
  639. {Intensity follows F(oreground); ignores blinking.}
  640. begin
  641.    CombinedAttributeOf := ((B and 7) shl 4) or (F and 15)
  642. end; {CombinedAttributeOf}
  643.  
  644. function PadOrChop(L: string; Len: byte):string;                   {.CP6}
  645. begin
  646.    while length(L)<Len do L := L + #32;
  647.    if length(L)>Len then L[0] := char(Len);
  648.    PadOrChop := L;
  649. end; {PadOrChop}
  650.  
  651. procedure Replace; {(This,WithThat: string; var TheLine: string); {.CP11}
  652. var
  653.    P,K: integer;
  654. begin
  655.    P := pos(This,TheLine);
  656.    while P>0 do begin
  657.       for K := 1 to length(This) do delete(TheLine,P,1);
  658.       insert(WithThat,TheLine,P);
  659.       P := pos(This,TheLine);
  660.    end; {while P>0}
  661. end; {Replace}
  662.  
  663. function StrgI(B,L: Integer): Str9;                                    {.CP7}
  664.    var
  665.    S: string;
  666. begin
  667.    str(B:L,S);
  668.    StrgI := S
  669. end; {StrgB}
  670.  
  671. function Strip(L: string; NoNo: CharSet): string;                  {.CP7}
  672. {remove leading & trailing junk (list comes in  NoNo)}
  673. begin {Strip}
  674.    while (length(L)>0) and (L[1] in NoNo) do delete(L,1,1);
  675.    while L[length(L)] in NoNo do dec(L[0]);
  676.    Strip := L
  677. end; {Strip}
  678. (*
  679. function InCapitals(L: string): string;                            {.CP7}
  680. var   {old form}
  681.    K:              byte;
  682. begin {InCapitals}
  683.    for K := 1 to length(L) do L[K] := UpCase(L[K]);
  684.    InCapitals := L
  685. end; {InCapitals}
  686. *)
  687. function InCapitals(S: string): string; Assembler;                {.CP25}
  688. {PC Techniques HAX 144 v3n6 definitely faster than old form }
  689. {oddly, adding Hax 147 doesn't make it faster}
  690. ASM
  691.    push ds           {Preserve data segment}
  692.    lds  si,S         {Load DS:SI w S's address}
  693.    les  di,@result   {Load ES:DI w function result's address}
  694.    cld               {SI will be incremented}
  695.    lodsb             {Get S[0]; put it in AL}
  696.    stosb             {Store AL in ES:01}
  697.    cmp al,2          {Check for zero length  --This is what HAX 144 missed}
  698.    jl  @out          {actually, minimum parameter is 2 char (1 for the blank}
  699.    xor ch,ch         {Zero CH}
  700.    mov cl,al         {Length of S into counter CL}
  701. @more:
  702.    lodsb             {next char -> AL}
  703.    cmp al,'a'        {is it 'a'?}
  704.    jb  @no           {if below, skip out}
  705.    cmp al,'z'        {is it 'z'?}
  706.    ja  @no           {if above, skip out}
  707.    sub al,20h        {subtract 32 = lower case}
  708. @no:
  709.    stosb             {store AL in ES:DI}
  710. @loopy:
  711.    loop @more        {Go back for next until CX=0}
  712. @out:
  713.    pop  ds           {Restore data segment}
  714. end; {InCapitals}
  715.  
  716.  
  717. function KbIn;                                                        {.CP15}
  718. var
  719.    C:              char;
  720.    N:              integer;
  721.    R:              DOS.Registers;
  722. begin
  723.    C := ReadKey;
  724.    if C<>#0 then
  725.       Extended := False
  726.    else begin
  727.       Extended := True;
  728.       C := ReadKey
  729.    end; {else}
  730.    KbIn := C;
  731. end; {KbIn}
  732.  
  733. function EditTrm;                                                      {.CP8}
  734. const
  735.    Outs: set of char = [#3,#13,#27];
  736. var
  737.    C:         char;
  738.    S:         string;
  739.    Ext:       boolean;
  740.    X,Y:       byte;
  741.  
  742.    procedure DeleteOne;                                                {.CP9}
  743.    begin
  744.       if length(S)>0 then begin
  745.          delete(S,length(S),1);
  746.          write(#8,#32,#8)
  747.       end {if length>0}
  748.       else
  749.          Bip
  750.    end; {DeleteOne}
  751.  
  752. begin {EditTrm}                                                       {.CP21}
  753.    S := '';
  754.    CursorOn;
  755.    repeat
  756.       X := WhereX; Y := WhereY;
  757.       C := Kbin(Ext);
  758.       GotoXY(X,Y);
  759.       if Ext then
  760.          if C='K'                                                {back-arrow}
  761.             then DeleteOne
  762.             else bip                            {beep for improper keystroke}
  763.       else if C=#8 then
  764.          DeleteOne
  765.       else if (C=#27) or (C=#3) then
  766.          S := #27
  767.       else if C<>#13 then begin
  768.          S := S + C;
  769.          write(C)
  770.       end; {if}
  771.    until (length(S)>=N) or (C in Outs);
  772.    EditTrm := S;
  773.    CursorOff
  774. end; {EditTrm}
  775.  
  776. function CurrentDriveAndDirectory;                                      {.CP8}
  777. {Returns full current drive:\directory}
  778. {Needs types: string, DOS.Registers}
  779. var
  780.    Data: array[1..64] of char;
  781.    Regs: DOS.Registers;
  782.    Bt:  byte;
  783.    S:    string;
  784.  
  785.    function CurrentDrive: byte;                                         {.CP9}
  786.    {Returns 0 for A:, 1 for B:, etc.}
  787.    var
  788.       Regs: DOS.Registers;
  789.    begin
  790.       Regs.AH := $19;
  791.       MsDos(Regs);
  792.       CurrentDrive := Regs.AL
  793.    end; {CurrentDrive}
  794.  
  795. begin                                                                  {.CP17}
  796.    Bt := CurrentDrive;
  797.    with Regs do begin
  798.       AH := $47;
  799.       DL := succ(Bt);
  800.       DS := Seg(Data);
  801.       SI := Ofs(Data);
  802.       MsDos(Regs);
  803.    end; {with Regs}
  804.    S := char(Bt+65) + ':\';
  805.    Bt := 1;
  806.    while Data[Bt]<>#0 do begin
  807.       S := S + UpCase(Data[Bt]);
  808.       Bt := succ(Bt)
  809.    end; {while}
  810.    CurrentDriveAndDirectory := S
  811. end; {CurrentDriveAndDirectory}
  812.  
  813. function EnvironLine;                                                  {.CP30}
  814. { Searches DOS Environment for line beginning with LineStart        }
  815. { Returns line with LineStart removed it in EnvironLine if found.   }
  816. { Returns "NONE" if not found. }
  817. var
  818.    S:               string;
  819.    EnvAdd:          word;
  820.    B:               word;
  821.    LineFound:       boolean;
  822. begin
  823.    EnvAdd := MemW[PrefixSeg:$2C];
  824.    B := 0;
  825.    LineFound := False;
  826.    LineStart := InCapitals(LineStart);
  827.    repeat
  828.       S := '';
  829.       while Mem[EnvAdd:B]<>0 do begin
  830.          S := S + UpCase(char(Mem[EnvAdd:B]));
  831.          B := succ(B);
  832.          if S='PATH' then
  833.             B := B;
  834.       end; {while}
  835.       if pos(LineStart,S)=1 then begin
  836.          delete(S,1,length(LineStart));
  837.          while S[1] in [' ','='] do delete(S,1,1);
  838.          EnvironLine := S;
  839.          LineFound := True
  840.       end; {if PATH}
  841.       B := succ(B)
  842.    until (length(S)=0) or LineFound;
  843.    if not LineFound then EnvironLine := 'NONE'
  844. end; {EnvironLine}
  845.  
  846. function FindFile;                                                      {.CP9}
  847. {Takes File name.  Searches for file on default drive & along DOS PATH.  }
  848. {Reports success or failure in FindFile.                                 }
  849. {If file is found, returns openable FName with successful path prefixed. }
  850. var
  851.    Paths,
  852.    Try:       string;
  853.    F:         text;   {File type doesn't matter.  File only reset, not read.}
  854.    GotIt:     boolean;
  855.  
  856.    function Path(var P: string): string;                          {.CP15}
  857.    {Takes DOS PATH line and peels one path specifier from it.  }
  858.    {Returns specifier in Path, bobtailed DOS PATH line in P.   }
  859.    var
  860.       Chunk:     string;
  861.    begin
  862.       Chunk := '';
  863.       while (P[1]<>';') and (length(P)<>0) do begin
  864.          Chunk := Chunk + P[1];
  865.          delete(P,1,1)
  866.       end; {while not ";"}
  867.       while (P[1]=';') and (length(P)<>0) do delete(P,1,1);
  868.       if Chunk[length(Chunk)]<>'\' then Chunk := Chunk + '\';
  869.       Path := Chunk
  870.    end; {Path}
  871.  
  872.    function Found(var F: text): boolean;                              {.CP14}
  873.    {Takes file variable, tries to open it.  Closes file if opened. }
  874.    {Reports success or failure in Found.                           }
  875.    begin
  876.       {$I-}
  877.       reset(F);
  878.       {$I+}
  879.       if IOresult=0 then begin
  880.          Found := True;
  881.          close(F);
  882.       end {if 0}
  883.       else
  884.          Found := False;
  885.    end; {Found}
  886.  
  887. begin {FindFile}                                                      {.CP23}
  888.    assign(F,FName);
  889.    if Found(F) then
  890.       GotIt := True
  891.    else begin                                          {Strip all path specs}
  892.       while (pos(':',FName)<>0) or (pos('\',FName)<>0) do
  893.          delete(FName,1,1);
  894.       Paths := EnvironLine('PATH');               {Get PATH from Environment}
  895.       if Paths='NONE' then begin
  896.          assign(F,FName);                     {if no PATH, try default drive}
  897.          GotIt := Found(F)
  898.       end {if NONE}
  899.       else begin                                     {else search along PATH}
  900.          repeat
  901.             Try :=  Path(Paths);
  902.             assign(F,Try + FName);
  903.             GotIt := Found(F)
  904.          until (Try='\') or GotIt;
  905.          if GotIt then FName := Try + FName
  906.       end {else found a PATH}
  907.    end; {else not on default drive}
  908.    FindFile := GotIt;
  909. end; {FindFile}
  910.  
  911. function Escape: boolean;                                             {.CP15}
  912. {  Empties the keyboard buffer & returns False if no trigger}
  913. {  Does not wait for a keypress}
  914. var
  915.    C:              char;
  916.    Temp:           boolean;
  917. begin {Escape}
  918.    Temp := False;
  919.    while KeyPressed and not Temp do begin
  920.       C := ReadKey;
  921.       if C in Triggers then Temp := True
  922.    end; {while}
  923.    Escape := Temp;
  924. end; {Escape}
  925.  
  926. procedure CloseCarefully;                                               {.CP9}
  927. {Closes text file whether open or not.  Closing open file in TP3 was harm-}
  928. {less, but TP4 birks at closing files which aren't open.  Unfortunately,  }
  929. {you need one of these for each file type.  This is for text files.       }
  930. var
  931.    Err: word;
  932. begin
  933.    {$I-}
  934.    close(F);
  935.    {$I+}
  936.    Err := IOresult;  {draws the teeth of IOresult}
  937. end; {CloseCarefully}
  938.  
  939. procedure Blank(Top,Bot: integer);                                     {.CP6}
  940. var
  941.    Row:              integer;
  942. begin
  943.    for Row := Top to Bot do CenterCRT('',Row,Bright,Inside)
  944. end; {Blank}
  945.  
  946. procedure ByeBye;                                                     {.CP19}
  947. begin
  948.    if PrePSent then write(Lst,QuitStrg);
  949.    CloseCarefully(Lst);
  950.    Blank(8,9);
  951.    Blank(18,19);
  952.    if Enough
  953.       then CenterCRT('That''s it, then.',18,Bright,0)
  954.       else CenterCRT('Done.  ' + FileName + ' sent to ' + OutputDevice
  955.                      + '.',10,Bright,Inside);
  956.    CenterCRT('Signing Off.',19,Bright,0);
  957.    if InABatch and Enough then begin
  958.       CenterCRT('Can''t find ' + FileName,11,Bright,0);
  959.       SetErrorLevel(1)      {BEWARE: RUN FROM TP 3, THIS QUITS TO DOS}
  960.    end {if InABatch}
  961.    else begin
  962.       RestoreScreen;
  963.       halt
  964.    end
  965. end; {ByeBye}
  966.  
  967. procedure GetOutOfHere;                                                {.CP5}
  968. begin
  969.    Enough := True;
  970.    ByeBye
  971. end; {GetOutOfHere}
  972.  
  973. procedure PXLRectangle;                                               {.CP11}
  974. var
  975.    I: integer;
  976. begin
  977.    WipeSlate(Scr,Bright);
  978.    Rectangle(Scr,BoxT,BoxL,BoxB,BoxR,Dim,2,2);
  979.    Center(Scr,TitleStr,pred(BoxT),Dim,Inside);
  980.    WriteIt(Scr,CreditStr,succ(BoxB),41,Dim);
  981.    Center(Scr,'To stop, press <Esc>',BoxB -2,Bright,Inside);
  982.    ToScrn(Scr);
  983. end; {Rectangle}
  984.  
  985. procedure CantCont(FilNam,Comment: string);                         {.CP19}
  986. var
  987.    B:              byte;
  988. begin
  989.    Beep;
  990.    if PrePSent then write(Lst,QuitStrg);
  991.    CloseCarefully(Lst);
  992.    Blank(10,18);
  993.    CenterCRT('Can''t continue',10,Bright,0);
  994.    if FilNam<>'' then CenterCRT('Error reading ' + FilNam,12,Bright,0);
  995.    CenterCRT(Comment,13,Bright,0);
  996.    Bop;
  997.    if InABatch then
  998.       SetErrorLevel(1)
  999.    else begin
  1000.       RestoreScreen;
  1001.       Halt
  1002.    end
  1003. end; {CantCont}
  1004.  
  1005. procedure GetPrinterData;                                             {.CP10}
  1006. {If constant DataFiles is True, this procedure loads printer control }
  1007. {symbols from PrnFileName.  If it's false, they're set here.         }
  1008. type
  1009.    OldByteLine   = array[0..4] of byte;
  1010.    OldFileType   = File of OldByteLine;
  1011. var
  1012.    Fb:      file of byte;
  1013.    FName:   string;
  1014.    T:       TpFace;
  1015.  
  1016.    procedure ReadPrnFile;                                              {.CP7}
  1017.    var
  1018.       Fb: file of byte;
  1019.       F:  NeoFileType;
  1020.       I:  integer;
  1021.       B:  byte;
  1022.       Found: FoundType;
  1023.  
  1024.       function WhatWeGot: FoundType;                                  {.CP15}
  1025.       var
  1026.          Len: longint;
  1027.       begin
  1028.          assign(Fb,FName);
  1029.          reset(Fb);
  1030.          Len := FileSize(Fb);
  1031.          case Len of
  1032.             PalaeoFileSize: WhatWeGot := Palaeo;
  1033.             EoFileSize:     WhatWeGot := Eo;
  1034.             NeoFileSize:    WhatWeGot := Neo;
  1035.             else            WhatWeGot := Wrong;
  1036.          end; {Case}
  1037.          close(Fb);
  1038.       end; {WhatWeGot}
  1039.  
  1040.       procedure ReadInOldFile;                                        {.CP20}
  1041.       Type
  1042.          OldTpface = (OldMrkB,OldMrkE,OldSmallB,OldSmallE,
  1043.                       OldCondB,OldCondE,OldPreP,OldPostP,OldFF);
  1044.          OldBLine  = array[0..7] of byte;
  1045.       var
  1046.          Len,B: byte;
  1047.          T: OldTpface;
  1048.          OInst: array[OldMrkB..OldFF] of OldBLine;
  1049.          EliteIsCond: boolean;
  1050.       begin
  1051.          if Found=Eo
  1052.             then Len := 7         {Eo files have 7-byte strings}
  1053.             else Len := 3;        {Palaeo files have 3-byte strings}
  1054.          for T := OldMrkB to OldFF do begin  {carefully empty Inst}
  1055.             OInst[T,0] := 0;
  1056.             fillchar(OInst[T,1],Len,$FF);
  1057.          end; {for T}
  1058.          assign(Fb,FName);
  1059.          reset(Fb);
  1060.          for T := OldMrkB to OldCondE do                              {.CP10}
  1061.             for B := 0 to Len do
  1062.                read(Fb,OInst[T,B]);
  1063.          if Found=Eo then                {Eo files have 2 extra instructions}
  1064.             for T := OldPreP to OldPostP do
  1065.                for B := 0 to Len do
  1066.                   read(Fb,OInst[T,B]);
  1067. (*         read(Fb,OInst[OldFF,0],OInst[OldFF,1]); *)
  1068.          read(Fb,OInst[OldFF,0],OInst[OldFF,1]); {get just the first 2 bytes}
  1069.          close(Fb);
  1070.          EliteIsCond := True;                                         {.CP22}
  1071.          for B := 0 to Len do
  1072.             if OInst[OldSmallB,B]<>OInst[OldCondB,B] then
  1073.                EliteIsCond := False;
  1074.          if OInst[OldFF,0]=1 then Inst.Bt[FF] := OInst[OldFF,1];
  1075.          Move(OInst[OldMrkB],Inst.Tp[MrkB],succ(OInst[OldMrkB,0]));
  1076.          Move(OInst[OldMrkE],Inst.Tp[MrkE],succ(OInst[OldMrkE,0]));
  1077.          if Found=Eo then begin
  1078.             Move(OInst[OldPreP], Inst.Tp[PreP], succ(OInst[OldPreP,0]));
  1079.             Move(OInst[OldPostP],Inst.Tp[PostP],succ(OInst[OldPostP,0]));
  1080.          end; {if Eo}
  1081.          if OInst[OldSmallB,0]<>0 then begin
  1082.             Move(OInst[OldSmallB],Inst.Tp[SetSm],succ(OInst[OldSmallB,0]));
  1083.             Move(OInst[OldSmallE],Inst.Tp[SetLg],succ(OInst[OldSmallE,0]));
  1084.          end {if OldSmall}
  1085.          else if OInst[OldCondB,0]<>0 then begin
  1086.             Move(OInst[OldCondB],Inst.Tp[SetSm],succ(OInst[OldCondB,0]));
  1087.             Move(OInst[OldCondE],Inst.Tp[SetLg],succ(OInst[OldCondE,0]));
  1088.             Inst.Bt[SW] := 131;
  1089.          end; {else if OldCond}
  1090.          if EliteIsCond then Inst.Bt[SW] := 131;
  1091.       end; {ReadInOldFile}
  1092.  
  1093.    begin  {ReadPrnFile}                                               {.CP25}
  1094.       FName := PrnFileName;
  1095.       if FindFile(Fname) then begin
  1096.          GotPrnData := TRUE;
  1097.          Found := WhatWeGot;
  1098.          if Found=Neo then begin
  1099.             assign(F,FName);
  1100.             Reset(F);
  1101.             read(F,Inst);
  1102.             close(F);
  1103.          end {else neo style}
  1104.          else begin
  1105.             Inst.Bt[LW] := 79; {default}
  1106.             Inst.Bt[SW] := 95; {assumption}
  1107.             if Found in [Eo,Palaeo]
  1108.                then ReadInOldFile
  1109.                else GotPrnData := False; {Found=Wrong --file is ng}
  1110.          end {if old file}
  1111.       end {if found file}
  1112.       else begin
  1113.          Found := NoFile;
  1114.          GotPrnData := FALSE;
  1115.          GotoXY(1,23)
  1116.       end; {else}
  1117.    end; {ReadPrnFile}
  1118.  
  1119.    procedure IntPrn; {Set here for Epson FX-80}                        {.CP4}
  1120.    begin
  1121.       {Note: MrkB & MrkE are set for underline.  If you prefer some other}
  1122.       {way of marking the key words, change them here. If you put nothing}
  1123.       {for both of them (set Tp[MrkB,0] := 0 and Tp[MrkE,0] := 0) the key}
  1124.       {words will be marked by printing them in CAPITALS.                }
  1125.       with Inst do begin
  1126.          Tp[MrkB,0] := 3;                                              {.CP4}
  1127.             Tp[MrkB,1] := 27;    Tp[MrkB,2] := 45;    Tp[MrkB,3] := 1;
  1128.             Tp[MrkB,4] := $FF;   Tp[MrkB,5] := $FF;   Tp[MrkB,6] := $FF;
  1129.             Tp[MrkB,7] := $FF;
  1130.          Tp[MrkE,0] := 3;                                              {.CP4}
  1131.             Tp[MrkE,1] := 27;    Tp[MrkE,2] := 45;    Tp[MrkE,3] := 0;
  1132.             Tp[MrkE,4] := $FF;   Tp[MrkE,5] := $FF;   Tp[MrkB,6] := $FF;
  1133.             Tp[MrkE,7] := $FF;
  1134.          Tp[SetSm,0] := 2; {Elite}                                     {.CP4}
  1135.             Tp[SetSm,1] := 27;  Tp[SetSm,2] := 77;  Tp[SetSm,3] := $FF;
  1136.             Tp[SetSm,4] := $FF; Tp[SetSm,5] := $FF; Tp[SetSm,6] := $FF;
  1137.             Tp[SetSm,7] := $FF;
  1138.          Tp[SetLg,0] := 2; {Pica}                                      {.CP4}
  1139.             Tp[SetLg,1] := 27;  Tp[SetLg,2] := 80;  Tp[SetLg,3] := $FF;
  1140.             Tp[SetLg,4] := $FF; Tp[SetLg,5] := $FF; Tp[SetLg,6] := $FF;
  1141.             Tp[SetLg,7] := $FF;
  1142.          Tp[PreP,0] := 0;                                              {.CP4}
  1143.             Tp[PreP,1] := $FF;   Tp[PreP,2] := $FF;   Tp[PreP,3] := $FF;
  1144.             Tp[PreP,4] := $FF;   Tp[PreP,5] := $FF;   Tp[PreP,6] := $FF;
  1145.             Tp[PreP,7] := $FF;
  1146.          Tp[PostP,0] := 0;                                            {.CP10}
  1147.             Tp[PostP,1] := $FF;  Tp[PostP,2] := $FF;  Tp[PostP,3] := $FF;
  1148.             Tp[PostP,4] := $FF;  Tp[PostP,5] := $FF;  Tp[PostP,6] := $FF;
  1149.             Tp[PostP,7] := $FF;
  1150.          Bt[FF] := 12;   {form-feed}
  1151.          Bt[LW] := 79;   {pica length}
  1152.          Bt[SW] := 95;   {elite length}
  1153.       end; {with Inst}
  1154.       GotPrnData := True;
  1155.    end; {IntPrn}
  1156.  
  1157. begin {GetPrinterData}                                                {.CP16}
  1158.    if DataFiles then
  1159.       ReadPrnFile
  1160.    else
  1161.       IntPrn;
  1162.    if not GotPrnData then
  1163.       with Inst do begin
  1164.          Bt[FF] := 66;            {Default to Vanilla printer @ 66 lines/page}
  1165.          Bt[LW] := 79;            {pica width}
  1166.          Bt[SW] := 79;            {elite width -can't assume a small font}
  1167.          for T := MrkB to PostP do Inst.Tp[T,0] := 0  {Blank other instrucs}
  1168.       end; {with Inst}  
  1169.    MarkWCR := (Inst.Tp[MrkB,0]=0) and (Inst.Tp[MrkE,0]=0);
  1170.    if Inst.Bt[FF]=12                       {Set Lines/Page}
  1171.       then MaxLin := 66 - BottomMargin            {if using Form-Feed}
  1172.       else MaxLin := Inst.Bt[FF] - (BottomMargin) {else paging w so many LFs}
  1173. end; {GetPrinterData}
  1174.  
  1175. function DefaultDrive: char; {Returns letter of Default Drive}        {.CP10}
  1176. var
  1177.    Regs:      Registers;
  1178. begin
  1179.    with Regs do begin
  1180.       AH := $19;
  1181.       MsDos(Regs);
  1182.       DefaultDrive := char(65 + AL)
  1183.    end {with Regs}
  1184. end; {DefaultDrive}
  1185.  
  1186. procedure FixUpFileName(Var FilNam: string);                        {.CP31}
  1187. const
  1188.    PathSigns: set of char = [':','\'];
  1189. var
  1190.    B,Len:       byte;
  1191. begin
  1192.    while (FilNam[1]=#32) and (length(FilNam)>0) do     {Strip leading blanks}
  1193.       delete(FilNam,1,1);
  1194.    while FilNam[length(FilNam)]=#32 do                {Strip trailing blanks}
  1195.       dec(FilNam[0]);
  1196.    for B := 1 to Length(FilNam) do                               {Capitalize}
  1197.       FilNam[B] := UpCase(FilNam[B]);
  1198.    B := length(FilNam);                           {count length of bare name}
  1199.    while (B>0) and not (FilNam[B] in PathSigns) do
  1200.       dec(B);
  1201.    Len := length(FilNam) - B;
  1202.    if pos(':',FilNam)=0 then          {if no drive letter, add Default Drive}
  1203.       FilNam := DefaultDrive + ':' + FilNam;
  1204.    if pos('.',FilNam)<>0 then begin                  {if has a period       }
  1205.       while (length(FilNam)>0) and (FilNam[length(FilNam)]='.') do begin
  1206.          dec(FilNam[0]);                               {delete terminal dots}
  1207.          Len := pred(Len)                              {adjust length count }
  1208.       end {while terminal dot}
  1209.    end {if has "."}
  1210.    else if Len>10 then begin                    {else if long, insert period}
  1211.       B := length(FilNam) - Len + 8;
  1212.       FilNam := concat(copy(FilNam,1,B),'.',copy(FilNam,succ(B),3))
  1213.    end {else no "." & over long}
  1214.    else
  1215.       FilNam := concat(FilNam,'.PAS')            {otherwise, default to .PAS}
  1216. end; {FixUpFileName}
  1217.  
  1218. function Shortened(FileName: string): Str20;                         {.CP6}
  1219. begin
  1220.    while (pos(':',FileName)<>0) or (pos('\',FileName)<>0) do
  1221.       delete(FileName,1,1);
  1222.    Shortened := FileName;
  1223. end; {Shortened}
  1224.  
  1225. procedure MakeBlnkLn; {private to PXLINIT}                             {.CP9}
  1226. var
  1227.    K: integer;
  1228. begin
  1229.    BlnkLn := '';
  1230.    for K := 1 to StdLineWidth do
  1231.       BlnkLn := BlnkLn + #32;
  1232.    Inside := pred(BoxR) - succ(BoxL);
  1233. end; {MakeBlnkLn}
  1234.  
  1235. begin {initialize PXLINIT}                                             {.CP5}
  1236.    OrigAtt := CurrentAttribute;
  1237.    GetScreen;
  1238.    MakeBlnkLn;
  1239.    PrePSent := False;
  1240.    QuitStrg := '';
  1241. end.
  1242.