-- subroutines for command interpreter part of silicon (pretty picture) program
-- modified by E. McCreight, January 4, 1983 3:28 PM
-- modified by Petit, September 22, 1981 5:44 PM
DIRECTORY
ChipUserInt,
InlineDefs,
StringDefs,
ppoutdefs,
ppdddefs,ppddefs,
ppdefs,
ppMainDefs;
ppmain2: PROGRAM
IMPORTS ChipUserInt, ppdefs, ppddefs, ppdddefs,ppoutdefs,
StringDefs, InlineDefs, ppMainDefs
EXPORTS ppMainDefs = PUBLIC
BEGIN
OPEN ppdefs, ppddefs, ppdddefs,ppoutdefs, StringDefs, InlineDefs,
ChipUserInt, ppMainDefs;
rotCompensate:PROCEDURE[p:listPtr] RETURNS[w,l,dw,dl:INTEGER] =
BEGIN
switchXY:PROCEDURE=BEGIN t:INTEGER←l;l←w;w←t;t←dl;dl←dw;dw←t;END;
reflW:PROCEDURE=BEGIN w←p.ob.size[0]-w;dw←-dw;END;
reflL:PROCEDURE=BEGIN l←p.ob.size[1]-l;dl←-dl;END;
l←markPnt.y-p.ly;dl←yy-markPnt.y;
w←markPnt.x-p.lx;dw←xx-markPnt.x;
SELECT p.idx FROM
0,2 => BEGIN RETURN;END;
1,3 => BEGIN reflW[];END;
4,6 => BEGIN switchXY[];reflL[];END;
5,7 => BEGIN switchXY[];END;
8,10 => BEGIN reflW[];reflL[];END;
9,11 => BEGIN reflL[];END;
12,14 => BEGIN switchXY[];reflW[];END;
13,15 => BEGIN switchXY[];reflW[];reflL[];END;
ENDCASE;
END;
findWhichWire:PUBLIC PROCEDURE [lp:listPtr] RETURNS[wNum:INTEGER,
onTheWire:BOOLEAN,wl1,wl2,w,l,dw,dl:INTEGER] =
BEGIN
ob:LONG POINTER TO bus object←LOOPHOLE[lp.ob];
[w,l,dw,dl]←rotCompensate[lp];
onTheWire←FALSE;
wNum←0;
IF lp.ob.otyp#bus THEN RETURN;
IF w>=0 THEN
BEGIN
wNum←w/ob.wspace;
IF wNum>=ob.wCnt THEN wNum←ob.wCnt-1;
END;
wl1←ob.offsetFirst+wNum*ob.topIncr;
wl2←wl1+ob.firstLength+ob.lenIncr*wNum;
IF w>= wNum*ob.wspace AND w<= wNum*ob.wspace+ob.wwidth
AND l >= wl1 AND l<= wl2 THEN onTheWire←TRUE;
END;
convToBus: cmdProc =
BEGIN
makeBusCmd[k,FALSE];
END;
convToBusDamnit: cmdProc =
BEGIN
makeBusCmd[k,TRUE];
END;
makeBusCmd:PROCEDURE[k:keyEvent,damnit:BOOLEAN] =
BEGIN
fstl,fstw,scnd,tp,ttp: listPtr;
fLen,wid,spc,cnt,tinc,linc,binc,i,j,fx,fy:INTEGER;
vert,maxok:BOOLEAN←FALSE;
l:level;
tp←masterList;
cnt←0;
WHILE tp#NIL DO
IF tp.selected THEN
BEGIN
IF tp.ob.otyp#wire THEN BEGIN tp.selected←FALSE;LOOP;END;
cnt←cnt+1;
IF cnt=1 THEN
BEGIN
fstl←tp;
fstw←tp;
vert←BITAND[tp.idx,4]=0;
END;
IF cnt=2 THEN scnd←tp;
IF cnt>1 THEN
BEGIN
IF vert THEN
BEGIN
IF BITAND[tp.idx,4]#0 THEN RETURN;
IF tp.lx<scnd.lx THEN scnd←tp;
IF scnd.lx<fstw.lx THEN BEGIN ttp←fstw;
fstw←scnd;scnd←ttp;END;
END
ELSE
BEGIN
IF BITAND[tp.idx,4]=0 THEN RETURN;
IF tp.ly<scnd.ly THEN scnd←tp;
IF scnd.ly<fstw.ly THEN BEGIN ttp←fstw;
fstw←scnd;scnd←ttp;END;
END;
END;
END;
tp←tp.nxt;
ENDLOOP;
IF cnt<2 THEN RETURN;
fLen←fstw.ob.size[1];
wid←fstw.ob.size[0];
linc←scnd.ob.size[1]-fLen;
fx←fstw.lx;
fy←fstw.ly;
l←fstw.ob.l;
IF vert THEN
BEGIN
spc←scnd.lx-fx;
tinc←scnd.ly-fy;
binc←scnd.ly+scnd.ob.size[1]-fLen-fy;
END
ELSE
BEGIN
spc←scnd.ly-fy;
tinc←scnd.lx-fx;
binc←scnd.lx+scnd.ob.size[1]-fLen-fx;
END;
tp←fstl;
i←0;
IF NOT damnit THEN
BEGIN
WHILE i<cnt DO
IF tp.selected THEN
BEGIN
i←i+1;
IF tp.ob.l#l THEN RETURN;
IF tp.ob.size[0]#wid THEN RETURN;
IF vert THEN
BEGIN
j←(tp.lx-fx)/spc;
IF j=cnt-1 THEN maxok←TRUE;
SELECT j FROM
0 => IF tp#fstw THEN RETURN;
1 => IF tp#scnd THEN RETURN;
ENDCASE => BEGIN
IF j*spc+fx#tp.lx THEN RETURN;
IF j*tinc#tp.ly-fy THEN RETURN;
END;
END
ELSE
BEGIN
j←(tp.ly-fy)/spc;
IF j=cnt-1 THEN maxok←TRUE;
SELECT j FROM
0 => IF tp#fstw THEN RETURN;
1 => IF tp#scnd THEN RETURN;
ENDCASE => BEGIN
IF j*spc+fy#tp.ly THEN RETURN;
IF j*tinc#tp.lx-fx THEN RETURN;
END;
END;
IF j*linc#tp.ob.size[1]-fLen THEN RETURN;
END;
tp←tp.nxt;
ENDLOOP;
IF NOT maxok THEN RETURN;
END;
flushDelSel[]; -- delete all selected things (the wires);
IF vert THEN BEGIN IF tinc<0 THEN fy←fy+(cnt-1)*tinc;i←tinc;j←binc;END
ELSE BEGIN IF tinc<0 THEN fx←fx+(cnt-1)*tinc;j←-tinc;i←-binc;END;
lp ← makeList[makeBus[fLen,wid,l,cnt,spc,i,j], fx, fy, IF vert THEN 0 ELSE 2, 0];
masterList ← insertList[masterList, lp];
IF createSel THEN BEGIN selNewThing[masterList, lp, TRUE]; END;
reDrawRect[getRect[lp], 1, TRUE, TRUE, FALSE];
END;
modParam: cmdProc =
BEGIN
qqq:BOOLEAN←FALSE;
sgn:INTEGER;
apply:PROCEDURE[pt:parmType] =
BEGIN
lp←masterList;
WHILE lp#NIL DO
IF lp.selected THEN []←lp.ob.p.setParm[lp,pt,sgn,1,FALSE];
lp←lp.nxt;
ENDLOOP;
END;
IF k.ctl=1 THEN sgn←1 ELSE sgn←-1;
UNTIL qqq DO
ke←getchr[];
SELECT ke.k FROM
9 => IF ke.ctl=1 THEN sgn←1 ELSE sgn←-1;-- 9
26 => qqq←TRUE;-- Q
12 => apply[count];-- C
29 => apply[lSpace];-- T
11 => apply[bSpace];-- B
28 => apply[wSpace];-- S
ENDCASE;
reDrawRect[[0, 0, 0, 0], 2, TRUE, TRUE, TRUE];
ENDLOOP;
dChange ← TRUE;
END;
doInput: cmdProc =
BEGIN
sss: STRING ← [40];
ok: BOOLEAN;
[ok, ss, ke] ← typeIn["", "Type File Name:", ""];
IF NOT ok THEN RETURN;
dChange ← TRUE;
IF ss.length > 0 THEN fileName ← ss;
sss.length ← 0;
FOR i: CARDINAL IN [0..fileName.length) DO
IF fileName[i] = '. THEN BEGIN fileName.length ← i; EXIT; END; ENDLOOP;
AppendString[sss, fileName];
AppendString[sss, ".chip"];
IF NOT openIfile[sss] THEN RETURN;
typeOut["", "Reading File:", sss];
[lp, cp] ← readAll[];
closeFile[];
anyChanges ← TRUE;
sinceIOchanges ← masterList # NIL;
lpp ← lp;
WHILE lpp # NIL DO
lp ← lpp.nxt; masterList ← insertList[masterList, lpp]; lpp ← lp; ENDLOOP;
cpp ← cp;
WHILE cpp # NIL AND cpp.nxt # NIL DO cpp ← cpp.nxt; ENDLOOP;
IF cpp # NIL THEN BEGIN cpp.nxt ← cellList; cellList ← cp; END;
refreshTypeInScreen[];
END;
doOutput: cmdProc =
BEGIN ENABLE Punt => GOTO ForgetOutput;
sss: STRING;
topMasterList: listPtr ← masterList;
lp: listPtr ← masterList;
cp: cellSEPtr ← cellStack;
IF cellStack#NIL THEN
BEGIN
cp: cellSEPtr ← cellStack;
WHILE cp.nxt#NIL DO cp ← cp.nxt ENDLOOP;
topMasterList ← cp.lp;
IF HeSaysYes["You're pushed down in a cell now. Do you want the whole",
"design anyway? (It will include perhaps some but perhaps not all of the",
"changes you've made since pushing from the top level. (Y/N)"] THEN
lp ← topMasterList
ELSE IF HeSaysYes["We'll just write the current cell as the top level",
"design, and all the named cells as well, OK?"] THEN NULL
ELSE RETURN;
END;
ss ← RequestString["Enter File Name:"];
IF ss=NIL THEN RETURN;
IF ss.length > 0 THEN fileName ← ss;
sss ← FixExtension[newString[fileName], ".chip"];
IF NOT openOfile[sss, FALSE] THEN
BEGIN
IF NOT HeSaysYes["File Already Exists", sss, "OK to Overwrite?(Y/N):"] OR
NOT openOfile[sss, TRUE] THEN RETURN;
END;
typeOut["", "Writing File:", sss];
writeAll[lp, cellList];
closeFile[];
IF cellStack=NIL THEN sinceIOchanges ← FALSE;
FreeString[sss];
refreshTypeInScreen[];
EXITS
ForgetOutput => NULL;
END;
makeCif: cmdProc =
BEGIN
ok: BOOLEAN;
[ok, ss, ke] ← typeIn["", "Type Cif File Name:", "Without extension"];
IF NOT ok THEN RETURN;
cifOutDrawing[ss, masterList];
refreshTypeInScreen[];
END;
defCell: cmdProc =
BEGIN
mix, max, miy, may: INTEGER;
backPnt: LONG POINTER TO listPtr;
obp: obPtr;
ok,reDef: BOOLEAN←FALSE;
cpp:cListPtr;
sqs:STRING←[200];
cob:cellPtr;
DO
[ok, ss, ke] ← typeIn["", "Type Cell Name:", "<CR> for none"];
IF NOT ok THEN {refreshTypeInScreen[];RETURN;};
IF ss.length=0 OR (cpp←FindNamedCell[ss]) = NIL THEN EXIT;
sqs.length←0;
AppendString[sqs,"There is already a cell named "];
AppendString[sqs,ss];
ke ← typeInC[sqs,"Type M to make multiple cells with same name,",
"R to redefine old one, N to try another name"];
IF ke.k = 26B THEN EXIT; -- M
IF ke.k = 33B THEN {reDef←TRUE;EXIT}; -- R
ENDLOOP;
selCount ← 0;
lpp ← NIL;
lp ← masterList;
backPnt ← @masterList;
WHILE lp # NIL DO
IF lp.selected THEN
BEGIN
ii ← IF BITAND[lp.idx, 4] = 0 THEN 0 ELSE 1;
IF lpp = NIL THEN
BEGIN
mix ← lp.lx;
max ← lp.lx + lp.ob.size[ii];
miy ← lp.ly;
may ← lp.ly + lp.ob.size[ii + 1];
END
ELSE
BEGIN
mix ← MIN[mix, lp.lx];
max ← MAX[max, lp.lx + lp.ob.size[ii]];
miy ← MIN[miy, lp.ly];
may ← MAX[may, lp.ly + lp.ob.size[ii + 1]];
END;
backPnt↑ ← lqp ← lp.nxt;
lp.nxt ← lpp;
lpp ← lp;
lp ← lqp;
END
ELSE BEGIN backPnt ← @lp.nxt; lp ← lp.nxt; END;
ENDLOOP;
IF lpp # NIL THEN
BEGIN
anyChanges ← sinceIOchanges ← TRUE;
IF reDef THEN
BEGIN
obp←cob←LOOPHOLE[cpp.ob];
flushDel[cob.ptr];
cob.ptr ← lpp;
END
ELSE
BEGIN
lqp ← makeList[obp ← makeCell
[max - mix, may - miy, 0, lpp], mix, miy, 0, 0];
masterList ← insertList[masterList, lqp];
cob←LOOPHOLE[obp]
END;
lqp ← lpp;
WHILE lpp # NIL DO
lpp.lx ← lpp.lx - mix;
lpp.ly ← lpp.ly - miy;
lpp.selected ← FALSE;
lpp ← lpp.nxt;
ENDLOOP;
IF ss.length>0 AND NOT reDef THEN
BEGIN
cp ← alocCList[];
cp.nxt ← cellList;
cellList ← cp;
cp.ob ← obp.p.anotherme[obp];
obp.returnable ← FALSE;
cp.name ← ss;
END;
dChange ← TRUE;
IF reDef THEN
BEGIN
cob.size[0] ← cob.size[2] ← max - mix;
cob.size[1] ← may - miy;
AdjustCallersBBoxes[cob];
END;
END;
END;
getCell: cmdProc =
BEGIN
ok: BOOLEAN;
[ok, ss, ke] ← typeIn["", "Type Cell Name:", ""];
IF NOT ok THEN BEGIN refreshTypeInScreen[];RETURN;END;
cp ← cellList;
WHILE cp # NIL DO
IF EqualString[cp.name, ss] THEN
BEGIN
anyChanges ← sinceIOchanges ← TRUE;
lp ← makeList[cp.ob.p.anotherme[cp.ob], xx, yy, 0, 0];
masterList ← insertList[masterList, lp];
IF createSel THEN
BEGIN selNewThing[masterList, lp, TRUE]; putMark[xx, yy]; END;
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
refreshTypeInScreen[];
EXIT;
END;
cp ← cp.nxt;
ENDLOOP;
FreeString[ss];
END;
selLayer: cmdProc = BEGIN favLev ← SELECT k.k FROM 1 => dif , 2 => pol , 3 => met , 4 => pdif , ENDCASE => met2; END;
makCont: cmdProc =
BEGIN
anyChanges ← sinceIOchanges ← TRUE;
IF BITAND[k.ctl,10B]=0 THEN -- no TAB held down
BEGIN
SELECT k.k FROM
1 =>
BEGIN
lp ← makeList[makeDifcon[0], xx, yy, 0, 0];
masterList ← insertList[masterList, lp];
END;
2 =>
BEGIN
lp ← makeList[makePolycon[0], xx, yy, 0, 0];
masterList ← insertList[masterList, lp];
END;
3 =>
BEGIN
lp ← makeList[makeButcon[], xx, yy, basicOrientation, 0];
masterList ← insertList[masterList, lp];
END;
4 =>
BEGIN
IF cMos THEN
BEGIN
lp←makeList[makePDifcon[0],xx,
yy,basicOrientation,0];
masterList ← insertList[masterList, lp];
END
ELSE
BEGIN
lp←makeList[makeBuCont[10,8,4,2],xx,yy,basicOrientation,0];
masterList ← insertList[masterList, lp];
END;
END;
5 =>
BEGIN
lp ← makeList[makeMmCont[0,4,2], xx, yy, basicOrientation, 0];
masterList ← insertList[masterList, lp];
END;
ENDCASE;
END
ELSE
BEGIN
SELECT k.k FROM
1 =>
BEGIN
lp ← makeList[makeMmDifcon[0], xx, yy, 0, 0];
masterList ← insertList[masterList, lp];
END;
2 =>
BEGIN
lp ← makeList[makeMmPolcon[0], xx, yy, 0, 0];
masterList ← insertList[masterList, lp];
END;
3 =>
BEGIN
RETURN;-- for now
-- lp ← makeList[makeButcon[], xx, yy, basicOrientation, 0];
-- masterList ← insertList[masterList, lp];
END;
4 =>
BEGIN
lp←makeList[makeMPDifcon[0],xx,
yy,basicOrientation,0];
masterList ← insertList[masterList, lp];
END;
5 =>
BEGIN
lp ← makeList[makeMmCont[0,4,2], xx, yy, basicOrientation, 0];
masterList ← insertList[masterList, lp];
END;
ENDCASE;
END;
IF createSel THEN
BEGIN selNewThing[masterList, lp, TRUE]; putMark[xx, yy]; END;
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
END;
makWCont: cmdProc =
BEGIN
lp ← makeList[makeNwellcon[0], xx, yy, 0, 0];
masterList ← insertList[masterList, lp];
IF createSel THEN
BEGIN selNewThing[masterList, lp, TRUE]; putMark[xx, yy]; END;
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
END;
doOvg: cmdProc =
BEGIN
sx, sy: INTEGER;
ii: CARDINAL;
IF NOT bb THEN RETURN;
lp ← masterList;
WHILE lp # NIL DO
IF lp.ob.otyp = wire AND (lp.ob.l = met OR lp.ob.l=met2)
AND lp.ob.p.inMe[lp.ob, xx - lp.lx, yy - lp.ly, lp.idx] THEN
BEGIN
ii ← IF BITAND[lp.idx, 4] = 0 THEN 0 ELSE 1;
sx ← lp.ob.size[ii] - 16;
sy ← lp.ob.size[ii + 1] - 16;
IF sx < 1 OR sy < 1 THEN RETURN;
lp ← makeList[makeRect[sx, sy, ovg], lp.lx + 8, lp.ly + 8, 0, 0];
masterList ← insertList[masterList, lp];
-- lp↑.nxt←masterList;
-- masterList←lp;
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
RETURN;
END;
lp ← lp.nxt;
ENDLOOP;
END;
doTub: cmdProc =
BEGIN
sx, sy: INTEGER;
IF NOT bb THEN RETURN;
sx←ABS[markPnt.x-xx];sy←ABS[markPnt.y-yy];
lp ← makeList[makeRect[sx, sy, nwel],
MIN[markPnt.x,xx], MIN[markPnt.y,yy], 0, 0];
masterList ← insertList[masterList, lp];
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
END;
doOvgR: cmdProc =
BEGIN
sx, sy: INTEGER;
IF NOT bb THEN RETURN;
sx←ABS[markPnt.x-xx];sy←ABS[markPnt.y-yy];
lp ← makeList[makeRect[sx, sy, ovg],
MIN[markPnt.x,xx], MIN[markPnt.y,yy], 0, 0];
masterList ← insertList[masterList, lp];
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
END;
doRectangle: cmdProc =
BEGIN
sx, sy: INTEGER;
IF rectangleMode THEN
BEGIN
IF NOT bb THEN RETURN;
sx←ABS[markPnt.x-xx];sy←ABS[markPnt.y-yy];
lp ← makeList[makeRect[sx, sy, rectLev],
MIN[markPnt.x,xx], MIN[markPnt.y,yy], 0, 0];
masterList ← insertList[masterList, lp];
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
END;
END;
doRepeatOb: cmdProc =
BEGIN
lp:listPtr←masterList;
slp:listPtr←NIL;
ox,oy:INTEGER;
ok: BOOLEAN;
x,y,cnt:INTEGER;
ke:keyEvent;
ob:obPtr;
mirror:BOOLEAN;
checkMark:keCheckProc =
BEGIN
return←FALSE;
execute←(k.k=64B OR k.k=65B OR k.k=73B);
IF (k.k=77B AND BITAND[15,k.ctl]=1) OR k.k=56B THEN
{return←TRUE;execute←FALSE};
END;
WHILE lp#NIL DO
IF lp.selected THEN {IF slp#NIL THEN --error-- RETURN;slp←lp;};
lp←lp.nxt;
ENDLOOP;
IF slp=NIL THEN RETURN;
ox←slp.lx;
oy←slp.ly;
ke←CmdTwerpMess["","Mark Origin of Second Copy",
"(upper left corner)",checkMark];
IF ke.k=56B THEN RETURN;
[ok, x, y] ← deScaledCursor[ke.mx, ke.my];
IF NOT ok THEN RETURN;
x←x-ox;
y←y-oy;
[ok,cnt,]←typeInNum["","Type Number of Copies",""];
IF NOT ok THEN RETURN;
anyChanges ← sinceIOchanges ← TRUE;
mirror←(x<0 AND y>=0) OR (x>=0 AND y<0);
IF x<0 THEN {ox←ox+x*(cnt-1);x←-x;};
IF y<0 THEN {oy←oy+y*(cnt-1);y←-y;};
ob←makeRep[slp.ob,0,0,x,y,cnt,
(IF mirror THEN BITXOR[slp.idx,1] ELSE slp.idx)];
slp.lx←ox;slp.ly←oy;
slp.ob←ob;
slp.idx←IF mirror THEN 1 ELSE 0;
slp.ridx←BITXOR[slp.idx,1];
reDrawRect[getRect[slp], 1, TRUE, TRUE, FALSE];
END;
doBurr: cmdProc =
BEGIN
sx, sy, dx, dy: INTEGER;
dw, pw: listPtr ← NIL;
di, pi: CARDINAL ← 0;
overFlg: BOOLEAN ← FALSE;
IF NOT bb THEN RETURN;
lp ← masterList;
WHILE lp # NIL DO
IF lp.ob.otyp = wire AND lp.ob.l = pol
AND lp.ob.p.inMe[lp.ob, xx - lp.lx, yy - lp.ly, lp.idx] THEN
BEGIN IF pw = NIL THEN pw ← lp ELSE overFlg ← TRUE; END;
IF lp.ob.otyp = wire AND lp.ob.l = dif
AND lp.ob.p.inMe[lp.ob, xx - lp.lx, yy - lp.ly, lp.idx] THEN
BEGIN IF dw = NIL THEN dw ← lp ELSE overFlg ← TRUE; END;
lp ← lp.nxt;
ENDLOOP;
IF dw = NIL OR pw = NIL THEN overFlg ← TRUE;
IF NOT overFlg THEN
BEGIN
di ← IF BITAND[dw.idx, 4] = 0 THEN 0 ELSE 1;
pi ← IF BITAND[pw.idx, 4] = 0 THEN 0 ELSE 1;
IF di = pi THEN overFlg ← TRUE
ELSE
BEGIN
IF di = 0 THEN
BEGIN
dx ← dw.lx - 2;
dy ← pw.ly - 2;
sx ← dw.ob.size[0] + 4;
sy ← pw.ob.size[0] + 6;
IF dy > dw.ly THEN
BEGIN
dy ← dy - 2;
IF dw.ly + dw.ob.size[1] > dy + 10 THEN sy ← sy + 2;
END;
END
ELSE
BEGIN
dx ← pw.lx - 2;
dy ← dw.ly - 2;
sx ← pw.ob.size[0] + 6;
sy ← dw.ob.size[0] + 4;
IF dx > dw.lx THEN
BEGIN
dx ← dx - 2;
IF dw.lx + dw.ob.size[1] > dx + 10 THEN sx ← sx + 2;
END;
END;
END;
END;
IF overFlg THEN BEGIN dx ← xx - 4; dy ← yy - 4; sx ← sy ← 8; END;
lp ← makeList[makeRect[sx, sy, bur], dx, dy, 0, 0];
masterList ← insertList[masterList, lp];
-- lp↑.nxt←masterList;
-- masterList←lp;
reDrawRect[getRect[lp], 0, TRUE, TRUE, FALSE];
END;
flushDelSel: PROCEDURE =
BEGIN
backPnt: LONG POINTER TO listPtr;
lpp ← NIL;
lp ← masterList;
backPnt ← @masterList;
WHILE lp # NIL DO
IF lp.selected THEN
BEGIN
lp.deleted ← TRUE;
backPnt↑ ← lqp ← lp.nxt;
lp.nxt ← lpp;
lpp ← lp;
lp ← lqp;
END
ELSE BEGIN backPnt ← @lp.nxt; lp ← lp.nxt; END;
ENDLOOP;
IF lpp # NIL THEN flushDel[lpp];
END;
delSel: cmdProc =
BEGIN
backPnt: LONG POINTER TO listPtr;
lpp ← NIL;
lp ← masterList;
backPnt ← @masterList;
WHILE lp # NIL DO
IF lp.selected THEN
BEGIN
lp.deleted ← TRUE;
backPnt↑ ← lqp ← lp.nxt;
lp.nxt ← lpp;
lpp ← lp;
lp ← lqp;
END
ELSE BEGIN backPnt ← @lp.nxt; lp ← lp.nxt; END;
ENDLOOP;
IF lpp # NIL THEN doTheDelete[lpp];
END;
delPnt: cmdProc =
BEGIN
backPnt: LONG POINTER TO listPtr;
lpp ← NIL;
lp ← masterList;
backPnt ← @masterList;
WHILE lp # NIL DO
IF lp.ob.p.inMe[lp.ob, xx - lp.lx, yy - lp.ly, lp.idx] THEN
BEGIN
lp.deleted ← TRUE;
backPnt↑ ← lqp ← lp.nxt;
lp.nxt ← lpp;
lpp ← lp;
lp ← lqp;
EXIT;
END
ELSE BEGIN backPnt ← @lp.nxt; lp ← lp.nxt; END;
ENDLOOP;
IF lpp # NIL THEN doTheDelete[lpp];
END;
doTheDelete: PROCEDURE [lpp: listPtr] =
BEGIN
jj,ii:INTEGER;
anyChanges ← sinceIOchanges ← TRUE;
IF (unDelGrpCnt >= unDelGrpMax AND unDelItemCnt >= unDelItemMin)
OR unDelItemCnt >= unDelItemMax THEN flushOne[];
jj ← 0;
ii ← IF unDelPnt = NIL THEN 0 ELSE 1 - unDelPnt.mark;
lp ← lpp;
WHILE lp.nxt # NIL DO
lp.mark ← ii;
reDrawRect[getRect[lp], 3, TRUE, TRUE, FALSE];
IF lp.selected THEN selCount ← selCount - 1;
lp ← lp.nxt;
jj ← jj + 1;
ENDLOOP;
reDrawRect[getRect[lp], 3, TRUE, TRUE, FALSE];
IF lp.selected THEN selCount ← selCount - 1;
lp.mark ← ii;
lp.nxt ← unDelPnt;
unDelPnt ← lpp;
unDelGrpCnt ← unDelGrpCnt + 1;
unDelItemCnt ← unDelItemCnt + jj + 1;
IF unDelItemCnt >= unDelItemMax THEN flushOne[];
END;
flushOne: PROCEDURE =
BEGIN
jj:INTEGER;
ii:CARDINAL;
jj ← 0;
lp ← unDelPnt;
IF lp = NIL THEN BEGIN unDelGrpCnt ← unDelItemCnt ← 0; RETURN; END;
FOR ii IN [2..unDelGrpCnt] DO
WHILE lp.nxt # NIL AND lp.mark = lp.nxt.mark DO
lp ← lp.nxt; jj ← jj + 1; ENDLOOP;
IF ii # unDelGrpCnt AND lp.nxt # NIL THEN
BEGIN lp ← lp.nxt; jj ← jj + 1; END;
ENDLOOP;
flushDel[lp.nxt];
lp.nxt ← NIL;
unDelGrpCnt ← unDelGrpCnt - 1;
unDelItemCnt ← jj + 1;
END;
doWidenSel: cmdProc = BEGIN doParmSel[width, FALSE, TRUE, lambdaGrid, 1]; END;
doWidenPnt: cmdProc =
BEGIN
IF NOT bb THEN RETURN;
doParmPnt[width, FALSE, TRUE, lambdaGrid, 1];
END;
doNarwSel: cmdProc = BEGIN doParmSel[width, TRUE, FALSE, -lambdaGrid, 1]; END;
doNarwPnt: cmdProc =
BEGIN
IF NOT bb THEN RETURN;
doParmPnt[width, TRUE, FALSE, -lambdaGrid, 1];
END;
doDefaultSel: cmdProc = BEGIN doParmSel[default, TRUE, TRUE, 0, 0]; END;
doDefaultPnt: cmdProc =
BEGIN IF NOT bb THEN RETURN; doParmPnt[default, TRUE, TRUE, 0, 0]; END;
doLenSel: cmdProc = BEGIN doParmSel[length, FALSE, TRUE, lambdaGrid, 1]; END;
doLenPnt: cmdProc =
BEGIN
IF NOT bb THEN RETURN;
doParmPnt[length, FALSE, TRUE, lambdaGrid, 1];
END;
doShrtSel: cmdProc =
BEGIN
IF wiring AND busMaking THEN
BEGIN
bmNews←IF BITAND[k.ctl,20B]=0 THEN bmNews+lambdaGrid ELSE
MAX[0,bmNews-lambdaGrid];
setBusParms[FALSE];
RETURN;
END;
doParmSel[length, TRUE, FALSE, -lambdaGrid, 1];
END;
doShrtPnt: cmdProc =
BEGIN
IF NOT bb THEN RETURN;
doParmPnt[length, TRUE, FALSE, -lambdaGrid, 1];
END;
doParmSel: PROCEDURE [
typ: parmType, earlyRect, lateRect: BOOLEAN, dx, dy: INTEGER] =
BEGIN
r: Rect;
lp ← masterList;
WHILE lp # NIL DO
IF lp.selected THEN
BEGIN
IF earlyRect THEN r ← getRect[lp];
IF lp.ob.p.setParm[lp, typ, dx, dy, TRUE] THEN
BEGIN
anyChanges ← sinceIOchanges ← TRUE;
IF lateRect THEN
r ← (IF earlyRect THEN mergeRects[getRect[lp], r] ELSE getRect[lp]);
reDrawRect[r, 1, TRUE, TRUE, FALSE];
END;
END;
lp ← lp.nxt;
ENDLOOP;
END;
doParmPnt: PROCEDURE [
typ: parmType, earlyRect, lateRect: BOOLEAN, dx, dy: INTEGER] =
BEGIN
r: Rect;
IF NOT bb THEN RETURN;
lp ← masterList;
WHILE lp # NIL DO
IF lp.ob.p.inMe[lp.ob, xx - lp.lx, yy - lp.ly, lp.idx] THEN
BEGIN
IF earlyRect THEN r ← getRect[lp];
IF lp.ob.p.setParm[lp, typ, dx, dy, TRUE] THEN
BEGIN
anyChanges ← sinceIOchanges ← TRUE;
IF lateRect THEN
r ← (IF earlyRect THEN mergeRects[getRect[lp], r] ELSE getRect[lp]);
reDrawRect[r, 1, TRUE, TRUE, FALSE];
END;
END;
lp ← lp.nxt;
ENDLOOP;
END;
setBusParms: PROCEDURE [big: BOOLEAN] =
BEGIN
x, y, ww,wd,offs, sx,sy,corn: INTEGER;
wd ← minWidthAr[wiringLev];
ww ← (wd*cScaleN)/cScaleD;
offs←((wd+lambdaGrid)/(2*lambdaGrid))*lambdaGrid;
offs ← (offs*cScaleN)/cScaleD;
-- [, x, y, , ] ← cscaleRect[wclNx, wclNy, cClipx2 - 2, cClipy2 - 2];
x←((cxoff+wclNx)*cScaleN)/cScaleD;
y←((cyoff+wclNy)*cScaleN)/cScaleD;
sx←(bm2dx*cScaleN)/cScaleD;
sy←(bm2dy*cScaleN)/cScaleD;
corn←(bmNews*cScaleN)/cScaleD;
setupTempBus[[x,y],wiringOrn,wiringLev,ww,offs,big,sx,sy,corn,bmCount];
END;
END.