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