%begin; !SHOWBOARD: draw layout of a blank board
! Input 1: ESDL code of board library
! Input 2: ESDL code of package library
!modded 5/6/85 jhb. Put MAX up (below). Showboard crashes with ?corrupt stack
!otherwise

%include "EDWIN:specs.INC"
%include "inc:util.imp"
%EXTERNALINTEGERFNSPEC DEF STREAMS(%STRING(127) PARM, DEFAULTS)
%OWNSTRING(31) DEFAULTS=".LIB,.LIB/:n.PDF"

%constinteger maxnames=150,
              maxgram=2000,
{jhb}              max=254
!jhb!              max=25

%recordformat pfm(%integer name,x,y,x1,y1)
%record(pfm)%name pack
%record(pfm)%array packs(1:maxnames)
%string(max)%array name(1:maxnames)
%integerarray gram(1:maxgram)
%integer namelim=0,glim=2,i

!ESDL -> ^S num[0:eic,1:fic,2:cic,3:bic] UNIT*
!UNIT -> ^U type[1:spec,2:unit,3:chip,4:board,5:pack,+8:generic]
!        HEAD UNIT* ^J num[num of subinstances] (HEAD)num of sub
!        (^N (^A netname num[of fans] (instnum termnum)fan)+)*
!        ^E
!HEAD -> ^H opt[0] in out inout terms string1 string2
!        (^T termno<<2+in<<1+out pinstring namestring)terms
!        (^P parmnum[1:at,2:on,3:pack,4:subpack,5:delay,6:value,7:size,
!                    8:place] parmstring)*
!        ^G

%constinteger c=128

%integer sym

%routinespec read string

%routine readsym
  readsymbol(sym) %until sym#nl
  %if sym='^' %start
    readsym; sym=sym+c
    %if sym=c+'K' %start
      read string; readsym
    %finish
  %finish
%end

%routine show grammar and dict;  ! <Used only in case of gram failure>
%integer i,g
  printstring("Grammar
")
  %for i=1,1,glim %cycle
    g=gram(i)
    %if i>1 %and gram(i-1)&255=0 %then write(g,6) %elsestart
      write(g>>8,4); space; g=g&255
      %if g=0 %then printsymbol('-') %else printsymbol(g)
    %finish
    write(i,5) %and newline %if i&7=0
  %repeat
  newline
  printstring("Dict =
")
  %for i=1,1,namelim %cycle
    printstring(name(i)); spaces(16-length(name(i)))
    write(i,3) %and newline %if i&3=0
  %repeat
  newline
%end

%string(max+1)s
%integerfn codestring
%integer pos,i,g
! Would-be slow linear search
!  %for pos=namelim,-1,1 %cycle
!    %result=pos %if name(pos)=s
!  %repeat
!  namelim=namelim+1; name(namelim)=s; %result=namelim

! Amazing super-fast search by self-extending grammar
  length(s)=length(s)+1
  charno(s,length(s))=0;  !terminator
  i=1; sym=charno(s,i); pos=1
  %cycle
    g=gram(pos)
    %if g&255=sym %start; !Match so far
      pos=pos+1
      %if sym=0 %start;   !Complete match
        pos=gram(pos); length(s)=length(s)-1
        %result=pos %if s=name(pos)
        printstring("Name("); write(pos,0); printstring(")=")
        printstring(name(pos)); printsymbol('#'); printstring(s)
        newline; show grammar and dict; %signal 15
      %finish
      i=i+1; sym=charno(s,i)
    %else;                !No match here, seek alternative
      %if g>>8=0 %start;  !No alternative, extend grammar
        gram(pos)=(glim+1)<<8+g
        %cycle
          glim=glim+1; gram(glim)=sym
          %exitif sym=0; i=i+1; sym=charno(s,i)
        %repeat
        namelim=namelim+1; length(s)=length(s)-1; name(namelim)=s
        glim=glim+1; gram(glim)=namelim; %result=namelim
      %finish
      pos=g>>8;           !Alternative position
    %finish
  %repeat
%end

%routine read string
%integer len,pos,i
  read(len); readsym
  pos=len; pos=max %if pos>max
  length(s)=pos; %returnif len=0
  pos=0
  %for i=1,1,len %cycle
    pos=pos+1; readsym
!    %if sym='/' %then pos=0 %elsestart
      charno(s,pos)=sym %unless pos>max
!    %finish
  %repeat
%end

%integerfn readname
  read string; %result=codestring
%end

%routine printname(%integer n)
  printstring(name(n)) %unless n=0
%end

%routine extract(%integername x,y)
%integername z
%integer p,l,sym,sign
  l=length(s); p=1; x=0; y=0; z==x; sign=1
  %cycle
    %returnif p>l; sym=charno(s,p)
    %if sym='-' %start
      sign=-sign
    %finishelseif sym=':' %start
      z==y; sign=1
    %finishelseif '0'<=sym<='9' %start
      z=z*10+sign*(sym-'0')
    %finish
    p=p+1
  %repeat
%end

gram(1)=0; gram(2)=0

  selectoutput(0)
  i = defstreams(cliparam,defaults)
  selectoutput(0)
  %unless i=1 %start
     printstring("Define Streams error "); phex(i); newline
{jhb}printline(event_message)
     %stop
  %finish
  selectinput(1); readsym
  %unless sym=c+'S' %start
    printline("Board file corrupt"); %stop
  %finish
  selectinput(2); readsym
  %unless sym=c+'S' %start
    printline("Package file corrupt"); %stop
  %finish

%routine read package library
%string(max)coo
%onevent 3,9 %start
  ->end
%finish
%cycle
  readsym %until sym=c+'H'
  read(sym); read(sym); read(sym); read(sym); read(sym)
  readstring; sym=readname; pack==packs(sym)
  printstring(s); newline
  pack=0; pack_name=sym
  %cycle
    readsym; %exitif sym=c+'G'
    %if sym=c+'P' %start
      read(sym)
      %if sym=7 %start
        readstring; extract(pack_x,pack_y)
      %finish
    %finishelseif sym=c+'T' %start
      read(sym); readstring; coo=s; readstring
      %if s="1" %start
        s=coo; extract(pack_x1,pack_y1)
      %finish
    %finish
  %repeat
  readsym %until sym=c+'E'
%repeat
end:
  printsymbol('.'); newline
%end; read package library

selectinput(1)
%routine read board file
%integer limit=namelim,x,y,ty
%integer sp=glim

%routine stackxy
  sp=sp+1; gram(sp)=x; sp=sp+1; gram(sp)=y
%end

%routine unstack
  %cycle
    %returnif sp<=glim; y=gram(sp); sp=sp-1; x=gram(sp); sp=sp-1
    markerabs(0,x,y)
  %repeat
%end

!%routine drawchip(%integer x,y,xs,ys,x1,y1)
!drawchip(x,y,pack_x,pack_y,pack_x1,pack_y1)
%routine drawchip(%integer x,y,%record(pfm)%name p)
%integer xs=p_x,ys=p_y,x1=p_x1,y1=p_y1
%integer xl,xr,yt,yb,xm,ym
  %if xs<0 %then xr=x %and xl=x+xs %else xl=x %and xr=x+xs
  %if ys<0 %then yt=y %and yb=y+ys %else yb=y %and yt=y+ys
  xm=(xl+xr)>>1; ym=(yb+yt)>>1; x1=x1+x; y1=y1+y
  moveabs(xl,yb)
  lineabs(xr,yb); lineabs(xr,yt); lineabs(xl,yt); lineabs(xl,yb)
  %if xl#x1#xr %and yb#y1#yt %then markerabs(0,x1,y1) %elsestart
    %if x1>xm %then x1=xr %and xs=-8 %else x1=xl %and xs=8
    %if y1>ym %then y1=yt %and ys=-8 %else y1=yb %and ys=8
    moveabs(x1+xs,y1); lineabs(x1,y1+ys)
  %finish
%end

%on 3,9 %start
  terminate edwin
  %stop
%finish

  initialise for (defaultdevice)
  printstring("Terminal set to "); print string (device data_name); newline
%cycle
  selectinput(1); readsym %until sym=c+'H'
  read(sym); read(sym); read(sym); read(sym); read(sym)
  readstring; readstring
! printstring("Draw board "); printstring(s); printsymbol('?'); newline
! selectinput(0); prompt("Y or N?")
! readsymbol(sym) %and sym=sym!32 %until sym='y' %or sym='n'
! selectinput(1)
! %if sym='n' %start
!   readsym %until sym=c+'E'
!   %continue
! %finish
  %cycle
    readsym; %exitif sym=c+'G' %or sym=c+'P'
    %if sym=c+'T' %start
      read(sym); readstring; extract(x,y); stackxy
    %finish
  %repeat
  x=0; y=0; newframe
  %while sym#c+'G' %cycle
    %if sym=c+'P' %start
      read(sym)
      %if sym=7 %start
        readstring; extract(x,y)
        window(-10,x+10,-10,y+10)
        moveabs(0,0); linerel(x,0); linerel(0,y)
        linerel(-x,0); linerel(0,-y); unstack
      %finish
    %finish
    readsym
  %repeat
  %if x=0 %and y=0 %start
    printline("Size not specified"); %stop
  %finish
  %cycle
    readsym
    %exitif sym=c+'E'
    %if sym=c+'H' %start
      read(sym); read(sym); read(sym); read(sym); read(sym)
      readstring; sym=readname
      %if sym>limit %start
        update
        printstring("Unknown package ".s); newline
        readsym %until sym=c+'G'
      %finishelsestart
        pack==packs(sym)
        %cycle
          readsym; %exitif sym=c+'G'
          %if sym=c+'P' %start; read(sym); %if sym=1 %start
            readstring; extract(x,y)
            drawchip(x,y,pack); !drawchip(x,y,pack_x,pack_y,pack_x1,pack_y1)
          %finish; %finish
        %repeat
      %finish
    %finish
  %repeat
  update
%repeat
%end; read board file

%endofprogram
