-- a program to run within Chipmonk
-- last modified by Petit, October 8, 1981 2:20 PM
-- written by Petit, October 5, 1981 6:45 PM
DIRECTORY
ppddefs,
ppdefs,
rldefs,
ppdddefs,
StringDefs;
rlgate: PROGRAM
IMPORTS ppddefs, ppdefs, ppdddefs, StringDefs EXPORTS rldefs =
BEGIN OPEN ppddefs, rldefs, ppdefs, ppdddefs, StringDefs;
-- gate creation routines:
parma:ARRAY parmaCnt OF POINTER TO gateTypeRecord ←
[@gtr1,@gtr2,@gtr3,@gtr4,@gtr5];
currentParameters:POINTER TO gateTypeRecord;
currentParamNumber:parmaCnt;
gtr1:gateTypeRecord ← [
wWid:4,
mwWid:8,
norWireOff:2,
standWidth:16,
strtY:30,
invOff:10,
putWid:4,
putLen:4,
makAnd:mAnd1,
makPu:mPu1,
makConts:mCont1,
makTopWire:mTW1,
calcMaxy:mCalc1
];
gtr2:gateTypeRecord ← [
wWid:4,
mwWid:8,
norWireOff:2,
standWidth:32,
strtY:30,
invOff:10,
putWid:8,
putLen:4,
makAnd:mAnd1,
makPu:mPu1,
makConts:mCont1,
makTopWire:mTW1,
calcMaxy:mCalc1
];
gtr3:gateTypeRecord ← [
wWid:4,
mwWid:8,
norWireOff:2,
standWidth:48,
strtY:30,
invOff:10,
putWid:12,
putLen:4,
makAnd:mAnd1,
makPu:mPu1,
makConts:mCont1,
makTopWire:mTW1,
calcMaxy:mCalc1
];
gtr4:gateTypeRecord ← [
wWid:4,
mwWid:8,
norWireOff:2,
standWidth:8,
strtY:28, -- putLen+20
invOff:6,
putWid:4,
putLen:8,
makAnd:mAnd1,
makPu:mPu2,
makConts:mCont1,
makTopWire:mTW1,
calcMaxy:mCalc1
];
gtr5:gateTypeRecord ← [
wWid:4,
mwWid:8,
norWireOff:2,
standWidth:4,
strtY:36, -- putLen+20
invOff:6,
putWid:4,
putLen:16,
makAnd:mAnd1,
makPu:mPu2,
makConts:mCont1,
makTopWire:mTW1,
calcMaxy:mCalc1
];
gateList:LONG POINTER TO gate←NIL;
getGate:PUBLIC PROCEDURE[gc:LONG POINTER TO gateCharac,parms:INTEGER]
RETURNS[gat:LONG POINTER TO gate] =
BEGIN
gat←gateList;
WHILE gat#NIL DO
IF gat.parmNum = parms AND gcSame[gc,gat.charac] THEN RETURN;
gat←gat.nxt;
ENDLOOP;
gat←makeGate[gc,parms];
gat.nxt←gateList;
gateList←gat;
END;
gcSame:PROCEDURE[a,b:LONG POINTER TO gateCharac] RETURNS[BOOLEAN] =
BEGIN
IF a.inCnt#b.inCnt OR a.norCnt#b.norCnt THEN RETURN[FALSE];
FOR i:INTEGER IN [0..a.norCnt) DO
IF a.ands[i] # b.ands[i] THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE];
END;
makeGate:PROCEDURE[gc:LONG POINTER TO gateCharac,parms:parmaCnt]
RETURNS[gat:LONG POINTER TO gate] =
BEGIN
OPEN currentParameters;
lp:LONG POINTER TO list;--←NIL;
ob:LONG POINTER TO object;
cp:LONG POINTER TO cList;
x:locNum;
y:locNum;
i,inIdx,acnt,mx,maxy:INTEGER;
topx1,topx2,dx,width,botx:INTEGER;
currentParameters←parma[parms];
currentParamNumber←parms;
gat←GetSpace[SIZE[gate[gc.inCnt]]];
gat.inCnt←gc.inCnt;
gat.nxt←NIL;
gat.charac←gc;
gat.parmNum←currentParamNumber;
mx←0;
y←strtY;
maxy←y+calcMaxy[gc];
x←-2;
[dx,,lp]←makConts[0,gc.ands[0],x,y,maxy,NIL,gc.inCnt];
x←x+dx;
botx←0;
inIdx←0;
FOR i IN [0..gc.norCnt) DO
acnt←gc.ands[i];
[dx,width,lp]←makAnd[acnt,x,y,lp,inIdx,gat,gc.inCnt];
inIdx←inIdx+acnt;
mx←MAX[mx,x+width];
x←x+dx;
IF i=0 THEN topx1←x+norWireOff;
IF i MOD 2 = 0 THEN
BEGIN
topx2←x+norWireOff+wWid;
[dx,lp]←makTopWire[x+norWireOff,lp,gc.inCnt];
x←x+dx;
mx←MAX[mx,topx2];
END
ELSE
BEGIN
[dx,width,lp]←makConts[acnt,(IF i=gc.norCnt-1 THEN 0
ELSE gc.ands[i+1]),x,y,maxy,lp,gc.inCnt];
botx←x+2;
mx←MAX[mx,x+width];
x←x+dx;
END;
ENDLOOP;
[dx,lp]←makPu[topx1,topx2,mx,lp,gat,gc.inCnt];
mx←MAX[mx,dx];
IF botx>0 THEN
BEGIN
lp←insertList[lp,makeList[makeWire[botx+mwWid,6,met]
,0,maxy-2,2,0]];
END;
gat.gnd←[botx+2,maxy-2];
ob←makeCell[mx,maxy+4,0,lp];
cp←alocCList[];
cp.ob←ob;
cp.name←makeCellName[gc];
ob.returnable←FALSE;
gat.cell←cp;
cp.nxt←cellList;
cellList←cp;
END;
makeCellName:PROCEDURE[gc:LONG POINTER TO gateCharac] RETURNS[s:STRING] =
BEGIN
ss:STRING←[101];
ss.length←0;
AppendString[ss,"GATE"];
AppendDecimal[ss,currentParamNumber];
AppendChar[ss,'-];
AppendDecimal[ss,gc.norCnt];
FOR i:INTEGER IN [0..gc.norCnt) DO
IF ss.length>92 THEN BEGIN AppendString[ss,".ETC"];EXIT;END;
IF gc.ands[i]>1 THEN
BEGIN
AppendChar[ss,'-];
AppendChar[ss,('A+i)];
AppendDecimal[ss,gc.ands[i]];
END;
ENDLOOP;
s←newString[ss];
END;
mAnd1:mAndProcd =
BEGIN
OPEN currentParameters;
i:INTEGER;
ll:LONG POINTER TO list;
dx←0;
gat.firstInTopAvail←TRUE;
IF totIns=1 THEN
BEGIN
y←y+invOff;
ll←makeList[makeXstr[standWidth,cLength],x,y-4,0,0];
lp←insertList[lp,ll];
gat.ins[0]←[x,y];
gat.firstInTop←[x-2,y+4];
gat.rSpac←2;
gat.lSpac←3;
dx←standWidth+2;
nl←lp;
wid←dx+6;
RETURN;
END;
IF inputs=0 THEN gat.lSpac←gat.rSpac←1;
FOR i IN [0..aCnt) DO
ll←makeList[makeXstr[standWidth*aCnt,cLength],x+dx,y,2,0];
lp←insertList[lp,ll];
gat.ins[inputs+i]←[x+dx+4+cLength/2,y+standWidth*aCnt+6];
IF inputs+i=0 THEN gat.firstInTop←[x+dx+4+cLength/2,y+2];
dx←dx+8;
ENDLOOP;
nl←lp;
wid←dx+4;
END;
mPu1:mPuProcd =
BEGIN
OPEN currentParameters;
lpp:LONG POINTER TO list;
wid:INTEGER←putWid+12;
t:INTEGER←x2-wid;
ox:INTEGER←mx+gat.rSpac*2;
y:INTEGER←16;
IF totIns=1 THEN
BEGIN
x2←x1;
x1←x1-standWidth;
t←x2-wid;
y←y+invOff;
END;
IF t<x1 THEN t←MIN[x1,mx-wid];
IF t<0 THEN t←0;
x1←MIN[t,x1];
x2←MAX[x2,t+wid];
lpp←makeList[makeWire[x2-x1,wWid,dif],x1,y+8,2,0];
lp←insertList[lp,lpp];
lpp←makeList[makeButcon[],t,y,0,0];
lp←insertList[lp,lpp];
lpp←makeList[makeDifcon[MAX[8,putWid]],t+12,0,2,0];
lp←insertList[lp,lpp];
dx←MAX[t+wid+4,x2];
IF t+wid+2<ox THEN
BEGIN
dx←MAX[ox+2,dx];
lpp←makeList[makeWire[ox-t-wid,4,pol],t+wid+2,y+2,2,0];
lp←insertList[lp,lpp];
gat.out←[ox+2,y+2];
END
ELSE
BEGIN
gat.out←[t+wid+4,y+2];
END;
lpp←makeList[makeWire[y-6,putWid,dif],t+12,6,0,0];
lp←insertList[lp,lpp];
lpp←makeList[makeXstr[putWid,putLen,TRUE],t+8,y-2,0,0];
nl←insertList[lp,lpp];
END;
mPu2:mPuProcd =
BEGIN
OPEN currentParameters;
lpp:LONG POINTER TO list;
wid:INTEGER=10;
t:INTEGER←x2-wid;
ox:INTEGER←mx+gat.rSpac*2;
y:INTEGER←strtY-12;
IF totIns=1 THEN
BEGIN
x2←x1;
x1←x1-standWidth;
t←x2-wid;
y←y+invOff;
END;
IF t<x1-2 THEN t←MIN[x1-2,mx-wid];
IF t<0 THEN t←0;
x1←MIN[t+2,x1];
x2←MAX[x2,t+wid];
lpp←makeList[makeWire[x2-x1,wWid,dif],x1,y+6,2,0];
lp←insertList[lp,lpp];
lpp←makeList[makeDifcon[8],t+2,0,2,0];
lp←insertList[lp,lpp];
dx←MAX[t+wid+2,x2];
IF t+wid<ox THEN
BEGIN
dx←MAX[ox+2,dx];
lpp←makeList[makeWire[ox-t-wid,4,pol],t+wid+2,y,2,0];
lp←insertList[lp,lpp];
gat.out←[ox+2,y];
END
ELSE
BEGIN
gat.out←[t+wid+4,y];
END;
lpp←makeList[makePullup[putWid,putLen],t,
(IF totIns>1 THEN 8 ELSE invOff+8),0,0];
nl←insertList[lp,lpp];
IF totIns=1 THEN
BEGIN
lpp←makeList[makeWire[invOff+4,putWid,dif],t+4,6,0,0];
nl←insertList[nl,lpp];
END;
END;
mTW1:mTWProcd =
BEGIN
IF totIns=1 THEN {dx←10;nl←lp;RETURN};
nl←makeList[makeWire[14,currentParameters.wWid,dif],
x,currentParameters.strtY-6,0,0];
nl←insertList[lp,nl];
dx←currentParameters.wWid;
END;
mCont1:mContProcd =
BEGIN
OPEN currentParameters;
lh,rh,ny,c:INTEGER;
lh←standWidth*lCnt;
rh←standWidth*rCnt;
IF totIns=1 THEN
BEGIN
x←x+6;
y←y-2+invOff;
ny←y + 8;
nl←makeList[makeDifcon[8],x,ny,0,0];
lp←insertList[lp,nl];
nl←makeList[makeWire[lh,4,dif],x,ny+2,2,0];
lp←insertList[lp,nl];
IF maxy-ny>2 THEN
BEGIN
nl←makeList[makeWire[maxy-ny+2,mwWid,met],x,ny+2,0,0];
nl←insertList[lp,nl];
END;
dx←2;
wid←2;
RETURN;
END;
x←x+2;
c←IF MAX[rh,lh]<12 THEN 1 ELSE (MAX[rh,lh]-8)/16+1;
y←y+4;
ny←y + ((MAX[rh,lh]-8)MOD 16);
FOR i:INTEGER IN [0..c) DO
nl←makeList[makeDifcon[8],x,ny+i*16,0,0];
lp←insertList[lp,nl];
ENDLOOP;
nl←makeList[makeWire[MAX[rh,lh],4,dif],x+2,y,0,0];
lp←insertList[lp,nl];
nl←makeList[makeWire[maxy-ny+4,mwWid,met],x,ny,0,0];
nl←insertList[lp,nl];
dx←8;
wid←10;
END;
mCalc1:calcMyProcd =
BEGIN
my←0;
FOR i:INTEGER IN [0..gc.norCnt) DO
my←MAX[my,gc.ands[i]];
ENDLOOP;
my←my*currentParameters.standWidth+8;
END;
END. -- of rlgate