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)
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;
The pads stacks are:
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: BOOLEANFALSE;
stream: IO.STREAMIO.RIS[cmd.commandLine];
fileName: ROPEIO.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;
Reading Input files:
Top side :
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;
Bottom side :
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;
Left side:
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;
Right side:
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 {
Writing output file
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.