%include "Inc:UTIL.Imp"
%include "DISQIO.INC"
%externalroutinespec show disq status

%constinteger track size = 32
%constinteger blocks = 2 * 256 * 4 * 16
%constinteger limit = 1000 000

%ownintegerarray b(0 : 32 * 128) = 16_AAAAAAAA (*)

%externalroutine pdate
  printstring(time); space
%end

%integerfn do read(%integer start, blocks)
   %integername x
   %integer wanted, c
try again:
      wanted = blocks << 9
      c = limit
      x == transfer(D write ! D verify, wanted, start << 9, b(0))
      c = c - 1 %while x = 0 %and c > 0
      %if c <= 0 %start
         printstring("Disc timeout");  newline
         show disq status
         -> try again
      %else %unless x = wanted
         %result = -1
      %finish
      c = limit
      x == transfer(D read ! D verify, wanted, start << 9, b(0))
      c = c - 1 %while x = 0 %and c > 0
      %if c <= 0 %start
         printstring("Disc timeout");  newline
         show disq status
         -> try again
      %else %if x = wanted
         %result = 0
      %else
         %result = -1
      %finish
%end

%routine error(%integer block)
   %owninteger errors = 0
      errors = errors + 1
      printstring("Error ");  write(errors, 0)
      printstring(": unable to read block ");  write(block, 0)
      newline
      select output(3)
      printstring("Error ");  write(errors, 0)
      printstring(": unable to read block ");  write(block, 0)
      newline
      select output(0)
%end

%routine try one(%integer block)
   %integer x
      write(block,0);newline
      x = do read(block, 1)
      error(block) %if x # 0
%end          

%routine try several(%integer start, blocks)
   %integer i, x
      %if start & (16 * 32 - 1) = 0 %start
         pdate
         printstring("Cylinder ")
         write(start >> 9, 0)
         newline
      %finish
      x = do read(start, blocks)
      %return %if x = 0
{}printsymbol(7)
      try one(i) %for i = start, 1, start + blocks - 1
%end

%begin
   %constinteger chunk = track size; !16
   %integer i
   %string(255)log
      log = cliparam
      log = "BAD.DAT" %if log=""
      open output(3, log)
      select output(3)
      printstring("Bad block run starting at ")
      pdate; newline
      select output(0)
      try several(i, chunk) %for i = 0, chunk, blocks - chunk
      select output(3)
      printstring("Bad block run finished at ")
      pdate; newline
      close output
      select output(0)
%end %of %program
