File: Pga257.mesa
Christophe Cuenod January 15, 1988 2:49:54 pm PST
Enables to generate easily 257 pins PGA parts for EXPERT (Sparc or FPU).
Requires one input file: Filename.pins and generates two files Filename.A.part and Filename.B.part (to be transformed by the NewPart program).
The file has to be 256 lines long exactly. Each line has to content either NC, VCC, GND or PinName PinType (I, O, D, ...) and SwapNumber. (i.e. K5 D 5)
The pads stacks are:
- pin 1 stack 8
- corners stack 10
- power or gnd stack 12
- nul pin stack 11
- remaining stack 9
DIRECTORY
Commander USING [CommandProc, Register],
Rope USING [Cat, Equal, ROPE],
FS USING [StreamOpen],
IO USING [ BreakProc, card, Close, EndOfStream, GetCard, GetTokenRope, PutF, RIS, rope, STREAM];
Pga257:
CEDAR
PROGRAM
IMPORTS IO, Commander, Rope, FS =
BEGIN
ROPE: TYPE = Rope.ROPE;
PGAPinsRep: TYPE = ARRAY[1..19] OF ARRAY[1..19] OF ROPE;
PGAPins: TYPE = REF PGAPinsRep;
Pos:
TYPE =
RECORD [
x: CARD,
y: CARD
];
Line:
TYPE =
RECORD [
name: ROPE,
type: CARD,
swap: CARD
];
BadFile: SIGNAL [];
Position:
PROC [i:
CARD]
RETURNS [position: Pos] ~ {
SELECT i
FROM
IN [1..19] => {
position.x ← 0;
position.y ← 100*(i-1);
};
IN [20..37] => {
position.x ← 100*(i-19);
position.y ← 1800;
};
IN [38..55] => {
position.x ← 1800;
position.y ← 100*(55-i);
};
IN [56..72] => {
position.x ← 100*(73-i);
position.y ← 0;
};
IN [73..89] => {
position.x ← 100;
position.y ← 100*(i-72);
};
IN [90..105] => {
position.x ← 100*(i-88);
position.y ← 1700;
};
IN [106..121] => {
position.x ← 1700;
position.y ← 100*(122-i);
};
IN [122..136] => {
position.x ← 100*(138-i);
position.y ← 100;
};
IN [137..151] => {
position.x ← 200;
position.y ← 100*(i-135);
};
IN [152..165] => {
position.x ← 100*(i-149);
position.y ← 1600;
};
IN [166..179] => {
position.x ← 1600;
position.y ← 100*(181-i);
};
IN [180..192] => {
position.x ← 100*(195-i);
position.y ← 200;
};
IN [193..205] => {
position.x ← 300;
position.y ← 100*(i-190);
};
IN [206..217] => {
position.x ← 100*(i-202);
position.y ← 1500;
};
IN [218..229] => {
position.x ← 1500;
position.y ← 100*(232-i);
};
IN [230..240] => {
position.x ← 100*(244-i);
position.y ← 300;
};
Last raw
IN [241..244] => {
position.x ← 400;
position.y ← 600 +200*(i-241);
};
IN [245..248] => {
position.x ← 600+200*(i-245);
position.y ← 1400;
};
IN [249..252] => {
position.x ← 1400;
position.y ← 1200-200*(i-249);
};
IN [253..256] => {
position.x ← 1200-200*(i-253);
position.y ← 400;
};
ENDCASE => ERROR;
};
TokenBreak:
IO.BreakProc ~ {
IF char = ' OR char = '\t OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
GetLine:
PROC [in:
IO.
STREAM, display:
IO.
STREAM, i:
CARD, file:
ROPE]
RETURNS [line: Line] ~ {
type: ROPE;
line.name ← IO.GetTokenRope[in, TokenBreak ! IO.EndOfStream => CONTINUE].token;
IF line.name =
NIL
THEN {
IO.PutF[display, "File %g is too short: line %g is missing.\n",
IO.rope[file], IO.card[i]];
SIGNAL BadFile[];
};
SELECT
TRUE
FROM
Rope.Equal[line.name, "nc",
FALSE] =>{
line.name ← "NC";
line.type ← 0; --Unspecified
line.swap ← 1;
};
Rope.Equal[line.name, "vcc",
FALSE]
OR Rope.Equal[line.name, "vdd",
FALSE] =>{
line.name ← "VCC";
line.type ← 4; --Power
line.swap ← 1;
};
Rope.Equal[line.name, "gnd",
FALSE]
OR Rope.Equal[line.name, "vss",
FALSE] =>{
line.name ← "GND";
line.type ← 5; --Ground
line.swap ← 1;
};
ENDCASE => {
type ← IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token;
SELECT
TRUE
FROM
Rope.Equal[type, "i", FALSE] => line.type ← 1; --input
Rope.Equal[type, "o", FALSE] => line.type ← 2; --output
Rope.Equal[type, "d", FALSE] => line.type ← 3; --duplex
ENDCASE => {
IO.PutF[display, "The Second word on line %g has to be I,O or D instead of %g\n",
IO.card[i], IO.rope[type]];
SIGNAL BadFile[];
};
line.swap ← IO.GetCard[in ! IO.Error[SyntaxError] => CONTINUE];
line.swap ← IO.GetCard[in];
};
};
InsertPin:
PROC [out:
IO.
STREAM, position: Pos, i:
CARD, line: Line] ~ {
IO.PutF[out, "%g %g %g %g 19 ", IO.card[position.x], IO.card[position.y], IO.rope[line.name], IO.card[line.swap]];
IF line.type = 1
OR line.type = 2
OR line.type = 3
THEN
IO.PutF[out, "1 %g",
IO.card[line.type]]
ELSE IO.PutF[out, "256 %g", IO.card[line.type]];
IF i = 1
THEN
IO.PutF[out, " 8\n"]
--Pad stack for pin 1
ELSE IF i = 19 OR i = 37 OR i = 55 THEN IO.PutF[out, " 10\n"] --Corner Pad stack
ELSE IF line.type = 4 OR line.type = 5 THEN IO.PutF[out, " 12\n"] --Power Pad stack
ELSE IO.PutF[out, " 9\n"]; --Pad stack for standard pin
};
Pga257Proc: Commander.CommandProc =
BEGIN
fault: BOOLEAN ← FALSE;
i: CARD ← 1;
in: IO.STREAM;
out: IO.STREAM;
stream: IO.STREAM ← IO.RIS[cmd.commandLine];
fileName: ROPE ← IO.GetTokenRope[stream].token;
in ← FS.StreamOpen[Rope.Cat[fileName,".pin"]];
out ← FS.StreamOpen[Rope.Cat[fileName,".A.part"],$create];
IO.PutF[out, "4096 2048 -550 -300 2050 2200 700 -150 %g-A PARC-%g-A U\n",
IO.rope[fileName], IO.rope[fileName]];
WHILE i
IN [1..255]
DO
InsertPin[out, Position[i], i, GetLine[in, cmd.out, i, Rope.Cat[fileName,".pin"] ! BadFile => {
i ← 256;
fault ← TRUE;
CONTINUE;
}]];
i ← i+1;
ENDLOOP;
IO.Close[out];
IF
~ fault
THEN {
out ← FS.StreamOpen[Rope.Cat[fileName,".B.part"],$create];
IO.PutF[out, "4096 2048 -550 -300 2050 2200 1100 -150 %g-B PARC-%g-B U\n",
IO.rope[fileName], IO.rope[fileName]];
IO.PutF[out, "0 0 DUMMY 1 0 256 0 11\n"];
InsertPin[out, Position[256], 256, GetLine[in, cmd.out, 256, Rope.Cat[fileName,".pin"] ! BadFile => {
fault ← TRUE;
CONTINUE;
}]];
IO.PutF[out, "400 400 INDEX 1 0 256 0 9\n"];
IO.Close[out];
};
IF
~ fault
THEN {
IO.PutF[cmd.out, "Files %g.A.part and %g.B.part Written\n", IO.rope[fileName], IO.rope[fileName]];
};
END;
Commander.Register[
key: "Pga257", proc: Pga257Proc, doc: "Transform the input file: Filename.pins into Filename.A.part and Filename.B.part (to be used by the NewPart program)."];
END.