DIRECTORY Commander USING [CommandProc, Register], Rope USING [ROPE, Equal, Find, Length, Cat, Substr], FS USING [StreamOpen], IO USING [ card, Close, EndOfStream, GetTokenRope, int, PutF, PutRope, RIS, rope, STREAM]; Pga300: CEDAR PROGRAM IMPORTS IO, Commander, Rope, FS = BEGIN ROPE: TYPE = Rope.ROPE; SideRep: TYPE = ARRAY[0..iCSideSize) OF RECORD[ x: INTEGER, y: INTEGER ]; Side: TYPE = REF SideRep; PGAPinsRep: TYPE = ARRAY[1..pGASideSize] OF ARRAY[1..pGASideSize] OF ROPE; PGAPins: TYPE = REF PGAPinsRep; iCSideSize: CARD ~ 67; pGASideSize: CARD ~ 20; pGARows: CARD ~ 5; 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, "File %g line %g second word has to be I,O or D instead of %g\n", IO.rope[file], IO.card[i+1], IO.rope[secondToken]]; SIGNAL BadFile[]; }; line _ Rope.Cat[firstToken, " ", secondToken]; line _ Rope.Cat[line, " ", thirdToken]; }; }; InsertPin: PROC [x: CARD, y: CARD, dx: INT, dy: INT, pga: PGAPins, out: IO.STREAM] ~ { name, type, swap: ROPE; pos1, pos2, pad: INT; IO.PutF[out, "%g %g ", IO.int[100*(x-dx-1)], IO.int[100*(y-dy-1)]]; IF Rope.Equal[pga[x][y], "NC"] THEN IO.PutF[out, "NC 1 19 256 0 "] ELSE IF Rope.Equal[pga[x][y], "GND"] THEN IO.PutF[out, "GND 1 19 256 5 "] ELSE IF Rope.Equal[pga[x][y], "VCC"] THEN IO.PutF[out, "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.PutF[out, "%g ",IO.rope[name]]; IO.PutF[out, "%g 19 1 ",IO.rope[swap]]; IF Rope.Equal[type, "I", FALSE] THEN IO.PutF[out, "1 "]; IF Rope.Equal[type, "O", FALSE] THEN IO.PutF[out, "2 "]; IF Rope.Equal[type, "D", FALSE] THEN IO.PutF[out, "3 "]; }; pad _ 29; IF x = 1 AND y = 1 THEN pad _ 28; IF x = 1 AND y = pGASideSize THEN pad _ 31; IF x = pGASideSize AND y = 1 THEN pad _ 31; IF x = pGASideSize AND y = pGASideSize THEN pad _ 31; IF Rope.Equal[pga[x][y], "GND"] THEN pad _ 30; IF Rope.Equal[pga[x][y], "VCC"] THEN pad _ 30; IO.PutF[out, "%g\n", IO.int[pad]]; }; Pga300Proc: 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] _ [4,4]; top[1] _ [3,2]; top[2] _ [4,3]; top[3] _ [5,4]; top[4] _ [2,2]; top[5] _ [6,5]; top[6] _ [2,1]; top[7] _ [4,2]; top[8] _ [5,3]; top[9] _ [6,4]; top[10] _ [3,1]; top[11] _ [4,1]; top[12] _ [5,2]; top[13] _ [6,3]; top[14] _ [7,4]; top[15] _ [5,1]; top[16] _ [6,2]; top[17] _ [7,3]; top[18] _ [6,1]; top[19] _ [7,2]; top[20] _ [8,4]; top[21] _ [7,1]; top[22] _ [8,3]; top[23] _ [8,2]; top[24] _ [8,1]; top[25] _ [9,4]; top[26] _ [9,3]; top[27] _ [9,2]; top[28] _ [9,1]; top[29] _ [10,1]; top[30] _ [10,4]; top[31] _ [10,3]; top[32] _ [10,2]; top[33] _ [11,2]; top[34] _ [11,3]; top[35] _ [11,4]; top[36] _ [11,1]; top[37] _ [12,1]; top[38] _ [12,2]; top[39] _ [12,3]; top[40] _ [12,4]; top[41] _ [13,1]; top[42] _ [13,2]; top[43] _ [13,3]; top[44] _ [14,1]; top[45] _ [13,4]; top[46] _ [14,2]; top[47] _ [15,1]; top[48] _ [14,3]; top[49] _ [15,2]; top[50] _ [16,1]; top[51] _ [14,4]; top[52] _ [15,3]; top[53] _ [16,2]; top[54] _ [17,1]; top[55] _ [18,1]; top[56] _ [15,4]; top[57] _ [16,3]; top[58] _ [17,2]; top[59] _ [19,1]; top[60] _ [15,5]; top[61] _ [20,1]; top[62] _ [16,4]; top[63] _ [17,3]; top[64] _ [18,2]; top[65] _ [18,3]; top[66] _ [16,5]; FOR i IN [0..iCSideSize) DO left[i].x _ top[iCSideSize-1-i].y; left[i].y _ pGASideSize+1 - top[iCSideSize-1-i].x; ENDLOOP; FOR i IN [0..iCSideSize) DO right[i].x _ pGASideSize+1 - top[i].y; right[i].y _ top[i].x; ENDLOOP; FOR i IN [0..iCSideSize) DO bottom[i].x _ pGASideSize+1 - top[iCSideSize-1-i].x; bottom[i].y _ pGASideSize+1 - top[iCSideSize-1-i].y; ENDLOOP; FOR y IN [1..pGASideSize] DO FOR x IN [1..pGASideSize] DO pga[x][y] _ "NC"; ENDLOOP; ENDLOOP; FOR i IN [0..4) DO pga[7+2*i][5] _ "VCC"; pga[16][7+2*i] _ "VCC"; pga[14-2*i][16] _ "VCC"; pga[5][14-2*i] _ "VCC"; pga[8+2*i][5] _ "GND"; pga[16][8+2*i] _ "GND"; pga[13-2*i][16] _ "GND"; pga[5][13-2*i] _ "GND"; ENDLOOP; in _ FS.StreamOpen[Rope.Cat[fileName,".top"]]; FOR i IN [0..iCSideSize) 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..iCSideSize) 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..iCSideSize) 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..iCSideSize) 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,".top.part"],$create]; IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gT PARC-%gT U\n", IO.rope[fileName], IO.rope[fileName]]; FOR y IN [1..pGARows] DO FOR x IN [1..pGASideSize] DO InsertPin[x, y, 0, 0, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [pGARows+1..pGASideSize/2] DO FOR x IN [1..pGARows] DO InsertPin[x, y, 0, 0, pga, out]; ENDLOOP; FOR x IN [pGASideSize-pGARows+1..pGASideSize] DO InsertPin[x, y, 0, 0, pga, out]; ENDLOOP; ENDLOOP; IO.Close[out]; cmd.out.PutRope[Rope.Cat["File ", fileName,".top.part Written\n"]]; out _ FS.StreamOpen[Rope.Cat[fileName,".bottom.part"],$create]; IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gB PARC-%gB U\n", IO.rope[fileName], IO.rope[fileName]]; FOR y IN [pGASideSize/2+1..pGASideSize-pGARows] DO FOR x IN [1..pGARows] DO InsertPin[x, y, 0, pGASideSize/2, pga, out]; ENDLOOP; FOR x IN [pGASideSize-pGARows+1..pGASideSize] DO InsertPin[x, y, 0, pGASideSize/2, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [pGASideSize-pGARows+1..pGASideSize] DO FOR x IN [1..pGASideSize] DO InsertPin[x, y, 0, pGASideSize/2, pga, out]; ENDLOOP; ENDLOOP; IO.Close[out]; IO.PutF[cmd.out, "File %g.bottom.part Written\n", IO.rope[fileName]]; out _ FS.StreamOpen[Rope.Cat[fileName,".inner.part"],$create]; IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gI PARC-%gI U\n", IO.rope[fileName], IO.rope[fileName]]; FOR y IN [2..pGARows] DO FOR x IN [2..pGASideSize-1] DO InsertPin[x, y, 1, 1, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [pGARows+1..pGASideSize-pGARows] DO FOR x IN [2..pGARows] DO InsertPin[x, y, 1, 1, pga, out]; ENDLOOP; FOR x IN [pGASideSize-pGARows+1..pGASideSize-1] DO InsertPin[x, y, 1, 1, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [pGASideSize-pGARows+1..pGASideSize-1] DO FOR x IN [2..pGASideSize-1] DO InsertPin[x, y, 1, 1, pga, out]; ENDLOOP; ENDLOOP; IO.Close[out]; IO.PutF[cmd.out, "File %g.inner.part Written\n", IO.rope[fileName]]; out _ FS.StreamOpen[Rope.Cat[fileName,".outer.part"],$create]; IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gO PARC-%gO U\n", IO.rope[fileName], IO.rope[fileName]]; FOR x IN [1..pGASideSize] DO InsertPin[x, 1, 0, 0, pga, out]; ENDLOOP; FOR y IN [2..pGASideSize-1] DO InsertPin[1, y, 0, 0, pga, out]; InsertPin[pGASideSize, y, 0, 0, pga, out]; ENDLOOP; FOR x IN [1..pGASideSize] DO InsertPin[x, pGASideSize, 0, 0, pga, out]; ENDLOOP; IO.Close[out]; IO.PutF[cmd.out, "File %g.outer.part Written\n", IO.rope[fileName]]; out _ FS.StreamOpen[Rope.Cat[fileName,".sides.part"],$create]; IO.PutF[out, "4096 2048 -300 -100 1800 2000 700 -100 %gS PARC-%gS U\n", IO.rope[fileName], IO.rope[fileName]]; IO.PutF[out, "0 0 DUMMY 1 0 1 0 11\n"]; FOR y IN [1..pGASideSize] DO InsertPin[1, y, 2, 0, pga, out]; InsertPin[2, y, 2, 0, pga, out]; InsertPin[pGASideSize-1, y, 2, 0, pga, out]; InsertPin[pGASideSize, y, 2, 0, pga, out]; ENDLOOP; IO.Close[out]; IO.PutF[cmd.out, "File %g.sides.part Written\n", IO.rope[fileName]]; out _ FS.StreamOpen[Rope.Cat[fileName,".center.part"],$create]; IO.PutF[out, "4096 2048 -300 -100 1800 2000 1100 -100 %gC PARC-%gC U\n", IO.rope[fileName], IO.rope[fileName]]; FOR y IN [1..pGARows] DO FOR x IN [3..pGASideSize-2] DO InsertPin[x, y, 2, 0, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [pGARows+1..pGASideSize-pGARows] DO FOR x IN [3..pGARows] DO InsertPin[x, y, 2, 0, pga, out]; ENDLOOP; FOR x IN [pGASideSize-pGARows+1..pGASideSize-2] DO InsertPin[x, y, 2, 0, pga, out]; ENDLOOP; ENDLOOP; FOR y IN [pGASideSize-pGARows+1..pGASideSize] DO FOR x IN [3..pGASideSize-2] DO InsertPin[x, y, 2, 0, pga, out]; ENDLOOP; ENDLOOP; IO.Close[out]; IO.PutF[cmd.out, "File %g.center.part Written\n", IO.rope[fileName]]; }; END; Commander.Register[ key: "Pga300", proc: Pga300Proc, doc: "Transform the 4 input files: \n\tFilename.left\n\tFilename.top\n\tFilename.right\n\tFilename.bottom\ninto: \n\t\tFilename.top.part & Filename.bottom.part and\n\t\tFilename.inner.part & Filename.outer.part\n(to be used by the NewPart program)."]; END. LFile: Pga300.mesa Christophe Cuenod December 11, 1987 4:27:22 pm PST Enables to generate easily 300 pins PGA parts for EXPERT. Requires 4 input files: Filename.left, Filename.top, Filename.right, Filename.bottom and generates files: Filename.top.part, Filename.bottom.part Filename.inner.part and Filename.outer.part Filename.sides.part and Filename.center.part (to be transformed by the NewPart program). Each file has to be iCSideSize 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: - nul pin stack 11 - pin 1 stack 28 - power or gnd stack 30 - corners stack 31 - remaining stack 29 Reading Input files: Top side : Bottom side : Left side: Right side: Writing output files (too much pins for one part => split into 2 parts Κ Dprogram– "Cedar" style–i(firstHeadersAfterPage) {1} .cvx .def (firstPageNumber) {1} .cvx .def (oneSidedFormat) {.false} .cvx .def˜– "Cedar" stylešΟnœ ™Kšœ2™2Kšœ%Οkœ žœ™:K™šœi™iKšœ(™(Kšœ+™+Kšœ,™,Kšœ+™+—K™KšœTžœA™—K™K™™K™K™K™K™K™——šž ˜ Kšœ žœ˜(Kšœžœžœ$˜4Kšžœžœ˜Kšžœžœ?žœžœ˜Z—K˜šœžœž˜Kšžœžœžœ˜"—Kšž˜Kšžœžœžœ˜š œ žœžœžœžœ˜/Kšœžœ˜ Kšœž˜ K˜—Kšœžœžœ ˜Kš œ žœžœžœžœžœžœ˜JKšœ žœžœ ˜K˜K˜K˜K˜K˜Icodešœžœ˜šœžœžœžœ žœžœžœžœžœžœ˜_Lšœ%žœ˜*Lšœ"žœžœ˜Dšžœžœžœ˜-Lšœ˜L˜—šžœ˜Lšœžœžœžœ˜ELšœ žœžœžœ˜Dšžœžœžœžœžœžœžœ˜CLšžœLžœ žœ ˜kLšžœ ˜L˜—šžœžœžœžœžœžœžœžœ˜LšžœRžœ žœ žœ˜‡Lšžœ ˜L˜—Lšœ.˜.Lšœ'˜'L˜—L˜—š œžœžœžœžœžœžœžœ˜WKšœžœ˜Kšœžœ˜KšžœA˜CKšžœžœžœ˜BKšžœžœžœžœ˜IKšžœžœžœžœ˜Išžœ˜Kšœ$žœ˜*Kšœ)žœ˜/Kšœ'˜'Kšœ3˜3KšœE˜EKšžœžœ ˜"Kšžœžœ ˜'Kšžœžœžœžœ˜9Kšžœžœžœžœ˜8Kšžœžœžœžœ˜8K˜—Kšœ ˜ Kšžœžœžœ ˜!Kšžœžœžœ ˜+Kšžœžœžœ ˜+Kšžœžœžœ ˜5Kšžœžœ ˜.Kšžœžœ ˜.Kšžœžœ ˜"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˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜šžœžœž˜Kšœ"˜"Kšœ2˜2Kšžœ˜—K˜šžœžœž˜Kšœ&˜&K˜Kšžœ˜—K˜šžœžœž˜Kšœ4˜4Kšœ4˜4Kšžœ˜—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™FK™Kšœžœ4˜Kšžœl˜nšžœžœž˜šžœžœž˜K˜ Kšžœ˜—Kšžœ˜—šžœžœ"ž˜,šžœžœž˜Kšœ ˜ Kšžœ˜—šžœžœ(ž˜2Kšœ ˜ Kšžœ˜—Kšžœ˜—šžœžœ(ž˜2šžœžœž˜Kšœ ˜ Kšžœ˜—Kšžœ˜—Kšžœ ˜KšžœD˜FK˜Kšœžœ6˜>Kšžœl˜nšžœžœž˜K˜ Kšžœ˜—šžœžœž˜Kšœ ˜ Kšœ*˜*Kšžœ˜—šžœžœž˜Kšœ*˜*Kšžœ˜—Kšžœ ˜KšžœD˜FK˜K˜K˜Kšœžœ6˜>Kšžœl˜nKšžœ%˜'šžœžœž˜Kšœ ˜ Kšœ ˜ Kšœ,˜,Kšœ*˜*Kšžœ˜—Kšžœ ˜KšžœD˜FK˜Kšœžœ7˜?Kšžœm˜ošžœžœž˜šžœžœž˜K˜ Kšžœ˜—Kšžœ˜—šžœžœ"ž˜,šžœžœž˜Kšœ ˜ Kšžœ˜—šžœžœ(ž˜2Kšœ ˜ Kšžœ˜—Kšžœ˜—šžœžœ&ž˜0šžœžœž˜Kšœ ˜ Kšžœ˜—Kšžœ˜—Kšžœ ˜KšžœE˜GK˜—Kšžœ˜—šœ˜Kšœœ˜œ—Kšžœ˜—…—&Ό7L