-- procedure exporting module of silicon (pretty picture) program -- last modified by McCreight, December 3, 1982 9:40 AM -- to remove repeated objects DIRECTORY InlineDefs, SegmentDefs, StringDefs, ppdddefs,ppddefs, pppdefs, ppdefs; ppprocs: PROGRAM IMPORTS ppdefs, ppddefs, ppdddefs, InlineDefs, pppdefs EXPORTS ppdefs,ppdddefs = BEGIN OPEN ppdefs, ppdddefs,ppddefs, SegmentDefs, InlineDefs, pppdefs; anyChanges, sinceIOchanges: PUBLIC BOOLEAN ← FALSE; Width: TYPE = locNum ← 0; minWidthAr: PUBLIC ARRAY level OF Width ← [ cut: 2*Lambda, dif: 2*Lambda, pol: 2*Lambda, met: 3*Lambda, cut2: 3*Lambda, pdif: 2*Lambda, met2: 4*Lambda]; bwGrain: PUBLIC INTEGER ← 10; colGrain: PUBLIC INTEGER ← 1; wireList: PUBLIC ARRAY level OF LONG POINTER TO wire object ← ALL[NIL]; tranList: PUBLIC LONG POINTER TO xstr object ← NIL; puList: PUBLIC LONG POINTER TO xstr object ← NIL; contList: PUBLIC LONG POINTER TO cont object ← NIL; textProcs:Procs ← [ drawme:ALL[drText],inBox:rectIB,inMe:inMeRect,release:nullRel, anotherme:permAnother,setParm:setNullParm]; rectProcs:Procs ← [ drawme:[ drRect0,drRect0,drRect0,drRect0,drRect2,drRect2,drRect2,drRect2, drRect0,drRect0,drRect0,drRect0,drRect2,drRect2,drRect2,drRect2], inBox:rectIB,inMe:inMeRect,release:refCntRelease,anotherme:permAnother, setParm:setWireParm]; xstrProcs:Procs ← [ drawme:[ drXstr0,drXstr0,drXstr0,drXstr0,drXstr2,drXstr2,drXstr2,drXstr2, drXstr0,drXstr0,drXstr0,drXstr0,drXstr2,drXstr2,drXstr2,drXstr2], inBox:rectIB,inMe:inMeRect,release:refCntRelease,anotherme:permAnother, setParm:setXstrParm]; pxstrProcs:Procs ← [ drawme:[ drXstr0,drXstr0,drXstr0,drXstr0,drXstr2,drXstr2,drXstr2,drXstr2, drXstr0,drXstr0,drXstr0,drXstr0,drXstr2,drXstr2,drXstr2,drXstr2], inBox:rectIB,inMe:inMeRect,release:refCntRelease,anotherme:permAnother, setParm:setPXstrParm]; angxstrProcs:Procs ← [ drawme:[ drAXstr0,drAXstrR0,drAXstr0,drAXstrR0,drAXstr2,drAXstrR2,drAXstr2,drAXstrR2, drAXstr4,drAXstrR4,drAXstr4,drAXstrR4,drAXstr6,drAXstrR6,drAXstr6,drAXstrR6], inBox:rectIB,inMe:inMeRect,release:refCntRelease,anotherme:permAnother, setParm:setAXstrParm]; cellProcs:Procs ← [ drawme:[ drCell0,drCell0R,drCell0,drCell0R,drCell2,drCell2R,drCell2,drCell2R, drCell4,drCell4R,drCell4,drCell4R,drCell6,drCell6R,drCell6,drCell6R], inBox:rectIB,inMe:inMeRect,release:cellRel,anotherme:permAnother, setParm:setNullParm]; wireProcs:Procs ← [ drawme:[ drWire0,drWire0,drWire0,drWire0,drWire2,drWire2,drWire2,drWire2, drWire0,drWire0,drWire0,drWire0,drWire2,drWire2,drWire2,drWire2], inBox:rectIB,inMe:inMeRect,release:refCntRelease,anotherme:permAnother, setParm:setWireParm]; pwireProcs:Procs ← [ drawme:[ drPWire0,drPWire0,drPWire0,drPWire0,drPWire2,drPWire2,drPWire2,drPWire2, drPWire0,drPWire0,drPWire0,drPWire0,drPWire2,drPWire2,drPWire2,drPWire2], inBox:rectIB,inMe:inMeRect,release:refCntRelease,anotherme:permAnother, setParm:setWireParm]; busProcs:Procs ← [ drawme:[ drBus0,drBusR0,drBus0,drBusR0,drBus2,drBusR2,drBus2,drBusR2, drBus4,drBusR4,drBus4,drBusR4,drBus6,drBusR6,drBus6,drBusR6], inBox:rectIB,inMe:inMeRect,release:uniqueRelease,anotherme:busAnother, setParm:setBusParm]; puProcs:Procs ← [ drawme:[ drPu0,drPu0,drPu0,drPu0,drPu2,drPu6,drPu2,drPu6,drPu4,drPu4,drPu4, drPu4,drPu6,drPu2,drPu6,drPu2],inBox:rectIB,inMe:inMeRect, release:refCntRelease,anotherme:permAnother,setParm:setPuParm]; bcProcs:Procs ← [ drawme:[ drBC0,drBC0,drBC0,drBC0,drBC2,drBC6,drBC2,drBC6,drBC4,drBC4,drBC4, drBC4,drBC6,drBC2,drBC6,drBC2],inBox:rectIB,inMe:inMeRect, release:nullRel,anotherme:permAnother,setParm:setNullParm]; mcProcs:Procs ← [ drawme:[ drMDC0,drMDC0,drMDC0,drMDC0,drMDC2,drMDC2,drMDC2,drMDC2,drMDC0,drMDC0, drMDC0,drMDC0,drMDC2,drMDC2,drMDC2,drMDC2],inBox:rectIB,inMe:inMeRect, release:refCntRelease,anotherme:permAnother,setParm:setContParm]; dcProcs:Procs ← [ drawme:[ drDC0,drDC0,drDC0,drDC0,drDC2,drDC2,drDC2,drDC2,drDC0,drDC0,drDC0, drDC0,drDC2,drDC2,drDC2,drDC2],inBox:rectIB,inMe:inMeRect, release:refCntRelease,anotherme:permAnother,setParm:setContParm]; mpdcProcs:Procs ← [ drawme:[ drMPDC0,drMPDC0,drMPDC0,drMPDC0,drMPDC2,drMPDC2,drMPDC2,drMPDC2, drMPDC0,drMPDC0,drMPDC0, drMPDC0,drMPDC2,drMPDC2,drMPDC2,drMPDC2],inBox:rectIB,inMe:inMeRect, release:refCntRelease,anotherme:permAnother,setParm:setContParm]; pdcProcs:Procs ← [ drawme:[ drPDC0,drPDC0,drPDC0,drPDC0,drPDC2,drPDC2,drPDC2,drPDC2, drPDC0,drPDC0,drPDC0, drPDC0,drPDC2,drPDC2,drPDC2,drPDC2],inBox:rectIB,inMe:inMeRect, release:refCntRelease,anotherme:permAnother,setParm:setContParm]; bucProcs:Procs ← [ drawme:[ drBuC0,drBuC4,drBuC0,drBuC4,drBuC2,drBuC2,drBuC2,drBuC2, drBuC4,drBuC0,drBuC4,drBuC0,drBuC6,drBuC6,drBuC6,drBuC6], inBox:rectIB,inMe:inMeRect, release:refCntRelease,anotherme:permAnother,setParm:setBuContParm]; mmcProcs:Procs ← [ drawme:[ drMM0,drMM0,drMM0,drMM0,drMM2,drMM2,drMM2,drMM2,drMM0,drMM0,drMM0, drMM0,drMM2,drMM2,drMM2,drMM2],inBox:rectIB,inMe:inMeRect, release:refCntRelease,anotherme:permAnother,setParm:setContParm]; bcObject:cont object ← [ p:@bcProcs,size:[butconSX,butconSY,butconSX],l:cut,refCnt:0, returnable:FALSE,marked:FALSE, varpart:cont[typ:butt,magicN:butconSX/4]]; cnTextProcs:Procs ← [ drawme:ALL[drCnText],inBox:rectIB,inMe:inMeRect,release:cnRelease, anotherme:permAnother,setParm:setNullParm]; nullRel: relProc = BEGIN ob.refCnt ← ob.refCnt - 1; END; refCntRelease: relProc = BEGIN ob.refCnt ← ob.refCnt - 1; -- IF ob.refCnt>1 THEN ob.refCnt←ob.refCnt-1 -- ELSE FreeSpace[ob]; END; cellRel: relProc = BEGIN cc: LONG POINTER TO cell object; ob.refCnt ← ob.refCnt - 1; IF ob.refCnt > 0 OR NOT ob.returnable THEN RETURN; cc ← LOOPHOLE[ob]; flushDel[cc.ptr]; freeCell[cc]; END; cnRelease: relProc = BEGIN p: LONG POINTER TO cnText object = LOOPHOLE[ob]; FreeString[p.s]; FreeSpace[ob]; END; uniqueRelease: relProc = BEGIN FreeSpace[ob]; END; permAnother: anoProc = BEGIN ob.refCnt ← ob.refCnt + 1; RETURN[ob]; END; busAnother: anoProc = BEGIN nob:LONG POINTER TO bus object ← alocBusD[]; oob:LONG POINTER TO bus object = LOOPHOLE[ob]; nob↑←oob↑; RETURN[nob]; END; makePullup: PUBLIC PROCEDURE [w,l:INTEGER,wExt:INTEGER←wXExtension,lExt:INTEGER←lXExtension] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO xstr object ← puList; w ← MAX[w, 2*Lambda]; l ← MAX[l, 2*Lambda]; wExt ← MAX[wExt, 0]; lExt ← MAX[lExt, 0]; WHILE dp # NIL DO IF dp.width = w AND dp.length = l AND dp.wExt = wExt AND dp.lExt = lExt AND dp.l=dif THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocXstrD[]; dp.super ← puList; puList ← dp; p↑.p ← @puProcs; dp↑.l ← dif; dp↑.width ← w; dp↑.length ← l; dp↑.wExt ← wExt; dp↑.lExt ← lExt; dp↑.impl ← TRUE; dp↑.pullup ← TRUE; dp↑.size[0] ← dp↑.size[2] ← MAX[dp.width + dp.wExt*2, 4*Lambda]; dp↑.size[1] ← MAX[dp.length + dp.lExt + 3*Lambda, 6*Lambda]; END; -- of makePullup makeXstr: PUBLIC PROCEDURE [w, l: INTEGER, imp: BOOLEAN ← FALSE , wExt: INTEGER ← wXExtension, lExt: INTEGER ← lXExtension] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO xstr object ← tranList; w ← MAX[w, 2*Lambda]; l ← MAX[l, 2*Lambda]; wExt ← MAX[wExt, 0]; lExt ← MAX[lExt, 0]; WHILE dp # NIL DO IF dp.width = w AND dp.length = l AND dp.impl = imp AND dp.wExt = wExt AND dp.lExt = lExt AND NOT dp.angle AND dp.l=dif THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocXstrD[]; dp.super ← tranList; tranList ← dp; p↑.p ← @xstrProcs; dp↑.l ← dif; dp↑.width ← w; dp↑.length ← l; dp↑.wExt ← wExt; dp↑.lExt ← lExt; dp↑.impl ← imp; dp↑.pullup ← FALSE; dp↑.size[0] ← dp↑.size[2] ← dp.width + dp.wExt*2; dp↑.size[1] ← dp.length + dp.lExt*2; END; -- of makeXstr makeAngleXstr: PUBLIC PROCEDURE [w, l: INTEGER, imp: BOOLEAN ← FALSE , wExt: INTEGER ← wXExtension, lExt: INTEGER ← lXExtension,aExt:INTEGER←0] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO xstr object ← tranList; siz1:INTEGER; wExt ← MAX[wExt, 0]; lExt ← MAX[lExt, 0]; aExt ← MAX[aExt, -lExt]; l ← MAX[l, 2*Lambda]; w ← MAX[w, 2*lExt]; -- the width of the straight-line -- parts of the gate, excluding the corner siz1 ← wExt+2*lExt+aExt+l; WHILE dp # NIL DO IF dp.width = w AND dp.length = l AND dp.impl = imp AND dp.wExt=wExt AND dp.lExt=lExt AND dp.angle AND dp.size[1]=siz1 AND dp.l=dif THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocXstrD[]; dp.super ← tranList; tranList ← dp; p↑.p ← @angxstrProcs; dp↑.l ← dif; dp↑.width ← w; dp↑.length ← l; dp↑.wExt ← wExt; dp↑.lExt ← lExt; dp↑.impl ← imp; dp↑.angle ← TRUE; dp↑.pullup ← FALSE; dp↑.size[0] ← dp↑.size[2] ← wExt+(w-lExt-aExt)+l+lExt; dp↑.size[1] ← siz1; END; makePXstr: PUBLIC PROCEDURE [w,l:INTEGER,imp:BOOLEAN←FALSE, wExt:INTEGER←wXExtension,lExt:INTEGER←lXExtension ,surr:INTEGER←wellSurround] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO xstr object ← tranList; w ← MAX[w, 2*Lambda]; l ← MAX[l, 2*Lambda]; wExt ← MAX[wExt, 0]; lExt ← MAX[lExt, 0]; WHILE dp # NIL DO IF dp.width = w AND dp.length = l AND dp.impl = imp AND dp.wExt = wExt AND dp.lExt = lExt AND NOT dp.angle AND dp.l=pdif AND dp.surround=surr THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocXstrD[]; dp.super ← tranList; tranList ← dp; p↑.p ← @pxstrProcs; dp↑.l ← pdif; dp↑.surround ← surr; dp↑.width ← w; dp↑.length ← l; dp↑.wExt ← wExt; dp↑.lExt ← lExt; dp↑.impl ← imp; dp↑.pullup ← FALSE; dp↑.size[0] ← dp↑.size[2] ← w + dp.wExt*2; dp↑.size[1] ← l + dp.lExt*2; END; makeRect: PUBLIC PROCEDURE [x, y: INTEGER, l: level] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO rect object; x ← MAX[x, 1]; y ← MAX[y, 1]; p ← dp ← alocRectD[]; p↑.p ← @rectProcs; dp↑.size[0] ← dp↑.size[2] ← x; dp↑.size[1] ← y; dp↑.l ← l; END; makeText: PUBLIC PROCEDURE [s: STRING] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO text object; p ← dp ← alocTextD[]; p↑.p ← @textProcs; dp↑.size[0] ← dp↑.size[2] ← 6*s.length; dp↑.size[1] ← 8; dp↑.s ← s; dp↑.l ← cut; END; makeCnText: PUBLIC PROCEDURE [ s: STRING, xw, byw, yw: INTEGER, op: LONG POINTER TO cell object, np: LONG POINTER TO cList] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO cnText object; p ← dp ← alocCnTextD[]; p↑.p ← @cnTextProcs; dp↑.size[0] ← xw; dp↑.size[1] ← byw; dp↑.size[2] ← byw*yw; dp↑.s ← newString[s]; dp↑.np ← np; dp↑.op ← op; END; makeButcon: PUBLIC PROCEDURE RETURNS [p: LONG POINTER TO object] = BEGIN p ← @bcObject; p.refCnt ← p.refCnt + 1; END; makePolycon: PUBLIC PROCEDURE [lll: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO cont object ← contList; IF lll < butconSX THEN lll ← butconSX; WHILE dp # NIL DO IF dp.size[1] = lll AND dp.typ = mPol THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← butconSX; dp.size[1] ← lll; dp.p ← @dcProcs; dp.typ ← mPol; dp.magicN ← butconSX/4; dp.l←pol END; makeDifcon: PUBLIC PROCEDURE [lll: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO cont object ← contList; IF lll < butconSX THEN lll ← butconSX; WHILE dp # NIL DO IF dp.size[1] = lll AND dp.typ = mDif THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← butconSX; dp.size[1] ← lll; dp.p ← @dcProcs; dp.typ ← mDif; dp.magicN ← butconSX/4; dp.l←dif END; makeMmDifcon: PUBLIC PROCEDURE [lll: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN mins:INTEGER=cut2min+2*mmContExt; dp: LONG POINTER TO cont object ← contList; IF lll < mins THEN lll ← mins; WHILE dp # NIL DO IF dp.size[1] = lll AND dp.typ = mmDif THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← mins; dp.size[1] ← lll; dp.p ← @mcProcs; dp.typ ← mmDif; dp.magicN ← (mins-4)/2; dp.m2Ext ← (mins-butconSX)/2; dp.c2Ext ← mmContExt; dp.l←dif END; makeMmPolcon: PUBLIC PROCEDURE [lll: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN mins:INTEGER=cut2min+2*mmContExt; dp: LONG POINTER TO cont object ← contList; IF lll < mins THEN lll ← mins; WHILE dp # NIL DO IF dp.size[1] = lll AND dp.typ = mmPol THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← mins; dp.size[1] ← lll; dp.p ← @mcProcs; dp.typ ← mmPol; dp.magicN ← (mins-4)/2; dp.m2Ext ← (mins-butconSX)/2; dp.c2Ext ← mmContExt; dp.l←pol END; makeNwellcon: PUBLIC PROCEDURE [lll: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO cont object ← contList; IF lll < butconSX THEN lll ← butconSX; WHILE dp # NIL DO IF dp.size[1] = lll AND dp.typ = nwell THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← butconSX; dp.size[1] ← lll; dp.p ← @dcProcs; dp.typ ← nwell; dp.magicN ← butconSX/4; dp.l←nwelCont END; makePDifcon: PUBLIC PROCEDURE [lll: INTEGER,surr:INTEGER←wellSurround] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO cont object ← contList; IF lll < butconSX THEN lll ← butconSX; WHILE dp # NIL DO IF dp.size[1] = lll AND dp.typ = mPDif AND dp.surround=surr THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← butconSX; dp.size[1] ← lll; dp.p ← @pdcProcs; dp.typ ← mPDif; dp.magicN ← butconSX/4; dp.l←pdif; dp.surround←surr; END; makeMPDifcon: PUBLIC PROCEDURE [lll: INTEGER,surr:INTEGER←wellSurround] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO cont object ← contList; mins:INTEGER=cut2min+2*mmContExt; IF lll < mins THEN lll ← mins; WHILE dp # NIL DO IF dp.size[1] = lll AND dp.typ = mmPDif AND dp.surround=surr THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← mins; dp.size[1] ← lll; dp.surround←surr; dp.p ← @mpdcProcs; dp.typ ← mmPDif; dp.magicN ← (mins-4)/2; dp.m2Ext ← (mins-butconSX)/2; dp.c2Ext ← mmContExt; dp.l←pdif END; makeBuCont: PUBLIC PROCEDURE [wid,len,wex,lex: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN dp: LONG POINTER TO cont object ← contList; IF wex<0 THEN wex←0;IF lex<0 THEN lex←0; IF wid < 2*wex+2 THEN wid ← 2*wex+2; IF len < 2*lex+4 THEN len ← 2*lex+4; WHILE dp # NIL DO IF dp.typ=burr AND dp.size[1] = len AND dp.size[0] = wid AND dp.wExt=wex AND dp.lExt=lex THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← wid; dp.size[1] ← len; dp.p ← @bucProcs; dp.typ ← burr; dp.wExt←wex; dp.lExt←lex; dp.magicN←IF wid>=2*wex+4 THEN 0 ELSE 2*wex+4-wid; END; makeMmCont: PUBLIC PROCEDURE [len,wex,lex: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN mins:INTEGER=cut2min+2*mmContExt; dp: LONG POINTER TO cont object ← contList; IF len < mins THEN len ← mins; -- IF wex<0 THEN wex←0;IF lex<0 THEN lex←0; -- IF wid < 2*wex+2 THEN wid ← 2*wex+2; -- IF len < 2*lex+4 THEN len ← 2*lex+4; WHILE dp # NIL DO IF dp.typ=mm2 AND dp.size[1] = len --AND dp.size[0] = wid AND --dp.wExt=wex AND dp.lExt=lex --THEN BEGIN p ← dp.p.anotherme[dp]; RETURN; END; dp ← dp.super; ENDLOOP; p ← dp ← alocContD[]; dp.super ← contList; contList ← dp; dp.size[0] ← dp.size[2] ← mins; dp.size[1] ← len; dp.p ← @mmcProcs; dp.typ ← mm2; -- dp.wExt←wex; -- dp.lExt←lex; dp.magicN←mmContExt; END; makeWire:PUBLIC PROCEDURE[len,wid:INTEGER,l:level,surr:INTEGER←wellSurround] RETURNS [p: LONG POINTER TO object] = BEGIN dc: LONG POINTER TO wire object; IF wireOK[l]--=dif OR l=pol OR l=met OR l=met2-- THEN BEGIN dc ← wireList[l]; WHILE dc # NIL DO IF dc.size[0] = wid AND dc.size[1] = len AND (l#pdif OR dc.surround=surr) THEN BEGIN p ← dc.p.anotherme[dc]; RETURN; END; dc ← dc.super; ENDLOOP; END; p ← dc ← alocWireD[]; IF wireOK[l] THEN BEGIN dc.super ← wireList[l]; wireList[l] ← dc; END; p↑.p ← IF NOT wireOK[l] THEN @rectProcs ELSE IF l=pdif THEN @pwireProcs ELSE @wireProcs; -- IF l=pdif THEN {dc.size[0]←dc.size[2]←wid+2*tubMinExt; -- dc.size[1]←len+2*tubMinExt;} -- ELSE {--dc↑.size[0] ← dc↑.size[2] ← wid; dc↑.size[1] ← len;--}; dc.surround←IF l=pdif THEN surr ELSE 0; dc↑.l ← l; END; makeBus: PUBLIC PROCEDURE [len, wid: INTEGER, l: level, cnt, spc, tinc, binc: INTEGER] RETURNS [p: LONG POINTER TO object] = BEGIN b: LONG POINTER TO bus object; p ← b ← alocBusD[]; p↑.p ← @busProcs; b.wspace ← spc; b.firstLength ← len; b.topIncr ← tinc; b.lenIncr ← binc - tinc; b.wwidth ← wid; b.wCnt ← cnt; p.l ← l; setBusSizes[b]; END; setBusSizes:PROCEDURE[p:LONG POINTER TO bus object] = BEGIN binc:INTEGER←p.lenIncr+p.topIncr; p.offsetFirst ← IF p.topIncr>=0 THEN 0 ELSE (1-p.wCnt)*p.topIncr; p.size[0] ← p.size[2] ← (p.wCnt-1)*p.wspace + p.wwidth; p.size[1] ← IF binc>0 THEN p.offsetFirst+p.firstLength+(p.wCnt-1)*binc ELSE p.offsetFirst+p.firstLength; END; makeRep: PUBLIC PROC [ob:obPtr,winc,linc,dx,dy,cnt:INTEGER, idx:orientationIndex] RETURNS [p: LONG POINTER TO object] = BEGIN repeat: cellPtr ← p ← makeCell[sx: 0, sy: 0, cnt: cnt, ptr: NIL]; FOR i: INTEGER IN [0..cnt) DO repeat.ptr ← insertList[mp: repeat.ptr, lp: makeList[p: ob.p.anotherme[ob], x: i*dx, y: i*dy, o: idx/2, refl: idx MOD 2]]; ENDLOOP; [max: repeat.size[0], may: repeat.size[1]] ← minmax[repeat.ptr]; repeat.size[2] ← repeat.size[0]; -- sigh! END; makeCell: PUBLIC PROCEDURE [ sx, sy: INTEGER, cnt: CARDINAL, ptr: LONG POINTER TO list] RETURNS [p: LONG POINTER TO cell object] = BEGIN dc: LONG POINTER TO cell object; p ← dc ← alocCellD[]; p↑.p ← @cellProcs; dc↑.ptr ← ptr; dc↑.size[0] ← dc↑.size[2] ← sx; dc↑.size[1] ← sy; dc↑.l ← cut; dc↑.cnt ← cnt; END; inMeRect: inMeProc = --tells if cursor(or whatever)at x,y is inside object BEGIN xs, ys: INTEGER; IF BITAND[o, 4] = 0 THEN BEGIN xs ← ob.size[0]; ys ← ob.size[1]; END ELSE BEGIN xs ← ob.size[1]; ys ← ob.size[0]; END; IF x IN [0..xs] AND y IN [0..ys] THEN RETURN[TRUE] ELSE RETURN[FALSE]; END; rectIB: ibProc = BEGIN x, y, sx, sy: INTEGER; x ← lp.lx; y ← lp.ly; IF BITAND[lp.idx, 4] = 0 THEN BEGIN sx ← lp.ob.size[0]; sy ← lp.ob.size[1]; END ELSE BEGIN sx ← lp.ob.size[1]; sy ← lp.ob.size[0]; END; IF x >= x2 OR y >= y2 OR x + sx <= x1 OR y + sy <= y1 THEN RETURN[FALSE]; RETURN[TRUE]; END; setWireParm: parmProc = BEGIN dp: LONG POINTER TO wire object ← LOOPHOLE[lp.ob]; nw, nl, wd, ln, mn: INTEGER; l: level ← dp.l; movl:BOOLEAN←FALSE; wd ← dp.size[0]; ln ← dp.size[1]; SELECT pt FROM width => BEGIN nl ← ln; nw ← (wd*dy) + dx; END; length => BEGIN nl ← (ln*dy) + dx; nw ← wd; END; default => BEGIN IF NOT wireOK[l] THEN RETURN[FALSE]; nl ← ln; nw ← minWidthAr[l]; END; wSpace => BEGIN nl ← ln; nw ← wd + dx; END; ENDCASE => RETURN[FALSE]; IF nw < INTEGER[lambdaGrid] THEN nw ← lambdaGrid; IF nl<1 THEN {IF nl<0 THEN {movl←TRUE;nl←-nl} ELSE nl←Lambda;}; -- IF l=pdif THEN {IF nw<INTEGER[lambdaGrid]+2*tubMinExt THEN -- nw←lambdaGrid+2*tubMinExt; -- IF nl<2*tubMinExt+1 THEN nl←2*tubMinExt+1;}; IF nw = wd AND nl = ln THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 THEN BEGIN IF cent THEN {lp.lx ← lp.lx + lambdaGrid*(wd/mn - nw/mn); lp.ly ← lp.ly + lambdaGrid*(ln/mn - nl/mn);}; IF movl THEN lp.ly ← lp.ly - nl; END ELSE BEGIN IF cent THEN {lp.lx ← lp.lx + lambdaGrid*(ln/mn - nl/mn); lp.ly ← lp.ly + lambdaGrid*(wd/mn - nw/mn);}; IF movl THEN lp.lx ← lp.lx - nl; END; RETURN[NewObject[lp, makeWire[nl, nw, l]]]; END; NewObject: PROCEDURE [lp: listPtr, ob: obPtr] RETURNS [BOOLEAN] = BEGIN lp.ob.p.release[lp.ob]; lp.ob ← ob; RETURN[TRUE]; END; setBusParm: parmProc = BEGIN dp: LONG POINTER TO bus object ← LOOPHOLE[lp.ob]; nw, nl, wd, ln, mn: INTEGER; l: level ← dp.l; wd ← dp.wwidth; ln ← dp.firstLength; SELECT pt FROM width => BEGIN nl ← ln; nw ← (wd*dy) + dx; END; length => BEGIN nl ← (ln*dy) + dx; nw ← wd; END; default => BEGIN IF NOT (l=dif OR l=pol OR l=met OR l=met2) THEN RETURN[FALSE]; nl ← ln; nw ← minWidthAr[l]; END; ENDCASE => BEGIN SELECT pt FROM wSpace => BEGIN dp.wspace←dp.wspace + dx; IF dp.wspace<dp.wwidth+1 THEN dp.wspace←dp.wwidth+1; END; count => BEGIN dp.wCnt←dp.wCnt + dx; IF dp.wCnt<1 THEN dp.wCnt←1; END; lSpace => BEGIN dp.topIncr←dp.topIncr + dx; END; bSpace => BEGIN dp.lenIncr←dp.lenIncr + dx; END; ENDCASE; setBusSizes[dp]; RETURN[TRUE]; END; IF nw < INTEGER[lambdaGrid] THEN nw ← lambdaGrid; IF nl < 1 THEN nl ← 1; IF nw = wd AND nl = ln THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 AND cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(wd/mn - nw/mn); lp.ly ← lp.ly + lambdaGrid*(ln/mn - nl/mn); END ELSE IF cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(ln/mn - nl/mn); lp.ly ← lp.ly + lambdaGrid*(wd/mn - nw/mn); END; dp.size[0] ← dp.size[2] ← dp.size[0] + nw - wd; dp.size[1] ← dp.size[1] + nl - ln; dp.wwidth ← nw; dp.firstLength ← nl; RETURN[TRUE]; END; setNullParm: parmProc = BEGIN RETURN[FALSE]; END; setAXstrParm: parmProc = BEGIN dp: LONG POINTER TO xstr object ← LOOPHOLE[lp.ob]; nw, nl, wd, ln, mn,nwe,nle,nax,oax: INTEGER; im: BOOLEAN ← dp.impl; nw←wd ← dp.width; nl←ln ← dp.length; nwe←dp.wExt; nle←dp.lExt; oax←nax←dp.size[1]-dp.length-2*dp.lExt-dp.wExt; SELECT pt FROM width => BEGIN nw ← (wd*dy) + dx; END; length => BEGIN nw ← (wd*dy) + dx; nax←nax+nw-wd;END; default => BEGIN nl ← cLength*xRatiol; nw ← cWidth*xRatiow; nax←0; nwe←wXExtension;nle←lXExtension;END; wSpace => BEGIN IF -dx>dp.wExt THEN dx←-dp.wExt;nwe←dp.wExt+dx; END; lSpace => BEGIN IF -dx>dp.lExt THEN dx←-dp.lExt;nle←dp.lExt+dx; END; count => BEGIN im←IF dx<0 THEN FALSE ELSE TRUE; END; ENDCASE => RETURN[FALSE]; -- new parameter ranges now tested in makeAngleXstr IF nw = wd AND nl = ln AND dp.wExt=nwe AND dp.lExt=nle AND oax=nax AND dp.impl=im THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 AND cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*((wd-oax)/mn - (nw-nax)/mn); lp.ly ← lp.ly + lambdaGrid*(oax/mn - nax/mn); END ELSE IF cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(oax/mn - nax/mn); lp.ly ← lp.ly + lambdaGrid*((wd-oax)/mn - (nw-nax)/mn); END; RETURN[NewObject[lp, makeAngleXstr[nw, nl, im,nwe,nle,nax]]]; END; setXstrParm: parmProc = BEGIN dp: LONG POINTER TO xstr object ← LOOPHOLE[lp.ob]; nw, nl, wd, ln, mn,nwe,nle: INTEGER; im: BOOLEAN ← dp.impl; nw←wd ← dp.width; nl←ln ← dp.length; nwe←dp.wExt; nle←dp.lExt; SELECT pt FROM width => BEGIN nw ← (wd*dy) + dx; END; length => BEGIN nl ← (ln*dy) + dx; END; default => BEGIN nl ← cLength*xRatiol; nw ← cWidth*xRatiow; nwe←wXExtension;nle←lXExtension;END; wSpace => BEGIN IF -dx>dp.wExt THEN dx←-dp.wExt;nwe←dp.wExt+dx; END; lSpace => BEGIN IF -dx>dp.lExt THEN dx←-dp.lExt;nle←dp.lExt+dx; END; count => BEGIN im←IF dx<0 THEN FALSE ELSE TRUE; END; ENDCASE => RETURN[FALSE]; -- new parameter ranges now tested in makeXstr IF nw = wd AND nl = ln AND dp.wExt=nwe AND dp.lExt=nle AND dp.impl=im THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 AND cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(wd/mn - nw/mn); lp.ly ← lp.ly + lambdaGrid*(ln/mn - nl/mn); END ELSE IF cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(ln/mn - nl/mn); lp.ly ← lp.ly + lambdaGrid*(wd/mn - nw/mn); END; RETURN[NewObject[lp, makeXstr[nw, nl, im,nwe,nle]]]; END; setPXstrParm: parmProc = BEGIN dp: LONG POINTER TO xstr object ← LOOPHOLE[lp.ob]; nw, nl, wd, ln, mn,nwe,nle: INTEGER; im: BOOLEAN ← dp.impl; nw←wd ← dp.width; nl←ln ← dp.length; nwe←dp.wExt; nle←dp.lExt; SELECT pt FROM width => BEGIN nw ← (wd*dy) + dx; END; length => BEGIN nl ← (ln*dy) + dx; END; default => BEGIN nl ← cLength*xRatiol; nw ← cWidth*xRatiow; nwe←wXExtension;nle←lXExtension;END; wSpace => BEGIN IF -dx>dp.wExt THEN dx←-dp.wExt;nwe←dp.wExt+dx; END; lSpace => BEGIN IF -dx>dp.lExt THEN dx←-dp.lExt;nle←dp.lExt+dx; END; count => BEGIN im←IF dx<0 THEN FALSE ELSE TRUE; END; ENDCASE => RETURN[FALSE]; -- new parameter ranges now tested in makePXstr IF nw = wd AND nl = ln AND dp.wExt=nwe AND dp.lExt=nle AND dp.impl=im THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 AND cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(wd/mn - nw/mn); lp.ly ← lp.ly + lambdaGrid*(ln/mn - nl/mn); END ELSE IF cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(ln/mn - nl/mn); lp.ly ← lp.ly + lambdaGrid*(wd/mn - nw/mn); END; RETURN[NewObject[lp, makePXstr[nw, nl, im,nwe,nle]]]; END; setPuParm: parmProc = BEGIN dp: LONG POINTER TO xstr object ← LOOPHOLE[lp.ob]; nw, nl, wd, ln, mn,nwe,nle: INTEGER; nw←wd ← dp.width; nl←ln ← dp.length; nwe←dp.wExt; nle←dp.lExt; SELECT pt FROM width => BEGIN nw ← (wd*dy) + dx; END; length => BEGIN nl ← (ln*dy) + dx; END; default => BEGIN nl ← cLength*pRatiol; nw ← cWidth*pRatiow; END; wSpace => BEGIN IF -dx>dp.wExt THEN dx←-dp.wExt;nwe←dp.wExt+dx; END; lSpace => BEGIN IF -dx>dp.lExt THEN dx←-dp.lExt;nle←dp.lExt+dx; END; ENDCASE => RETURN[FALSE]; -- new parameter ranges now tested in makePu IF nw = wd AND nl = ln AND dp.wExt=nwe AND dp.lExt=nle THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 AND cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(wd/mn - nw/mn); lp.ly ← lp.ly + lambdaGrid*(ln/mn - nl/mn); END ELSE IF cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(ln/mn - nl/mn); lp.ly ← lp.ly + lambdaGrid*(wd/mn - nw/mn); END; RETURN[NewObject[lp, makePullup[nw, nl,nwe,nle]]]; END; setContParm: parmProc = BEGIN dp: LONG POINTER TO cont object ← LOOPHOLE[lp.ob]; nl, ln, mn: INTEGER; typ: contType ← dp.typ; ln ← dp.size[1]; SELECT pt FROM length => BEGIN nl ← (ln*dy) + dx; END; default => BEGIN nl ← butconSX; END; ENDCASE => RETURN[FALSE]; IF nl < butconSX THEN nl ← butconSX; IF nl = ln THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 AND cent THEN BEGIN lp.ly ← lp.ly + lambdaGrid*(ln/mn - nl/mn); END ELSE IF cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(ln/mn - nl/mn); END; RETURN[NewObject[lp, SELECT typ FROM mPol => makePolycon[nl], mDif => makeDifcon[nl], mPDif => makePDifcon[nl], ENDCASE => makeMmCont[nl,0,0]]]; END; setBuContParm: parmProc = BEGIN dp: LONG POINTER TO cont object ← LOOPHOLE[lp.ob]; nw, nl, wd, ln, mn,nwe,nle: INTEGER; nw←wd ← dp.size[0]; nl←ln ← dp.size[1]; nwe←dp.wExt; nle←dp.lExt; SELECT pt FROM width => BEGIN nw ← (wd*dy) + dx; END; length => BEGIN nl ← (ln*dy) + dx; END; default => BEGIN nl ← 8; nw ← 10;nwe←4;nle←2;END; wSpace => BEGIN IF -dx>dp.wExt THEN dx←-dp.wExt; nwe←dp.wExt+dx;nw←nw+dx*2; END; lSpace => BEGIN IF -dx>dp.lExt THEN dx←-dp.lExt; nle←dp.lExt+dx;nl←nl+dx*2; END; ENDCASE => RETURN[FALSE]; IF nwe<0 THEN nwe←0;IF nle<0 THEN nle←0; IF nw < 2*nwe+2 THEN nw ← 2*nwe+2; IF nl < 2*nle+4 THEN nl ← 2*nle+4; IF nw = wd AND nl = ln AND dp.wExt=nwe AND dp.lExt=nle THEN RETURN[FALSE]; mn ← 2*lambdaGrid; IF BITAND[lp.idx, 4] = 0 AND cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(wd/mn - nw/mn); lp.ly ← lp.ly + lambdaGrid*(ln/mn - nl/mn); END ELSE IF cent THEN BEGIN lp.lx ← lp.lx + lambdaGrid*(ln/mn - nl/mn); lp.ly ← lp.ly + lambdaGrid*(wd/mn - nw/mn); END; RETURN[NewObject[lp, makeBuCont[nw, nl, nwe,nle]]]; END; END.