--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.