home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol148 / erase.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1984-04-29  |  5.1 KB  |  209 lines

  1. .po 0
  2. PROGRAM ERASE;
  3. { This program will erase only files that show in the directory. It will
  4. not touch any file that is R/O or SYS. }
  5.  
  6.  
  7. TYPE
  8.     byte=0..255;
  9.     string12=packed array [1..12] of char;
  10.  
  11.     registers=record
  12.         a:0..255;        { A register }
  13.         bc,de,hl:integer    { BC, DE, HL registers }
  14.     end;
  15. {**********************************************************************}
  16.  
  17. VAR
  18.     currentdisk { disk user is logged into },
  19.     dircode     { return code from CP/M }        :byte;
  20.  
  21.     found    :boolean;    { found a directory file to delete }
  22.     reg    :registers;
  23. {**********************************************************************}
  24.  
  25. { call is provided on Pascal/Z source disk.  CALL the memory
  26.     location pointed to by 'address' with the values in the required
  27.     registers. }
  28.  
  29. procedure call(var regs:registers;address:integer);external;
  30.  
  31. {***********************************************************************}
  32.  
  33. {* You can find the assembler source for peek and poke written by      *
  34.  * Ray Penley in the PascalZ Users Group Newsletter #14, Sept., 1982   *
  35.  * on page 5                                                           *}
  36.  
  37. function peek (address:integer):byte;external;
  38.  
  39. procedure poke (address:integer;abyte:byte);external;
  40.  
  41. {***********************************************************************}
  42.  
  43. procedure directory(var dircode:byte;var title:string12);
  44. const
  45.     srchfst=17;        { CP/M function code = search first }
  46.     srchnxt=18;        { CP/M function code = search next }
  47.     delfile=19;        { CP/M function code = delete file }
  48.     bdos=5;            { CP/M BDOS entry point }
  49.     eodir=255;        { end of directory flag }
  50. {=======================================================================}
  51.  
  52. var
  53.     ch    :char;        
  54.     fcb    :integer;    { address of the file control block }        
  55.     i    :byte;        { indexer }
  56.     dirptr    :integer;
  57.     func    :integer;    { function code to be passed to CP/M }
  58. {========================================================================}
  59.  
  60. procedure search(var dircode:byte;func:integer);
  61. begin
  62.     fcb:=92;
  63.     reg.de:=fcb;
  64.     reg.bc:=func;
  65.     call(reg,bdos);
  66.     dircode:=reg.a
  67. end;
  68. {========================================================================}
  69.  
  70. { This procedure does the actual deleting of files that are DIR and R/W. }
  71.  
  72. procedure eraser;
  73. begin
  74.  
  75. { If the high bit is set for any of the three characters used for file type
  76.     then the particular file in question is not DIR and R/W. }
  77.  
  78.     if (peek(dirptr+9) < 128) and (peek(dirptr+10) < 128) and
  79.         (peek(dirptr+11) < 128) then begin
  80.     
  81.     reg.de:=dirptr;
  82.     reg.bc:=delfile;
  83.     call(reg,bdos);        { delete the file when DIR and R/W }
  84.     dircode:=reg.a;
  85.  
  86.     found:=true        { found a file to delete }
  87.     
  88.     end {if}
  89. end;
  90. {==========================================================================}
  91.  
  92. begin  {directory}
  93.     found:=false;
  94.  
  95. { First find out what drive the user is logged into and save }
  96.     reg.a    :=0;
  97.     reg.bc    :=25;        { CP/M return current disk function }
  98.     reg.de    :=0;        
  99.     reg.hl    :=0000;
  100.     call(reg,5);
  101.     currentdisk:=reg.a;
  102.  
  103. { set up the address at which we wish to leave anything that CP/M reads
  104.    from the disk to 80H = 128 dec }    
  105.     reg.a    :=0;
  106.     reg.bc    :=26;         { CP/M set DMA address function}
  107.     reg.de    :=128;         {to 80H}
  108.     reg.hl    :=0000;
  109.     call(reg,5);
  110.     
  111.     fcb:=92;        { set pointer to the default file control 
  112.                 block at memory location 5CH = 92 dec }
  113.     
  114.     for i:=1 to 12 do begin
  115.         poke(fcb,ord(title[i]));
  116.         fcb:=fcb+1
  117.     end;
  118.  
  119.     func:=srchfst;
  120.     search(dircode,func);
  121.  
  122.     func:=srchnxt;
  123.  
  124. { set the directory pointer at the start of information received from the
  125.   directory and erase DIR, R/W files }
  126.     while dircode <> eodir do begin
  127.         dirptr:=128 + (dircode*32);
  128.         eraser;
  129.         search(dircode,func)
  130.     end {while}
  131.  
  132. end {directory};
  133.  
  134. {*******************************************************************}
  135.  
  136. { Process the directory list for selected drive }
  137.  
  138. procedure list;
  139. var     
  140.     title:string12;
  141.     ch:char;
  142.     i:byte;
  143. {=====================================================================}
  144.  
  145. { Converts all letters to uppercase }
  146. function toupper(ch:char):char;
  147. begin
  148.     if ('a' <= ch) and (ch <= 'z') then
  149.         toupper:=chr(ord(ch)-32)
  150.     else
  151.         toupper:=ch
  152. end;
  153. {=====================================================================}
  154.  
  155. begin { list procedure }
  156.  
  157.     title:='0???????????';    { 12 chars. 1st char = drive unit }
  158.  
  159. { I have inserted a clear screen for my terminal (an ADDS Regent 40)
  160.   at this point }
  161.     write(chr(12)); 
  162.     writeln; writeln; 
  163.     write('Erase directory files on what drive (A thru P)? ');
  164.     readln(ch);
  165.     ch:=toupper(ch);
  166.  
  167. { Construct the proper binary unit identifier:
  168.     1 = drive A
  169.     2 = drive B
  170.     .
  171.     .
  172.     16 = drive P                           }
  173.  
  174.     title[1]:=chr(ord(ch)-ord('@'));
  175.  
  176. { Log on to the drive that files are to be deleted on }
  177.     reg.a    :=0;
  178.     reg.bc    :=14;        { select disk }
  179.     reg.de    :=ord(title[1]) - 1;
  180.     reg.hl    :=0000;
  181.     call(reg,5);
  182.  
  183.     writeln;
  184.  
  185. { Repeat finding and erasing files until end of directory and no other
  186.   files are found to delete. }
  187.     repeat
  188.         directory (dircode,title)
  189.     until (found=false) and (dircode=255);
  190.  
  191. { Return to the user logged in disk }
  192.     reg.a    :=0;
  193.     reg.bc    :=14;        { select disk }
  194.     reg.de    :=currentdisk;
  195.     reg.hl    :=0000;
  196.     call(reg,5)
  197.  
  198. end;
  199.  
  200. {*******************************************************************}
  201.  
  202. { This is where the program begins. }
  203.  
  204. {$C+}{enable control-c from the keyboard}
  205.  
  206. BEGIN
  207.     list
  208. END.
  209.