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