--routeInter.mesa DIRECTORY RouteDefs; RouteInter:PROGRAM IMPORTS RouteDefs EXPORTS RouteDefs=BEGIN OPEN RouteDefs; --RouteIntersections figures out the intersection --InterSilicon turns the internal representation into rectangles --WhereIs takes a path and a side and returns the runNo of that wire -- WhereIs returns the first matching path among equals --the circuit in IWire is the current assignment. -1 means unassigned Error:SIGNAL=CODE; spaceB:Lambda_0; RouteIntersections:PUBLIC CtlProc=BEGIN ShowLabel["INTERSECTIONS"]; EnumerateRectangles[SetSizeC]; EnumerateInters[MakeIWires]; --sets type,h,wire,path EnumerateInters[AssignIWires]; --sets nx,sx,ey,wy EnumerateAllIWire[CheckInter]; EnumerateInters[ShowInter]; EnumerateInters[ShowIWire]; RETURN[-1]; END; EnumerateAllPaths:PROCEDURE[c:PROCEDURE[PathPtr]]=BEGIN FOR wl:PathwayListPtr_paths, wl.t UNTIL wl=NIL DO FOR pl:PathListPtr_wl.h.path, pl.t UNTIL pl=NIL DO c[pl.h]; ENDLOOP; ENDLOOP; END; EnumerateIWire:PROCEDURE[r:RectanglePtr, c:PROCEDURE[RectanglePtr,IWirePtr]]= {FOR l:IWireListPtr_r.junction.iwires,l.t UNTIL l=NIL DO c[r,l.h]; ENDLOOP}; EnumerateAllIWire:PROCEDURE[c:PROCEDURE[RectanglePtr,IWirePtr]]=BEGIN Sub:PROCEDURE[rect:RectanglePtr]={EnumerateIWire[rect,c]}; EnumerateInters[Sub]; END; SetSizeC:PROCEDURE[rect:RectanglePtr]=BEGIN ew:INTEGER=(East[rect]-West[rect]+4)/7; ns:INTEGER=(North[rect]-South[rect]+4)/7; IF rect.orient=inter THEN {rect.sizeC.x_ew; rect.sizeC.y_ns} ELSE rect.sizeC.y_IF rect.orient=hor THEN ns ELSE ew; END; MakeIWires:PROCEDURE[inter:RectanglePtr]=BEGIN AddIWire:PROCEDURE[path:PathPtr]=BEGIN IF path.inter#inter THEN RETURN ELSE BEGIN h:Huggers=path.huggers; type:InterType=MakeType[n:path.n#NIL,e:path.e#NIL,s:path.s#NIL,w:path.w#NIL]; list:IWireListPtr_AllocateList[]; wire:IWirePtr_AllocateIWire[]; wire.type_type; wire.h_h; wire.path_path; path.wire_wire; list^_[wire,inter.junction.iwires]; inter.junction.iwires_list; wire.be1_wire.h.n#w OR wire.h.s#w; wire.be2_wire.h.n#w AND wire.h.s#w; wire.bn1_wire.h.e=n OR wire.h.w=n; wire.bn2_wire.h.e=n AND wire.h.w=n; wire.nx_wire.sx_wire.ey_wire.wy_-1; END; END; EnumerateAllPaths[AddIWire]; END; RR:TYPE=PROCEDURE[r:RectanglePtr] RETURNS[x:Lambda]; South:RR={x_r.pos.y+r.levelers.s+r.margins.s}; West:RR ={x_r.pos.x+r.levelers.w+r.margins.w}; North:RR={x_r.pos.y+r.sizeL.y-r.levelers.n-r.margins.n}; East:RR ={x_r.pos.x+r.sizeL.x-r.levelers.e-r.margins.e}; AlreadyUsed:PROCEDURE[s:Side,junct:JunctionPtr,x:RunNo] RETURNS[BOOLEAN]= BEGIN t:BOOLEAN_FALSE; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w:IWirePtr=iwl.h; y:RunNo=SELECT s FROM n=>w.nx, s=>w.sx, e=>w.ey, ENDCASE=>w.wy; IF y=x THEN {IF t THEN RETURN[TRUE]; t_TRUE}; ENDLOOP; RETURN[FALSE]; END; AssignIWires:PROCEDURE[rect:RectanglePtr]=BEGIN junct:JunctionPtr=rect.junction; rw:RectanglePtr=IF rect.w=NIL THEN rect ELSE rect.w; re:RectanglePtr=IF rect.e=NIL THEN rect ELSE rect.e; rn:RectanglePtr=IF rect.n=NIL THEN rect ELSE rect.n; rs:RectanglePtr=IF rect.s=NIL THEN rect ELSE rect.s; ssw:RunNo_MAX[0,(West[rs]-West[rect]+6)/7]; sse:RunNo_MAX[0,(East[rect]-East[rs]+6)/7]; nnw:RunNo_MAX[0,(West[rn]-West[rect]+6)/7]; nne:RunNo_MAX[0,(East[rect]-East[rn]+6)/7]; wsw:RunNo_MAX[0,(South[rw]-South[rect]+6)/7]; ese:RunNo_MAX[0,(South[re]-South[rect]+6)/7]; wnw:RunNo_MAX[0,(North[rect]-North[rw]+6)/7]; ene:RunNo_MAX[0,(North[rect]-North[re]+6)/7]; Setnx:PROCEDURE[b:BOOLEAN]=BEGIN IF w.nx#-1 THEN RETURN; IF nne+nnw=topx+1 THEN Error ELSE IF b THEN {w.nx_topx-nne; nne_nne+1} ELSE {w.nx_nnw; nnw_nnw+1}; IF rect.n.orient=inter AND AlreadyUsed[n,junct,w.nx] THEN {w.nx_-1; Setnx[b]}; END; Setsx:PROCEDURE[b:BOOLEAN]=BEGIN IF w.sx#-1 THEN RETURN; IF sse+ssw=topx+1 THEN Error ELSE IF b THEN {w.sx_topx-sse; sse_sse+1} ELSE {w.sx_ssw; ssw_ssw+1}; IF rect.s.orient=inter AND AlreadyUsed[s,junct,w.sx] THEN {w.sx_-1; Setsx[b]}; END; Setey:PROCEDURE[b:BOOLEAN]=BEGIN IF w.ey#-1 THEN RETURN; IF ene+ese=topy+1 THEN Error ELSE IF b THEN {w.ey_topy-ene; ene_ene+1} ELSE {w.ey_ese; ese_ese+1}; IF rect.e.orient=inter AND AlreadyUsed[e,junct,w.ey] THEN {w.ey_-1; Setey[b]}; END; Setwy:PROCEDURE[b:BOOLEAN]=BEGIN IF w.wy#-1 THEN RETURN; IF wnw+wsw=topy+1 THEN Error ELSE IF b THEN {w.wy_topy-wnw; wnw_wnw+1} ELSE {w.wy_wsw; wsw_wsw+1}; IF rect.w.orient=inter AND AlreadyUsed[w,junct,w.wy] THEN {w.wy_-1; Setwy[b]}; END; ThruNS:PROCEDURE[z:BOOLEAN]={Setnx[z]; Setsx[z]}; ThruEW:PROCEDURE[z:BOOLEAN]={Setwy[z]; Setey[z]}; topx:RunNo_rect.sizeC.x-1; topy:RunNo_rect.sizeC.y-1; w:IWirePtr_NIL; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w_iwl.h; SELECT w.type FROM 05=>{Setnx[TRUE]; Setey[TRUE]}; 06=>{Setsx[TRUE]; Setey[FALSE]}; 09=>{Setnx[FALSE]; Setwy[TRUE]}; 10=>{Setsx[FALSE]; Setwy[FALSE]}; ENDCASE; ENDLOOP; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w_iwl.h; SELECT w.type FROM 07=>Setey[w.h.e=n]; 11=>Setwy[w.h.w=n]; 13=>Setnx[w.h.n#w]; 14=>Setsx[w.h.s#w]; ENDCASE; ENDLOOP; nne_sse_MAX[nne,sse]; nnw_ssw_MAX[nnw,ssw]; ese_wsw_MAX[ese,wsw]; ene_wnw_MAX[ene,wnw]; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w_iwl.h; SELECT w.type FROM 07=>ThruNS[w.be1]; 11=>ThruNS[w.be2]; 13=>ThruEW[w.bn1]; 14=>ThruEW[w.bn2]; ENDCASE; ENDLOOP; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w_iwl.h; IF w.type=15 THEN {ThruNS[w.be1]; ThruEW[w.bn1]}; ENDLOOP; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w_iwl.h; IF w.type=03 THEN ThruNS[w.be1]; IF w.type=12 THEN ThruEW[w.bn1]; ENDLOOP; junct.bridgeNS_nne; junct.bridgeEW_ese; FixNeighbor[rect]; END; FixNeighbor:PROCEDURE[rect:RectanglePtr]=BEGIN rw:RectanglePtr=IF rect.w=NIL THEN rect ELSE rect.w; re:RectanglePtr=IF rect.e=NIL THEN rect ELSE rect.e; rn:RectanglePtr=IF rect.n=NIL THEN rect ELSE rect.n; rs:RectanglePtr=IF rect.s=NIL THEN rect ELSE rect.s; deltxN:RunNo=West[rn]-West[rect]; deltxS:RunNo=West[rs]-West[rect]; deltxE:RunNo=South[re]-South[rect]; deltxW:RunNo=South[rw]-South[rect]; deltaN:RunNo=IF deltxN>=0 THEN (deltxN+6)/7 ELSE (deltxN-6)/7; deltaS:RunNo=IF deltxS>=0 THEN (deltxS+6)/7 ELSE (deltxS-6)/7; deltaE:RunNo=IF deltxE>=0 THEN (deltxE+6)/7 ELSE (deltxE-6)/7; deltaW:RunNo=IF deltxW>=0 THEN (deltxW+6)/7 ELSE (deltxW-6)/7; Sub:PROCEDURE[rect:RectanglePtr,w:IWirePtr]=BEGIN IF w.path.n#NIL AND w.path.n.wire#NIL AND w.path.n.wire.sx=-1 THEN w.path.n.wire.sx_w.nx-deltaN; IF w.path.s#NIL AND w.path.s.wire#NIL AND w.path.s.wire.nx=-1 THEN w.path.s.wire.nx_w.sx-deltaS; IF w.path.e#NIL AND w.path.e.wire#NIL AND w.path.e.wire.wy=-1 THEN w.path.e.wire.wy_w.ey-deltaE; IF w.path.w#NIL AND w.path.w.wire#NIL AND w.path.w.wire.ey=-1 THEN w.path.w.wire.ey_w.wy-deltaW; END; EnumerateIWire[rect,Sub]; END; CheckInter:PROCEDURE[rect:RectanglePtr,w:IWirePtr]=BEGIN lastx:INTEGER=rect.sizeC.x-1; realType:InterType=MakeType[n:w.nx#-1,e:w.ey#-1,s:w.sx#-1,w:w.wy#-1]; IF w.type#realType THEN Error; IF w.sx NOT IN [-1..rect.sizeC.x) THEN Error; IF w.nx NOT IN [-1..rect.sizeC.x) THEN Error; IF w.ey NOT IN [-1..rect.sizeC.y) THEN Error; IF w.wy NOT IN [-1..rect.sizeC.y) THEN Error; IF w.sx#-1 AND w.nx#-1 AND w.sx#w.nx THEN Error; IF w.ey#-1 AND w.wy#-1 AND w.ey#w.wy THEN Error; FOR iwl2:IWireListPtr_rect.junction.iwires,iwl2.t UNTIL iwl2=NIL DO w2:IWirePtr=iwl2.h; IF w2=w THEN EXIT; IF w.nx=w2.nx AND w.nx#-1 THEN Error; IF w.sx=w2.sx AND w.sx#-1 THEN Error; IF w.ey=w2.ey AND w.ey#-1 THEN Error; IF w.wy=w2.wy AND w.wy#-1 THEN Error; ENDLOOP; END; ShowInter:PROCEDURE[rect:RectanglePtr]=BEGIN junct:JunctionPtr=rect.junction; LineHor:PROCEDURE[lev,st,end:INTEGER]=BEGIN IF end=-1 THEN end_lasty; lev_2*lev+2; st_2*st+2; end_2*end+2; FOR j:INTEGER IN [st..end] DO Store[lev,j]; ENDLOOP; END; LineVer:PROCEDURE[lev,st,end:INTEGER]=BEGIN IF end=-1 THEN end_lastx; lev_2*lev+2; st_2*st+2; end_2*end+2; FOR j:INTEGER IN [st..end] DO Store[j,lev]; ENDLOOP; END; Store:PROCEDURE[x,y:INTEGER]=BEGIN IF x NOT IN [0..size/2) THEN {x_x-2*lastx-2+size-1; IF x NOT IN [size/2..size) THEN RETURN}; IF y NOT IN [0..size/2) THEN {y_y-2*lasty-2+size-1; IF y NOT IN [size/2..size) THEN RETURN}; copout[x][y]_TRUE; END; size:INTEGER=28; copout:ARRAY [0..size) OF ARRAY [0..size) OF BOOLEAN_ALL[ALL[FALSE]]; topY:INTEGER_0; lastx:INTEGER=rect.sizeC.x-1; lasty:INTEGER=rect.sizeC.y-1; Return[]; ShowDecimal[rect.channelNo,"Int "L]; Return[]; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w:IWirePtr=iwl.h; SELECT w.type FROM 03=> LineVer[w.sx,-1,-1]; 05=>{LineHor[w.ey,w.nx,-1]; LineVer[w.nx,w.ey,-1]}; 06=>{LineHor[w.ey,w.sx,-1]; LineVer[w.sx,-1,w.ey]}; 07=>{LineHor[w.ey,w.sx,-1]; LineVer[w.nx,-1,-1]}; 09=>{LineHor[w.wy,-1,w.nx]; LineVer[w.nx,w.wy,-1]}; 10=>{LineHor[w.wy,-1,w.sx]; LineVer[w.sx,-1,w.wy]}; 11=>{LineHor[w.wy,-1,w.sx]; LineVer[w.sx,-1,-1]}; 12=> LineHor[w.wy,-1,-1]; 13=>{LineHor[w.wy,-1,-1]; LineVer[w.nx,w.wy,-1]}; 14=>{LineHor[w.wy,-1,-1]; LineVer[w.sx,-1,w.wy]}; 15=>{LineHor[w.wy,-1,-1]; LineVer[w.sx,-1,-1]}; ENDCASE=>Error; ENDLOOP; Return[]; FOR i:INTEGER DECREASING IN [0..size) DO found:BOOLEAN_FALSE; FOR j:INTEGER IN [0..size) DO IF copout[i][j] THEN found_TRUE; EXIT; ENDLOOP; IF found THEN {topY_i+1; EXIT}; ENDLOOP; FOR i:INTEGER DECREASING IN [0..topY) DO y:INTEGER=i; --y:INTEGER=SELECT i FROM 0=>0, 2*lasty+2=>i-2, ENDCASE=>i-1; Return[]; FOR j:INTEGER IN [0..size) DO --z:INTEGER=SELECT j FROM 0=>0, 2*lastx+2=>j-2, ENDCASE=>j-1; z:INTEGER=j; ShowChar[IF copout[y][z] THEN 'b ELSE ' ]; ENDLOOP; ENDLOOP; END; ShowIWire:PROCEDURE[inter:RectanglePtr]=BEGIN Return[]; FOR wl:IWireListPtr_inter.junction.iwires,wl.t UNTIL wl=NIL DO wire:IWirePtr=wl.h; Return[]; ShowDecimal[wire.type, " type: "]; ShowDecimal[wire.nx, " nx: "]; ShowDecimal[wire.sx, " sx "]; ShowDecimal[wire.ey, " ey: "]; ShowDecimal[wire.wy, " wy: "]; ENDLOOP; END; InterSilicon:PUBLIC PROCEDURE[rect:RectanglePtr]=BEGIN junct:JunctionPtr=rect.junction; sB:Lambda_spaceB_rect.margins.s+rect.levelers.s; x:Lambda=rect.pos.x; width:Lambda=rect.sizeL.x; lastx:INTEGER=rect.sizeC.x-1; edge:Lambda=East[rect]-Across[lastx]-3; y:Lambda=rect.pos.y; LineHor:PROCEDURE[lev,st,end:INTEGER]=BEGIN yy:Lambda=y+AcrossS[lev]; xBot:Lambda=IF st=-1 THEN x ELSE edge+Across[st]; xTop:Lambda=IF end=-1 THEN x+rect.sizeL.x ELSE edge+Across[end]+3; MakeBlue[TRUE,xBot,yy,xTop-xBot]; END; LineVer:PROCEDURE[lev,st,end:INTEGER]=BEGIN xx:Lambda=edge+Across[lev]; yBot:Lambda=IF st=-1 THEN 0 ELSE AcrossS[st]; yTop:INTEGER=IF end=-1 THEN rect.sizeL.y ELSE AcrossS[end]+3; MakeBlue[FALSE,xx,y+yBot,yTop-yBot]; END; MakeBridge[rect]; FOR iwl:IWireListPtr_junct.iwires,iwl.t UNTIL iwl=NIL DO w:IWirePtr=iwl.h; SELECT w.type FROM 03=> LineVer[w.sx,-1,-1]; 05=>{LineHor[w.ey,w.nx,-1]; LineVer[w.nx,w.ey,-1]}; 06=>{LineHor[w.ey,w.sx,-1]; LineVer[w.sx,-1,w.ey]}; 07=>{LineHor[w.ey,w.sx,-1]; LineVer[w.nx,-1,-1]}; 09=>{LineHor[w.wy,-1,w.nx]; LineVer[w.nx,w.wy,-1]}; 10=>{LineHor[w.wy,-1,w.sx]; LineVer[w.sx,-1,w.wy]}; 11=>{LineHor[w.wy,-1,w.sx]; LineVer[w.sx,-1,-1]}; 12=> LineHor[w.wy,-1,-1]; 13=>{LineHor[w.wy,-1,-1]; LineVer[w.nx,w.wy,-1]}; 14=>{LineHor[w.wy,-1,-1]; LineVer[w.sx,-1,w.wy]}; 15=>{LineHor[w.wy,-1,-1]; LineVer[w.sx,-1,w.wy]; LineVer[w.sx,w.wy,-1];}; ENDCASE=>Error; ENDLOOP; END; Bridge:TYPE=ARRAY[0..4) OF Span_ALL[[]]; Span:TYPE=RECORD[none,hRed:BOOLEAN_TRUE,n,e:Lambda_-1,s,w:Lambda_bigRun]; SpanPtr:TYPE=POINTER TO Span; MakeBridge:PUBLIC PROCEDURE[rect:RectanglePtr]=BEGIN j:JunctionPtr=rect.junction; x:Lambda=rect.pos.x; y:Lambda=rect.pos.y; l:INTEGER; lastx:INTEGER=rect.sizeC.x-1; edge:Lambda=x+rect.sizeL.x-Across[lastx]-rect.margins.e-rect.levelers.e-3; bridge_ALL[[]]; FOR iwl:IWireListPtr_j.iwires,iwl.t UNTIL iwl=NIL DO w:IWirePtr=iwl.h; a,b,c,d:INTEGER_-1; SELECT w.type FROM 03=>{a_IF w.be1 THEN 2 ELSE 0; b_a+1}; 05=>IF w.nx>=j.bridgeNS THEN {IF w.eyIF w.sx>=j.bridgeNS THEN {IF w.ey>=j.bridgeEW THEN {a_c_3; b_2}} ELSE IF w.ey>=j.bridgeEW THEN {b_d_1; a_0; c_3} ELSE {d_2; a_c_0}; 07=>{a_IF w.be1 THEN 2 ELSE 0; b_a+1; c_IF w.h.e=n THEN 3 ELSE 2; IF a=0 THEN d_c-2}; 09=>IF w.nxIF w.sx=j.bridgeEW THEN {a_c_1; b_0}} ELSE IF w.wy>=j.bridgeEW THEN {b_d_3; a_2; c_1} ELSE {d_0; a_c_2}; 11=>{a_IF w.be2 THEN 2 ELSE 0; b_a+1; d_IF w.h.w=n THEN 1 ELSE 0; IF a=2 THEN d_c+2}; 12=>{c_IF w.bn1 THEN 1 ELSE 0; d_c+2}; 13=>{c_IF w.bn1 THEN 1 ELSE 0; d_c+2; b_IF w.h.n#w THEN 3 ELSE 1; IF c=1 THEN a_b-1}; 14=>{c_IF w.bn2 THEN 1 ELSE 0; d_c+2; a_IF w.h.s#w THEN 2 ELSE 0; IF c=0 THEN a_b+1}; 15=>{a_IF w.be1 THEN 2 ELSE 0; b_a+1; c_IF w.bn1 THEN 1 ELSE 0; d_c+2}; ENDCASE=>LOOP; IF a#-1 THEN {l_w.sx; IF l=-1 OR l=bigRun THEN l_w.nx; bridge[a].e_MAX[bridge[a].e,l]; bridge[a].w_MIN[bridge[a].w,l]}; IF b#-1 THEN {l_w.sx; IF l=-1 OR l=bigRun THEN l_w.nx; bridge[b].e_MAX[bridge[b].e,l]; bridge[b].w_MIN[bridge[b].w,l]}; IF c#-1 THEN {l_w.ey; IF l=-1 OR l=bigRun THEN l_w.wy; bridge[c].s_MIN[bridge[c].s,l]; bridge[c].n_MAX[bridge[c].n,l]}; IF d#-1 THEN {l_w.ey; IF l=-1 OR l=bigRun THEN l_w.wy; bridge[d].s_MIN[bridge[d].s,l]; bridge[d].n_MAX[bridge[d].n,l]}; ENDLOOP; FOR i:INTEGER IN [0..4) DO span:SpanPtr_@bridge[i]; IF span.e=-1 OR span.n=-1 OR span.w=bigRun OR span.s=bigRun THEN LOOP; span.w_MAX[edge+Across[span.w]-3,x-4]; span.e_MIN[edge+Across[span.e]+7,x+rect.sizeL.x]; span.s_MAX[y+AcrossS[span.s]-3,y-4]; span.n_MIN[y+AcrossS[span.n]+7,y+rect.sizeL.y]; span.none_FALSE; ENDLOOP; Return[]; ShowDecimal[rect.channelNo, "bridge "]; FOR i:INTEGER IN [0..4) DO span:SpanPtr_@bridge[i]; Return[]; ShowString[IF span.none THEN " off " ELSE IF span.hRed THEN " hor " ELSE " vert "]; ShowDecimal[span.w, " w "]; ShowDecimal[span.e, " e "]; ShowDecimal[span.n, " n "]; ShowDecimal[span.s, " s "]; ENDLOOP; END; MakeBlue:PROCEDURE[hor:BOOLEAN,x,y,l:Lambda]=BEGIN IF l<0 THEN {IF hor THEN x_x+l ELSE y_y+l; l_-l}; IF hor THEN FOR i:INTEGER IN [0..4) DO s:SpanPtr_@bridge[i]; x1,x2:Lambda; IF s.none OR ~s.hRed THEN LOOP; IF y NOT IN [s.s..s.n) THEN LOOP; IF x NOT IN (s.w-l..s.e] THEN LOOP; IF ~s.hRed THEN BEGIN IF x IN (s.w..s.e] THEN MakeContact[x,y]; IF x+l IN (s.w..s.e] THEN MakeContact[x+l-3,y]; LOOP; END; x1_IF xs.e-3 THEN s.e ELSE x+l-4; IF xs.n-3 THEN s.n ELSE y+l-4; IF yi.n, s=>i.s, e=>i.e, ENDCASE=>i.w; excessL:Lambda=SELECT ss FROM n,s=>East[i]-East[j], ENDCASE=>South[j]-South[i]; excessC:RunNo=excessL/7; desNo:RunNo=SELECT ss FROM n,s=>top-desired-excessC, ENDCASE=>excessC+desired; w:IWirePtr_FindOne[p,ss,desNo]; IF w=NIL OR j=NIL THEN {Error; RETURN[0]}; w.circuit_p.circuit; BEGIN myNo:RunNo=SELECT ss FROM n=>top-w.nx, s=>top-w.sx, e=>w.ey, ENDCASE=>w.wy; IF excessC>myNo THEN Error; RETURN[myNo-excessC]; END; END; FindOne:PUBLIC PROCEDURE[p:PathPtr,ss:Side,desired:RunNo] RETURNS[w:IWirePtr]=BEGIN best:INTEGER_10000; i:RectanglePtr=p.inter; ns:BOOLEAN=ss=n OR ss=s; type:InterType=MakeType[n:p.n#NIL,e:p.e#NIL,s:p.s#NIL,w:p.w#NIL]; FOR iwl:IWireListPtr_i.junction.iwires,iwl.t UNTIL iwl=NIL DO ww:IWirePtr_iwl.h; IF ww.type=type AND ww.circuit=p.circuit THEN RETURN[ww]; ENDLOOP; w_NIL; FOR iwl:IWireListPtr_i.junction.iwires,iwl.t UNTIL iwl=NIL DO ww:IWirePtr_iwl.h; IF ww.type=type AND ww.circuit=-1 -- AND EquivalentHugs[p.huggers,ww.h] THEN BEGIN this:RunNo=SELECT ss FROM e=>ww.ey, w=>ww.wy, n=>ww.nx, ENDCASE=>ww.sx; IF this=desired THEN RETURN[ww]; SELECT ABS[this-desired]-best FROM <0 => {w_ww; best_ABS[this-desired]}; -- 0 =>IF (SELECT type FROM -- 03=>ww.be1, 05=>ns, 06=>TRUE, 10=>~ns, 12=>~ww.bn1, -- 07=>IF ns THEN ww.be1 ELSE ww.h.e#n, -- 11=>IF ns THEN ww.be2 ELSE ww.h.w#n, -- 13=>IF ~ns THEN ~ww.bn1 ELSE ww.h.n#w, -- 14=>IF ~ns THEN ~ww.bn2 ELSE ww.h.s#w, -- 15=>IF ~ns THEN ~ww.bn1 ELSE ww.be1, -- ENDCASE=>FALSE)=(this