<> <> << Enables to generate easily 176 pins PGA parts for EXPERT.>> <<>> <> <<>> <> <<>> <<>> 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.