! ROM:  a routine to generate an ILAP PLA from a ROM description.

%include "nmos.inc"
%include "plautils.inc"
!%external %integer %fn %spec REM (%integer A, B)
!%external %integer %fn %spec IN STREAM
!%external %routine %spec CLOSE INPUT

   {#########################################################################}
   {#                                                                       #}
   {#      This program is part of the ILAP library, and was written in     #}
   {#   The Department of Computer Science at the University of Edinburgh   #}
   {#       (James Clerk Maxwell Building, Kings Buildings, Edinburgh)      #}
   {#                                                                       #}
   {#   This software is available free to other educational establisments  #}
   {#   but the University of Edinburgh, retains all commercial rights.     #}
   {#   It is a condition of having this software is that the sources are   #}
   {#   not passed on to any other site, and that Edinburgh University is   #}
   {#   given credit in any re-implementations of any of the algorithms     #}
   {#   used, or articles published which refer to the software.            #}
   {#                                                                       #}
   {#   There is no formal support for this software, but any bugs should   #}
   {#   be reported to Gordon Hughes or David Rees at the above address,    #}
   {#   are likely to be fixed in a future release.                         #}
   {#                                                                       #}
   {#########################################################################}

%external %routine srom %alias "ILAP_SROM" (%string (31) symbol name,
   %string (255) file, %integer mode,
   %integer %array %name ispec,%Integer %array %name ospec,
   %integer %name phi1y, phi2y,
   %integer %array %name inx,%integer %array %name outx)

   %byte %array table ( 1:100, 1:500 )
   %integer oldin
   %string(255) fin,fout
   %integer inn, outn
   %integer length, depth

   !  next bit is the original ROM routine
   %routine orom(%integer ins,outs, %integerarray(2)%name data )
      %integer ins2,dr,dc,t,andp,orp,prods,b

      ins2=2\\ins
      %integerarray z(0:ins2-1),and(1:ins*ins2),or(1:outs*ins2)

      prods=0
      %for dr=0,1,ins2-1 %cycle
        t=0
        t=t!data(dr,dc) %for dc=1,1,outs
        z(dr)=t
        %if t#0 %then prods=prods+1
      %repeat

      ! fill in and-plane
      andp=1
      %for dr=0,1,ins2-1 %cycle
        %if z(dr)#0 %then %start
          %for b=0,1,ins-1 %cycle
            %if (dr>>b)&1=0 %then and(andp)=-1 %else and(andp)=1
            andp=andp+1
          %repeat
        %finish
      %repeat
    
      ! fill in or-plane
      orp=1
      %for dc=1,1,outs %cycle
        %for dr=0,1,ins2-1 %cycle
          %if z(dr)#0 %then or(orp)=data(dr,dc) %and orp=orp+1
        %repeat
      %repeat

      %if mode&(stretchinputs!stretchoutputs!stretch)=0 %c
        %then npla(symbolname,mode,ispec,ospec,ins,outs,
                    0,prods,and,or,phi1y,phi2y,inx,outx) %c
      %else %start
        select output(0)
        print string("Warning: Stretched ROMs no longer available.
")
{        PLA(symbolname,mode,ispec,ospec,ins,outs,feeds,prods,and,or,
{                 phi1y,phi2y,inx,outx)
      %finish
   %end { of original ROM }


   %integer %function logb2 ( %integer i )
      disaster ("taking log of zero") %if i <= 0
      %result = 0 %if i = 1
      %result = 1 + logb2( i//2 + rem(i,2))
   %end

   %routine read table
      %integer x,y
      %integer ch
      %integer power of 2
      %on 9 %start
          depth = y - 1
          power of 2 = 2\\(logb2(depth)) 
          %for y = depth+1, 1, power of 2 %cycle
            %for x = 1,1,length %cycle
              table(x,y) = 0
            %repeat
          %repeat           
    
          depth = power of 2
          %return
      %finish
    
      y = 0
      %cycle
         y = y + 1
         x = 0
         %cycle
            read symbol(ch)
            x = x + 1
            %if ch = '0' %start
              table(x,y) = 0
            %finish %else %if ch = '1' %start
              table(x,y) = 1
            %finish %else %if ch = ' ' %or ch = ',' %start
              x = x - 1
            %finish %else %if ch = nl %start
              disaster ("ROM: inconsistant line length") %if length#-1 %and length#x-1
              length = x - 1
              %exit
            %finish
         %repeat
      %repeat
   %end

   oldin = in stream
   print string("ROM: Version 4.1") %and newline %if diags = true
   parse filespec ( file, "rom", "", fin, fout, inn, outn )
   select input( inn )
   length = -1
   read table

   %begin
      %integer %array data ( 0:depth-1,1:length )
      %integer i,j
      %for i = 0,1,depth-1 %cycle
         %for j = 1,1,length %cycle
              data(i,j) = table(j,i+1)
              write(data(i,j),0) %and space %if diags = true
         %repeat
         newline %if diags = true
      %repeat
      orom (logb2(depth), length, data)
   %end
   close input
   select input( oldin )
%end

%external %routine rom %alias "ILAP_ROM" (%string (31) symbol name,
   %string (255) file, %integer %name phi1y, phi2y,
   %integer %array %name inx,%integer %array %name outx)
   %integer %array none (1:1)

   srom (symbol name, file, 0, none, none, phi1y, phi2y, inx, outx)
%end

%end %of %file
