-- feed-back area module of silicon (pretty picture) program -- modified by McCreight, December 16, 1982 5:57 PM DIRECTORY multiGraphicsDefs, InlineDefs, StringDefs, DirectoryDefs, AltoFileDefs, IODefs, StreamDefs, ppdddefs,ppddefs, ppdefs,ppfeeddefs; ppfeed2: PROGRAM IMPORTS ppdddefs,ppddefs,ppdefs,StringDefs,DirectoryDefs,StreamDefs, ppfeeddefs,InlineDefs,multiGraphicsDefs EXPORTS ppdefs,ppddefs,ppdddefs,ppfeeddefs = PUBLIC BEGIN OPEN ppdefs,ppdddefs,ppddefs,ppfeeddefs,StringDefs,InlineDefs, DirectoryDefs,IODefs,StreamDefs,multiGraphicsDefs; cx,cy:PUBLIC INTEGER; ystrt:INTEGER=350; mButs: POINTER TO CARDINAL = LOOPHOLE[177030B]; scaleArray:ARRAY[1..20] OF RECORD[INTEGER,INTEGER]← [[1,256],[1,128],[1,64],[1,32],[1,16],[1,8],[1,4],[1,2],[1,1], [2,1],[3,1],[4,1],[6,1],[8,1],[12,1],[16,1],[24,1],[32,1],[48,1],[64,1]]; colTb:ARRAY[0..7] OF STRING=["Cut,","Dif,","Pol,","Met,","Imp,","?","?","?"]; sCodeDisp:ARRAY[1..2] OF PROCEDURE[qq:INTEGER] = [setCscale,setBWscale]; -- MAGIC (variable) CONSTANTS: --Xstr (transistor) parameters: xRatiow:PUBLIC INTEGER←2; xRatiol:PUBLIC INTEGER←1; implant:PUBLIC BOOLEAN←FALSE; pRatiow:PUBLIC INTEGER←1; pRatiol:PUBLIC INTEGER←2; pushLevel:PUBLIC INTEGER←0; setInt:setProc = BEGIN j:CARDINAL; i:INTEGER; WHILE si<s.length AND NOT s[si] IN ['0..'9] DO si←si+1;ENDLOOP; [i,j]←scan[s,si]; IF i>max THEN i←max; IF i<min THEN i←min; IF code>1 THEN i←i*code; p↑←i; END; scan:PROCEDURE[s:STRING,si:CARDINAL] RETURNS[i:INTEGER,rsi:CARDINAL]= BEGIN j:CARDINAL; i←0; FOR j IN [si..s.length) DO IF NOT s[j] IN ['0..'9] THEN BEGIN rsi←j;EXIT END; i←i*10+(s[j]-'0); ENDLOOP; END; setBool:setProc = BEGIN WHILE si<s.length AND s[si] IN ['A..'z] DO si←si+1;ENDLOOP; WHILE si<s.length AND (s[si]=' OR s[si]=': OR s[si]='=) DO si←si+1;ENDLOOP; IF s[si]='1 OR s[si]='y OR s[si]='Y OR s[si]='t OR s[si]='T THEN p↑←TRUE; IF s[si]='0 OR s[si]='n OR s[si]='N OR s[si]='f OR s[si]='F THEN p↑←FALSE; END; setCmx:setProc = BEGIN x,y,z:INTEGER; WHILE si<s.length AND NOT s[si] IN ['0..'9] DO si←si+1;ENDLOOP; [x,si]←scan[s,si]; WHILE si<s.length AND NOT s[si] IN ['0..'9] DO si←si+1;ENDLOOP; [y,si]←scan[s,si]; z←findCTab[x,y]; IF z>=0 THEN setColorTable[z]; END; setScl:setProc = BEGIN j:CARDINAL; i:INTEGER; WHILE si<s.length AND NOT s[si] IN ['0..'9] DO si←si+1;ENDLOOP; [i,j]←scan[s,si]; IF i>max THEN i←max; IF i<min THEN i←min; sCodeDisp[code][i]; END; doParmLine:PROCEDURE[s:STRING] = BEGIN i,j,k:CARDINAL; ts:STRING; okMatch:BOOLEAN; FOR i IN [0..fbC) DO ts←fbAr[i].setStr; k←0; okMatch←TRUE; IF ts.length=0 THEN okMatch←FALSE; FOR j IN [0..ts.length) DO WHILE k<s.length AND NOT (s[k]=ts[j] OR s[k]+40B=ts[j]) DO k←k+1;ENDLOOP; k←k+1; IF k>=s.length THEN BEGIN okMatch←FALSE;EXIT;END; ENDLOOP; IF okMatch THEN BEGIN fbAr[i].setP[fbAr[i].prm,fbAr[i].m,fbAr[i].n,fbAr[i].code,s,k,@fbAr[i]]; EXIT; END; ENDLOOP; END; doParmInit:PUBLIC PROCEDURE = BEGIN fHandle:DiskHandle; fp:AltoFileDefs.FP; s:STRING←[200]; k:CARDINAL; IF NOT DirectoryLookup[@fp,"chipmonk.profile",FALSE] THEN RETURN; fHandle←NewByteStream["chipmonk.profile",Read]; UNTIL fHandle.endof[fHandle] DO s.length←0; k←fHandle.get[fHandle]; UNTIL fHandle.endof[fHandle] OR k=15B DO AppendChar[s,LOOPHOLE[k]]; k←fHandle.get[fHandle]; ENDLOOP; doParmLine[s]; ENDLOOP; fHandle.destroy[fHandle]; END; dspCMix:dProc = BEGIN i,j:CARDINAL; t,xx,yy:INTEGER; FOR i IN [0..cTabCnt) DO j←colorTabs[i][0]; xx←BITSHIFT[j,-8]; yy←BITAND[j,377B]; t←IF i=currentCTab THEN 7 ELSE 3; xx←xx*10+x-t/2; yy←yy*10+y-t/2; ReplaceArea[xx,yy,xx+t,yy+t]; ENDLOOP; RETURN[x]; END; setCMix:modProc = BEGIN x,y,z:INTEGER; x←(cx-max)/10; y←(cy-min)/10; z←findCTab[x,y]; IF z>=0 THEN setColorTable[z]; END; resetCMix:modProc = BEGIN setColorTable[0]; END; moveCMix:modProc = BEGIN i:CARDINAL; ke:keyEvent; x,y,z,w:INTEGER; x←(cx-max)/10; y←(cy-min)/10; IF x<-5 OR y<-5 THEN RETURN; z←findCTab[x,y]; IF z<0 THEN RETURN; SetGrayLevel[14]; XorGray[max,min,max+90,min+100]; ke←getchr[]; UNTIL ke.k=77B DO IF ke.k=56B THEN BEGIN SetGrayLevel[14];XorGray[max,min,max+90,min+100]; RETURN;END;ke←getchr[];ENDLOOP; SetGrayLevel[14]; XorGray[max,min,max+90,min+100]; x←(ke.mx-colWidth-max)/10; y←(ke.my-min)/10; IF x<-5 OR y<-5 THEN RETURN; w←findCTab[x,y]; IF w<0 THEN BEGIN w←cTabCnt; cTabCnt←w+1; i←BITOR[BITSHIFT[x,8],y]; colorTabs[w][0]←i; END; FOR i IN [1..49) DO colorTabs[w][i]←colorTabs[z][i];ENDLOOP; setColorTable[w]; anyCTChanges←TRUE; END; currentPattern: PUBLIC CARDINAL ← 0; dspCPat:dProc = BEGIN i:CARDINAL; xx,yy:INTEGER; yy←y+5; FOR i IN [0..colPatNum) DO xx←x+i*10; ReplaceArea[xx-3,yy,xx+3,yy]; ReplaceArea[xx,yy-3,xx,yy+3]; IF i=currentPattern THEN ReplaceArea[xx-2,yy-2,xx+2,yy+2]; ENDLOOP; RETURN[x]; END; setCPat:modProc = BEGIN x:INTEGER; x←(cx-max)/10; IF colPatternBits[x]#0 THEN BEGIN currentPattern←x; orLtab←colPatternTabs[x]; END; END; resetCPat:modProc = BEGIN currentPattern←0; orLtab←colPatternTabs[0]; END; moveCPat:modProc = BEGIN ke:keyEvent; x,z:INTEGER; z←(cx-max)/10; IF z<-5 THEN RETURN; IF colPatternBits[z]=0 THEN RETURN; SetGrayLevel[14]; XorGray[max,min,max+90,min+18]; ke←getchr[]; UNTIL ke.k=77B DO IF ke.k=56B THEN BEGIN SetGrayLevel[14];XorGray[max,min,max+90,min+18]; RETURN;END;ke←getchr[];ENDLOOP; SetGrayLevel[14]; XorGray[max,min,max+90,min+18]; x←(ke.mx-colWidth-max)/10; IF x<-5 THEN RETURN; colPatternTabs[x]←colPatternTabs[z]; colPatternBits[x]←15; anyCTChanges←TRUE; currentPattern←x; orLtab←colPatternTabs[x]; END; findCTab:PROCEDURE[x,y:INTEGER] RETURNS[INTEGER] = BEGIN cc,i:CARDINAL; IF x<0 THEN x←0;IF y<0 THEN y←0; cc←BITOR[BITSHIFT[x,8],y]; FOR i IN [0..cTabCnt) DO IF cc=colorTabs[i][0] THEN RETURN[i]; ENDLOOP; RETURN[-1]; END; nullMP:modProc = BEGIN NULL END; nullDP:dProc = BEGIN RETURN[x] END; dspLevVisible: dProc = BEGIN l: level = LOOPHOLE[code]; Surround[p: [parm.sx, parm.sy], s: parm.s1, gray: NOT showColorLevel[l], box: l=favLev]; RETURN[x]; END; flipLevVisible: modProc = BEGIN l: level = LOOPHOLE[code]; showColorLevel[l] ← NOT showColorLevel[l]; parm.chgC ← TRUE; END; nullST:setProc = {NULL}; dspLam:dProc = BEGIN pp:POINTER TO INTEGER=LOOPHOLE[p]; ds:STRING←[14]; ds.length←0; AppendDecimal[ds,pp↑/2]; RETURN[PutText[ds,x,y,fnt,normal]]; END; dspCore:dProc = BEGIN ds:STRING←[18]; ds.length←0; AppendDecimal[ds,swdsAloc]; AppendString[ds,", "]; appendLongDecimal[ds,lwdsAloc]; x←PutText[ds,x,y,fnt,normal]; RETURN[x]; END; appendLongDecimal:PROCEDURE[s:STRING,n:LONG INTEGER]= BEGIN IF n<0 THEN BEGIN AppendChar[s,'-];n←-n;END; apLD[s,n]; END; apLD:PROCEDURE[s:STRING,n:LONG INTEGER]= BEGIN q:LONG INTEGER; r:INTEGER; q←n MOD 10; r←LowHalf[q]; q←n/10; IF q#0 THEN apLD[s,q]; AppendChar[s,'0+r] END; dspName:dProc = BEGIN s:STRING; s←p↑; RETURN[PutText[s,x,y,fnt,normal]]; END; dspLM:dProc = BEGIN i,j:INTEGER; i←p↑; IF i=0 THEN RETURN[PutText["- - -",x,y,fnt,normal]]; FOR j IN [0..7] DO IF BITAND[i,BITSHIFT[1,j]]#0 THEN x←PutText[colTb[j],x,y,fnt,normal]; ENDLOOP; RETURN[x]; END; Surround: PROC [p: Point, s: STRING, box, gray: BOOLEAN ← FALSE, font: StrikeFontPtr ← NIL] = BEGIN lastX: INTEGER; IF font=NIL THEN font ← fnt; lastX ← p.x+MeasureText[s: s, font: font]; IF box THEN BEGIN ReplaceArea[x1: p.x-2, y1: p.y-fnt.ascent-2, x2: p.x-1, y2: p.y+fnt.descent+1]; ReplaceArea[x1: lastX, y1: p.y-fnt.ascent-2, x2: lastX+1, y2: p.y+fnt.descent+1]; ReplaceArea[x1: p.x-2, y1: p.y-fnt.ascent-2, x2: lastX+1, y2: p.y-fnt.ascent-1]; ReplaceArea[x1: p.x-2, y1: p.y+fnt.descent, x2: lastX+1, y2: p.y+fnt.descent+1]; END; IF gray THEN BEGIN halfGray: GrayPattern ← [125252B, 52525B, 125252B, 52525B, 125252B, 52525B, 125252B]; SetArea[x1: p.x-1, y1: p.y-fnt.ascent-1, x2: lastX, y2: p.y+fnt.descent, fn: paint, gray: @halfGray]; END; END; dspCM, dspFL:dProc = BEGIN Surround[p: [parm.sx, parm.sy], s: parm.s1, box: (code#0)=cMos]; RETURN[x]; END; codeLev:ARRAY level OF CARDINAL = [0,1,2,3,0,0,0,0,0,4,0,5,0,0,0,0]; setFL:modProc = {favLev←LOOPHOLE[code, level]; parm.chgC ← FALSE}; setCM:modProc = BEGIN cMos←code#0; END; dspScl:dProc = BEGIN pos,i:INTEGER; ds:STRING←[14]; ds.length←0; i←p↑; AppendDecimal[ds,i]; pos←PutText[ds,x,y,fnt,normal]; ReplaceArea[x,bwFeedTop+30,x+2,bwFeedTop+110]; ReplaceArea[x-4,bwFeedTop+113-i*4,x+6,bwFeedTop+115-i*4]; RETURN[pos]; END; tyScl:modProc = BEGIN i:INTEGER; i←bwFeedTop+114-cy; i←i/4; IF i>max THEN i←max; IF i<min THEN i←min; sCodeDisp[code][i]; END; incScl:modProc = BEGIN i:INTEGER; i←p↑; i←i+1; IF i>max THEN i←max; sCodeDisp[code][i]; END; decScl:modProc = BEGIN i:INTEGER; i←p↑; i←i-1; IF i<min THEN i←min; sCodeDisp[code][i]; END; dspBool:dProc = BEGIN b:BOOLEAN; b←LOOPHOLE[p↑]; IF b THEN RETURN[PutText["YES",x,y,fnt,normal]] ELSE RETURN[PutText["NO",x,y,fnt,normal]]; END; incBool:modProc = BEGIN b:BOOLEAN; b←TRUE; p↑←b; END; decBool:modProc = BEGIN b:BOOLEAN; b←FALSE; p↑←b; END; cmpBool:modProc = BEGIN b:BOOLEAN; b←p↑; b←NOT b; p↑←b; END; dspMode:dProc = BEGIN IF wiring THEN RETURN[PutText["Wiring",x,y,fnt,normal]]; IF boxing THEN RETURN[PutText["AreaSel",x,y,fnt,normal]]; RETURN[PutText["none",x,y,fnt,normal]]; END; dspInt:dProc = BEGIN ds:STRING←[14]; ds.length←0; IF code>1 THEN BEGIN i:INTEGER←LOOPHOLE[p↑]; i←i/code; AppendDecimal[ds,i]; END ELSE AppendDecimal[ds,p↑]; RETURN[PutText[ds,x,y,fnt,normal]]; END; incInt:modProc = BEGIN i:INTEGER; i←p↑; i←i+MAX[code,1]; IF i>max THEN i← IF code=1 THEN min ELSE max; p↑←i; END; decInt:modProc = BEGIN i:INTEGER; i←p↑; i←i-MAX[code,1]; IF i<min THEN i← IF code=1 THEN max ELSE min; p↑←i; END; tyInt:modProc = BEGIN i:INTEGER; ke:keyEvent; ke←getchr[]; UNTIL ke.k=60B OR ke.k=65B DO -- CR or ESC IF ke.k=71B OR ke.k=72B OR ke.k=73B OR ke.k=56B THEN RETURN; ke←getchr[]; ENDLOOP; i←getNumber[]; IF i>max THEN i←max; IF i<min THEN i←min; IF code>1 THEN i←i*code; p↑←i; END; displayParameters:PUBLIC PROCEDURE = BEGIN i:CARDINAL; xx,yy:INTEGER; EraseArea[0,bwFeedTop,606,808]; PutArea[0,bwBottom+1,700,bwBottom+3]; PutArea[0,bwMsgBottom-5,700,bwMsgBottom-3]; FOR i IN [0..fbC) DO xx←fbAr[i].sx; yy←fbAr[i].sy; IF fbAr[i].s1.length>0 THEN xx←PutText[fbAr[i].s1,xx,yy,fnt,normal]; xx←fbAr[i].dspPrm[fbAr[i].prm,xx,yy,fbAr[i].code,@fbAr[i]]; IF fbAr[i].s2.length>0 THEN xx←PutText[fbAr[i].s2,xx,yy,fnt,normal]; ENDLOOP; END; doRfeed:PUBLIC PROCEDURE RETURNS[BOOLEAN,BOOLEAN] = BEGIN i:CARDINAL; b:BOOLEAN; [b,i]←feedTrack[]; IF NOT b THEN RETURN[FALSE,FALSE]; fbAr[i].rbP[fbAr[i].prm,fbAr[i].m,fbAr[i].n,fbAr[i].code,@fbAr[i]]; RETURN[fbAr[i].chgC,fbAr[i].chgB]; END; doYfeed:PUBLIC PROCEDURE RETURNS[BOOLEAN,BOOLEAN] = BEGIN i:CARDINAL; b:BOOLEAN; [b,i]←feedTrack[]; IF NOT b THEN RETURN[FALSE,FALSE]; fbAr[i].ybP[fbAr[i].prm,fbAr[i].m,fbAr[i].n,fbAr[i].code,@fbAr[i]]; RETURN[fbAr[i].chgC,fbAr[i].chgB]; END; doBfeed:PUBLIC PROCEDURE RETURNS[BOOLEAN,BOOLEAN] = BEGIN i:CARDINAL; b:BOOLEAN; [b,i]←feedTrack[]; IF NOT b THEN RETURN[FALSE,FALSE]; fbAr[i].bbP[fbAr[i].prm,fbAr[i].m,fbAr[i].n,fbAr[i].code,@fbAr[i]]; RETURN[fbAr[i].chgC,fbAr[i].chgB]; END; feedTrack:PROCEDURE RETURNS[b:BOOLEAN,n:CARDINAL]= BEGIN i:CARDINAL; ke:keyEvent; b←FALSE; UNTIL BITAND[mButs↑,7]=7 DO cx←curx-colWidth;cy←cury; IF b AND NOT (cx IN [fbAr[n].tx1..fbAr[n].tx2] AND cy IN [fbAr[n].ty1..fbAr[n].ty2]) THEN BEGIN b←FALSE; XorArea[fbAr[n].tx1,fbAr[n].ty1,fbAr[n].tx2,fbAr[n].ty2]; END; IF NOT b THEN FOR i IN [0..fbC) DO IF cx IN [fbAr[i].tx1..fbAr[i].tx2] AND cy IN [fbAr[i].ty1..fbAr[i].ty2] THEN BEGIN n←i; b←TRUE; XorArea[fbAr[i].tx1,fbAr[i].ty1,fbAr[i].tx2,fbAr[i].ty2]; EXIT; END; ENDLOOP; ENDLOOP; ke←getchr[]; UNTIL ke.k IN [72B..74B] DO ke←getchr[];ENDLOOP; cx←ke.mx-colWidth;cy←ke.my; b←FALSE; FOR i IN [0..fbC) DO IF cx IN [fbAr[i].tx1..fbAr[i].tx2] AND cy IN [fbAr[i].ty1..fbAr[i].ty2] THEN BEGIN n←i; b←TRUE; EXIT; END; ENDLOOP; END; END.