home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol255 / dpm.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-03-22  |  26.9 KB  |  990 lines

  1. program dp;     { Floppy disk  patch program }
  2.                 { Used compiler : Pascal/mt+ }
  3. {-------------------------------------------------------------}
  4. {                                                             }
  5. {       Program Title: Floppy Disk  Patch Program             }
  6. {                                                             }
  7. {       Program  file:  DPM.PAS         ... Main control      }
  8. {                       DPEDIT.PAS      ... Edit module       }
  9. {                       DPIO.PAS        ... I/O  module       }
  10. {                       DPL.CMD         ... Linkage parameter }
  11. {                                                             }
  12. {       Last update : 21-Oct-1984 by K.Maeda                  }
  13. {                                                             }
  14. {           Note : This program was originally written by     }
  15. {               Keizo Maeda and checked (and enhanced) by     }
  16. {               Sakurao Nemoto and is a Public Domain Soft-   }
  17. {               ware (JUG-CP/M). If you make revisions, etc.  }
  18. {               please leave the author and modifiers name    }
  19. {               in the source file. Thank you.                }
  20. {                                                             }
  21. {          Ver-Rev :                                          }
  22. {                       0.0 : 7 July, 83       by  K.Maeda    }
  23. {                       2.0 : 28 July,83                      }
  24. {                             ...check sum...  by  S.Nemoto   }
  25. {                       3.0 : 20 September,83                 }
  26. {                             ...8 inch support...            }
  27. {                       5.3 : 6 November, 83                  }
  28. {                             ...Printing Hard Copy...        }
  29. {                       5.5 : 23 December,83                  }
  30. {                             ...Read EBCDIK code...          }
  31. {                       6.0 : 12 May,84                       }
  32. {                             ...Make File...                 }
  33. {                       6.1 : 18 May,84                       }
  34. {                             ...Exclusive Find...            }
  35. {                       6.2 : 17 June,84                      }
  36. {                       6.3 : 21 October,84                   }
  37. {                             ...beep at print_mode...        }
  38. {                                                             }
  39. {-------------------------------------------------------------}
  40.  
  41.  
  42. type
  43. iooperation  = (get_disk, put_disk);
  44. buffer = array [0..255] of byte ;
  45. ptr = ^integer;
  46.  
  47. var
  48.  
  49.   cmdch:        char;
  50.   sb_last_x,
  51.   sb_last_y:    integer; { for software clr to eol/ clr to eos routines }
  52.  
  53.   cdisk:        integer; { current Drive no. }
  54.  
  55.   ch_drv:       char;    { Input  drive name }
  56.   ch_drv_o:     char;    { Output drive name }
  57.  
  58.   in_drive,in_trk,in_sec,in_skew,          { variables for FD i/o }
  59.   in_trk_num,in_sec_num,
  60.   e_trk,e_sec,
  61.   o_drive,o_trk,o_sec,o_skew,
  62.   o_trk_num,o_sec_num   : integer;
  63.  
  64.   p_drive,p_trk,p_sec,p_skew,
  65.   p_trk_num,p_sec_num   : integer;         { for verify }
  66.  
  67.   skew_tab:   array[0..2,1..52] of byte;   { skew table }
  68.  
  69.   pat :         buffer;
  70.   lng_pat :     integer;
  71.   buff:         array[0..15] of buffer;        { I/O Buffer }
  72.  
  73.  
  74.   flg_85 :      boolean;       { flag for 8 inch <--> 5 inch   }
  75.   fl_type:      string;        { MD1D , MD2D , FD1 , FD2D }
  76.  
  77.   f_exit:       boolean;       { flag of read next  ..EDIT }
  78.  
  79.   ch:           char;
  80.   str:          string;
  81.   delimiter:    char;
  82.   i,j,k:        integer;
  83.  
  84.   noerr:        boolean;       { i/o error flag }
  85.  
  86.   pr_flg ,
  87.   pr2_flg:      boolean;       { flag for Hard Copy }
  88.   ebcdik :      boolean;       { flag for EBCDIK code disk }
  89.  
  90. const
  91.   ctrl_a = $01;
  92.   ctrl_c = $03;
  93.   ctrl_d = $04;
  94.   ctrl_e = $05;
  95.   ctrl_l = $0c;
  96.   ctrl_r = $12;
  97.   ctrl_s = $13;
  98.   ctrl_x = $18;
  99.   esc    = $1b;
  100.   bs     = $08;
  101.   cr     = $0d;
  102.   ctrl_ar= $1e;
  103.   drive_max = 7;
  104.  
  105. external procedure prologue;
  106. external procedure wboot;
  107. external procedure rset_drv;            { reset disk drive }
  108. external procedure set_drive( dr : integer );
  109. external procedure get_buff(var buff:buffer; var noerr:boolean);
  110. external procedure put_buff(var buff:buffer; var noerr:boolean);
  111. external procedure kind_dsk(drive:integer;var ftype:string;
  112.                             var trk_num,sec_num,skew:integer;
  113.                             var noerr:boolean               );
  114. external procedure dump_buff;
  115. external procedure edit_buff;
  116. external procedure wr_buff;
  117. external procedure count_up (var trk,sec,sec_num:integer);
  118. external procedure count_dwn(var trk,sec,sec_num:integer);
  119. external procedure pr_out_ch(ch:char);
  120. external procedure sb_out_ch(ch:char);    { console only }
  121. external procedure lst_out  (ch:char);    { printer only }
  122. external function  sb_getch:char;
  123. external function  sb_up_case(ch:char):char;
  124. external function  sb_stcon : byte;
  125. external procedure xygoto(x,y:integer);
  126. external procedure sb_clr_scrn;
  127. external procedure sb_clr_eos;
  128. external procedure sb_clr_line;
  129. external procedure prnt_at(row,col:integer; s:string);
  130. external procedure hex( x:byte );
  131. external procedure ascii( x:byte );
  132. external procedure hlp_msg;
  133. external function get_str(var str:string; var delimiter:char):integer;
  134. external function get_num(var str:string; delimiter:char):integer;
  135.  
  136. procedure ioerror(iotype : iooperation);
  137. var
  138.   ch : char;
  139. begin
  140.   xygoto(0,18);
  141.   sb_clr_line;
  142.   if iotype=get_disk then
  143.         write([addr(sb_out_ch)],'Read Error occured.')
  144.   else  write([addr(sb_out_ch)],'Write Error occured.');
  145.  
  146.   while (sb_stcon=255) do ch:=sb_getch;
  147.  
  148.  
  149.   write([addr(sb_out_ch)],' Continue (Y/N) ?');
  150.   ch:=sb_up_case(sb_getch);
  151.   sb_out_ch(ch);
  152.   if ch='Y' then noerr:=true else wboot;
  153. end;
  154.  
  155. (*--- change and save   disk access parameters ---*)
  156.  
  157. procedure in_d_rset;    { in_drive,in_trk... -->  p_drive,p_trk.. }
  158. begin
  159.   p_drive:=in_drive;  p_trk:=in_trk;  p_sec:=in_sec;
  160.   p_trk_num:=in_trk_num;   p_sec_num:=in_sec_num;  p_skew:=in_skew
  161. end;
  162.  
  163. procedure in_d_set;     { p_drive,p_trk...  -->  in_drive,in_sec.. }
  164. begin
  165.   in_drive:=p_drive;  in_trk:=p_trk;  in_sec:=p_sec;
  166.   in_trk_num:=p_trk_num;   in_sec_num:=p_sec_num; in_skew:=p_skew
  167. end;
  168.  
  169. procedure out_d_rset;   { in_drive,in_trk... -->  o_drive,o_trk... }
  170. begin
  171.   o_drive:=in_drive;  o_trk:=in_trk;  o_sec:=in_sec;
  172.   o_trk_num:=in_trk_num;   o_sec_num:=in_sec_num; o_skew:=in_skew
  173. end;
  174.  
  175. procedure out_d_set;    { o_drive,o_trk...  -->  in_drive,in_sec.. }
  176. begin
  177.   in_drive:=o_drive;  in_trk:=o_trk;  in_sec:=o_sec;
  178.   in_trk_num:=o_trk_num;   in_sec_num:=o_sec_num; in_skew:=o_skew
  179. end;
  180.  
  181.  
  182. procedure slip;            (* move 1 Sector for making delay  *)
  183. begin
  184.   in_sec:=in_sec-1;
  185.   if in_sec<1  then  in_sec:=in_sec+2;
  186. end;
  187.  
  188.  
  189. procedure menu;
  190. begin
  191.   flg_85:=false;
  192.   sb_clr_scrn;
  193.   if pr_flg then prnt_at(0,78,'*');
  194.  
  195.   prnt_at(1,1,'Floppy Disk Patch Program v6.3 by Kei.M');
  196.   prnt_at(2,1,' Public Domain Soft. 21-Oct-84 JUG-CP/M');
  197.   prnt_at(4,1,'Options:           D)ump  Sector');
  198.   prnt_at(5,20,                  'L)ist  HexDec');
  199.   prnt_at(6,20,                  'E)dit  Sector');
  200.   prnt_at(7,20,                  'C)opy  Sector');
  201.   prnt_at(8,20,                  'V)erify');
  202.   prnt_at(9,20,                  'M)ake  File');
  203.   prnt_at(10,20,                 'F)ind  Pattern');
  204.   prnt_at(11,20,                 'X)clusive Find');
  205.   prnt_at(12,20,                 'R)eset Drive');
  206.   prnt_at(13,20,                 'H)elp');
  207.   prnt_at(14,20,                 'Q)uit');
  208.   prnt_at(22,1,'Command? ');
  209. end;
  210.  
  211. function  dump_menu(msg:string): boolean;
  212. var ch : char;
  213. begin
  214.   sb_clr_scrn;
  215.   if pr_flg then prnt_at(0,78,'*');
  216.  
  217.   prnt_at(2,7,msg);
  218.   prnt_at(4,7,'Drive (A,B,...) : ');
  219.   prnt_at(5,7,'Drive   Type    : ');
  220.   prnt_at(6,7,'Start   Track   : ');
  221.   prnt_at(7,7,'Start   Sector  : ');
  222.  
  223.   repeat
  224.     repeat                                              { Drive }
  225.       xygoto(25,4);
  226.         i:=get_str(str,delimiter);
  227.         if i=1 then ch:=sb_up_case(str[1])
  228.                 else ch:=' ';
  229.         if delimiter=chr(ESC) then begin
  230.                         dump_menu:=true; exit end;
  231.  
  232.         in_drive:=ord(ch)-65;
  233.     until(in_drive >= 0) and (in_drive < drive_max);
  234.  
  235.     ch_drv  :=ch;
  236.     kind_dsk(in_drive,fl_type,in_trk_num,in_sec_num,in_skew,noerr);
  237.   until  noerr ;
  238.  
  239.   if in_trk_num > 40 then flg_85:=true;
  240.  
  241.   xygoto(25,5);
  242.   write([addr(sb_out_ch)],fl_type);
  243.   if in_skew < 0 then begin
  244.   repeat
  245.     prnt_at(5,33,'skew(0,3,6) : ');
  246.     i:=get_str(str,delimiter);
  247.     if delimiter=chr(ESC) then begin
  248.                 dump_menu:=true; exit end;
  249.     in_skew:=get_num(str,' ');
  250.   until (in_skew=0) or (in_skew=3) or (in_skew=6);
  251.  
  252.   in_skew:=in_skew div 3
  253.   end;
  254.  
  255.   repeat                                        { Track }
  256.     xygoto(25,6);
  257.     i:=get_str(str,delimiter);
  258.     if delimiter=chr(ESC) then begin
  259.                 dump_menu:=true; exit end;
  260.     in_trk:=get_num(str,' ');
  261.     xygoto(25,6);
  262.     write([addr(sb_out_ch)],in_trk,'   ');sb_clr_line;
  263.   until (in_trk < in_trk_num);
  264.  
  265.   repeat                                        { Sector }
  266.     xygoto(25,7);
  267.     i:=get_str(str,delimiter);
  268.     if delimiter=chr(ESC) then begin
  269.                 dump_menu:=true; exit end;
  270.     in_sec:=get_num(str,' ');
  271.     xygoto(25,7);
  272.     write([addr(sb_out_ch)],in_sec,'   ');sb_clr_line;
  273.   until (in_sec <= in_sec_num) and (in_sec > 0);
  274.   dump_menu := false;
  275. end;
  276.  
  277.  
  278. procedure dump_proc;
  279. begin
  280.   if dump_menu('+++ Dump +++') then exit;
  281.        pr2_flg:=pr_flg;
  282.        repeat
  283.         get_buff( buff[0],noerr );
  284.          if noerr then begin
  285.          dump_buff; pr_flg:=pr2_flg;
  286.          prnt_at(22,1,
  287.          '<space>: Forward, <bs>: Backward,  P)rint, <esc>: Exit');
  288.          end
  289.            else ioerror(get_disk);
  290.  
  291.            ch:=sb_up_case(sb_getch);
  292.            if ch=chr(ctrl_c) then wboot;
  293.            if ch='P' then begin
  294.                           pr2_flg:=pr_flg;  pr_flg:=true;
  295.                      end;
  296.  
  297.          if ch=chr(bs)
  298.           then count_dwn( in_trk,in_sec,in_sec_num )
  299.           else if ch<>'P'
  300.                then count_up ( in_trk,in_sec,in_sec_num );
  301.           if in_trk>=in_trk_num then begin
  302.                                       in_trk:=in_trk_num-1;
  303.                                       in_sec:=in_sec_num
  304.                                     end;
  305.    until (ch=chr(esc)) or ( not noerr );
  306. end;
  307.  
  308. procedure edit_proc;
  309. begin
  310.    if dump_menu('+++ Edit +++') then exit;
  311.  
  312.    repeat
  313.      out_d_rset;
  314.      get_buff(buff[0],noerr);
  315.      if (not noerr) then ioerror(get_disk);
  316.      move(buff[0],buff[1],256);
  317.  
  318.      pr2_flg:=pr_flg;
  319.      repeat
  320.        dump_buff; pr_flg:=pr2_flg;
  321.  
  322.        f_exit:=false;  { exit flag from repeat loop }
  323.  
  324.        prnt_at(21,0,
  325.      'Command?   E)dit,N)ext,W)rite and next,');
  326.        prnt_at(21,39,
  327.       'B)ackward,R)eturn to original, Q)uit');
  328.        xygoto(8,21);
  329.  
  330.        ch:=sb_up_case(sb_getch);
  331.        if ch=chr(ctrl_c) then wboot;
  332.        if ch='P' then begin
  333.                        pr2_flg:=pr_flg; pr_flg:=true;
  334.                 end;
  335.        if ch <> chr(esc) then sb_out_ch(ch);
  336.  
  337.        case ch of
  338.  
  339.         'E' : edit_buff;
  340.  
  341.         'N' : begin
  342.                 f_exit:=true;
  343.                 count_up( in_trk,in_sec,in_sec_num);
  344.                 if in_trk>=in_trk_num then begin
  345.                                            in_trk:=in_trk_num-1;
  346.                                            in_sec:=in_sec_num
  347.                                       end;
  348.               end;
  349.         'B' : begin
  350.                 f_exit:=true;
  351.                 count_dwn(in_trk,in_sec,in_sec_num);
  352.               end;
  353.         'R' : move( buff[1],buff[0],256 );
  354.  
  355.         'W' : wr_buff;
  356.  
  357.         'Q' : f_exit:=true;
  358.  
  359.         end;
  360.       until f_exit;
  361.     until  (ch='Q');
  362. end;
  363.  
  364. procedure ver_proc;
  365. begin
  366.   if copy_menu('+++ Verify +++') then exit;
  367.   in_d_rset;
  368.  
  369.   repeat
  370.      get_buff(buff[1],noerr);
  371.      if (not noerr) then ioerror(get_disk);
  372.      out_d_set;
  373.      get_buff(buff[0],noerr);
  374.      if (not noerr) then ioerror(get_disk);
  375.      in_d_set;
  376.  
  377.      xygoto(1,22);
  378.      write([addr(sb_out_ch)],
  379.      'Verifing    Drive:',ch_drv,',  Tr',in_trk:2,',  Sc',in_sec:2,
  380.      '  and    Drive:',ch_drv_o,',  Tr',o_trk:2,',  Sc',o_sec:2) ;
  381.  
  382.   { verify }
  383.      ch:=' ' ; i:=0 ; j:=-1 ; repeat
  384.      if buff[0][i] <> buff[1][i]    then  j:=i;
  385.      i:=i+1;
  386.   until ( i >= 256 ) or ( j >= 0 );
  387.   if j >= 0 then
  388.   begin
  389.     if pr_flg then
  390.        write([addr(lst_out)],
  391.        'Unmatching. Drive:',ch_drv,', Tr',in_trk:2,', Sc',in_sec:2,
  392.        ' <---> Drive:',ch_drv_o,', Tr',o_trk:2,', Sc',o_sec:2,', Addr ');
  393.  
  394.     xygoto(1,20);
  395.     write([addr(sb_out_ch)],'Unmatching at ');
  396.     hex(j);
  397.     if pr_flg then
  398.        writeln([addr(lst_out)]);
  399.  
  400.  
  401.     write([addr(sb_out_ch)],
  402.      '.  Continue ?      <space>: next, <esc>: exit');
  403.     ch:=sb_getch
  404.   end;
  405.   count_up(in_trk,in_sec,in_sec_num);
  406.   count_up(o_trk, o_sec, o_sec_num );
  407.   in_d_rset;
  408.   until cend or (ch=chr(esc));
  409. end;
  410.  
  411.  
  412. function  copy_menu(msg:string): boolean;
  413. var ch : char;
  414. begin
  415.   sb_clr_scrn;
  416.   if pr_flg then prnt_at(0,78,'*');
  417.  
  418.   prnt_at(1,7,msg);
  419.   prnt_at(3,4,'Input disk');
  420.   prnt_at(4,7,   'Drive (A,B,...) : ');
  421.   prnt_at(5,7,   'Drive   Type    : ');
  422.   prnt_at(6,7,   'Start   Track   : ');
  423.   prnt_at(7,7,   'Start   Sector  : ');
  424.   prnt_at(8,7,   'End     Track   : ');
  425.   prnt_at(9,7,   'End     Sector  : ');
  426.  
  427.   prnt_at(11,4,'Output or Verify disk');
  428.   prnt_at(12,7,   'Drive (A,B,...) : ');
  429.   prnt_at(13,7,   'Drive   Type    : ');
  430.   prnt_at(14,7,   'Start   Track   : ');
  431.   prnt_at(15,7,   'Start   Sector  : ');
  432.  
  433.   repeat
  434.     repeat
  435.     repeat
  436.       xygoto(25,4);
  437.         i:=get_str(str,delimiter);
  438.         if i=1 then ch:=sb_up_case(str[1])
  439.                 else ch:=' ';
  440.         if delimiter=chr(ESC) then begin
  441.                         copy_menu:=true; exit end;
  442.  
  443.         in_drive:=ord(ch)-65;
  444.      until (in_drive >= 0) and (in_drive < drive_max);
  445.       ch_drv:=ch;
  446.       kind_dsk(in_drive,fl_type,in_trk_num,in_sec_num,in_skew,noerr);
  447.     until noerr ;
  448.     if in_trk_num > 40 then flg_85:=true;
  449.  
  450.     xygoto(25,5);
  451.     write([addr(sb_out_ch)],fl_type);
  452.     if in_skew < 0 then begin
  453.     repeat
  454.         prnt_at(5,33,'skew(0,3,6) : ');
  455.         i:=get_str(str,delimiter);
  456.         in_skew:=get_num(str,' ');
  457.     until (in_skew=0) or (in_skew=3) or (in_skew=6);
  458.  
  459.     in_skew:=in_skew div 3
  460.     end;
  461.  
  462.  
  463.     repeat
  464.         xygoto(25,6);
  465.         i:=get_str(str,delimiter);
  466.         in_trk:=get_num(str,' ');
  467.         xygoto(25,6);
  468.         write([addr(sb_out_ch)],in_trk,'   '); sb_clr_line;
  469.     until (in_trk < in_trk_num);
  470.  
  471.     repeat
  472.         xygoto(25,7);
  473.         i:=get_str(str,delimiter);
  474.         in_sec:=get_num(str,' ');
  475.         xygoto(25,7);
  476.         write([addr(sb_out_ch)],in_sec,'   '); sb_clr_line;
  477.     until (in_sec <= in_sec_num) and (in_sec > 0);
  478.  
  479.     repeat
  480.         xygoto(25,8);
  481.         i:=get_str(str,delimiter);
  482.         e_trk:=get_num(str,' ');
  483.         xygoto(25,8);
  484.         write([addr(sb_out_ch)],e_trk,'   ');sb_clr_line;
  485.     until(e_trk >= in_trk) and (e_trk < in_trk_num);
  486.  
  487.     repeat
  488.         xygoto(25,9);
  489.         i:=get_str(str,delimiter);
  490.         e_sec:=get_num(str,' ');
  491.         xygoto(25,9);
  492.         write([addr(sb_out_ch)],e_sec,'   ');sb_clr_line;
  493.     until (e_sec <= in_sec_num) and (e_sec > 0);
  494.  
  495.     repeat
  496.     repeat
  497.         xygoto(25,12);
  498.         i:=get_str(str,delimiter);
  499.         if i=1 then ch:=sb_up_case(str[1])
  500.                 else ch:=' ';
  501.         if delimiter=chr(ESC) then begin
  502.                         copy_menu:=true; exit end;
  503.  
  504.         o_drive:=ord(ch)-65;
  505.      until (o_drive >= 0) and (o_drive < drive_max);
  506.       ch_drv_o:=ch;
  507.       kind_dsk(o_drive,fl_type,o_trk_num,o_sec_num,o_skew,noerr);
  508.     until noerr;
  509.     if o_trk_num > 40 then flg_85:=true;
  510.  
  511.     xygoto(25,13);
  512.     write([addr(sb_out_ch)],fl_type);
  513.     if o_skew < 0 then begin
  514.     repeat
  515.         prnt_at(13,33,'skew(0,3,6) : ');
  516.         i:=get_str(str,delimiter);
  517.         o_skew:=get_num(str,' ');
  518.     until (o_skew=0) or (o_skew=3) or (o_skew=6);
  519.  
  520.     o_skew:=o_skew div 3
  521.     end;
  522.  
  523.  
  524.     repeat
  525.         xygoto(25,14);
  526.         i:=get_str(str,delimiter);
  527.         o_trk:=get_num(str,' ');
  528.         xygoto(25,14);
  529.         write([addr(sb_out_ch)],o_trk,'   '); sb_clr_line;
  530.     until (o_trk < o_trk_num);
  531.  
  532.     repeat
  533.         xygoto(25,15);
  534.         i:=get_str(str,delimiter);
  535.         o_sec:=get_num(str,' ');
  536.         xygoto(25,15);
  537.         write([addr(sb_out_ch)],o_sec,'   '); sb_clr_line;
  538.     until (o_sec <= o_sec_num) and (o_sec > 0);
  539.  
  540.     prnt_at(22,1,'Ready (Y/N) :');
  541.     ch:=sb_up_case( sb_getch );
  542.     if ch=chr(ctrl_c)  then  wboot;
  543.     sb_out_ch(ch);
  544.   until ch='Y' ;
  545.   copy_menu := false;
  546. end;
  547.  
  548. function cend: boolean ;  { detect copy end }
  549. var flag: boolean ;
  550. begin
  551.   flag:=false;
  552.   if in_trk > e_trk       then flag:=true;
  553.   if (in_trk = e_trk)     and
  554.      (in_sec > e_sec)     then flag:=true;
  555.   if (o_trk >= o_trk_num) then flag:=true;
  556.   cend:=flag
  557. end;
  558.  
  559. procedure copy_proc;
  560. begin
  561.   if copy_menu('+++ Copy +++') then exit;
  562.   repeat
  563.         get_buff( buff[0],noerr );
  564.         if ( not noerr ) then ioerror(get_disk);
  565.  
  566.         in_d_rset;  out_d_set;  {  parm  in->p , o->in }
  567.         slip;
  568.         put_buff( buff[0],noerr );
  569.         if ( not noerr )   then ioerror(put_disk);
  570.         if flg_85 then get_buff( buff[0],noerr );      { get after put }
  571.         if ( not noerr )   then ioerror(put_disk);
  572.         in_d_set;               {  parm  p->in  }
  573.         xygoto(1,22);
  574.         write([addr(sb_out_ch)],
  575.               'Copied from  Drive:',ch_drv,',  Tr',in_trk:2,',  Sc',in_sec:2,
  576.               '  ...to...   Drive:',ch_drv_o,',  Tr',o_trk:2, ',  Sc',o_sec:2);
  577.  
  578.         count_up(in_trk,in_sec,in_sec_num);
  579.         count_up(o_trk, o_sec, o_sec_num );
  580.   until cend ;
  581. end;
  582.  
  583. function  dup_menu(msg:string): boolean;
  584. var ch : char;
  585. begin
  586.   sb_clr_scrn;
  587.   if pr_flg then prnt_at(0,78,'*');
  588.  
  589.   prnt_at(1,7,msg);
  590.   prnt_at(3,4,'Input disk');
  591.   prnt_at(4,7,   'Drive (A,B,...) : ');
  592.   prnt_at(5,7,   'Drive   Type    : ');
  593.   prnt_at(6,7,   'Start   Track   : ');
  594.   prnt_at(7,7,   'Start   Sector  : ');
  595.   prnt_at(8,7,   'End     Track   : ');
  596.   prnt_at(9,7,   'End     Sector  : ');
  597.  
  598.  
  599.     repeat
  600.     repeat
  601.         xygoto(25,4);
  602.         i:=get_str(str,delimiter);
  603.         if i=1 then ch:=sb_up_case(str[1])
  604.                 else ch:=' ';
  605.         if delimiter=chr(ESC) then begin
  606.                         dup_menu := true; exit end;
  607.  
  608.         in_drive:=ord(ch)-65;
  609.      until (in_drive >= 0) and (in_drive < drive_max);
  610.       ch_drv:=ch;
  611.       kind_dsk(in_drive,fl_type,in_trk_num,in_sec_num,in_skew,noerr);
  612.     until noerr ;
  613.     if in_trk_num > 40 then flg_85:=true;
  614.  
  615.     xygoto(25,5);
  616.     write([addr(sb_out_ch)],fl_type);
  617.     if in_skew < 0 then begin
  618.     repeat
  619.         prnt_at(5,33,'skew(0,3,6) : ');
  620.         i:=get_str(str,delimiter);
  621.         in_skew:=get_num(str,' ');
  622.     until (in_skew=0) or (in_skew=3) or (in_skew=6);
  623.  
  624.     in_skew:=in_skew div 3
  625.     end;
  626.  
  627.  
  628.     repeat
  629.         xygoto(25,6);
  630.         i:=get_str(str,delimiter);
  631.         in_trk:=get_num(str,' ');
  632.         xygoto(25,6);
  633.         write([addr(sb_out_ch)],in_trk,'   ');sb_clr_line;
  634.     until (in_trk < in_trk_num);
  635.  
  636.     repeat
  637.         xygoto(25,7);
  638.         i:=get_str(str,delimiter);
  639.         in_sec:=get_num(str,' ');
  640.         xygoto(25,7);
  641.         write([addr(sb_out_ch)],in_sec,'   ');sb_clr_line;
  642.     until (in_sec <= in_sec_num) and (in_sec > 0);
  643.  
  644.     repeat
  645.         xygoto(25,8);
  646.         i:=get_str(str,delimiter);
  647.         e_trk:=get_num(str,delimiter);
  648.         xygoto(25,8);
  649.         write([addr(sb_out_ch)],e_trk,'   ');sb_clr_line;
  650.     until(e_trk >= in_trk) and (e_trk < in_trk_num);
  651.  
  652.     repeat
  653.         xygoto(25,9);
  654.         i:=get_str(str,delimiter);
  655.         e_sec:=get_num(str,delimiter);
  656.         xygoto(25,9);
  657.         write([addr(sb_out_ch)],e_sec,'   ');sb_clr_line;
  658.     until (e_sec <= in_sec_num) and (e_sec > 0);
  659.     dup_menu := false;
  660.  
  661. end;
  662.  
  663. procedure lt_proc;
  664. var
  665.   ch: char;
  666.   ii: integer;
  667. begin
  668.     repeat
  669.         if dup_menu('+++ List +++') then exit;
  670.         prnt_at(22,1,'Ready (Y/N) :');
  671.         ch:=sb_up_case( sb_getch );
  672.         if ch=chr(ctrl_c)  then  wboot;
  673.         if ch=chr(ESC)     then  exit;
  674.         sb_out_ch(ch);
  675.     until ch='Y' ;
  676.  
  677.     o_trk:=0; o_trk_num:=1;
  678.     repeat
  679.         get_buff( buff[0],noerr );
  680.         if noerr then dump_buff else ioerror(get_disk);
  681.         count_up(in_trk,in_sec,in_sec_num);
  682.  
  683.         ii:=sb_stcon;
  684.     until (ii=255) or cend;
  685.  
  686.     if ii=255 then ch:=sb_getch;
  687.     while (sb_stcon=255) do ch:=sb_getch;
  688. end;
  689.  
  690. procedure search;
  691. var
  692.   i,j,k: integer;
  693.   ch : char;
  694. begin
  695.   { first character }
  696.   i:=0; j:=0;
  697.  
  698.   repeat
  699.  
  700.         write([addr(sb_out_ch)],'Searching Tr',
  701.         in_trk:2,',  Sc',in_sec:2); sb_out_ch(chr(CR));
  702.  
  703.  
  704.         while (buff[0][i]<>pat[j]) and (i<256) do i:=i+1;
  705.         if i>=256 then exit; { not found }
  706.  
  707.   { another character }
  708.         k:=i+1; j:=j+1;
  709.         while (buff[0][k]=pat[j]) and (j<lng_pat)
  710.         do begin
  711.                 k:=k+1;
  712.                 j:=j+1;
  713.         end;
  714.  
  715.         if j>=lng_pat then begin        {--- found ---}
  716.                 write([addr(pr_out_ch)],'Found at  Tr',
  717.                 in_trk:2,',  Sc',in_sec:2,',  Addr ');
  718.                 hex(lo(i)); writeln([addr(pr_out_ch)])
  719.         end;
  720.  
  721.         j:=0;
  722.         i:=i+1;
  723.   until (sb_stcon=255) or (i>=256);
  724. end;
  725.  
  726. procedure fnd_pat;
  727. var
  728.   fmode   : char;
  729.   upv,lov : integer;
  730.   i,ii    : integer;
  731.   ch : char;
  732. begin
  733.     repeat
  734.         if dup_menu('+++ Find +++') then exit;
  735.         prnt_at(13,1,'H)ex or S)tring : ');
  736.         ch:=sb_up_case( sb_getch );
  737.         if ch=chr(ctrl_c)  then  wboot;
  738.         if ch=chr(ESC) then exit;
  739.         sb_out_ch(ch);
  740.         if ch='H' then write([addr(sb_out_ch)],'ex');
  741.         if ch='S' then write([addr(sb_out_ch)],'tring');
  742.  
  743.     until (ch='H') or (ch='S');
  744.  
  745.     fmode:=ch;
  746.  
  747.     prnt_at(15,1,'Pattern : ');
  748.     i:=get_str(str,delimiter);
  749.     if (i=0) or (delimiter=chr(ESC)) then exit;
  750.  
  751.     if pr_flg then begin
  752.         writeln([addr(lst_out)]);
  753.         if fmode='H' then write([addr(lst_out)],'Hex')
  754.                      else write([addr(lst_out)],'String');
  755.         writeln([addr(lst_out)],' Pattern : ',str);
  756.         writeln([addr(lst_out)]);
  757.     end;
  758.  
  759.  
  760.     xygoto(0,17);
  761.     if fmode='S' then begin
  762.                         lng_pat:=i;
  763.                         for i:=1 to lng_pat do
  764.                                 pat[i-1]:=ord(str[i]); end
  765.     else begin
  766.         lng_pat:=(i+1) div 2;
  767.         if lng_pat<>(i div 2) then str:=concat('0',str);
  768.         for i:=0 to lng_pat do
  769.           begin
  770.                 ch:=sb_up_case( str[i*2+1] );
  771.                 if (ch>='0') and (ch<='9')
  772.                 then upv:=ord(ch)-48
  773.                 else if (ch>='A') and (ch<='F')
  774.                      then upv:=ord(ch)-55
  775.                      else upv:=0;
  776.  
  777.                 ch:=sb_up_case( str[i*2+2] );
  778.                 if (ch>='0') and (ch<='9')
  779.                 then lov:=ord(ch)-48
  780.                 else if (ch>='A') and (ch<='F')
  781.                      then lov:=ord(ch)-55
  782.                 else lov:=0;
  783.  
  784.                 pat[i] := upv*16 + lov;
  785.           end;
  786.     end;
  787.  
  788.  
  789.     o_trk:=0; o_trk_num:=1;
  790.     repeat
  791.         get_buff( buff[0],noerr );
  792.         if (not noerr) then ioerror(get_disk);
  793.         count_up(in_trk,in_sec,in_sec_num);
  794.         if (not cend ) then
  795.           get_buff( buff[1],noerr );
  796.           if (not noerr) then ioerror(get_disk);
  797.  
  798.         count_dwn(in_trk,in_sec,in_sec_num);
  799.         search;
  800.         count_up( in_trk,in_sec,in_sec_num);
  801.  
  802.         ii:=sb_stcon; (* key press ? *)
  803.     until (ii=255) or cend;
  804.     if ii=255 then ch:=sb_getch;
  805.  
  806.     while (sb_stcon=255) do ch:=sb_getch;
  807.  
  808.     writeln([addr(sb_out_ch)]);
  809.     write([addr(sb_out_ch)],'Hit any key'); ch:=sb_getch;
  810. end;
  811.  
  812. procedure ex_fnd;
  813. var
  814.   upv,lov : integer;
  815.   i,ii    : integer;
  816.   ch      : char;
  817. begin
  818.   if dup_menu('+++ Ex Find +++') then exit;
  819.   prnt_at(13,0,'HexDec Byte Data : ');
  820.   i:=get_str(str,delimiter);
  821.   if (i=0) or (delimiter=chr(ESC)) then exit;
  822.  
  823.   str[1] := sb_up_case( str[1] );
  824.   str[2] := sb_up_case( str[2] );
  825.  
  826.   if (str[1]>='0') and (str[1]<='9')
  827.   then upv:=ord(str[1])-48
  828.   else if (str[1]>='A') and (str[1]<='F')
  829.     then upv:=ord(str[1])-55
  830.     else upv:=0;
  831.  
  832.   if (str[2]>='0') and (str[2]<='9')
  833.   then lov:=ord(str[2])-48
  834.   else if (str[2]>='A') and (str[2]<='F')
  835.     then lov:=ord(str[2])-55
  836.     else lov:=0;
  837.  
  838.   pat[0]:= upv*16 + lov;
  839.  
  840.   xygoto(0,12);
  841.   writeln([addr(pr_out_ch)]);
  842.   write([addr(pr_out_ch)],'Exclusive Find Code : ');
  843.     hex( pat[0] );
  844.   write([addr(pr_out_ch)],'   ');
  845.     ascii( pat[0] );
  846.   writeln([addr(pr_out_ch)]);
  847.   writeln([addr(pr_out_ch)]);
  848.  
  849.  
  850.     xygoto(0,17);
  851.     o_trk:=0; o_trk_num:=1;
  852.     repeat
  853.         get_buff( buff[0],noerr );
  854.         if (not noerr) then ioerror(get_disk);
  855.         x_search;
  856.         count_up( in_trk,in_sec,in_sec_num);
  857.  
  858.         ii:=sb_stcon; (* key press ? *)
  859.     until (ii=255) or cend;
  860.     if ii=255 then ch:=sb_getch;
  861.  
  862.     while (sb_stcon=255) do ch:=sb_getch;
  863.  
  864.     writeln([addr(sb_out_ch)]);
  865.     write([addr(sb_out_ch)],'Hit any key'); ch:=sb_getch;
  866. end;
  867.  
  868. procedure x_search;
  869. var
  870.   i,j,k: integer;
  871.   ch : char;
  872. begin
  873.   write([addr(sb_out_ch)],'Searching Tr',
  874.   in_trk:2,',  Sc',in_sec:2); sb_out_ch(chr(CR));
  875.  
  876.   i:=0;
  877.   while (buff[0][i]=pat[0]) and (i<256) do i:=i+1;
  878.  
  879.   if i<256 then begin
  880.         write([addr(pr_out_ch)],'Found at  Tr',
  881.         in_trk:2,',  Sc',in_sec:2,',  Addr ');
  882.         hex(lo(i)); writeln([addr(pr_out_ch)]);
  883.   end;
  884.  
  885. end;
  886.  
  887.  
  888. procedure mk_proc;
  889. var
  890.   dfile : file;
  891.   ofnam : string;
  892.   delimiter : char;
  893.   ii,result : integer;
  894.   irec,orec : integer;
  895.   qt : boolean;
  896. begin
  897.   rset_drv; { reset drive }
  898.   repeat
  899.     if dup_menu('+++ Make File +++') then exit;
  900.  
  901.         repeat
  902.         repeat
  903.           prnt_at(13,1,'Output Drive : ');
  904.           i:=get_str(str,delimiter);
  905.           if i=1 then ch:=sb_up_case(str[1])
  906.                   else ch:=' ';
  907.           if delimiter=chr(ESC) then exit;
  908.           o_drive:=ord(ch)-65;
  909.          until (o_drive >= 0) and (o_drive < 6);
  910.           ch_drv_o:=ch;
  911.           kind_dsk(o_drive,fl_type,o_trk_num,o_sec_num,o_skew,noerr);
  912.         until noerr;
  913.  
  914.         prnt_at(14,1,'File Name : ');
  915.         ii:=get_str(ofnam,delimiter);
  916.         if delimiter=chr(ESC) then exit;
  917.   until ii>0;
  918.  
  919.     xygoto(0,15);
  920.     o_trk:=0; o_trk_num:=1;
  921.     set_drive( o_drive );
  922.  
  923.     assign( dfile,ofnam );
  924.     rewrite(dfile);
  925.  
  926.     orec := 0;
  927.     repeat
  928.       irec := 0;
  929.       repeat
  930.         write([addr(sb_out_ch)],'Reading   Tr',
  931.         in_trk:2,',  Sc',in_sec:2,chr(CR));
  932.         get_buff( buff[irec],noerr );
  933.         if not noerr then ioerror(get_disk);
  934.         count_up(in_trk,in_sec,in_sec_num);
  935.         irec := irec + 1;
  936.         qt := cend;
  937.       until qt or (irec > 15);
  938.  
  939.       set_drive( o_drive );
  940.  
  941.       write([addr(sb_out_ch)],'Writing ......           ',chr(CR));
  942.  
  943.       blockwrite( dfile,buff[0],result,256*irec,orec);
  944.       if result<>0 then begin
  945.             ioerror(put_disk); exit end;
  946.       orec := orec + irec*2;
  947.       if not qt then
  948.          blockwrite( dfile,buff[0],result,256,orec );
  949.     until qt;
  950.     close( dfile,result );
  951. end;
  952.  
  953.  
  954.  
  955.  
  956. { ==============  main procedure =============== }
  957.  
  958. begin
  959.   prologue;
  960.   repeat
  961.     menu;
  962.     cmdch:=sb_up_case(sb_getch);
  963.     if cmdch>=' ' then sb_out_ch(cmdch);
  964.  
  965.     case cmdch of
  966.  
  967.     'D' : dump_proc;
  968.     'E' : edit_proc;
  969.     'H' : hlp_msg;
  970.  
  971.     'C' : copy_proc;
  972.  
  973.     'V' : ver_proc;
  974.     'L' : lt_proc;
  975.  
  976.     'M' : mk_proc;
  977.  
  978.     'F' : fnd_pat;
  979.  
  980.     'X' : ex_fnd;  { May 18, 84 }
  981.  
  982.     'R' : rset_drv; {------ Reset Drive ------}
  983.  
  984.         end;  { case of cmdch }
  985.  
  986.       until (cmdch='Q') or (cmdch=chr(ctrl_c));
  987.  
  988.       wboot
  989. end.
  990.