File: Plcc84.mesa
Christophe Cuenod March 23, 1989 10:28:24 am PST

Enables to generate 84 pins PLCC parts (NCR53C94...) for EXPERT.
Requires 1 input file: Filename.tioga and generates file Filename.part
(to be transformed by the NewPart program).
The file Filename.tioga has one line per pin.
It must be exactly 84 non empty lines long.
The correct line formats are:
- PinName PinType (I, O, D, ...) and SwapNumber. (i.e. A0 O 0)
- PinName (if VCC or GND)
DIRECTORY
Commander USING [CommandProc, Register],
Rope USING [Cat, Equal, ROPE],
FS USING [StreamOpen],
IO USING [card, Close, EndOfStream, Error, GetInt, GetLineRope, GetTokenRope, int, PutF, RIS, rope, STREAM];
Plcc84: CEDAR PROGRAM
IMPORTS IO, Commander, Rope, FS =
BEGIN
ROPE: TYPE = Rope.ROPE;
Pin: TYPE = RECORD [
pinName: ROPE,
pinSite: NAT,
pinType: ROPE,
pinSwap: NAT
];
PLCCPinsRep: TYPE = ARRAY[1..pLCCSize] OF Pin;
PLCCPins: TYPE = REF PLCCPinsRep;
pLCCSize: INT ~ 84;
pin1Pad: INT ~ 28;
standardPad: INT ~ 29;
diameter: INT ~ 1; -- Max diameter of the lead in mills
BadFile: SIGNAL [];
InsertPin: PROC [i: INT, pLCCPins: PLCCPins, out: IO.STREAM] ~ {
x, y, type, pad: INT;
SELECT TRUE FROM
Rope.Equal [pLCCPins[i].pinType, "U", FALSE] => type ← 0;
Rope.Equal [pLCCPins[i].pinType, "I", FALSE] => type ← 1;
Rope.Equal [pLCCPins[i].pinType, "O", FALSE] => type ← 2;
Rope.Equal [pLCCPins[i].pinType, "D", FALSE] => type ← 3;
Rope.Equal [pLCCPins[i].pinType, "P", FALSE] => type ← 4;
Rope.Equal [pLCCPins[i].pinType, "G", FALSE] => type ← 5;
ENDCASE => ERROR;
IF i = 1 THEN pad ← pin1Pad
ELSE pad ← standardPad;
SELECT i FROM
IN [1..11] => {x ← (1-i)*50; y ← 0;};
IN [12..32] => {x ← -575; y ← 75 + (i-12)*50;};
IN [33..53] => {x ← -500 + (i-33)*50; y ← 1150;};
IN [54..74] => {x ← 575; y ← 1075 - (i-54)*50;};
IN [75..84] => {x ← 500 - (i-75)*50; y ← 0;};
ENDCASE => ERROR;
IO.PutF[out, "%g %g ", IO.int[x], IO.int[y]];
IO.PutF[out, "%g %g ", IO.rope[pLCCPins[i].pinName], IO.int[pLCCPins[i].pinSwap]];
IO.PutF[out, "%g %g ", IO.int[diameter], IO.int[pLCCPins[i].pinSite]];
IO.PutF[out, "%g %g\n", IO.int[type], IO.int[pad]];
};
GetLine: PROC [i: CARD, pLCCPins: PLCCPins, in, display: IO.STREAM, fileName: ROPE] ~ {
type, firstToken: ROPE;
firstToken ← IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token;
IF firstToken = NIL THEN {
IO.PutF[display, "File %g is too short: line %g is missing or incomplete.\n",
IO.rope[fileName], IO.card[i]];
SIGNAL BadFile[];
};
pLCCPins[i].pinName ← firstToken;
IF Rope.Equal[firstToken, "VCC", FALSE] OR
Rope.Equal[firstToken, "VDD", FALSE]THEN {
pLCCPins[i].pinSite ← 0; -- Site 0 = site 256
type ← "P";  -- Power
pLCCPins[i].pinSwap ← 1;
}
ELSE IF Rope.Equal[firstToken, "GND", FALSE] OR
Rope.Equal[firstToken, "VSS", FALSE] THEN {
pLCCPins[i].pinSite ← 0; -- Site 0 = site 256
type ← "G";  -- Ground
pLCCPins[i].pinSwap ← 1;
}
ELSE IF Rope.Equal[firstToken, "NC", FALSE] THEN {
pLCCPins[i].pinSite ← 0; -- Site 0 = site 256
type ← "U";  -- Undefined
pLCCPins[i].pinSwap ← 1;
}
ELSE {
pLCCPins[i].pinSite ← 1;
type ← IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token;
pLCCPins[i].pinSwap ← IO.GetInt[in ! IO.Error => {
IO.PutF[display, "File %g has not the right format: line %g the swap code number should be an integer.\n",
IO.rope[fileName], IO.card[i]];
SIGNAL BadFile[];
CONTINUE;}];
};
pLCCPins[i].pinType ← type;
IF NOT Rope.Equal[type, "U", FALSE] AND NOT Rope.Equal[type, "I", FALSE]
AND NOT Rope.Equal[type, "O", FALSE] AND NOT Rope.Equal[type, "D",FALSE]
AND NOT Rope.Equal[type, "P", FALSE] AND NOT Rope.Equal[type, "G", FALSE]
THEN {
IO.PutF[display, "File %g has not the right format: line %g the pin type should be I, O, or D instead of %g.\n",
IO.rope[fileName], IO.card[i], IO.rope[type]];
SIGNAL BadFile[];
};
[] ← IO.GetLineRope[in ! IO.EndOfStream => CONTINUE]; -- flush the end of the line
};
Plcc84Proc: Commander.CommandProc = BEGIN
i: INT;
in: IO.STREAM;
out: IO.STREAM;
tiogaFileName: ROPE;
fault: NAT ← 0;
fileName: ROPEIO.GetTokenRope[IO.RIS[cmd.commandLine]].token;
pLCCPins: PLCCPins ← NEW[PLCCPinsRep];
Reading Input file:
tiogaFileName ← Rope.Cat[fileName,".tioga"];
in ← FS.StreamOpen[tiogaFileName];
FOR i IN [1..pLCCSize] DO
GetLine[i, pLCCPins, in, cmd.out, tiogaFileName! BadFile => {
fault ← fault + 1;
CONTINUE;
}];
IF fault > 5 THEN {IO.PutF[cmd.out, "I give up ...\n"];EXIT;};
ENDLOOP;
IF fault = 0 THEN {
Writing output file
out ← FS.StreamOpen[Rope.Cat[fileName,".part"],$create];
IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %g84 PARC-%g84 U\n",
IO.rope[fileName], IO.rope[fileName]];
FOR i IN [1..pLCCSize] DO
InsertPin[i, pLCCPins, out];
ENDLOOP;
IO.Close[out];
IO.PutF[cmd.out, "File %g.part Written\n", IO.rope[fileName]];
};
END;
Commander.Register[
key: "Plcc84", proc: Plcc84Proc, doc: "Transform the input file: \tFilename.tioga into: \n\t\tFilename.part (to be used by the NewPart program)."];
END.