DIRECTORY Commander USING [CommandProc, Register], Convert USING [RopeFromInt], Rope USING [ROPE, Equal, Find, Length, Cat, Substr], FS USING [StreamOpen], IO USING [ card, Close, EndOfStream, GetTokenRope, int, Put, PutF, PutRope, RIS, rope, STREAM]; Pga176: CEDAR PROGRAM IMPORTS IO, Commander, Convert, Rope, FS = BEGIN ROPE: TYPE = Rope.ROPE; psPin1: NAT ~ 55; psPower: NAT ~ 57; psCorners: NAT ~ 58; psRemaining: NAT ~ 56; SideRep: TYPE = ARRAY[0..36) OF RECORD[ x: INTEGER, y: INTEGER ]; Side: TYPE = REF SideRep; PGAPinsRep: TYPE = ARRAY[1..15] OF ARRAY[1..15] OF ROPE; PGAPins: TYPE = REF PGAPinsRep; BadFile: SIGNAL []; GetLine: PROC [in: IO.STREAM, display: IO.STREAM, i: CARD, file: ROPE] RETURNS [line: ROPE] ~ { firstToken, secondToken, thirdToken: ROPE; firstToken _ IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token; IF Rope.Equal[firstToken, "NC", FALSE] THEN { line _ firstToken; } ELSE { secondToken _ IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token; thirdToken _ IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token; IF firstToken = NIL OR secondToken = NIL OR thirdToken = NIL THEN { IO.PutF[display, "File %g is too short: line %g is missing or incomplete.\n", IO.rope[file], IO.card[i+1]]; SIGNAL BadFile[]; }; IF NOT(Rope.Equal[secondToken, "I", FALSE] OR Rope.Equal[secondToken, "O", FALSE] OR Rope.Equal[secondToken, "D", FALSE]) THEN { IO.PutF[display, "The Second word on line %g has to be I,O or D instead of %g\n", IO.card[i+1], IO.rope[secondToken]]; SIGNAL BadFile[]; }; line _ Rope.Cat[firstToken, " ", secondToken]; line _ Rope.Cat[line, " ", thirdToken]; }; }; InsertPin: PROC [x: INT, y: INT, pga: PGAPins, out: IO.STREAM] ~ { name, type, swap: ROPE; pos1, pos2, pad: INT; IO.Put[out, IO.rope[Convert.RopeFromInt[100*(x-1)]], IO.rope[" "]]; IO.Put[out, IO.rope[Convert.RopeFromInt[100*(y-1)]], IO.rope[" "]]; IF Rope.Equal[pga[x][y], "NC"] THEN IO.Put[out, IO.rope["NC 1 19 256 0 "]] ELSE IF Rope.Equal[pga[x][y], "GND"] THEN IO.Put[out, IO.rope["GND 1 19 256 5 "]] ELSE IF Rope.Equal[pga[x][y], "VCC"] THEN IO.Put[out, IO.rope["VCC 1 19 256 4 "]] ELSE { pos1 _ Rope.Find[pga[x][y], " ", 0, TRUE]; pos2 _ Rope.Find[pga[x][y], " ", pos1+1, TRUE]; name _ Rope.Substr[pga[x][y], 0, pos1]; type _ Rope.Substr[pga[x][y], pos1+1, pos2-pos1-1]; swap _ Rope.Substr[pga[x][y], pos2+1, Rope.Length[pga[x][y]]-pos2-1]; IO.Put[out, IO.rope[name], IO.rope[" "]]; IO.Put[out, IO.rope[swap], IO.rope[" 19 1 "]]; IF Rope.Equal[type, "I"] THEN IO.Put[out, IO.rope["1 "]]; IF Rope.Equal[type, "O"] THEN IO.Put[out, IO.rope["2 "]]; IF Rope.Equal[type, "D"] THEN IO.Put[out, IO.rope["3 "]]; }; pad _ psRemaining; IF x = 1 AND y = 1 THEN pad _ psPin1; IF x = 1 AND y = 15 THEN pad _ psCorners; IF x = 15 AND y = 1 THEN pad _ psCorners; IF x = 15 AND y = 15 THEN pad _ psCorners; IF Rope.Equal[pga[x][y], "GND"] THEN pad _ psPower; IF Rope.Equal[pga[x][y], "VCC"] THEN pad _ psPower; IO.PutF[out, "%g\n",IO.int[pad]]; }; Pga176Proc: Commander.CommandProc = BEGIN i: CARD; x, y: CARD; in: IO.STREAM; out: IO.STREAM; fault: BOOLEAN _ FALSE; stream: IO.STREAM _ IO.RIS[cmd.commandLine]; fileName: ROPE _ IO.GetTokenRope[stream].token; top: Side _ NEW[SideRep]; bottom: Side _ NEW[SideRep]; left: Side _ NEW[SideRep]; right: Side _ NEW[SideRep]; pga: PGAPins _ NEW[PGAPinsRep]; top[0] _ [2,1]; top[1] _ [3,2]; top[2] _ [3,1]; top[3] _ [4,3]; top[4] _ [4,2]; top[5] _ [4,1]; top[6] _ [5,3]; top[7] _ [5,2]; top[8] _ [5,1]; top[9] _ [6,3]; top[10] _ [6,2]; top[11] _ [6,1]; top[12] _ [7,3]; top[13] _ [7,2]; top[14] _ [7,1]; top[15] _ [8,1]; top[16] _ [8,2]; top[17] _ [8,3]; top[18] _ [9,1]; top[19] _ [10,1]; top[20] _ [9,2]; top[21] _ [11,1]; top[22] _ [10,2]; top[23] _ [9,3]; top[24] _ [12,1]; top[25] _ [11,2]; top[26] _ [10,3]; top[27] _ [13,1]; top[28] _ [12,2]; top[29] _ [11,3]; top[30] _ [14,1]; top[31] _ [13,2]; top[32] _ [12,3]; top[33] _ [15,1]; top[34] _ [14,2]; top[35] _ [13,3]; FOR i IN [0..36) DO left[i].x _ top[35-i].y; left[i].y _ 16 - top[35-i].x; ENDLOOP; FOR i IN [0..36) DO right[i].x _ 16 - top[i].y; right[i].y _ top[i].x; ENDLOOP; FOR i IN [0..36) DO bottom[i].x _ 16 - top[35-i].x; bottom[i].y _ 16 - top[35-i].y; ENDLOOP; FOR y IN [1..15] DO FOR x IN [1..15] DO pga[x][y] _ "NC"; ENDLOOP; ENDLOOP; FOR i IN [0..4) DO pga[4+2*i][4] _ "VCC"; pga[12][4+2*i] _ "VCC"; pga[12-2*i][12] _ "VCC"; pga[4][12-2*i] _ "VCC"; pga[5+2*i][4] _ "GND"; pga[12][5+2*i] _ "GND"; pga[11-2*i][12] _ "GND"; pga[4][11-2*i] _ "GND"; ENDLOOP; in _ FS.StreamOpen[Rope.Cat[fileName,".top"]]; FOR i IN [0..36) DO pga[top[i].x][top[i].y] _ GetLine[in, cmd.out, i, Rope.Cat[fileName,".top"] ! BadFile => { fault _ TRUE; CONTINUE; }]; ENDLOOP; in _ FS.StreamOpen[Rope.Cat[fileName,".bottom"]]; FOR i IN [0..36) DO pga[bottom[i].x][bottom[i].y] _ GetLine[in, cmd.out, i, Rope.Cat[fileName,".bottom"] ! BadFile => { fault _ TRUE; CONTINUE; }]; ENDLOOP; in _ FS.StreamOpen[Rope.Cat[fileName,".left"]]; FOR i IN [0..36) DO pga[left[i].x][left[i].y] _ GetLine[in, cmd.out, i, Rope.Cat[fileName,".left"] ! BadFile => { fault _ TRUE; CONTINUE; }]; ENDLOOP; in _ FS.StreamOpen[Rope.Cat[fileName,".right"]]; FOR i IN [0..36) DO pga[right[i].x][right[i].y] _ GetLine[in, cmd.out, i, Rope.Cat[fileName,".right"] ! BadFile => { fault _ TRUE; CONTINUE; }]; ENDLOOP; IF NOT fault THEN { out _ FS.StreamOpen[Rope.Cat[fileName,".part"],$create]; IO.Put[out, IO.rope[Rope.Cat["4096 2048 -100 -100 1500 1500 700 -100 ", fileName, " PARC-", fileName, " U\n"]]]; FOR y IN [1..4] DO FOR x IN [1..15] DO InsertPin[x, y, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [5..11] DO FOR x IN [1..4] DO InsertPin[x, y, pga, out]; ENDLOOP; FOR x IN [12..15] DO InsertPin[x, y, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [12..15] DO FOR x IN [1..15] DO InsertPin[x, y, pga, out]; ENDLOOP; ENDLOOP; IO.Close[out]; cmd.out.PutRope[Rope.Cat["File ", fileName,".part Written\n"]]; }; END; Commander.Register[ key: "Pga176", proc: Pga176Proc, doc: "Transform the 4 input files: Filename.left, Filename.top, Filename.right, Filename.bottom into Filename.part (to be used by the NewPart program)."]; END. .File: Pga176.mesa Christophe Cuenod May 10, 1988 5:28:38 pm PDT Enables to generate easily 176 pins PGA parts for EXPERT. Requires 4 input files: Filename.left, Filename.top, Filename.right, Filename.bottom and generates a file Filename.part (to be transformed by the NewPart program). Each file has to be 36 lines long exactly. Each line has to content either NC or PinName PinType (I, O, D, ...) and SwapNumber. (i.e. K5 D 5) The pads stacks are: Reading Input files: Top side : Bottom side : Left side: Right side: Writing output file Κ [program– "Cedar" style–i(firstHeadersAfterPage) {1} .cvx .def (firstPageNumber) {1} .cvx .def (oneSidedFormat) {.false} .cvx .def˜– "Cedar" stylešΟnœ ™Kšœ-™-Kšœ%Οkœ žœ™:K™Kšœ£™£K™KšœLžœ:žœ™K™K™—šž ˜ Kšœ žœ˜(Kšœžœ˜Kšœžœžœ$˜4Kšžœžœ˜KšžœžœDžœžœ˜_—šœžœž˜Kšžœžœžœ˜+—Kšž˜Kšžœžœžœ˜K™K™K˜K˜K˜K˜K˜K˜K˜š œ žœžœžœžœ˜'Kšœžœ˜ Kšœž˜ K˜—Kšœžœžœ ˜Kš œ žœžœžœžœžœžœ˜8Kšœ žœžœ ˜K˜Icodešœžœ˜šœžœžœžœ žœžœžœžœžœžœ˜_Lšœ%žœ˜*Lšœ"žœžœ˜Dšžœžœžœ˜-Lšœ˜L˜—šžœ˜Lšœžœžœžœ˜ELšœ žœžœžœ˜Dšžœžœžœžœžœžœžœ˜CLšžœLžœ žœ ˜kLšžœ ˜L˜—šžœžœžœžœžœžœžœžœ˜LšžœQžœ žœ˜wLšžœ ˜L˜—Lšœ.˜.Lšœ'˜'L˜—L˜—š  œžœžœžœžœžœ˜CKšœžœ˜Kšœžœ˜Kšžœ žœ'žœ ˜CKšžœ žœ'žœ ˜CKšžœžœžœ žœ˜JKš žœžœžœžœ žœ˜QKš žœžœžœžœ žœ˜Qšžœ˜Kšœ$žœ˜*Kšœ)žœ˜/Kšœ'˜'Kšœ3˜3KšœE˜EKšžœ žœ žœ ˜)Kšžœ žœ žœ˜.Kšžœžœžœ žœ ˜9Kšžœžœžœ žœ ˜9Kšžœžœžœ žœ ˜9K˜—Kšœ˜Kšžœžœžœ˜%Kšžœžœžœ˜)Kšžœžœžœ˜)Kšžœžœžœ˜*Kšžœžœ˜3Kšžœžœ˜3Kšžœžœ ˜!K˜—K˜š œž˜)Kšœžœ˜Kšœžœ˜ Kšœžœžœ˜Kšœžœžœ˜Jšœžœžœ˜Kš œžœžœžœžœ˜,Kšœ žœžœ˜/Kšœ žœ ˜Kšœžœ ˜Kšœ žœ ˜Kšœžœ ˜Kšœžœ ˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜šžœžœ ž˜K˜K˜Kšžœ˜—K˜šžœžœ ž˜K˜K˜Kšžœ˜—K˜šžœžœ ž˜K˜K˜Kšžœ˜—K˜šžœžœ ž˜šžœžœ ž˜K˜Kšžœ˜—Kšžœ˜—K˜šžœžœž˜K˜K˜K˜K˜K˜K˜K˜K˜Kšžœ˜—K™K™K™K™K™ Kšœžœ'˜.šžœžœ ž˜šœZ˜ZJšœžœ˜ Jšžœ˜ Jšœ˜—Kšžœ˜—K˜K˜Kšœ ™ Kšœžœ*˜1šžœžœ ž˜šœc˜cJšœžœ˜ Jšžœ˜ Jšœ˜—Kšžœ˜—K˜K˜Kšœ ™ Kšœžœ(˜/šžœžœ ž˜šœ]˜]Jšœžœ˜ Jšžœ˜ Jšœ˜—Kšžœ˜—˜K˜—Kšœ ™ Kšœžœ)˜0šžœžœ ž˜šœ`˜`Jšœžœ˜ Jšžœ˜ Jšœ˜—Kšžœ˜—K˜K˜šžœžœžœ˜K™K™K™Kšœžœ0˜8K˜Kšžœ žœb˜pšžœžœž˜šžœžœ ž˜K˜Kšžœ˜—Kšžœ˜—šžœžœ ž˜šžœžœž˜K˜Kšžœ˜—šžœžœ ž˜K˜Kšžœ˜—Kšžœ˜—šžœžœ ž˜šžœžœ ž˜K˜Kšžœ˜—Kšžœ˜—Kšžœ ˜KšœA˜AK˜—Kšžœ˜—šœ˜Kšœ»˜»—Kšžœ˜—…—Φ#_