! Program to generate an inventory of APM bits & pieces from MANAGR:NS.DAT
!Takes managr:ns.dat as input.  Single optional parameter is output file.
! J. Butler July 85

%include "managr:nsdefs.inc"
%include "inc:fs.imp"
%include "inc:util.imp"
%include "managr:ns.inc"

%conststring (31) data file = "managr:ns.dat"
%constinteger locn = 1, peripherals = 2, shortname=4, longname=8,all = 255
%constinteger ff=12

%conststring (31) %array peripheral(0:25) = %c
{A} "0.5Mb memory board",       {B} "68010 processor board",
{C} "8MHz processor board",     {D} "10MHz processor board",
{E} "2MHz Ethernet board",      {F} "10MHz Ethernet board",
{G} "Level 1 graphics board",   {H} "Level 1.5 graphics board",
{I} "?MHz processor board",     {J} "level 2 graphics board",
{K} "K???",                     {L} "2.0Mb memory board",
{M} "Mouse controller",         {N} "N???",
{O} "O???",                     {P} "Laser printer controller",
{Q} "QSART board",              {R} "RTS interface board",
{S} "Special board",            {T} "T???",
{U} "U???",                     {V} "V???",
{W} "W???",                     {X} "MIT graphics monitor",
{Y} "Unknown monitor",          {Z} "Twin 3 inch Floppy-Disks"

%begin
%integer size,start,dte,i,j, k
%record (ns lfm) %name data
%record (ns fm) %name file
%ownintegerarray list(0:127) = 0(*)
%ownintegerarray boardtot(0:127) = 0(*)
%ownintegerarray boardlist(0:25, 0:127) = 0(*)
%ownintegerarray freelist(0:127) = 0(*)
%owninteger cases=0, lastcase=-1, freestns = 0
%string (255) outfile
%bytearray sname(0:8)

%integerfn hex(%string (*) %name s)
   %integer i,no,a
   no=0
   %for i=1,1,length(s) %cycle
      a=charno(s,i); a=a-' ' %if 'a'<=a<='z'; a=a-'0'
      a=a-7 %if a>9
      %exit %unless 0<=a<=15
      no=no<<4+a
   %repeat
   %result=no
%end

%routine dump location(%integer dte, qualifier)
   %integer i, j
   %record (ns lfm) %name data
   phex2(dte); spaces(2)
   data == file_l(dte)

   %if qualifier & shortname # 0 %start
      %for i=1,1,7 %cycle
         printsymbol(file_s(dte)_d(i))
      %repeat
      space
   %finish

   %if qualifier & locn # 0 %start
      %for i=1,1,4 %cycle; printsymbol(data_add(i)); %repeat
      space
   %finish

   %if qualifier & peripherals # 0 %start
      %for i=1,1,18 %cycle
         printsymbol(data_bpmap(i))
      %repeat
      space
   %finish

   %if qualifier & longname # 0 %start
      %if data_inon = 'I' %start
         printstring("In ")
      %elseif data_inon = 'O'
         printstring("On ")
      %elseif data_inon = 'A'
         printstring("At ")
      %finish
      
      printstring("the ") %if data_room = 'T'
      
      %for j=31,-1,1 %cycle; %exit %if data_lname(j) > ' '; %repeat
      %for i=1,1,j %cycle; printsymbol(data_lname(i)); %repeat
      printstring("'s room") %if data_room = 'R'
   %finish

   newline
%end

%routine casesort(%integerarrayname data, %integer entries)
   !Sort integer array data, throughout its length
    %integer i,j,k,l,n1, temp

      %integerfn s(%integer dte)
         %result = file_l(data(dte))_case
      %end

      n1 = 1
      l = entries - 2
      n1 = 2*n1 %while n1<l
      l = 0
       %while n1 > 1 %cycle
         n1 = n1 // 2
         i = l
          %cycle
            i = i+1
            j = i+n1
             %exitif j > entries
            k = i
             %cycle
                %exitif s(j) > s(k)
                temp = data(j); data(j) = data(k); data(k)= temp
               j = k
               k = k - n1
             %repeatuntil k < 1
          %repeat
       %repeat
    %end                 ; ! of routine CASESORT

%routine locnsort(%integerarrayname data, %integer entries)
   !Sort integer array data, throughout its length
    %integer i,j,k,l,n1, temp

      %integerfn s(%integer dte)
         %integer i, no
         no=0
         %for i=1,1,4 %cycle
            no = no<<8+file_l(data(dte))_add(i)
         %repeat
         %result=no
      %end

      n1 = 1
      l = entries - 2
      n1 = 2*n1 %while n1<l
      l = 0
       %while n1 > 1 %cycle
         n1 = n1 // 2
         i = l
          %cycle
            i = i+1
            j = i+n1
             %exitif j > entries
            k = i
             %cycle
                %exitif s(j) > s(k)
                temp = data(j); data(j) = data(k); data(k)= temp
               j = k
               k = k - n1
             %repeatuntil k < 1
          %repeat
       %repeat
    %end                 ; ! of routine LOCNSORT

%predicate assigned(%integer dte)
   %integer i
   %true %if file_l(dte)_case # 0
   %for i=1,1,16 %cycle
     %true %if file_l(dte)_bpmap(i) # '.'
   %repeat
   %true %if file_l(dte)_bpmap(17) # '*' %or file_l(dte)_bpmap(18) # '*'
   %false
%end


outfile = cliparam
%if outfile # "" %and outfile # ":" %start
   open output(1, outfile); selectoutput(1)
%finish
printline("APM inventory on ".date." at ".time.".  Source file: ".data file)

connect file(data file, 0, start, size)
file == record(start)
printline("""".file_comment.""""); newlines(2)

printsymbol(ff); printline("APMs by Station number"); newlines(2)

%for dte=1,1,max addr %cycle
   %if assigned(dte) %start
      dump location(dte, all)
   %else
      freestns=freestns+1
      freelist(freestns) = dte
   %finish
%repeat

printsymbol(ff); printline("APMs by location"); newlines(2)

%for dte=0,1,max addr %cycle
   list(dte) = dte
%repeat
locnsort(list, max addr)
%for i=1,1,max addr %cycle
   dump location(list(i), all) %if assigned(list(i))
%repeat
newline

write(freestns, -1); printline(" Unallocated Stations:"); newline
%for i=0,1,7 %cycle
   %for j=0,1,15 %cycle
      phex2(freelist(i*16+j+1)); space
      -> finished %if i*16+j+1 = freestns
   %repeat
   newline
%repeat
finished:
newlines(2)

%for dte=0,1,max addr %cycle
   data == file_l(dte)
   %if data_case#0 %start
      cases=cases+1; list(cases)=dte
   %finish
   %for i=1,1,18 %cycle
      j = data_bpmap(i); j=j-'a'+'A' %if 'a'<=j<='z'
      %if 'A'<=j<='Z' %start
         j=j-'A'
         boardtot(j)=boardtot(j)+1
         boardlist(j, boardtot(j)) = dte
      %finish
   %repeat
%repeat

newline; write(cases, -1); printline(" cases:"); newline

casesort(list, cases)
lastcase=-1

%for i=1,1,cases %cycle
   dte = list(i)
   write(file_l(dte)_case, 3); spaces(2); dump location(dte, locn ! longname)
   %if file_l(dte)_case = lastcase %start
      printline("*** This case assigned twice ***")
   %finish
   lastcase = file_l(dte)_case
%repeat
newline

%for j=0,1,25 %cycle
   k = boardtot(j)
   %if k # 0 %start
      write(k, 3); space
      printstring(peripheral(j))
      printsymbol('s') %if k>1
      newline
      %for i=1,1,k %cycle
         dte = boardlist(j, i)
         dump location(dte, locn ! longname)
      %repeat
      newline
   %finish
%repeat

printsymbol(ff); printstring("Peripherals listed by APM"); newlines(2)

%for dte=1,1,127 %cycle
   printstring("Station "); dump location(dte, \peripherals)
   
   %if file_l(dte)_case # 0 %or file_l(dte)_bpmap(1) # '.' %start
      printstring("   Recorded Peripherals for case")
      write(file_l(dte)_case,3); printline(":")
      %for i=1,1,18 %cycle
         %if file_l(dte)_bpmap(i) # '.' %and file_l(dte)_bpmap(i) # '*' %then %C
         printline("      ".peripheral(file_l(dte)_bpmap(i)-'A'))
      %repeat
   %finish
   newline
%repeat

%endofprogram
