--routeConn.mesa DIRECTORY RouteDefs; RouteConn:PROGRAM IMPORTS RouteDefs EXPORTS RouteDefs=BEGIN OPEN RouteDefs; --The function of conn is to identify all cross channel wires, --and create a structure containing event with start and end runs --conn does not worry about the offset of the wire. Error:SIGNAL=CODE; InstallCrossChannelConnections:PUBLIC CtlProc=BEGIN EnumerateChannels[MakeConnections]; EnumerateAllConns[CheckConnections]; --EnumerateChannels[ShowConnections]; RETURN[-1]; END; EnumerateRunPairs:PROCEDURE[r:RectanglePtr, c:PROCEDURE[RectanglePtr,RunPtr,RunPtr]]=BEGIN FOR rl:RunListPtr←r.runs,rl.t UNTIL rl=NIL DO FOR rl2:RunListPtr←rl.t,rl2.t UNTIL rl2=NIL DO c[r,rl.h,rl2.h]; ENDLOOP; ENDLOOP; END; MakeConnections:PROCEDURE[rect:RectanglePtr]=BEGIN EnumerateEvents[rect,MakeEdgeConnections]; EnumerateRunPairs[rect,MakeEdgeX]; END; MakeEdgeX:PROCEDURE[rect:RectanglePtr,r1:RunPtr,r2:RunPtr]=BEGIN IF r1.circuit=r2.circuit AND (r1.start=r2.end OR r2.start=r1.end) THEN MakeInternalConnections[rect,r1,r2]; END; MakeInternalConnections:PROCEDURE[rect:RectanglePtr,r1,r2:RunPtr]=BEGIN seen:BOOLEAN←FALSE; IF r1.start=r2.end THEN {t:RunPtr←r1; r1←r2; r2←t}; FOR cl:ConnListPtr←rect.conns,cl.t UNTIL cl=NIL OR seen DO seen←cl.h.circuit=r1.circuit AND cl.h.event=r1.end; ENDLOOP; IF ~seen THEN QueueConn[rect,[r1.circuit,MIN[r1.run,r2.run], MAX[r1.run,r2.run],r1.end]]; END; --EnumerateEventsWithAbort:PROCEDURE -- [r:RectanglePtr,c:PROCEDURE[RectanglePtr,EventPtr] RETURNS[BOOLEAN]]=BEGIN --FOR l:EventListPtr←rect.events, l.t UNTIL l=NIL -- DO IF c[r,l.h] THEN RETURN; ENDLOOP; --END; MakeEdgeConnections:PROCEDURE[rect:RectanglePtr,e:EventPtr]=BEGIN keyRun1,keyRun2,kk:RunPtr←NIL; FindExtreemRun:PROCEDURE[rect:RectanglePtr,r:RunPtr]=BEGIN IF ~(e.circuit=r.circuit AND e.index IN [r.start..r.end]) THEN RETURN; IF keyRun1=NIL OR r.run<keyRun1.run THEN keyRun1←r; IF keyRun2=NIL OR r.run>keyRun2.run THEN keyRun2←r; END; IF e.where=left OR e.where=right THEN RETURN; IF e.opposite#NIL AND e.circuit=e.opposite.circuit THEN BEGIN IF e.where#top THEN RETURN; QueueConn[rect,[e.circuit,-1,bigRun,e.index,,,,,e]]; e.opposite.conn←rect.conns.h; RETURN; END; EnumerateRuns[rect,FindExtreemRun]; kk←IF e.where=top THEN keyRun1 ELSE keyRun2; IF kk=NIL THEN RETURN; IF e.where=top THEN QueueConn[rect, [e.circuit,kk.run,bigRun,e.index,,,,,e,,kk]] ELSE QueueConn[rect, [e.circuit,-1,kk.run,e.index,,,,,e,,,kk]]; IF kk.start=e.index THEN kk.startConn←rect.conns.h ELSE kk.endConn←rect.conns.h; END; QueueConn:PROCEDURE[rect:RectanglePtr,conn:Conn]=BEGIN cp:ConnPtr=AllocateConn[]; cl:ConnListPtr=AllocateList[]; cp↑←conn; cl↑←[cp,rect.conns]; rect.conns←cl; IF cp.eventPtr#NIL THEN conn.eventPtr.conn←cp; END; GenerateRunmax:PROCEDURE[rect:RectanglePtr] RETURNS[runMax:INTEGER]=BEGIN runMax←0; FOR rl:RunListPtr←rect.runs,rl.t UNTIL rl=NIL DO runMax←MAX[runMax,rl.h.run]; ENDLOOP; END; CheckConnections:PROCEDURE[rect:RectanglePtr,con:ConnPtr]=BEGIN IF con.start=-1 THEN FOR t:EventListPtr←rect.events, t.t UNTIL t=NIL DO e:EventPtr←t.h; IF con.circuit = e.circuit AND con.event = e.index AND e.where=bottom THEN EXIT; REPEAT FINISHED=>Log[]; ENDLOOP ELSE FOR rl:RunListPtr←rect.runs,rl.t UNTIL rl=NIL DO r:RunPtr=rl.h; IF r.circuit=con.circuit AND r.run=con.start AND con.event IN [r.start..r.end] THEN EXIT; REPEAT FINISHED=>Log[]; ENDLOOP; IF con.end=bigRun THEN FOR t:EventListPtr←rect.events, t.t UNTIL t=NIL DO e:EventPtr←t.h; IF con.circuit = e.circuit AND con.event = e.index AND e.where=top THEN EXIT; REPEAT FINISHED=>Log[]; ENDLOOP ELSE FOR rl:RunListPtr←rect.runs,rl.t UNTIL rl=NIL DO r:RunPtr=rl.h; IF r.circuit=con.circuit AND r.run=con.end AND con.event IN [r.start..r.end] THEN EXIT; REPEAT FINISHED=>Log[]; ENDLOOP; END; plowOn:BOOLEAN←FALSE; Log:PROCEDURE={IF ~plowOn THEN Error}; ShowConnections:PROCEDURE[rect:RectanglePtr]=BEGIN Store:PROCEDURE[c:CHARACTER,x:INTEGER]=BEGIN IF x NOT IN [0..line/2) THEN {x←x-limit+line-1; IF x NOT IN [line/2..line) THEN RETURN}; IF c='r AND s[x]#' THEN c←'R; s[x]←c; END; limit:CARDINAL=4+2*GenerateRunmax[rect]; line:CARDINAL=40; limitE:CARDINAL=MAX[limit-1,line/2]; s:STRING←[line]; ShowLabel["CONNECTIONS "]; ShowDecimal[rect.channelNo]; Return[]; FOR i:INTEGER IN [0..rect.sizeC.x] DO SeeEvent:PROCEDURE[rect:RectanglePtr,e:EventPtr]=BEGIN IF i = e.index THEN BEGIN IF e.where=top THEN s[line-1]←ShowCircuit[e.circuit]; IF e.where=bottom THEN s[0]←ShowCircuit[e.circuit]; END; END; SeeConn:PROCEDURE[rect:RectanglePtr,con:ConnPtr]=BEGIN IF con.event=i THEN BEGIN stop:INTEGER=IF con.end=bigRun THEN limitE ELSE 2+2*con.end; FOR j:[0..10000) IN [2+2*con.start..stop] DO IF ~(j=0 OR j=limit) THEN Store['r,j]; ENDLOOP; END; END; SeeRun1:PROCEDURE[rect:RectanglePtr,r:RunPtr]= {IF i IN [r.start..r.end) THEN Store['b,2+2*r.run]}; SeeRun2:PROCEDURE[rect:RectanglePtr,r:RunPtr]= {IF i IN [r.start..r.end) THEN Store['b,2+2*r.run]}; Return[]; Clear[s]; EnumerateEvents[rect,SeeEvent]; EnumerateConns[rect,SeeConn]; EnumerateRuns[rect,SeeRun1]; ShowString[s]; Clear[s]; EnumerateRuns[rect,SeeRun2]; FOR zz:INTEGER IN [0..3) DO Return[]; ShowString[s]; ENDLOOP; ENDLOOP; END; END.