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