! BADDUMP, a program for dumping out a filestore's bad block list.
! (This will all be a thing of the past with the new discs....)
! GDMR, 14/02/86

%constinteger heads     =   16
%constinteger sectors   =   32
%constinteger cylinders = 1024

%include "INC:UTIL.IMP"
%include "SYSTEM:CONFIG.INC"

%constinteger bad limit = 512 - 3
%recordformat bad fm((%integer stamp, %integerarray bad(1 : bad limit),
                      %integer last bad, checksum) %c
                 %or %integerarray x(1 : 512))

%integerfn bad checksum(%record(bad fm)%name b)
   ! Calculate the checksum for the bad block lists
   %integer i, c
      c = 0
      c = c + b_x(i) %for i = 1, 1, 512
      %result = c
%end

%ownrecord(bad fm)%name bad block list

%routine analyse directories(%integer p)
   %integer i, start, finish, e = 0, n, c, h, s
      start = pd start(p);  finish = pd start(p) + dp size - 1
      %for i = 1, 1, bad block list_last bad %cycle
         n = bad block list_bad(i)
         %exit %if n > finish
         %if n >= start %start
            printstring("        directory");  write((n - start) // dir size, 3)
            printstring("  (")
            write(n, 6);  printstring(" physical,")
            h = n // sectors;  s = rem(n, sectors)
            c = h // heads;  h = rem(h, heads)
            write(c, 4);  print symbol('C')
            write(h, 2);  print symbol('H')
            write(s, 2);  print string("S)")
            newline
            e = e + 1
         %finish
      %repeat
      write(e, 4);  printstring(" bad directory block")
      print symbol('s') %if e # 1
      newline
%end

%routine analyse data(%integer p)
   %integer i, start, finish, e = 0, n, c, h, s
      start = p start(p);  finish = p start(p) + fp size - 1
      %for i = 1, 1, bad block list_last bad %cycle
         n = bad block list_bad(i)
         %exit %if n > finish
         %if n >= start %start
            write(n - start, 12);  printstring(" logical  (")
            write(n, 6);  printstring(" physical,")
            h = n // sectors;  s = rem(n, sectors)
            c = h // heads;  h = rem(h, heads)
            write(c, 4);  print symbol('C')
            write(h, 2);  print symbol('H')
            write(s, 2);  print string("S)")
            newline
            e = e + 1
         %finish
      %repeat
      write(e, 4);  printstring(" bad data block")
      print symbol('s') %if e # 1
      newline
%end

%begin
   %integer start, size, i, last, error
      %on 9 %start
         printstring("Error:");  printstring(event_message)
         newline
         %stop
      %finish
      connect file("$:BADLIST", 0, start, size)
      %if size # 4 * 512 %start
         printstring("Bad size for bad list");  newline
         %stop
      %finish
      bad block list == record(start)
      %unless bad checksum(bad block list) = 0 %start
         printstring("Bad block list checksum error")
         newline
         %stop
      %finish
      write(bad block list_last bad, 0)
      printstring(" bad block")
      print symbol('s') %if bad block list_last bad # 1
      printstring(", sequence ");  write(bad block list_stamp, 0)
      last = -1;  error = 0
      %for i = 1, 1, bad block list_last bad %cycle
         %if bad block list_bad(i) > last %start
            last = bad block list_bad(i) %if error = 0
         %else
            error = 1
         %finish
      %repeat
      printstring(" **monoticity error**") %if error # 0
      newline
      %for i = 0, 1, last partition %cycle
         newline
         printstring("Partition ");  write(i, 0)
         print symbol(':');  newline
         analyse directories(i)
         analyse data(i)
      %repeat
%end %of %program
