home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / catalog / dir405.arc / DIR405.PAS < prev   
Pascal/Delphi Source File  |  1986-12-04  |  56KB  |  1,839 lines

  1. {
  2.                   ╒═════════════════════════════════════════╕
  3.                   │  DIR405.PAS         -         9/14/86   │
  4.                   ╞═════════════════════════════════════════╡
  5.                   │  Written by Wes Meier (76703,747) and   │
  6.                   │  dedicated to the Public Domain.  The   │
  7.                   │  directory read code was written by     │
  8.                   │  Neil J. Rubenking. Fastwrite code by   │
  9.                   │  Marshall Brain.                        │
  10.                   │                                         │
  11.                   │  Modified by Eugene White     12/4/86   │
  12.                   ╘═════════════════════════════════════════╛
  13.  
  14.  Version history:
  15.  ----------------
  16.  
  17.    4.00 - 2/25/86. Original Turbo Pascal version. Previous versions in Basic.
  18.    4.01 - 3/15/86. Corrects unwanted "features" in 4.00.
  19.    4.02 - 3/28/86. Adds multiple disk label printout. Cosmetic code changes.
  20.    4.03 - 4/20/86. Adds code to restore the cursor shape to what it was
  21.                    on entry. Thanks to Chris 'Seedy' Dunford.
  22.    4.04 - 9/14/86. Adds Marshall Brain's Fastwrite code.
  23.    4.05 - 12/4/86. Allows ability to change default drive; display total
  24.                    number of files; save default drive in configuration file.
  25.                    Modifications by E. White.
  26. }
  27.  
  28. {$V- }
  29.  
  30. Type
  31.  
  32.   Regtype     = Record
  33.                   Ax,Bx,Cx,Dx,Bp,Si,Di,Ds,Es,Flags : integer
  34.                 End;
  35.   HalfRegtype = Record
  36.                   Al,Ah,Bl,Bh,Cl,Ch,Dl,Dh : byte
  37.                 End;
  38.   filename_type = string[64];
  39.   files_type = String[16];
  40.   Str255 = String[255];
  41.   Str80 = String[80];
  42.   Time = Record
  43.            Hours,Min,Sec,Hundreths : Byte
  44.          End;
  45.   DOW = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);
  46.   Date = Record
  47.            Month,Day : Byte;
  48.            Year : Integer;
  49.            DayOfWeek : DOW
  50.          End;
  51.  
  52. Const
  53.  
  54. {regs is defined as a typed constant in order to get it in the code segment}
  55.  
  56.   Regs : regtype = (Ax:0;Bx:0;Cx:0;Dx:0;Bp:0;Si:0;Di:0;Ds:0;Es:0;Flags:0);
  57.   Max_Entries = 3500;
  58.   DayName : Array [DOW] Of String[9] = ('Sunday','Monday','Tuesday',
  59.                                         'Wednesday','Thursday','Friday',
  60.                                         'Saturday');
  61.   CurStart = 0;
  62.   CurEnd = 12;
  63.   On = True;
  64.   Off = False;
  65.  
  66. Var
  67.  
  68.   SaveRegs   : regtype;
  69.   HalfRegs   : halfregtype absolute regs;
  70.   x,
  71.   y,
  72.   entries,
  73.   fore,back,
  74.   bord,
  75.   fore_hi,
  76.   attrib,
  77.   Start_Line,
  78.   End_Line   : integer;
  79.   filepath   : filename_type;
  80.   files      : Array [0..Max_Entries] of Files_Type;
  81.   ok,
  82.   Reading,
  83.   Sort_Flag,
  84.   List_Dta,
  85.   List_Act   : boolean;
  86.   defaultdrive,
  87.   ch,choice  : char;
  88.   cpi16      : string[20];
  89.   sx,
  90.   sy,
  91.   diskstr,
  92.   disk       : Str255;
  93.   ft                          : text;
  94.   a                           : byte;
  95.  
  96. Procedure Fastwrite(col,row,attrib:byte;str:str80);
  97.   Begin
  98.     Inline
  99.       ($1E/$1E/$8A/$86/row/$B3/$50/$F6/$E3/$2B/$DB/$8A/$9E/col/
  100.        $03/$C3/$03/$C0/$8B/$F8/$be/$00/$00/$8A/$BE/attrib/
  101.        $8a/$8e/str/$22/$c9/$74/$3e/$2b/$c0/$8E/$D8/$A0/$49/$04/
  102.        $1F/$2C/$07/$74/$22/$BA/$00/$B8/$8E/$DA/$BA/$DA/$03/$46/
  103.        $8a/$9A/str/$EC/$A8/$01/$75/$FB/$FA/$EC/$A8/$01/$74/$FB/
  104.        $89/$1D/$47/$47/$E2/$Ea/$2A/$C0/$74/$10/$BA/$00/$B0/
  105.        $8E/$DA/$46/$8a/$9A/str/$89/$1D/$47/$47/$E2/$F5/$1F);
  106.   End;
  107.  
  108. Procedure Set_Cursor(x, y : integer);
  109.   var
  110.     result : regtype;
  111.  
  112.   Begin
  113.     with result do
  114.       Begin
  115.         ax := $100;
  116.         cx := x shl 8 + y;
  117.         intr($10,result)
  118.       End
  119.   End; { Proc Set_Cursor }
  120.  
  121.  Procedure Cursor(On : boolean);
  122.    Begin
  123.      if On
  124.        then
  125.          Set_Cursor(CurStart,CurEnd)
  126.        else
  127.          Set_Cursor($20,$20)
  128.    End; { Proc Cursor }
  129.  
  130. Procedure Get_Cursor; { Stores the user's original cursor }
  131.  
  132.   type
  133.     regs = Record
  134.              ax,bx,cx,dx,bp,si,di,ds,es,flags : integer
  135.            End;
  136.  
  137.    var
  138.      result : regs;
  139.      cursor : integer;
  140.      mono   : boolean;
  141.  
  142.    Begin
  143.      with result do
  144.        Begin
  145.          ax := $300;
  146.          Intr($10,result);
  147.          cursor := cx;
  148.          ax := $0f00; { return current vid state in AL }
  149.          Intr($10,result);
  150.          mono := (lo(ax) = 7);
  151.          if (mono and ((cursor = $0067) or (cursor = $0607)))
  152.            then
  153.              cursor := $0b0c;
  154.          Start_line := hi(cursor);
  155.          End_line := lo(cursor)
  156.        End { with }
  157.    End; { Proc Cursor }
  158.  
  159. Procedure Pad_Left(var x       : Str255;
  160.                        padchar : char;
  161.                        num     : byte);
  162.  
  163.   var k : byte;
  164.  
  165.   Begin
  166.     for k := 1 to num do x := padchar + x;
  167.     x := copy(x,length(x) + 1 - num,num)
  168.   End; { Proc Pad_Left }
  169.  
  170. Procedure Pad_Right(var x       : Str255;
  171.                         padchar : char;
  172.                         num     : byte);
  173.   Begin
  174.     while length(x) < num do x := x + padchar;
  175.     x := copy(x,1,num)
  176.   End; { Proc Pad_Right }
  177.  
  178. Procedure Locate12;
  179.   Begin
  180.     ClrScr;
  181.     GotoXY(1,12)
  182.   End; { Proc Locate12 }
  183.  
  184. Procedure Check_Pos;
  185.     Begin
  186.       if WhereX > 70 then WriteLn;
  187.       if WhereY > 23
  188.         then
  189.           Begin
  190.             GotoXY(15,25);
  191.             Write('Press any key to continue (* or Q to quit) ...');
  192.             Repeat Until KeyPressed;
  193.             Read(Kbd,choice);
  194.             choice := UpCase(choice);
  195.             if choice = 'Q' then choice := '*';
  196.             ClrScr;
  197.             GotoXY(1,1)
  198.           End { if }
  199.     End; { Proc Check_Pos }
  200.  
  201. Procedure AtEnd;
  202.   var c : char;
  203.  
  204.   Begin
  205.     GotoXY(20,25);
  206.     Write('End of Directory. Press any key to continue ...');
  207.     Repeat Until Keypressed
  208.   End; { Proc AtEnd }
  209.  
  210. Procedure Get_File;
  211.  
  212.   type
  213.     Dir_Entry   = Record
  214.                     Reserved : array[1..21] of byte;
  215.                     Attribute: byte;
  216.                     Time, Date, FileSizeLo, FileSizeHi : integer;
  217.                     Name : string[13]
  218.                   End;
  219.  
  220.  var
  221.    RetCode   : byte;
  222.    Filename  : filename_type;
  223.    Buffer    : Dir_Entry;
  224.    Attribute : byte;
  225.  
  226.  Procedure CheckNulls;
  227.    var v : integer;
  228.  
  229.    Begin
  230.      for v := 1 to 12 do
  231.        Begin
  232.          if files[entries][v] = #0 then files[entries][v] := ' '
  233.        End { for v }
  234.    End; { Sub Proc CheckNulls }
  235.  
  236.  Procedure Disk_Trns_Addr(var Disk_Buf);
  237.    var
  238.      Registers : regtype;
  239.  
  240.   Begin
  241.     with Registers do
  242.       Begin
  243.         Ax := $1A shl 8;                 { Set disk transfer address to  }
  244.         Ds := seg(Disk_Buf);             { our disk buffer               }
  245.         Dx := ofs(Disk_Buf);
  246.         msdos(Registers)
  247.       End
  248.    End; { Proc Disk_Trns_Addr }
  249.  
  250.   Procedure Check_Max;
  251.     Begin
  252.       if entries > Max_Entries
  253.         then
  254.           Begin
  255.             WriteLn;
  256.             WriteLn;
  257.             WriteLn(#7,'You have reached the Maximum number of entries!');
  258.             WriteLn('Your DIR.DAT remains intact. You',#39,'ll have to create');
  259.             WriteLn('another DIR.DAT file on a different data disk.');
  260.             WriteLn;
  261.             WriteLn('DIR Halted.');
  262.             Halt
  263.           End { if }
  264.     End; { Proc Check_Max }
  265.  
  266.   Procedure Find_Next(var Att:byte;
  267.                       var Filename : Filename_type;
  268.                       var Next_RetCode : byte);
  269.     var
  270.       Registers  : regtype;
  271.       Carry_flag : integer;
  272.       N          : byte;
  273.  
  274.     Begin {Find_Next}
  275.       Buffer.Name := '             ';      { Clear result buffer }
  276.       with Registers do
  277.         Begin
  278.           Ax := $4F shl 8;                 { Dos Find next function }
  279.           MsDos(Registers);
  280.           Att := Buffer.Attribute;         { Set file attribute     }
  281.           Carry_flag := 1 and Flags;       { Isolate the Error flag }
  282.           Filename := '             ';
  283.           if Carry_flag = 1
  284.             then
  285.               Next_RetCode := Ax and $00FF
  286.             else
  287.               Begin                         { Move file name         }
  288.                 Next_RetCode := 0;
  289.                 for N := 0 to 11 do FileName[N+1] := Buffer.Name[N]
  290.               End { else }
  291.         End  { with }
  292.     End; { Proc Find_Next }
  293.  
  294.   Procedure Find_First (var Att: byte;
  295.                         var Filename: Filename_type;
  296.                         var RetCode_code : byte);
  297.  
  298.     var
  299.       Registers  :regtype;
  300.       Carry_flag :integer;
  301.       Mask, N    :byte;
  302.  
  303.     Begin
  304.      Disk_Trns_Addr(buffer);
  305.      Filename := Filename + chr(0);
  306.      Buffer.Name := '             ';
  307.      with Registers do
  308.        Begin
  309.          Ax := $4E shl 8;                { Dos Find First Function }
  310.          Cx := Att;                      { Attribute of file to fine }
  311.          Ds := seg(Filename);            { Ds:Dx Ascii string to find }
  312.          Dx := ofs(Filename) + 1;
  313.          MsDos(Registers);
  314.          Att := Buffer.Attribute;        { set the file attribute byte  }
  315.  
  316.                                          { If error occured set, Return code. }
  317.  
  318.          Carry_flag := 1 and Flags;      { If Carry flag, error occured }
  319.                                          { and Ax will contain Return code }
  320.          if Carry_flag = 1
  321.            then
  322.              RetCode_code := Ax and $00FF
  323.            else
  324.              Begin
  325.                RetCode_code := 0;
  326.                Filename := '             ';
  327.                for N := 0 to 11 do FileName[N+1] := Buffer.Name[N]
  328.              End { else }
  329.        End  {with}
  330.     End; { Proc Find_First }
  331.  
  332.   var
  333.     attribyte : byte;
  334.  
  335.   Begin { Primary block of Get_File }
  336.     filename := filepath;
  337.     attribyte := 0;
  338.     Find_First(attribyte,filename,Retcode);
  339.     If Retcode = 0
  340.       then
  341.         Begin
  342.           if Reading
  343.             then
  344.               Begin
  345.                 entries := entries + 1;
  346.                 Check_Max;
  347.                 files[entries] :=Filename;
  348.                 Pad_Right(files[entries],#32,12);
  349.                 files[entries] := files[entries] + disk;
  350.                 CheckNulls;
  351.               End { if Reading }
  352.             else
  353.               Begin
  354.                 Write(filename);
  355.                 Check_Pos;
  356.                 if choice = '*' then Retcode := 1;
  357.                 choice := ' '
  358.               End { else }
  359.         End; { if Retcode }
  360.  
  361.     { Now we Repeat Find_Next Until an error occurs }
  362.  
  363.     Repeat
  364.       Find_Next(attribyte,filename,Retcode);
  365.       if Retcode = 0
  366.         then
  367.           Begin
  368.             if Reading
  369.               then
  370.                 Begin
  371.                   entries := entries + 1;
  372.                   Check_Max;
  373.                   files[entries] :=Filename;
  374.                   Pad_Right(files[entries],' ',12);
  375.                   files[entries] := files[entries] + disk;
  376.                   CheckNulls;
  377.                 End { if Reading }
  378.               else
  379.                 Begin
  380.                   Write(filename);
  381.                   Check_Pos;
  382.                   if choice = '*' then Retcode := 1;
  383.                   choice := ' '
  384.                 End { else }
  385.           End { if Retcode }
  386.     Until Retcode <> 0;
  387.     if not Reading
  388.       then
  389.         if choice <> '*'
  390.           then
  391.             AtEnd
  392.   End; { Proc Get_File }
  393.  
  394. Procedure TimDat(var timestr, datestr, daystr :Str255);
  395.   Procedure GetTime(Var T:Time);
  396.     var regs : HalfRegType;
  397.  
  398.     Begin
  399.       With Regs,T Do
  400.         Begin
  401.           AH := $2C;
  402.           MsDos(Regs);
  403.           Hours := CH;
  404.           Min := CL;
  405.           Sec := DH;
  406.           Hundreths := DL
  407.        End { with }
  408.     End; { Sub Proc GetTime }
  409.  
  410.   Procedure GetDate(Var D:Date);
  411.     var
  412.       Regs : HalfRegType;
  413.  
  414.     Begin
  415.       With Regs,D Do
  416.         Begin
  417.           AH := $2A;
  418.           MsDos(Regs);
  419.           Month := DH;
  420.           Day := DL;
  421.           Year := 256 * CH + CL;
  422.           DayOfWeek := DOW(AL)
  423.         End { with }
  424.     End; { Sub Proc GetDate }
  425.  
  426.   Var
  427.     T1 : Time;
  428.     D1 : Date;
  429.     s1 : string[5];
  430.  
  431.   Begin { Proc TimDat Main }
  432.     GetTime(T1);
  433.     GetDate(D1);
  434.     With T1 Do
  435.       Begin
  436.         timestr := '';
  437.         str(hours,s1);
  438.         Pad_Left(s1,'0',2);
  439.         timestr := s1 + ':';
  440.         str(min,s1);
  441.         Pad_Left(s1,'0',2);
  442.         timestr := timestr + s1 + ':';
  443.         str(sec,s1);
  444.         Pad_Left(s1,'0',2);
  445.         timestr := timestr + s1
  446.       End; { with T1 }
  447.     With D1 Do
  448.       Begin
  449.         datestr := '';
  450.         str(month,s1);
  451.         Pad_Left(s1,'0',2);
  452.         datestr := s1 + '/';
  453.         str(day,s1);
  454.         Pad_Left(s1,'0',2);
  455.         datestr := datestr + s1 + '/';
  456.         str(year,s1);
  457.         datestr := datestr + s1;
  458.         daystr := DayName[DayOfWeek]
  459.       End  { with T1 }
  460.   End; { Proc TimDat }
  461.  
  462. Procedure Color(fr,bk,bd : integer);
  463.   Begin
  464.     TextColor(fr);
  465.     TextBackground(bk);
  466.     Port[$03d9] := bd
  467.   End; { Proc Color }
  468.  
  469. Procedure UpperCase(var x : Str255);
  470.   var i : integer;
  471.  
  472.   Begin
  473.     for i := 1 to length(x) do x[i] := UpCase(x[i])
  474.   End; { Proc UpperCase }
  475.  
  476. Procedure Sort;
  477.  label
  478.    B, C, D;
  479.  
  480.  var
  481.    i,j,k,l,m,n : integer;
  482.    t           : files_type;
  483.  
  484.  Begin
  485.    Cursor(Off);
  486.    Write ('Sorting');
  487.    n := entries;
  488.    m := n div 2;
  489.    While m > 0 do
  490.      Begin
  491.        Write ('.');   { Just to show that something's going on.... }
  492.        j := 1;
  493.        k := n - m;
  494. B:     i := j;
  495. C:     l := i + m;
  496.        if files[i] >= files[l]
  497.          then
  498.            Begin
  499.              t := files[i];
  500.              files[i] := files[l];
  501.              files[l] := t;
  502.              i := i - m;
  503.              if i >= 1 then goto C
  504.            End; { if }
  505. D:     j := j + 1;
  506.        if j <= k then goto B;
  507.        m := m div 2
  508.      End; { while m }
  509.    WriteLn;
  510.    Cursor(On)
  511.  End; { Proc Sort }
  512.  
  513. Procedure Sort_By_Num;
  514.   var i : integer;
  515.  
  516.   Begin
  517.     if Sort_Flag
  518.       then
  519.         Begin
  520.           Sort_Flag := False;
  521.           for i := 1 to entries do
  522.             files[i] := copy(files[i],5,12) + copy(files[i],1,4)
  523.         End { if }
  524.       else
  525.         Begin
  526.           Sort_Flag := True;
  527.           for i := 1 to entries do
  528.             files[i] := copy(files[i],13,4) + copy(files[i],1,12)
  529.         End; { else }
  530.     Sort
  531.   End; { Proc Sort_By_Num }
  532.  
  533. Function Exist(filenam : files_type) : Boolean;
  534.   var
  535.     f : file;
  536.  
  537.   Begin
  538.     Assign(f, filenam);
  539.     {$I- }
  540.     Reset(f);
  541.     {$I+ }
  542.     Exist := (IOresult = 0);
  543.     close(f)
  544.   End; { Function Exist }
  545.  
  546. Procedure Init;
  547.   var
  548.     fil    : text;
  549.  
  550.   Begin
  551.     if not Exist('dir4.cfg')
  552.       then
  553.         Begin
  554.           Assign(fil,'dir4.cfg');
  555.           ReWrite(fil);
  556.           {
  557.             Create the default parameters
  558.           }
  559.           fore := Green;
  560.           back := Black;
  561.           bord := Black;
  562.           fore_hi := Yellow;
  563.           cpi16 := #27 + 'P'; { Default to the Epson/IBM string }
  564.           defaultdrive := 'B';
  565.           WriteLn(fil,fore);
  566.           WriteLn(fil,back);
  567.           WriteLn(fil,bord);
  568.           WriteLn(fil,fore_hi);
  569.           WriteLn(fil,cpi16);
  570.           WriteLn(fil,defaultdrive);
  571.         End { if }
  572.       else
  573.         Begin
  574.           Assign(fil,'dir4.cfg');
  575.           Reset(fil);
  576.           ReadLn(fil,fore);
  577.           ReadLn(fil,back);
  578.           ReadLn(fil,bord);
  579.           ReadLn(fil,fore_hi);
  580.           ReadLn(fil,cpi16);
  581.           ReadLn(fil,defaultdrive);
  582.         End; { else }
  583.     close(fil);
  584.     Sort_Flag := False;
  585.     color(fore,back,bord);
  586.     a := ord(16 * back + fore);
  587.     ClrScr;
  588.     FastWrite(28, 9,a,'╒════════════════════════╕');
  589.     FastWrite(28,10,a,'│                        │');
  590.     FastWrite(28,11,a,'│        DIR 4.05        │');
  591.     FastWrite(28,12,a,'│                        │');
  592.     FastWrite(28,13,a,'│      by Wes Meier      │');
  593.     FastWrite(28,14,a,'│                        │');
  594.     FastWrite(28,15,a,'│  Modified by E. White  │');
  595.     FastWrite(28,16,a,'│                        │');
  596.     FastWrite(28,17,a,'│     December, 1986     │');
  597.     FastWrite(28,18,a,'│                        │');
  598.     FastWrite(28,19,a,'╞════════════════════════╡');
  599.     FastWrite(28,20,a,'│');
  600.     FastWrite(30,20, ord(16 * back + fore_hi),'FOR PUBLIC DOMAIN ONLY');
  601.     FastWrite(52,20,a,'│');
  602.     FastWrite(28,21,a,'╘════════════════════════╛');
  603.     Delay(500);
  604.   End; { Proc Init }
  605.  
  606. Procedure Read_Data_From_Disk;
  607.   var
  608.     dir_dat : text;
  609.  
  610.   Begin
  611.     if not Exist('DIR.DAT')
  612.       then
  613.         Begin
  614.           Assign(dir_dat,'DIR.DAT');
  615.           ReWrite(dir_dat);
  616.           Close(dir_dat)
  617.         End; { if }
  618.     Assign(dir_dat,'DIR.DAT');
  619.     Reset(dir_dat);
  620.     entries := 0;
  621.     while not EOF(dir_dat) do
  622.       Begin
  623.         entries := entries + 1;
  624.         ReadLn(dir_dat,sx);
  625.  
  626.         {
  627.          Are we Reading an old DIR3.n file?
  628.         }
  629.  
  630.         if pos('"',sx) > 0
  631.           then
  632.             Begin
  633.               sx := copy(sx,2,15);
  634.               sy := copy(sx,1,8);
  635.               while sy[length(sy)] = ' ' do
  636.                 Begin
  637.                   delete(sy,length(sy),1)
  638.                 End; { While }
  639.               sy := copy(sy + copy(sx,9,4) + '            ',1,12);
  640.               sx := sy + copy(sx,13,3);
  641.               insert('0',sx,13)
  642.             End; { if }
  643.         if copy(sx,13,4) = '0000'
  644.           then
  645.             entries := entries - 1  { don't allow files with '0000' in them }
  646.           else
  647.             files[entries] := sx
  648.       End; { while }
  649.     close(dir_dat)
  650.   End; { Proc Read_Data_From_Disk }
  651.  
  652. Procedure Dump_Data_To_Disk; { Terminal routine...re-execs the program }
  653.   var
  654.     dir_dat : text;
  655.     dir4    : file;
  656.     i       : integer;
  657.  
  658.   Begin
  659.     Cursor(Off);
  660.     TextColor(fore + blink);
  661.     ClrScr;
  662.     GotoXY(20,12);
  663.     Write('Dumping Data to Disk ....');
  664.     Assign(dir_dat,'dir.dat');
  665.     ReWrite(dir_dat);
  666.     for i := 1 to entries do
  667.       Begin
  668.         if files[i][1] <> ' ' then WriteLn(dir_dat,files[i])
  669.       End; { for }
  670.     close(dir_dat);
  671.     Assign(dir4,'DIR4.COM');
  672.     Set_Cursor(Start_Line,End_Line);
  673.     {$I- }
  674.       Execute(dir4);
  675.     {$I+ }
  676.     if IOResult <> 0
  677.       then
  678.         Begin
  679.           Locate12;
  680.           TextColor(fore);
  681.           WriteLn(^G,'The file "DIR4.COM" was not found.');
  682.           WriteLn('This program MUST be called "DIR4.COM" and be available in your default PATH.');
  683.           WriteLn;
  684.           WriteLn('Program Halted.');
  685.           Halt
  686.         End { if }
  687. End; { Proc Dump_Data_To_Disk }
  688.  
  689. Procedure ShowMenu;
  690.  
  691.   var
  692.     h   : byte;
  693.     ent : str80;
  694.  
  695.   Begin
  696.     ClrScr;
  697.     a := ord(16 * back + fore);
  698.     h := ord(16 * back + fore_hi);
  699.     str(entries,ent);
  700.     GotoXY(1,1);
  701.     FastWrite(19, 8,a,'╒═════════════════════════════════════════╕');
  702.     FastWrite(19, 9,a,'│     DIR 4.05 - ');
  703.     FastWrite(37, 9,a,ent + ' Entries on File');
  704.     FastWrite(61, 9,a,'│');
  705.     FastWrite(19,10,a,'├─────────────────────────────────────────┤');
  706.     FastWrite(19,11,a,'│ [');
  707.     FastWrite(22,11,h,'F');
  708.     FastWrite(23,11,a,']ind a File.                          │');
  709.     FastWrite(19,12,a,'│ [');
  710.     FastWrite(22,12,h,'A');
  711.     FastWrite(23,12,a,']dd File(s) to the Data Record.       │');
  712.     FastWrite(19,13,a,'│ [');
  713.     FastWrite(22,13,h,'P');
  714.     FastWrite(23,13,a,']rint or List the Data Record.        │');
  715.     FastWrite(19,14,a,'│ [');
  716.     FastWrite(22,14,h,'D');
  717.     FastWrite(23,14,a,']elete File(s) from the Data Record.  │');
  718.     FastWrite(19,15,a,'│ [');
  719.     FastWrite(22,15,h,'L');
  720.     FastWrite(23,15,a,']ist a Disk Directory (Data or Real). │');
  721.     FastWrite(19,16,a,'│ [');
  722.     FastWrite(22,16,h,'W');
  723.     FastWrite(23,16,a,']rite a Diskette Label.               │');
  724.     FastWrite(19,17,a,'│ [');
  725.     FastWrite(22,17,h,'B');
  726.     FastWrite(23,17,a,']ackup the Data Record File.          │');
  727.     FastWrite(19,18,a,'│ [');
  728.     FastWrite(22,18,h,'C');
  729.     FastWrite(23,18,a,']onfigure DIR4.                       │');
  730.     FastWrite(19,19,a,'│ [');
  731.     FastWrite(22,19,h,'Esc');
  732.     FastWrite(25,19,a,']ape Back to DOS.                   │');
  733.     FastWrite(19,20,a,'╘═════════════════════════════════════════╛');
  734.   End; { Proc ShowMenu }
  735.  
  736.   Function Yes : boolean;
  737.     var
  738.       c   : char;
  739.       yup : boolean;
  740.  
  741.     Begin
  742.       Repeat
  743.         Repeat Until KeyPressed;
  744.         Read(kbd,c);
  745.         c := UpCase(c)
  746.       Until c in [#13,'Y','N','0','1','-','+'];
  747.       yup := (c in [#13,'Y','+','1']);
  748.       yes := yup;
  749.       if yup
  750.         then
  751.           WriteLn('Yes')
  752.         else
  753.           WriteLn('No')
  754.     End; { Function Yes }
  755.  
  756.   Procedure Fix_Path(var x : files_type);
  757.     Begin
  758.       if x[length(x)] <> '\' then x := x + '\';
  759.       if x[2] <> ':' then insert(':',x,2);
  760.       if pos(x,'*.*') = 0 then x := x + '*.*'
  761.     End; { Proc Fix_Path }
  762.  
  763.   Procedure Add; { a file or files to the data Record }
  764.     Procedure Disk_Read;
  765.       var
  766.         drive : filename_type;
  767.         done,
  768.         f     : boolean;
  769.         i,j,w,z,
  770.         old_ent,
  771.         count : integer;
  772.  
  773.       Begin{ Disk_Read }
  774.         disk := '0000';
  775.         done := False;
  776.         Repeat { Until done }
  777.           Repeat { Until Yes and disk <> '0000' }
  778.             x := 0;
  779.             ClrScr;
  780.             GotoXY(20,3);
  781.             val(disk,x,z);
  782.             Write('Disk # to Read (1-9999). Default is ');
  783.             Write(x + 1);
  784.             Write(') ? ');
  785.             z := WhereX;
  786.             ReadLn(sx);
  787.             if sx = ''
  788.               then
  789.                 Begin
  790.                   Str((x + 1),sx);
  791.                   f := True
  792.                 End { if }
  793.               else
  794.                 Begin
  795.                   UpperCase(sx);
  796.                   f := False
  797.                 End; { else }
  798.             Pad_Left(sx,'0',4);
  799.             disk := sx;
  800.             if f
  801.               then
  802.                 Begin
  803.                   GotoXY(z,3);
  804.                   Write(sx)
  805.                 End; { if }
  806.             GotoXY(20,5);
  807.             Write('Enter Drive or Path (Default is ',DefaultDrive,':\) ? ');
  808.             z := WhereX;
  809.             ReadLn(filepath);
  810.             if filepath = ''
  811.               then
  812.                 Begin
  813.                   filepath := DefaultDrive + ':\';
  814.                   f := True
  815.                 End { if }
  816.               else
  817.                 f := False;
  818.             Fix_Path(filepath);
  819.             if f
  820.               then
  821.                 Begin
  822.                   GotoXY(z,5);
  823.                   Write(filepath)
  824.                 End; { if }
  825.             GotoXY(20,7);
  826.             Write('Verify Disk #',disk,' on drive ',filepath,' correct ? ');
  827.             if disk = '0000'
  828.               then
  829.                 Begin
  830.                   WriteLn;
  831.                   WriteLn(^G,'"0000" is an illegal Disk value.');
  832.                   WriteLn
  833.                 End { if }
  834.           Until yes and (disk <> '0000');
  835.           Reading := True;
  836.           count := 0;
  837.           Cursor(Off);
  838.           for i := 1 to entries do
  839.             Begin
  840.               if disk = copy(files[i],13,4)
  841.                 then
  842.                   Begin
  843.                     files[i][1] := ' ';
  844.                     count := count + 1
  845.                   End { if }
  846.             End; { for }
  847.           old_ent := entries;
  848.           Get_File;
  849.           GotoXY(20,9);
  850.           Write('Done. Total number of entries is ',entries);
  851.           GotoXY(20,10);
  852.           Write(entries - old_ent, ' Files were read. Read another disk? ');
  853.           Cursor(On);
  854.           Done := not Yes;
  855.           Cursor(Off)
  856.         Until done;
  857.         WriteLn;
  858.         GotoXY(20,11);
  859.         Sort;
  860.         Dump_Data_To_Disk
  861.       End; { sub Proc Disk_Read }
  862.  
  863.     Procedure Manual_Entry;
  864.       var
  865.         done,
  866.         new,
  867.         k    : boolean;
  868.         f,f1 : Str255;
  869.  
  870.       Begin{ Manual_Entry }
  871.         new := False;
  872.         done := False;
  873.         k := False;
  874.         Locate12;
  875.         Repeat { Until Done }
  876.           Repeat { Until done or k, where k = Yes }
  877.             Write('Enter File ("*" to Quit) ? ');
  878.             ReadLn(f);
  879.             if f = '*'
  880.               then
  881.                 Begin
  882.                   done := True;
  883.                   k := False
  884.                 End { if }
  885.               else
  886.                 Begin
  887.                   UpperCase(f);
  888.                   WriteLn;
  889.                   Write('Enter Disk # (1-9999) ? ');
  890.                   ReadLn(f1);
  891.                   Pad_Left(f1,'0',4);
  892.                   UpperCase(f1);
  893.                   WriteLn;
  894.                   Write('Is ',f,' on Disk #',f1,' Correct ? ');
  895.                   k := yes;
  896.                   if f1 = '0000'
  897.                     then
  898.                       Begin
  899.                         k := False;
  900.                         WriteLn(^G,'"0000" is an illegal Disk label!');
  901.                       End { if }
  902.                 End; { else }
  903.             WriteLn
  904.           Until done or k; { k = Yes }
  905.           if k
  906.             then
  907.               Begin
  908.                 new := True;
  909.                 entries := entries + 1;
  910.                 Pad_Right(f,' ',12);
  911.                 files[entries] := f + f1
  912.               End { if k }
  913.         Until done;
  914.         if new
  915.           then
  916.             Begin
  917.               Sort;
  918.               Dump_Data_To_Disk
  919.             End { if }
  920.       End; { sub Proc Manual_Entry }
  921.  
  922.     var
  923.       chc : char;
  924.  
  925.     Begin { Add }
  926.       ClrScr;
  927.       GotoXY(20,12);
  928.       Write('Manually ');
  929.       TextColor(fore_hi + blink);
  930.       Write('A');
  931.       TextColor(fore);
  932.       Write('dd file(s), Read a ');
  933.       TextColor(fore_hi + blink);
  934.       Write('D');
  935.       TextColor(fore);
  936.       Write('isk, or ');
  937.       TextColor(fore_hi + blink);
  938.       Write('Q');
  939.       TextColor(fore);
  940.       Write('uit ? ');
  941.       Repeat
  942.         Repeat Until Keypressed;
  943.         Read(kbd,chc);
  944.         chc := UpCase(chc)
  945.       Until pos(chc,'ADQ*') > 0;
  946.       Case chc of
  947.         'A' : manual_entry;
  948.         'D' : disk_Read
  949.       End { Case chc }
  950.     End; { Proc Add }
  951.  
  952. Procedure Configure;
  953.   var
  954.     chc,c :  char;
  955.     done  :  boolean;
  956.     i     :  integer;
  957.     h     :  byte;
  958.  
  959.   Begin
  960.     done := False;
  961.     Repeat { Until done }
  962.       h := ord(16 * back + fore_hi);
  963.       a := ord(16 * back + fore);
  964.       ClrScr;
  965.       Cursor(Off);
  966.       FastWrite(19, 1,a,'╒═════════════════════════════════════════╕');
  967.       FastWrite(19, 2,a,'│      DIR 4.05 - Configuration Menu      │');
  968.       FastWrite(19, 3,a,'├─────────────────────────────────────────┤');
  969.       FastWrite(19, 4,a,'│ Change [');
  970.       FastWrite(29, 4,h,'F');
  971.       FastWrite(30, 4,a,']oreground Color.              │');
  972.       FastWrite(19, 5,a,'│ Change [');    TextColor(Fore_hi);
  973.       FastWrite(29, 5,h,'H');
  974.       FastWrite(30, 5,a,']ighlight Color.               │');
  975.       FastWrite(19, 6,a,'│ Change [');
  976.       FastWrite(29, 6,h,'B');
  977.       FastWrite(30, 6,a,']ackground Color.              │');
  978.       FastWrite(19, 7,a,'│ Change Bo[');
  979.       FastWrite(31, 7,h,'R');
  980.       FastWrite(32, 7,a,']der Color.                  │');
  981.       FastWrite(19, 8,a,'│ Enter [');
  982.       FastWrite(28, 8,h,'P');
  983.       FastWrite(29, 8,a,']rinter 16 cpi Control String:  │');
  984.       FastWrite(19, 9,a,'│    Current String = ');
  985.       FastWrite(42, 9,h,copy(cpi16 + '                    ',1,20));
  986.       FastWrite(61, 9,a,'│');
  987.       FastWrite(19,10,a,'│ [');
  988.       FastWrite(22,10,h,'D');
  989.       FastWrite(23,10,a,']efault Drive ');
  990.       FastWrite(37,10,h,copy(defaultdrive + ':                   ',1,20));
  991.       FastWrite(61,10,a,'│');
  992.       FastWrite(19,11,a,'│ [');
  993.       FastWrite(22,11,h,'S');
  994.       FastWrite(23,11,a,']ave Configuration.                   │');
  995.       FastWrite(19,12,a,'│ [');
  996.       FastWrite(22,12,h,'Q');
  997.       FastWrite(23,12,a,']uit Back to the Main Menu.           │');
  998.       FastWrite(19,13,a,'╘═════════════════════════════════════════╛');
  999.       Repeat { Until valid choice selected }
  1000.         Repeat Until KeyPressed;
  1001.         Read(kbd,chc);
  1002.         chc := UpCase(chc)
  1003.       Until pos(chc,'FHBRDSPQ*') > 0;
  1004.       Window(20,16,80,24);
  1005.       GotoXY(1,1);
  1006.       ClrScr;
  1007.       Cursor(On);
  1008.       Case chc of
  1009.         'F' : Begin
  1010.                 for i:=0 to 15 do
  1011.                   Begin
  1012.                     TextColor(i);
  1013.                     Write('███')
  1014.                   End; { for }
  1015.                 TextColor(fore);
  1016.                 WriteLn;
  1017.                 WriteLn(' 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F');
  1018.                 Write(' Select New Foreground Color (0-F) ');
  1019.                 Repeat
  1020.                   Repeat Until KeyPressed;
  1021.                   Read(kbd,c);
  1022.                   c := UpCase(c);
  1023.                   i := pos(c,'0123456789ABCDEF')
  1024.                 Until i > 0;
  1025.                 fore := i - 1;
  1026.                 TextColor(fore)
  1027.               End; { Case 'F' }
  1028.         'H' : Begin
  1029.                 for i := 0 to 15 do
  1030.                   Begin
  1031.                     TextColor(i);
  1032.                     Write('███')
  1033.                   End; { for }
  1034.                 TextColor(fore);
  1035.                 WriteLn;
  1036.                 WriteLn(' 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F');
  1037.                 Write(' Select New Highlight Color (0-F) ');
  1038.                 Repeat
  1039.                   Repeat Until KeyPressed;
  1040.                   Read(kbd,c);
  1041.                   c := UpCase(c);
  1042.                   i := pos(c,'0123456789ABCDEF')
  1043.                 Until i > 0;
  1044.                 fore_hi := i - 1
  1045.               End; { Case 'H' }
  1046.         'B' : Begin
  1047.                 for i := 0 to 7 do
  1048.                   Begin
  1049.                     TextColor(i);
  1050.                     Write('███')
  1051.                   End; { for }
  1052.                 TextColor(fore);
  1053.                 WriteLn;
  1054.                 WriteLn(' 0  1  2  3  4  5  6  7');
  1055.                 Write(' Select New Background Color (0-7) ');
  1056.                 Repeat
  1057.                   Repeat Until KeyPressed;
  1058.                   Read(kbd,c);
  1059.                   c := UpCase(c);
  1060.                   i := pos(c,'01234567')
  1061.                 Until i > 0;
  1062.                 back := i - 1;
  1063.                 TextBackground(back);
  1064.                 window(1,1,80,25);
  1065.                 color(fore,back,bord)
  1066.               End;  { Case 'B' }
  1067.         'R' : Begin
  1068.                 for i := 0 to 7 do
  1069.                   Begin
  1070.                     TextColor(i);
  1071.                     Write('███')
  1072.                   End; { for }
  1073.                 TextColor(fore);
  1074.                 WriteLn;
  1075.                 WriteLn(' 0  1  2  3  4  5  6  7');
  1076.                 Write(' Select New Border Color (0-7) ');
  1077.                 Repeat
  1078.                   Repeat Until KeyPressed;
  1079.                   Read(kbd,c);
  1080.                   c := UpCase(c);
  1081.                   i := pos(c,'01234567')
  1082.                 Until i > 0;
  1083.                 bord := i - 1;
  1084.                 port[$03d9] := bord
  1085.               End;  { Case 'R' }
  1086.         'S' : Begin
  1087.                 Cursor(Off);
  1088.                 Assign(ft,'dir4.cfg');
  1089.                 ReWrite(ft);
  1090.                 WriteLn(ft,fore);
  1091.                 WriteLn(ft,back);
  1092.                 WriteLn(ft,bord);
  1093.                 WriteLn(ft,fore_hi);
  1094.                 WriteLn(ft,cpi16);
  1095.                 WriteLn(ft,defaultdrive);
  1096.                 close(ft);
  1097.                 Cursor(On)
  1098.               End;  { Case 'S' }
  1099.         'D' : Begin
  1100.                 Repeat
  1101.                 ClrScr;
  1102.                 Write('Enter the default drive letter (A - D): ');
  1103.                 Read(Kbd,DefaultDrive);
  1104.                 DefaultDrive := UpCase(DefaultDrive);
  1105.                 If Not (DefaultDrive In ['A'..'D']) Then Write(#7);
  1106.                 Until (DefaultDrive In ['A'..'D']);
  1107.               End;  { Case 'D' }
  1108.         'P' : Begin
  1109.                 WriteLn('Enter the command string that places your printer into');
  1110.                 WriteLn('condensed (16 cpi) mode. Use "{" for the Esc character');
  1111.                 Write('and "^" for Ctrl. String ? ');
  1112.                 ReadLn(cpi16);
  1113.                 if pos('{',cpi16)>0 then cpi16[pos('{',cpi16)] := #27;
  1114.                 i := pos('^',cpi16);
  1115.                 if i > 0
  1116.                   then
  1117.                     Begin
  1118.                       cpi16[i + 1] := UpCase(cpi16[i + 1]);
  1119.                       if (ord(cpi16[i + 1]) -64 >= 0) and
  1120.                          (ord(cpi16[i + 1]) -64 <= 31)
  1121.                         then
  1122.                           Begin
  1123.                             cpi16[i + 1] := chr(ord(cpi16[i + 1]) - 64);
  1124.                             delete(cpi16,i,1)
  1125.                           End { if (ord ... }
  1126.                     End { if i ... }
  1127.               End       { Case 'P' }
  1128.          else           { Cases Q and * }
  1129.            done := True
  1130.       End               { Case of chc }
  1131.     Until Done;
  1132.     window(1,1,80,25)
  1133.   End;                  { Proc Configure }
  1134.  
  1135. Procedure Backup;
  1136.   var
  1137.     dir_dat : text;
  1138.     ft      : Str255;
  1139.     i       : integer;
  1140.     no_err  : boolean;
  1141.  
  1142.   Begin
  1143.     Cursor(Off);
  1144.     Locate12;
  1145.     Repeat { until no_err }
  1146.       Write('Backup "DIR.DAT" onto which drive ("*" to quit) ? ');
  1147.       ReadLn(ft);
  1148.       if ft = '*' then Exit;
  1149.       UpperCase(ft);
  1150.       if copy(ft,length(ft),1) <> ':' then ft := ft + ':';
  1151.       Assign(dir_dat,ft + 'dir.dat');
  1152.       {$I- }
  1153.         ReWrite(dir_dat);
  1154.       {$I+ }
  1155.       no_err := (IOResult = 0);
  1156.       if not no_err
  1157.         then
  1158.           Begin
  1159.             WriteLn;
  1160.             WriteLn(^G,'An I/O error occurred. Drive "',ft,'" is probably incorrect. Please try again.');
  1161.             WriteLn
  1162.           End { if }
  1163.     Until no_err;
  1164.     ClrScr;
  1165.     GotoXY(20,12);
  1166.     TextColor(fore + blink);
  1167.     Write('Backing "DIR.DAT" to drive ',ft);
  1168.     for i := 1 to entries do
  1169.       Begin
  1170.         if files[i][1] <> ' ' then WriteLn(dir_dat,files[i])
  1171.       End; { for }
  1172.     close(dir_dat);
  1173.     TextColor(fore)
  1174.   End; { Proc BackUp }
  1175.  
  1176. Procedure Zap; { Deletes one or more files or a complete diskette }
  1177.   var
  1178.     i,j,k  : integer;
  1179.     c      : char;
  1180.     sx     : Str255;
  1181.     mark,
  1182.     done,
  1183.     zapped : boolean;
  1184.  
  1185.   Begin
  1186.     zapped := False;
  1187.     Locate12;
  1188.     Write('Delete a ');
  1189.     TextColor(fore_hi + blink);
  1190.     Write('F');
  1191.     TextColor(fore);
  1192.     Write('ile, a ');
  1193.     TextColor (fore_hi + blink);
  1194.     Write('D');
  1195.     TextColor(fore);
  1196.     Write('isk, or ');
  1197.     TextColor (fore_hi + blink);
  1198.     Write('Q');
  1199.     TextColor(fore);
  1200.     Write('uit back to the Main Menu ? ');
  1201.     Repeat
  1202.       Repeat Until KeyPressed;
  1203.       Read(kbd,c);
  1204.       c := UpCase(c)
  1205.     Until pos(c,'FDQ*') > 0;
  1206.     Case c of
  1207.       'F' : Begin
  1208.               Locate12;
  1209.               done := False;
  1210.               Repeat { Until done }
  1211.                 mark := False;
  1212.                 Write('File to delete ("*" to quit) ? ');
  1213.                 ReadLn(sx);
  1214.                 UpperCase(sx);
  1215.                 if sx = '*' then done := True;
  1216.                 if not done
  1217.                   then
  1218.                     for i := 1 to entries do
  1219.                       Begin
  1220.                         if pos(sx,files[i]) > 0
  1221.                           then
  1222.                             Begin
  1223.                               files[i][1] := ' ';
  1224.                               mark := True;
  1225.                               zapped := True
  1226.                             End { if }
  1227.                       End; { for i }
  1228.                 if not mark
  1229.                   then
  1230.                     Begin
  1231.                       WriteLn;
  1232.                       WriteLn('File "',sx,'" wasn',#39,'t found.');
  1233.                       WriteLn
  1234.                     End { if not mark }
  1235.                   else
  1236.                     WriteLn
  1237.               Until done
  1238.             End; { Case F }
  1239.       'D' : Begin
  1240.               j := 0;
  1241.               done := False;
  1242.               Locate12;
  1243.               done := False;
  1244.               Repeat { Until done }
  1245.                 Write('Enter Disk # (1-9999) to Delete ("*" to Quit) ? ');
  1246.                 ReadLn(sx);
  1247.                 UpperCase(sx);
  1248.                 if sx = '*'
  1249.                   then
  1250.                     done := True
  1251.                   else
  1252.                     Begin
  1253.                       Pad_Left(sx,'0',4) ;
  1254.                       mark := False;
  1255.                       j := 0;
  1256.                       for i := 1 to entries do
  1257.                         Begin
  1258.                           if sx = copy(files[i],13,4)
  1259.                           then
  1260.                             Begin
  1261.                               mark := True;
  1262.                               zapped := True;
  1263.                               files[i] := ' ';
  1264.                               j := j + 1
  1265.                             End { if }
  1266.                         End; { for i }
  1267.                       if mark
  1268.                         then
  1269.                           Begin
  1270.                             WriteLn;
  1271.                             WriteLn('Done. ',j,' files were deleted.')
  1272.                           End { if }
  1273.                         else
  1274.                           Begin
  1275.                             WriteLn;
  1276.                             WriteLn('Disk #',sx,' wasn',#39,'t found.')
  1277.                           End; { else }
  1278.                       WriteLn
  1279.                   End { else not done }
  1280.               Until done
  1281.             End { Case D }
  1282.     End; { Case of c }
  1283.     if zapped then Dump_Data_To_Disk
  1284.   End; { Proc Zap }
  1285.  
  1286. Procedure Strip_Z(var x : Str255); { Strip leading zeros }
  1287.   Begin
  1288.     while x[1] = '0' do delete(x,1,1)
  1289.   End; { Proc Strip_Z }
  1290.  
  1291. Procedure Find;
  1292.   Procedure Strip_S(var x : Str255); { Strips trailing spaces from a string }
  1293.     Begin
  1294.       while x[length(x)] = ' ' do delete(x,length(x),1)
  1295.     End; { Sub Proc Strip_S }
  1296.  
  1297.   var
  1298.     i,j              : integer;
  1299.     st,stmp,s        : Str255;
  1300.     done,found,mark  : boolean;
  1301.  
  1302.   Begin
  1303.     ClrScr;
  1304.     GotoXY(1,10);
  1305.     done := False;
  1306.     Repeat { Until done }
  1307.       Write('Enter File (or Partial) to Find ("*" to Quit) ? ');
  1308.       ReadLn(st);
  1309.       WriteLn;
  1310.       if st = '*'
  1311.         then
  1312.           done := True
  1313.         else
  1314.           Begin
  1315.             found := False;
  1316.             Repeat { Until found }
  1317.               UpperCase(st);
  1318.               mark := False;
  1319.               i := 0;
  1320.               Repeat { Until i >= entries OR Found }
  1321.                 i := i + 1;
  1322.                 if pos(st,copy(files[i],1,12)) > 0
  1323.                   then
  1324.                     Begin
  1325.                       mark := True;
  1326.                       stmp := copy(files[i],1,12);
  1327.                       Strip_S(stmp);
  1328.                       WriteLn(stmp,' may be found on Disk(s):');
  1329.                       s := copy(files[i],13,4);
  1330.                       Strip_Z(s);
  1331.                       i := i + 1;
  1332.                       Write(s,', ');
  1333.                       for j := i to entries do
  1334.                         Begin
  1335.                           if pos(stmp,files[j]) > 0
  1336.                             then
  1337.                               Begin
  1338.                                 s := copy(files[j],13,4);
  1339.                                 Strip_Z(s);
  1340.                                 Write(s,', ');
  1341.                                 i := i + 1
  1342.                               End { if }
  1343.                         End; { for j }
  1344.                       WriteLn;
  1345.                       WriteLn;
  1346.                       Write('Is this the file you wanted ? ');
  1347.                       Found := Yes;
  1348.                       WriteLn
  1349.                     End { if }
  1350.               Until (i >= entries) or Found;
  1351.               if not mark
  1352.                 then
  1353.                   Begin
  1354.                     WriteLn;
  1355.                     WriteLn('"',st,'" wasn',#39,'t found.');
  1356.                     WriteLn;
  1357.                     found := True
  1358.                   End { if }
  1359.                 else
  1360.                   Begin
  1361.                     if i >= entries
  1362.                       then
  1363.                         Begin
  1364.                           found := True;
  1365.                           WriteLn('No further incidences of "',st,'" were found.');
  1366.                           WriteLn
  1367.                         End { if }
  1368.                       else
  1369.                         WriteLn
  1370.                   End { else }
  1371.             Until Found
  1372.           End { else }
  1373.     Until done
  1374.   End; { Proc Find }
  1375.  
  1376. Procedure Print_List;
  1377.   Procedure Print_Prt;
  1378.     var
  1379.       i,page,pages   : integer;
  1380.       linestr,
  1381.       headerstr      : string[126];
  1382.       s,s1,ds,dys,ts : Str255;
  1383.  
  1384.     Begin{ Print_Prt - Prints 7 columns of 50 entries each }
  1385.       WriteLn;
  1386.       WriteLn;
  1387.       WriteLn('Position your printer to about ',#171,'" below the top perforation and press any');
  1388.       Write('key to start the printout ("*" to quit) ? ');
  1389.       Repeat Until Keypressed;
  1390.       Read(Kbd,ch);
  1391.       if ch = '*' then Exit;
  1392.       WriteLn;
  1393.       WriteLn;
  1394.       Write('Printing Data Record. Press any key to abort ....');
  1395.       Write(Lst,cpi16);
  1396.       pages := entries div 350 + 1;
  1397.       linestr :='';
  1398.       for i := 1 to 124 do linestr := linestr + '-';
  1399.       headerstr := '';
  1400.       for i := 1 to 7 do headerstr := headerstr + 'File        Disk  ';
  1401.       for page := 1 to pages do
  1402.         Begin
  1403.           WriteLn(Lst);
  1404.           TimDat(ts,ds,dys);
  1405.           WriteLn(Lst,'      DIR.DAT Listing as of ',dys,', ',ds,' @ ',ts,'.');
  1406.           WriteLn(Lst,'      Page ',page,' of ',pages,' Pages.');
  1407.           WriteLn(Lst,'      ',headerstr);
  1408.           WriteLn(Lst,'      ',linestr);
  1409.           for x:= (page - 1) * 350 to (page - 1) * 350 + 49 do
  1410.             Begin
  1411.               Write(Lst,'      ');
  1412.               y := 1;
  1413.               While y <= 350 do
  1414.                 Begin
  1415.                   if KeyPressed
  1416.                     then
  1417.                       Exit
  1418.                     else
  1419.                       Begin
  1420.                         if (x + y) <= entries
  1421.                           then
  1422.                             Begin
  1423.                               if Sort_Flag
  1424.                                 then
  1425.                                   Begin
  1426.                                     s := copy(files[x + y],1,4);
  1427.                                     Strip_Z(s);
  1428.                                     s1 := copy(files[x + y],5,12);
  1429.                                     s1 := copy(s1 + '    ',1,12);
  1430.                                     Write(Lst,s1,s:4,'  ')
  1431.                                   End { if Sort_Flag }
  1432.                                 else
  1433.                                   Begin
  1434.                                     s := copy(files[x + y],13,4);
  1435.                                     Strip_Z(s);
  1436.                                     s1 := copy(files[x + y],1,12) + '    ';
  1437.                                     s1 := copy(s1,1,12);
  1438.                                     Write(Lst,s1,s:4,'  ')
  1439.                                   End { else if Sort_Flag }
  1440.                             End { if }
  1441.                       End; { else if KeyPressed }
  1442.                   y := y + 50
  1443.                 End; { while y }
  1444.               WriteLn(Lst)
  1445.             End; { for x }
  1446.           WriteLn(Lst,'      ',linestr);
  1447.           for i := 1 to 10 do WriteLn(Lst)
  1448.         End; { for page }
  1449.       if KeyPressed then Read(Kbd,ch)
  1450.     End; { Sub Proc Print_Prt }
  1451.  
  1452.   Procedure Print_Crt;
  1453.     var
  1454.       i    : integer;
  1455.       s    : Str255;
  1456.  
  1457.     Begin{ Proc Print_Crt }
  1458.       ClrScr;
  1459.       GotoXY(1,1);
  1460.       i := 1;
  1461.       Repeat { Until c = * OR i > entries }
  1462.         if Sort_Flag
  1463.           then
  1464.             s := copy(files[i],1,4)
  1465.           else
  1466.             s := copy(files[i],13,4);
  1467.         Strip_Z(s);
  1468.         s := copy('    ' + s,length(s) + 1,4);
  1469.         if Sort_Flag
  1470.           then
  1471.             Write(s,' ',copy(files[i],5,12),'  ')
  1472.           else
  1473.             Write(s,' ',copy(files[i],1,12),'  ');
  1474.         Check_Pos;
  1475.         i := i + 1;
  1476.       Until (choice = '*') or (i > entries);
  1477.       choice := ' ';
  1478.       if i > entries then AtEnd;
  1479.       WriteLn
  1480.     End; { Sub Proc Print_Crt }
  1481.  
  1482.   var
  1483.     c : char;
  1484.  
  1485.   Begin{ Print_List Main }
  1486.     Locate12;
  1487.     Write('Do you want the Data Record Sorted by Disk Number ? ');
  1488.     if Yes
  1489.       then
  1490.         Begin
  1491.           WriteLn;
  1492.           Sort_By_Num
  1493.         End; { if }
  1494.     WriteLn;
  1495.     Write('Dump the Data Record to the ');
  1496.     TextColor(fore_hi + blink);
  1497.     Write('C');
  1498.     TextColor(Fore);
  1499.     Write('RT, the ');
  1500.     TextColor(fore_hi + blink);
  1501.     Write('P');
  1502.     TextColor(fore);
  1503.     Write('rinter, or ');
  1504.     TextColor(fore_hi + blink);
  1505.     Write('Q');
  1506.     TextColor(fore);
  1507.     Write('uit ? ');
  1508.     Repeat
  1509.       Repeat Until KeyPressed;
  1510.       Read(kbd,c);
  1511.       c := UpCase(c)
  1512.     Until pos(c,'CPQ*') > 0;
  1513.     Case c of
  1514.       'C' : Print_Crt;
  1515.       'P' : Print_Prt
  1516.     End { Case of c }
  1517.   End; { Proc Print_List }
  1518.  
  1519. Procedure List_Records;
  1520.   Procedure List_Actual;
  1521.     Var target : Str255;
  1522.  
  1523.     Begin
  1524.       Locate12;
  1525.       Write('Enter drive or path to be listed ("*" to quit) ? ');
  1526.       ReadLn(target);
  1527.       ClrScr;
  1528.       GotoXY(1,1);
  1529.       if target <> '*'
  1530.         then
  1531.           Begin
  1532.             Fix_Path(target);
  1533.             filepath := target;
  1534.             Reading := False;
  1535.             ClrScr;
  1536.             Get_File
  1537.           End { if target <> * }
  1538.     End; { Sub Proc List_Actual }
  1539.  
  1540.   Procedure List_Data;
  1541.     var i    : integer;
  1542.     target,s : Str255;
  1543.  
  1544.     Begin
  1545.       Locate12;
  1546.       Write('Enter disk # (1-9999) to be listed ("*" to quit) ? ');
  1547.       ReadLn(target);
  1548.       UpperCase(target);
  1549.       ClrScr;
  1550.       GotoXY(1,1);
  1551.       if target <> '*'
  1552.         then
  1553.           Begin
  1554.             i := 1;
  1555.             Pad_Left(target,'0',4);
  1556.             Repeat { until i > entries or choice = * }
  1557.               if target = copy(files[i],13,4)
  1558.                 then
  1559.                   Begin
  1560.                     s := copy(files[i],13,4);
  1561.                     Strip_Z(s);
  1562.                     Pad_Left(s,' ',4);
  1563.                     Write(s,' ',copy(files[i],1,12),'  ');
  1564.                     Check_Pos
  1565.                   End; { if target = }
  1566.               i := i + 1
  1567.             Until (i > entries) or (choice = '*');
  1568.             choice := ' ';
  1569.             if i > entries then AtEnd
  1570.           End { if target <> '*' }
  1571.     End; { Sub Proc List_Data }
  1572.  
  1573.   Begin{ Proc List_Records Main }
  1574.     Locate12;
  1575.     Write('List an ');
  1576.     TextColor(fore_hi + blink);
  1577.     Write('A');
  1578.     TextColor(Fore);
  1579.     Write('ctual Disk Directory, the ');
  1580.     TextColor(fore_hi + blink);
  1581.     Write('D');
  1582.     TextColor(fore);
  1583.     Write('ata Record, or ');
  1584.     TextColor(fore_hi + blink);
  1585.     Write('Q');
  1586.     TextColor(fore);
  1587.     Write('uit ? ');
  1588.     Repeat
  1589.       Repeat Until KeyPressed;
  1590.       Read(kbd,ch);
  1591.       ch := UpCase(ch)
  1592.     Until pos(ch,'ADQ*') > 0;
  1593.     Case ch of
  1594.       'A' : List_Actual;
  1595.       'D' : List_Data
  1596.     End { Case of ch }
  1597.   End; { Proc List_Records }
  1598.  
  1599. Procedure Write_Label;
  1600.   const
  1601.     titlel = '_____________________________________________';
  1602.  
  1603.   var
  1604.     i,count,count_t, tb, te           : integer;
  1605.     horiz_line, tmp_line, t_line      : string[74];
  1606.     target, tm, dt, dy, targ_b,targ_e,
  1607.     old_target, mask, titles          : Str255;
  1608.     numerous, alpha, exit_flag,
  1609.     match, title                      : boolean;
  1610.  
  1611.   Procedure Print_label(target_to_print : Str255);
  1612.     Begin
  1613.       i := 1;
  1614.       Pad_Left(target_to_print,'0',4);
  1615.       TimDat(tm,dt,dy);
  1616.       WriteLn(Lst,cpi16,horiz_line);
  1617.       tm := '| Disk #' + target_to_print + '. ' + dt;
  1618.       if title then tm := tm + '. ' + titles;
  1619.       Pad_Right(tm,#32,73);
  1620.       tm := tm + '|';
  1621.       WriteLn(Lst,tm);
  1622.       WriteLn(Lst,t_line);
  1623.       count := 2;
  1624.       tmp_line := '| ';
  1625.       Repeat { until i > entries }
  1626.         if (target_to_print = copy(files[i],13,4))
  1627.           or
  1628.            (sort_flag and (copy(files[i],1,4) = target_to_print))
  1629.           then
  1630.             Begin
  1631.               exit_flag := KeyPressed;
  1632.               if exit_flag then Exit;
  1633.               if sort_flag
  1634.                 then
  1635.                   tmp_line := tmp_line + copy(files[i],5,12) + '  '
  1636.                 else
  1637.                   tmp_line := tmp_line + copy(files[i],1,12) + '  ';
  1638.               if length(tmp_line) > 70
  1639.                 then
  1640.                   Begin
  1641.                     exit_flag := KeyPressed;
  1642.                     if exit_flag then Exit;
  1643.                     tmp_line := tmp_line + ' |';
  1644.                     WriteLn(Lst,tmp_line);
  1645.                     tmp_line := '| ';
  1646.                     count :=  count + 1
  1647.                   End { if length(tmp_line) }
  1648.             End; { if target_to_print }
  1649.         i := i + 1
  1650.       Until i > entries;
  1651.       while count < 26 do
  1652.         Begin
  1653.           exit_flag := KeyPressed;
  1654.           if exit_flag then Exit;
  1655.           while (length(tmp_line) < 72) do tmp_line := tmp_line + ' ';
  1656.           tmp_line := tmp_line + ' |';
  1657.           WriteLn(Lst,tmp_line);
  1658.           count := count + 1;
  1659.           tmp_line := '| '
  1660.         End; { while count }
  1661.       WriteLn(Lst,horiz_line);
  1662.       for i := 1 to 5 do WriteLn(Lst)
  1663.     End; { Sub Proc Print_label }
  1664.  
  1665.   Begin { Write_label Main code }
  1666.     target := ' '; { intialize it }
  1667.     title := False;
  1668.     horiz_line := '+';
  1669.     for i := 1 to 72 do horiz_line := horiz_line + '-';
  1670.     horiz_line := horiz_line + '+';
  1671.     t_line := '|' + copy(horiz_line,2,72) + '|';
  1672.     Locate12;
  1673.     Write('Do you want to write more than one label (Y/N) ? ');
  1674.     numerous := Yes;
  1675.     if not numerous
  1676.       then
  1677.         Begin
  1678.           Locate12;
  1679.           Write('Write a Label for which disk (1-9999, "*" to quit) ? ');
  1680.           ReadLn(target);
  1681.           UpperCase(target);
  1682.           Locate12;
  1683.           Write('Do you want to TITLE the label for Disk #',target,' (Y/N) ? ');
  1684.           title := Yes;
  1685.           if title
  1686.             then
  1687.               Begin
  1688.                 Locate12;
  1689.                 WriteLn('       ',titlel);
  1690.                 Write  ('Title: ');
  1691.                 ReadLn(Titles);
  1692.                 Titles := copy(titles,1,45)
  1693.               End; { if title }
  1694.           Locate12;
  1695.           Cursor(Off);
  1696.           Write('Printing Label .....');
  1697.           if target = '*'
  1698.             then
  1699.               Exit
  1700.             else
  1701.               print_label(target)
  1702.         End { if not numerous }
  1703.       else
  1704.         Begin
  1705.           if Target = '*' then Exit;
  1706.           locate12;
  1707.           Write('Will you be using labels that contain letters AND numbers (Y/N) ? ');
  1708.           alpha := Yes;
  1709.           if alpha
  1710.             then
  1711.               Begin
  1712.                 Cursor(off);
  1713.                 locate12;
  1714.                 Write('Please wait ... ');
  1715.                 Sort_by_Num;
  1716.                 locate12;
  1717.                 WriteLn('Enter disk mask. DOS wildcards, "?" and "*", are supported.');
  1718.                 WriteLn('Examples: MKC1 ... MKC9 = MKC?, MKC1 ... MK99 = MK?? or MK*');
  1719.                 WriteLn('Enter a single "*" to quit.');
  1720.                 Write('Mask: ');
  1721.                 ReadLn(mask);
  1722.                 if mask = '*'then Exit;
  1723.                 Pad_Right(mask,'?',4);
  1724.                 uppercase(mask);
  1725.                 if pos('*',mask) > 0
  1726.                   then
  1727.                     for x := pos('*',mask) to length(mask) do
  1728.                       mask[x] := '?';
  1729.                 locate12;
  1730.                 WriteLn('Printing all "',mask,'" labels. Press any key to abort ...');
  1731.                 WriteLn;
  1732.                 old_target := ' ';
  1733.                 cursor(off);
  1734.                 for x := 1 to entries do
  1735.                   Begin
  1736.                     if copy(files[x],1,4) <> Old_target
  1737.                       then
  1738.                         Begin
  1739.                           match := True;
  1740.                           for y := 1 to 4 do
  1741.                             Begin
  1742.                               if mask[y] <> '?'
  1743.                                 then
  1744.                                   if files[x][y] <> mask[y]
  1745.                                     then
  1746.                                       Begin
  1747.                                         match := False;
  1748.                                         y := 4
  1749.                                       End { if files }
  1750.                             End; { for y := }
  1751.                           if match
  1752.                             then
  1753.                               Begin
  1754.                                 target := copy(files[x],1,4);
  1755.                                 old_target := target;
  1756.                                 GotoXY(1,WhereY);
  1757.                                 Write('Writing Label for Disk ',target);
  1758.                                 print_label(target);
  1759.                                 if exit_flag
  1760.                                   then
  1761.                                     Begin
  1762.                                       WriteLn;
  1763.                                       WriteLn;
  1764.                                       Exit
  1765.                                     End { if Exit }
  1766.                               End { if match }
  1767.                         End { if copy }
  1768.                   End; { for x := }
  1769.                 WriteLn;
  1770.                 WriteLn
  1771.               End { if alpha }
  1772.             else
  1773.               Begin
  1774.                 ok := False;
  1775.                 Repeat { until Ok }
  1776.                   locate12;
  1777.                   Write('Enter beginning disk number (1-9999, "*" to quit) ? ');
  1778.                   ReadLn(targ_b);
  1779.                   if targ_b = '*' then Exit;
  1780.                   WriteLn;
  1781.                   Write('Enter ending disk number (1-9999, "*" to quit) ? ');
  1782.                   ReadLn(targ_e);
  1783.                   if targ_e = '*' then Exit;
  1784.                   val(targ_b,tb,x);
  1785.                   val(targ_e,te,y);
  1786.                   Ok := (x + y = 0)
  1787.                 Until Ok;
  1788.                 locate12;
  1789.                 Cursor(off);
  1790.                 Writeln('Press any key to abort printing ...');
  1791.                 WriteLn;
  1792.                 for count_t := tb to te do
  1793.                   Begin
  1794.                     GotoXY(1,WhereY);
  1795.                     Write('Writing Label for Disk ',target);
  1796.                     Str(count_t,target);
  1797.                     print_label(target);
  1798.                     if exit_flag then Exit
  1799.                   End { for count }
  1800.               End { else if alpha }
  1801.         End { else if not numerous }
  1802.   End; { Proc Write_Label }
  1803.  
  1804. Procedure Do_It; { Essentially the main loop }
  1805.   Begin
  1806.     Get_Cursor;
  1807.     Cursor(Off);
  1808.     Init;
  1809.     Read_Data_From_Disk;
  1810.     Repeat { Until Choice = Q, *, or Esc }
  1811.       if Sort_Flag then Sort_By_Num;
  1812.       ClrScr;
  1813.       Cursor(Off);
  1814.       ShowMenu;
  1815.       Repeat { Until a valid choice is selected }
  1816.         Repeat Until KeyPressed;
  1817.         Read(kbd,choice);
  1818.         choice := UpCase(choice)
  1819.       Until pos(choice,'ABCDFLPQW*' + #27) > 0;
  1820.       Cursor(On);
  1821.       Case choice of
  1822.         'A' : Add;
  1823.         'B' : Backup;
  1824.         'C' : Configure;
  1825.         'D' : Zap;
  1826.         'F' : Find;
  1827.         'L' : List_Records;
  1828.         'P' : Print_List;
  1829.         'W' : Write_Label
  1830.       End { Case of Choice }
  1831.     Until (choice = #27) or (choice = 'Q') or (choice = '*');
  1832.     Set_Cursor(Start_Line,End_Line);
  1833.     ClrScr;
  1834.   End; { Proc Do_It }
  1835.  
  1836. Begin       {     ╒═════════════════════════════════════════╕     }
  1837.   Do_It     {     │                  Main                   │     }
  1838. End.        {     ╘═════════════════════════════════════════╛     }
  1839.