-- I/O module of silicon (pretty picture) program -- last modified by McCreight, December 3, 1982 9:44 AM -- modified by Petit, September 20, 1981 DIRECTORY InlineDefs, StreamDefs, SystemDefs, IODefs, AltoDefs, DirectoryDefs, AltoFileDefs, StringDefs, ppoutdefs, ppdddefs,ppddefs, ppdefs; ppio: PROGRAM IMPORTS ppdefs, ppddefs, ppdddefs,ppoutdefs, InlineDefs, StreamDefs, StringDefs, DirectoryDefs EXPORTS ppddefs = BEGIN OPEN ppdefs, ppddefs, ppdddefs,ppoutdefs, InlineDefs, StreamDefs, IODefs, StringDefs, DirectoryDefs; fp: AltoFileDefs.FP; -- press command byte defs: fontset: CARDINAL = 160B; setx: CARDINAL = 356B; sety: CARDINAL = 357B; showchar: CARDINAL = 360B; showcharim: CARDINAL = 363B; showrect: CARDINAL = 376B; setBrt: CARDINAL = 370B; setHue: CARDINAL = 371B; setSat: CARDINAL = 372B; currentColor: level; hardCopyScaleNumber: INTEGER = 42; hScale: INTEGER; hBrttab: ARRAY level OF CARDINAL ← [30, 255, 255, 255, 235, 255, 190, 255 ,180,255,255,180,255,220,255,255]; hHuetab: ARRAY level OF CARDINAL ← [10, 70, 215, 130, 40, 220, 10, 220 ,10,70,255,15,255,5,5,255]; hSattab: ARRAY level OF CARDINAL ← [0, 190, 180, 190, 225, 220, 112, 120 ,255,190,255,200,255,80,255,255]; layNam: ARRAY level OF CHARACTER ← ['C, 'D, 'P, 'M, 'I, 'G, 'B, 'X, 'O, 'Q, 'X, 'S, 'X, 'T, 'X, 'X]; byteCnt, saveByte: CARDINAL; hscale: PROCEDURE [x, y: INTEGER] RETURNS [INTEGER, INTEGER]; -- dummy font name: fontName: ARRAY [1..20] OF CARDINAL ← [ 9, 110B, 105B, 114B, 126B, 105B, 124B, 111B, 103B, 101B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; inObject: PROCEDURE [version: CARDINAL] RETURNS [ob: LONG POINTER TO object] = BEGIN j, k: CARDINAL; w, l, we, le,ii,sur: INTEGER; lev:level; sur←6; j ← inWord[]; SELECT j FROM 1 => BEGIN k ← inWord[]; -- get unique cell id ob ← cellNameA[k].p.anotherme[cellNameA[k]] END; 2 => BEGIN w ← inWord[]; l ← inWord[]; k ← inWord[]; IF BITAND[k,20000B]#0 THEN j ← inWord[];-- if angle, get angle ext. IF version>4 AND BITAND[k,10000B]#0 THEN sur ← inWord[];-- if pdif, get surround we ← BITAND[BITSHIFT[k, -6], 77B]; le ← BITAND[k, 77B]; ob ← IF BITAND[k, 40000B] # 0 THEN makePullup[w, l,we,le] ELSE IF BITAND[k,20000B]#0 THEN makeAngleXstr[w, l, BITAND[k, 100000B] # 0,we,le,j] ELSE IF BITAND[k,10000B]#0 THEN makePXstr[w, l, BITAND[k, 100000B] # 0,we,le,sur] ELSE makeXstr[w, l, BITAND[k, 100000B] # 0,we,le]; END; 3 => BEGIN j ← inWord[]; -- get contact type k ← BITAND[j, 37B]; -- get contact type l ← BITSHIFT[j, -8]; IF version>4 THEN sur←inWord[]; SELECT contTypA[k] FROM mPol => ob ← makePolycon[l]; mDif => ob ← makeDifcon[l]; butt => ob ← makeButcon[]; burr => BEGIN w←inWord[]; k←inWord[]; j←BITSHIFT[k,-8]; ob ← makeBuCont[w,l,j,BITAND[k,377B]]; END; mm2 => ob ← makeMmCont[l,0,0]; mPDif => ob ← makePDifcon[l,sur]; nwell => ob ← makeNwellcon[l]; mmDif => ob ← makeMmDifcon[l]; mmPol => ob ← makeMmPolcon[l]; mmPDif => ob ← makeMPDifcon[l,sur]; ENDCASE => ERROR; END; 4 => BEGIN w ← inWord[]; l ← inWord[]; lev ← inWord[]; IF version>4 AND lev=pdif THEN sur←inWord[]; ob ← makeWire[l, w, lev,sur]; END; 5 => BEGIN w ← inWord[]; l ← inWord[]; lev ← inWord[]; ob ← makeRect[w, l, lev]; END; 6 => BEGIN ob ← makeText[inString[]]; END; 7 => BEGIN w ← inWord[]; l ← inWord[]; lev ← inWord[];--level j ← inWord[];--cnt we ← inWord[];--spacing le ← inWord[];--top incr ii ← inWord[];--bot incr ob ← makeBus[l, w, lev,j,we,le,ii]; END; 8 => BEGIN obb: obPtr = inObject[version]; w ← inWord[]; l ← inWord[]; we ← inWord[]; le ← inWord[]; ii ← inWord[];--cnt j ← inWord[];--idx ob ← makeRep[obb, w, l, we, le, ii, j]; END; ENDCASE => BEGIN ob ← NIL; END; END; inList: PROCEDURE [ver: CARDINAL] RETURNS [lp: LONG POINTER TO list] = BEGIN i, j, k, l: CARDINAL; tp: LONG POINTER TO list; pop: LONG POINTER TO prop; lp ← NIL; i ← inWord[]; FOR j IN [0..i) DO tp ← alocList[]; tp.nxt ← lp; tp.lx ← inWord[]; tp.ly ← inWord[]; tp.idx ← inWord[]; tp.ridx ← BITXOR[tp.idx, 1]; tp.ob ← inObject[ver]; tp.props ← NIL; IF ver > 3 THEN BEGIN k ← inWord[]; FOR l IN [0..k) DO pop ← inProp[]; IF pop # NIL THEN putProp[tp, pop]; IF pop # NIL AND pop.ptyp = text THEN tp.gotText ← TRUE; ENDLOOP; END; IF tp.ob # NIL THEN lp ← tp; ENDLOOP; END; inProp: PROCEDURE RETURNS [LONG POINTER TO prop] = BEGIN i: CARDINAL; i ← inWord[]; SELECT i FROM 1 => BEGIN tp: LONG POINTER TO text prop ← alocTextProp[]; tp.s ← inString[]; RETURN[tp]; END; ENDCASE => RETURN[NIL]; END; inWord: PROCEDURE RETURNS [UNSPECIFIED] = BEGIN IF NOT ppHandle.endof[ppHandle] THEN RETURN[ppHandle.get[ppHandle]] ELSE RETURN[0]; END; readAll: PUBLIC PROCEDURE RETURNS [mp: LONG POINTER TO list, cp: LONG POINTER TO cList] = BEGIN i, j, ver: CARDINAL; lp, lpp, lqp: LONG POINTER TO list; cdp: LONG POINTER TO cell object; cpp: LONG POINTER TO cList; ss: STRING; pop: LONG POINTER TO text prop; i ← inWord[]; -- read code word ver ← inWord[]; -- read version # cCnt ← inWord[]; -- read count of cells cellNameA ← DESCRIPTOR[ GetSpace[(cCnt + 1)*SIZE[LONG POINTER TO object]], cCnt + 1]; IF ver < 3 THEN ERROR; cp ← NIL; FOR i IN [0..cCnt] DO -- 0 is an illegal cell that can get generated by a bug -- in the output routines cellNameA[i] ← makeCell[Lambda, Lambda, 0, NIL]; ENDLOOP; FOR i IN [1..cCnt] DO j ← inWord[]; cdp ← cellNameA[j]; ss ← inString[]; cdp.size[0] ← cdp.size[2] ← inWord[]; cdp.size[1] ← inWord[]; cdp.cnt ← inWord[]; cdp.ptr ← inList[ver]; IF ss.length > 0 THEN BEGIN cpp ← alocCList[]; cpp.nxt ← cp; cp ← cpp; cpp.ob ← cdp.p.anotherme[cdp]; cpp.name ← ss; cdp.returnable ← FALSE; END; ENDLOOP; mp ← inList[ver]; -- get master list FOR i IN [1..cCnt] DO cellNameA[i].p.release[cellNameA[i]]; ENDLOOP; FreeSpace[BASE[cellNameA]]; lp ← mp; mp ← NIL; WHILE lp # NIL DO IF lp.ob.otyp = text THEN BEGIN lpp ← mp; lqp ← NIL; FOR i IN [0..1] DO DO IF lpp = NIL THEN BEGIN lpp ← lp.nxt; EXIT; END; IF ((lpp.ob.otyp = wire AND lpp.ob.l IN [dif..met]) OR lpp.ob.otyp = cont) AND lpp.ob.p.inMe[lpp.ob, lp.lx - lpp.lx, lp.ly - lpp.ly, lpp.idx] THEN BEGIN lqp ← lpp; EXIT; END; lpp ← lpp.nxt; ENDLOOP; IF lqp # NIL THEN EXIT; ENDLOOP; IF lqp # NIL THEN BEGIN pop ← alocTextProp[]; pop.s ← LOOPHOLE[lp.ob, LONG POINTER TO text object].s; putProp[lqp, pop]; lqp.gotText ← TRUE; END; lp ← lp.nxt; END ELSE BEGIN lpp ← lp.nxt; lp.nxt ← mp; mp ← lp; lp ← lpp; END; ENDLOOP; END; inString: PROCEDURE RETURNS [s: STRING] = BEGIN i, j, len: CARDINAL; flg: BOOLEAN; j ← inWord[]; len ← BITSHIFT[j, -8]; IF len = 0 THEN BEGIN s ← ""; RETURN; END; s ← GetString[len]; s.length ← 0; flg ← TRUE; FOR i IN [0..len) DO IF flg THEN AppendChar[s, BITAND[j, 377B]] ELSE BEGIN j ← inWord[]; AppendChar[s, BITSHIFT[j, -8]]; END; flg ← NOT flg; ENDLOOP; END; openIfile: PUBLIC PROCEDURE [fname: STRING] RETURNS [BOOLEAN] = BEGIN IF NOT DirectoryLookup[@fp, fname, FALSE] THEN RETURN[FALSE]; ppHandle ← NewWordStream[fname, Read]; RETURN[TRUE]; END; openOTfile: PUBLIC PROCEDURE [fname: STRING] RETURNS [BOOLEAN] = BEGIN -- IF NOT DirectoryLookup[@fp,fname,FALSE] THEN RETURN[FALSE]; ppHandle ← NewByteStream[fname, Write + Append]; RETURN[TRUE]; END; -- ******** hardcopy stuff: ovByteCnt: CARDINAL; ovLimit: CARDINAL = 10000; padWds, pagCnt: CARDINAL; hardDrR: drRecord ← [ [0,0,0,0], [0,0,0,0], hardOutArea, hardOutArea, nullOutl, nulldtxt, 0]; nullOutl: PROCEDURE [a, b, c, d: INTEGER, q: color, p: POINTER TO Rect] = BEGIN END; nulldtxt: PROCEDURE [a, b, c, d: INTEGER, s: STRING, p: POINTER TO Rect] = BEGIN END; hardOut: PUBLIC PROCEDURE [fn: STRING, lp: LONG POINTER TO list] = BEGIN j: CARDINAL; fullName: STRING ← [30]; dChange ← TRUE; fullName.length ← 0; AppendString[fullName, fn]; AppendString[fullName, ".press"]; IF NOT openOfile[fullName, TRUE] THEN RETURN; byteCnt ← 0; pagCnt ← 0; hWout[0]; -- no text, so this ends the DL ovByteCnt ← byteCnt; currentColor ← NOcOL; -- make sure first color we output isn't current hardDrR.r ← [cClipx1, cClipy1, cClipx2, cClipy2]; hardDrR.bigr ← [cClipx1-wellSurround, cClipy1-wellSurround, cClipx2+wellSurround, cClipy2+wellSurround]; hScale ← cScaleN*hardCopyScaleNumber; hscale ← IF cScaleD = 1 THEN hscale1 ELSE hscale2; WHILE lp # NIL DO lp.ob.p.drawme[lp.idx][lp.ob, lp.lx, lp.ly, @hardDrR]; lp ← lp.nxt; ENDLOOP; termEnt[]; padWds ← byteCnt MOD 512; padWds ← 256 - padWds/2; FOR j IN [0..padWds) DO hWout[0]; ENDLOOP; pagCnt ← pagCnt + ((byteCnt + 3)/512); byteCnt ← 0; hWout[16]; -- dummy font defn -length hWout[4]; -- font-set, font hBout[32]; hBout[127]; FOR j IN [1..20] DO hBout[fontName[j]]; ENDLOOP; hWout[32]; -- face, source hWout[10]; -- size hWout[0]; -- rotation FOR j IN [0..256 - 16) DO hWout[0]; ENDLOOP; hWout[0]; -- page part hWout[0]; -- starts at record 0 hWout[pagCnt]; -- length in pages hWout[padWds]; -- words of padding hWout[1]; -- font part hWout[pagCnt]; -- starts at record pagCnt hWout[1]; -- length in pages hWout[0]; -- undefined FOR j IN [0..256 - 8) DO hWout[0]; ENDLOOP; hWout[27183]; -- code word hWout[pagCnt + 3]; -- total records hWout[2]; -- # of parts hWout[pagCnt + 1]; -- where part dir starts hWout[1]; -- # of pages in part dir hWout[177777B]; -- # of parts hWout[112300B]; -- date hWout[106745B]; -- date hWout[1]; hWout[1]; hWout[177777B]; hWout[177777B]; hWout[124B]; FOR j IN [0..115) DO hWout[177777B]; ENDLOOP; FOR j IN [0..256 - 115 - 13) DO hWout[0]; ENDLOOP; closeFile[]; END; --hscale:PROCEDURE[x,y:INTEGER]RETURNS[INTEGER,INTEGER]= -- BEGIN -- RETURN[((cxoff+x)*hScale)/cScaleD,640-((cyoff+y)*hScale)/cScaleD]; -- RETURN[((cxoff+x)*hScale)/cScaleD,((cClipy2-y)*hScale)/cScaleD]; -- END; hscale1: PROCEDURE [x, y: INTEGER] RETURNS [INTEGER, INTEGER] = BEGIN tx, ty: INTEGER; ty ← cxoff + x; tx ← cyoff + y; RETURN[tx*hScale, ty*hScale]; END; hscale2: PROCEDURE [x, y: INTEGER] RETURNS [INTEGER, INTEGER] = BEGIN tx, ty: INTEGER; ty ← cxoff + x; tx ← cyoff + y; RETURN[ (tx/cScaleD)*hScale + ((tx MOD cScaleD)*hScale)/cScaleD, (ty/cScaleD)*hScale + ((ty MOD cScaleD)*hScale)/cScaleD]; END; hscaleRect: PROCEDURE [x1, y1, x2, y2: INTEGER] RETURNS [BOOLEAN, INTEGER, INTEGER, INTEGER, INTEGER] = INLINE BEGIN t: INTEGER; IF x1 > x2 THEN BEGIN t ← x1; x1 ← x2; x2 ← t; END; IF y1 > y2 THEN BEGIN t ← y1; y1 ← y2; y2 ← t; END; IF x1 > cClipx2 OR x2 < cClipx1 OR y1 > cClipy2 OR y2 < cClipy1 THEN RETURN[FALSE, 0, 0, 0, 0]; [x1, y1] ← hscale[MAX[x1, cClipx1], MAX[y1, cClipy1]]; [x2, y2] ← hscale[MIN[x2, cClipx2], MIN[y2, cClipy2]]; RETURN[TRUE, x1, y2, x2, y1]; END; hardOutArea: PROCEDURE [x1, y1, x2, y2: INTEGER, l: level, p: POINTER TO Rect] = BEGIN a, b, c, d: INTEGER; bb: BOOLEAN; [bb, a, b, c, d] ← hscaleRect[x1, y1, x2, y2]; IF bb THEN BEGIN IF l # currentColor THEN BEGIN currentColor ← l; hBout[setBrt]; hBout[hBrttab[l]]; hBout[setHue]; hBout[hHuetab[l]]; hBout[setSat]; hBout[hSattab[l]]; END; hBout[setx]; hWout[a]; hBout[sety]; hWout[b]; hBout[showrect]; hWout[c - a]; hWout[d - b]; IF byteCnt > ovByteCnt + ovLimit THEN termEnt[]; END; END; termEnt: PROCEDURE = BEGIN IF byteCnt = ovByteCnt THEN RETURN; IF BITAND[byteCnt, 1] # 0 THEN hBout[377]; hWout[0]; -- type,font set hWout[0]; --.. hWout[0]; -- begin byte # hWout[0]; -- first word of byte count hWout[0]; -- second word of ditto hWout[0]; -- Xe hWout[0]; -- Ye hWout[0]; -- left hWout[0]; -- bottom hWout[20600]; -- width hWout[27460]; -- height hWout[(byteCnt - ovByteCnt + 2)/2]; -- entity length pagCnt ← pagCnt + byteCnt/512; byteCnt ← byteCnt MOD 512; ovByteCnt ← byteCnt; currentColor ← NOcOL; -- make sure first color we output isn't current END; outWord: PROCEDURE [ww: UNSPECIFIED] = BEGIN ppHandle.put[ppHandle, ww]; END; hBout: PROCEDURE [u: UNSPECIFIED] = BEGIN IF BITAND[byteCnt, 1] = 0 THEN saveByte ← BITSHIFT[BITAND[u, 377B], 8] ELSE outWord[BITOR[saveByte, BITAND[u, 377B]]]; byteCnt ← byteCnt + 1; END; hWout: PROCEDURE [u: UNSPECIFIED] = BEGIN IF BITAND[byteCnt, 1] = 0 THEN BEGIN outWord[u]; byteCnt ← byteCnt + 2; END ELSE BEGIN hBout[BITSHIFT[u, -8]]; hBout[u]; END; END; -- ******** CIF output stuff cellCnt: CARDINAL; --matrx is indexed by the orientation index: 0 = no rot. -- 1= reflection, 4= rot 90 degress to the right, 5= rot 90 + reflected, -- 8= rotate 180, 9= rotate 180 + refl, 12= rot 270 (right), 13= 270 + refl. matrx: ARRAY [0..15] OF RECORD [xsx, xsy, ysx, ysy: [0..15]] = [ [0, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], [ 0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [1, 0, 0, 1], [0, 0, 0, 1], [ 1, 0, 0, 1], [0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 1, 0], [0, 0, 1, 0], [ 0, 1, 1, 0]]; -- [0,0,0,0],[0,0,0,0], [0,1,0,0],[0,1,0,0], -- [1,0,0,1],[1,0,0,1], [0,0,1,0],[0,0,1,0], -- [1,0,0,0],[1,0,0,0], [0,0,0,0],[0,0,0,0], -- [0,0,0,1],[0,0,0,1], [0,1,1,0],[0,1,1,0] ]; curLayer: level; cifScale: INTEGER ← 125; cifDrR: drRecord ← [ [0,0,0,0], [0,0,0,0], cifOrArea, cifOrArea, nullOutl, nullCifDrawText, 0]; nullCifDrawText:PROCEDURE[x,y,sx,sy:INTEGER,s:STRING,pz:POINTER TO Rect] = BEGIN NULL; END; cifOutDrawing: PUBLIC PROCEDURE [fn: STRING, lp: LONG POINTER TO list] = BEGIN fullName: STRING ← [30]; cifScale ← pCifScale/2; clearMarked[lp]; fullName.length ← 0; AppendString[fullName, fn]; AppendString[fullName, ".cif"]; IF NOT openOTfile[fullName] THEN RETURN; cellCnt ← 1; curLayer ← NOcOL; cifDrR.r ← [-77777B, -77777B, 77777B, 77777B]; cifDrR.bigr ← [-77777B, -77777B, 77777B, 77777B]; cifOutList[lp, 1, "TopLevel"]; cifOutStr["C 1 M Y;"]; cifOutChr[15C]; cifOutStr[" End ..."]; cifOutChr[15C]; ppHandle.destroy[ppHandle]; END; clearMarked: PROCEDURE [lp: LONG POINTER TO list] = BEGIN WHILE lp # NIL DO IF lp.ob.otyp = cell THEN BEGIN cp: LONG POINTER TO cell object ← LOOPHOLE[lp.ob]; clearMarked[cp.ptr]; END; lp.ob.marked ← FALSE; lp ← lp.nxt; ENDLOOP; END; cifOutList: PROCEDURE [lp: LONG POINTER TO list, cellNum: CARDINAL, cellnam:STRING] = BEGIN pp: LONG POINTER TO list ← lp; WHILE pp # NIL DO IF pp.ob.otyp = cell THEN BEGIN cp: LONG POINTER TO cell object ← LOOPHOLE[pp.ob]; IF NOT cp.marked THEN BEGIN cp.marked ← TRUE; cellCnt ← cellCnt + 1; cp.cnt ← cellCnt; cifOutList[cp.ptr, cellCnt, findname[cp]]; END; END; pp ← pp.nxt; ENDLOOP; cifOutStr["DS "]; curLayer ← NOcOL; cifOutNum[cellNum]; cifOutEndCom[]; IF cellnam.length>0 THEN cifDrawCellName[cellnam]; WHILE lp # NIL DO cifOutObject[lp, cellNum = 1]; lp ← lp.nxt; ENDLOOP; cifOutStr["DF"]; curLayer ← NOcOL; cifOutEndCom[]; END; cifOutObject: PROCEDURE [lp: LONG POINTER TO list, textOK: BOOLEAN] = BEGIN IF lp.ob.otyp = cell THEN BEGIN x, y: locNum; ob: LONG POINTER TO cell object ← LOOPHOLE[lp.ob]; ii: CARDINAL ← lp.idx; jj: CARDINAL; x ← lp.lx + ob.size[0]*matrx[ii].xsx + ob.size[1]*matrx[ii].xsy; y ← lp.ly + ob.size[0]*matrx[ii].ysx + ob.size[1]*matrx[ii].ysy; cifOutStr["C "]; cifOutNum[ob.cnt]; cifOutChr[' ]; IF ii # 0 THEN BEGIN IF (jj ← BITAND[ii, 12]) # 0 THEN BEGIN cifOutStr["R "]; cifOutStr[ (IF jj = 4 THEN "0,1 " ELSE IF jj = 8 THEN "-1,0 " ELSE IF jj = 12 THEN "0,-1 " ELSE "1,0 ")]; END; IF BITAND[ii, 1] # 0 THEN cifOutStr["M X "]; END; cifOutStr["T "]; cifOutPoint[x, y]; cifOutEndCom[]; END ELSE BEGIN lp.ob.p.drawme[lp.idx][lp.ob, lp.lx, lp.ly, @cifDrR]; IF textOK AND lp.gotText AND (lp.ob.otyp=wire OR lp.ob.otyp=cont) THEN BEGIN tp: LONG POINTER TO text prop ← getTextProp[lp]; cifDrawText[lp.lx, lp.ly, 0, 0, tp.s, NIL, IF lp.ob.otyp=cont THEN 'M ELSE layNam[lp.ob.l] ]; END; END; END; cifOrArea: PROCEDURE [x1, y1, x2, y2: INTEGER, l: level, p: POINTER TO Rect] = BEGIN x, y: LONG INTEGER; IF l # curLayer THEN BEGIN curLayer ← l; cifOutStr["LN"]; cifOutChr[layNam[l]]; cifOutEndCom[]; END; x ← x1; y ← y1; x ← (x + x2)*cifScale; y ← (y + y2)*cifScale; x ← x/2; y ← y/2; cifOutStr["B "]; cifOutSNum[ABS[x2 - x1]]; cifOutChr[' ]; cifOutSNum[ABS[y2 - y1]]; cifOutChr[' ]; cifOutLongInt[x]; cifOutChr[',]; cifOutLongInt[y]; cifOutEndCom[]; END; cifDrawText: PROCEDURE [ x, y, sx, sy: INTEGER, s: STRING, pz: POINTER TO Rect, ls:CHARACTER] = BEGIN cifOutStr["94 "]; cifOutStr[s]; cifOutChr[' ]; cifOutSNum[x + 1]; cifOutStr[" "]; cifOutSNum[y + 1]; cifOutStr[" N"]; cifOutChr[ls]; cifOutChr[' ]; cifOutEndCom[]; END; cifDrawCellName: PROCEDURE [s: STRING] = BEGIN cifOutStr["9 "]; cifOutStr[s]; cifOutEndCom[]; END; cifOutStr: PUBLIC PROCEDURE [s: STRING] = BEGIN FOR i: CARDINAL IN [0..s.length) DO ppHandle.put[ppHandle, s[i]]; ENDLOOP; END; cifOutChr: PUBLIC PROCEDURE [c: CHARACTER] = BEGIN ppHandle.put[ppHandle, c]; END; cifOutEndCom: PROCEDURE = BEGIN cifOutChr[';]; cifOutChr[15C]; END; cifOutLongInt: PUBLIC PROCEDURE [li: LONG INTEGER] = BEGIN q: LONG INTEGER; r: INTEGER; IF li < 0 THEN BEGIN cifOutChr['-]; li ← -li; END; q ← li/10; IF q # 0 THEN cifOutLongInt[q]; r ← LowHalf[li MOD 10]; cifOutChr['0 + r]; END; cifOutPoint: PROCEDURE [x, y: locNum] = BEGIN cifOutSNum[x]; cifOutChr[',]; cifOutSNum[y]; cifOutChr[' ]; END; cifOutSNum: PROCEDURE [x: locNum] = BEGIN a: LONG INTEGER; a ← cifScale; a ← a*x; cifOutLongInt[a]; END; cifOutNum: PUBLIC PROCEDURE [x: INTEGER] = BEGIN cifOutLongInt[LONG[x]]; END; findname: PROCEDURE [p: LONG POINTER TO cell object] RETURNS[s:STRING] = BEGIN cp: LONG POINTER TO cList←cellList; s ← ""; WHILE cp # NIL DO IF cp.ob = p THEN BEGIN s ← cp.name; RETURN; END; cp ← cp.nxt; ENDLOOP; END; --************* error file reading stuff: erfHan: DiskHandle; gotErf: BOOLEAN ← FALSE; erfLine: STRING ← [200]; gtByt: PROCEDURE RETURNS [CHARACTER] = BEGIN IF NOT erfHan.endof[erfHan] THEN RETURN[erfHan.get[erfHan]] ELSE RETURN[15C]; END; rdErfLine: PUBLIC PROCEDURE RETURNS [x, y: INTEGER, s: STRING, nums: BOOLEAN] = BEGIN c: CHARACTER; i, j: CARDINAL; x ← y ← 0; IF NOT gotErf OR erfHan.endof[erfHan] THEN BEGIN s ← "NONE"; nums ← FALSE; RETURN; END; cifScale ← pCifScale/2; erfLine.length ← 0; s ← erfLine; c ← 'a; WHILE c # 15C AND s.length < s.maxlength DO c ← gtByt[]; IF c # 15C THEN AppendChar[s, c]; ENDLOOP; WHILE c # 15C DO c ← gtByt[]; ENDLOOP; [x, i, nums] ← scanLine[s, 0]; IF nums THEN [y, i, nums] ← scanLine[s, i]; IF nums THEN y ← -y ELSE i ← 0; WHILE i < s.length AND s[i] = ' DO i ← i + 1; ENDLOOP; IF i # 0 THEN BEGIN j ← 0; WHILE i < s.length DO s[j] ← s[i]; i ← i + 1; j ← j + 1; ENDLOOP; s.length ← j; END; END; scanLine: PUBLIC PROCEDURE [s: STRING, i: CARDINAL] RETURNS [v: INTEGER, j: CARDINAL, any: BOOLEAN] = BEGIN vv: LONG INTEGER; minFlg: BOOLEAN ← FALSE; vv ← 0; j ← i; any ← TRUE; v ← 0; WHILE j < s.length AND (s[j] = 40C OR s[j] = 11C) DO j ← j + 1; ENDLOOP; IF j = s.length OR (s[j] # '- AND NOT s[j] IN ['0..'9]) THEN BEGIN any ← FALSE; RETURN; END; IF s[j] = '- THEN BEGIN minFlg ← TRUE; j ← j + 1; END; WHILE j < s.length AND s[j] IN ['0..'9] DO vv ← vv*10 + (s[j] - '0); j ← j + 1; ENDLOOP; vv ← vv/cifScale; v ← LowHalf[IF minFlg THEN -vv ELSE vv]; END; openErfile: PUBLIC PROCEDURE [fname: STRING] RETURNS [BOOLEAN] = BEGIN IF gotErf THEN erfHan.destroy[erfHan]; IF NOT DirectoryLookup[@fp, fname, FALSE] THEN RETURN[FALSE]; erfHan ← NewByteStream[fname, Read]; gotErf ← TRUE; RETURN[TRUE]; END; END.