!
! ALIST for IMP-11 programs.
!
! Takes a PDP-11 Imp77 relocatable object file, and its 
! source file, producing a listing matching code addresses 
! (relative to the file code-base) with the corresponding 
! source lines.
!

!E!  %include "ERCM11.IMP77_SPECS"
{EV} %external %routine %spec  SET IMP77 STREAMS (%string(255) flist, dlist,
{EV}                                              %integer %name  err)

! stream usage:
%const %integer  source = 1, object = 2
%const %integer  listing = 1


{DV}%begin
!E! %external %routine  ALIST11 (%string(255) param)

   %switch  c (1:11)
   %integer  error, n, modules, module, ca, code, gla

   %routine  GET (%integer %name n)
      %integer  s1, s2
      read symbol (s1);  read symbol (s2)
      n = s2<<8 + s1
   %end

   %routine  OCTAL (%integer n)
      %integer j
      n = n & 16_FFFF
      %for j = 15, -3, 0 %cycle
         print symbol (n>>j & 7 + '0')
      %repeat
   %end

   %routine  ENTRY (%integer mode)
      %integer  s, n, l, t
      %string(30)  text
      %if mode # 0 %start
         get (n)
      %finish
      read symbol (t);  read symbol (l)
      text = ""
      %while l > 0 %cycle
         read symbol (s)
         text = text . tostring(s)
         l = l - 1
      %repeat
      %if module = 1 %start;    ! This to be printed
         spaces (12 - length(text))
         print string (text)
         write (t, 1)
         %if mode # 0 %start
            space;  octal (n)
         %finish
         newline
      %finish
   %end

   %routine  COPY LINE (%integer to)
      %own %integer line no = 0, eof = 0
      %integer s
      %on 9 %start
         eof = 1
         %return
      %finish
      %return %if eof # 0
      select input (1)
      %while line no < to %and eof = 0 %cycle
         line no = line no + 1
         write (line no, -4);  spaces(2);  octal (ca);  spaces(2)
         %cycle
            read symbol (s)
            print symbol (s) 
         %repeat %until s = nl
      %repeat
      select input (2)
   %end

   %routine  SET UP STREAMS
{EV}  set imp77 streams (cli param, "IMP,REL=1/ALS", error)
      %if error = 0 %start
         ! Files valid - check for sensible types
         select input (source);   error = 1 %if in type <= 0; ! Dev or .N ??
         select input (object);   error = 1 %if in type <= 0; !  "  "  "
         select output (listing); error = 1 %if out type = 0; ! /.N ????????
         %if error # 0 %start
            print string ("Form:  ALIST source,object/listing")
            newline
         %finish
      %finish
   %end

   %on 9 %start
      print string ("EOF while reading object file")
      newline
      %return
   %finish

   error = 0

   set up streams;    %return %if error # 0;      ! Check streams

   newline
   print string ("ALIST of file ");  print string (in file name)
   newlines (2)

   get (modules);                       ! but only first module examined
   print string ("Entry points:");  newlines(2)
   %for module = 1, 1, modules %cycle
      get (n);                          ! No of definitions
      entry (1) %for n = 1, 1, n
      get (n)
      entry (0) %for n = 1, 1, n
      get (code);  get (gla)
      %if module = 1 %start
         newline;  print string ("Code size "); octal (code)
         newline;  print string (" Gla size "); octal (gla)
         newlines (2)
      %finish
   %repeat
   ca = 0
   %cycle
      read symbol (n)
      -> c(n) %if 1 <= n <= 11
      select output (0)
      printstring ("Corrupt object!"); newline
      %stop

c(1): ! Code word
      ca = ca + 2
      get (n)
      %continue
c(5): ! Change code base
      get (ca)
      %continue
c(6): ! Set line number
      get (n)
      copy line (n)
      %continue
c(4): ! Patch
      get (n)
c(2): ! Gla word
c(7): ! External index
      get(n)
c(9): ! Code base offset 
c(10):! Gla base offset
c(11):! PC offset
c(3): ! ???
   %repeat
c(8): ! end

   copy line (32767);  ! Should be enough????
   newline

%end %of %program