ExpertWrapProc: Commander.CommandProc =
BEGIN
TranslateAndScale:
PROC [oldPos: PinPos]
RETURNS [newPos: PinPos] ~ {
newPos.x ← (oldPos.x - origin.x)/100;
newPos.y ← (oldPos.y - origin.y)/100;
};
FileExistence:
PROC [fileName:
ROPE]
RETURNS [found:
BOOLEAN ←
TRUE] ~ {
[] ←
FS.FileInfo[fileName !
FS.Error => {
IF error.group = user
THEN {
IO.PutF[cmd.out, "%g\n", IO.rope[error.explanation]];
found ← FALSE;
CONTINUE;
};
}];
};
AddGndPin: SymTab.EachPairAction ~ {
pinInfo: ExpertPinRead.PinInfo;
pinInfoList: ExpertPinRead.PinInfoList ← NARROW[val];
refDes: ROPE ← pinInfoList.first.refDes;
part: ExpertPCBRead.Part ← NARROW[SymTab.Fetch[pCBTable, refDes].val];
libraryEntry: CARD ← part.libraryEntry;
gndPin: NAT ← ExpertLibRead.FirstPinOfThisType[libTable, libraryEntry, 5, 1];
IF gndPin = 0
THEN {
IO.PutF[cmd.out, "Part %g has no gnd pin defined\n", IO.rope[refDes]];
RETURN;
};
pinInfo.refDes ← refDes;
pinInfo.pinNumber ← gndPin;
pinInfo.symbolPinName ← "NoName";
pinInfo.pageNumber ← pinInfoList.first.pageNumber;
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[newGndPinTable, key, pinInfoList];
};
AddVccPin: SymTab.EachPairAction ~ {
pinInfo: ExpertPinRead.PinInfo;
pinInfoList: ExpertPinRead.PinInfoList ← NARROW[val];
refDes: ROPE ← pinInfoList.first.refDes;
part: ExpertPCBRead.Part ← NARROW[SymTab.Fetch[pCBTable, refDes].val];
libraryEntry: CARD ← part.libraryEntry;
vccPin: NAT ← ExpertLibRead.FirstPinOfThisType[libTable, libraryEntry, 4, 1];
IF vccPin = 0
THEN {
IO.PutF[cmd.out, "Part %g has no vcc pin defined\n", IO.rope[refDes]];
RETURN;
};
pinInfo.refDes ← refDes;
pinInfo.pinNumber ← vccPin;
pinInfo.symbolPinName ← "NoName";
pinInfo.pageNumber ← pinInfoList.first.pageNumber;
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[newVccPinTable, key, pinInfoList];
};
ReducePinList: SymTab.EachPairAction~ {
pinInfoList: ExpertPinRead.PinInfoList ← NIL;
FOR l: ExpertPinRead.PinInfoList ←
NARROW[val], l.rest
UNTIL l =
NIL
DO
IF ExpertKeepRead.KeepRefDes[refDesTable, l.first.refDes]
THEN {
pinInfoList ← CONS[l.first, pinInfoList];
};
ENDLOOP;
IF pinInfoList = NIL OR pinInfoList.rest = NIL THEN RETURN; -- Skip 0 or 1 pin net
SELECT
TRUE
FROM
Rope.Equal[key, "GND"] => gndInfoList ← pinInfoList;
Rope.Equal[key, "VCC"] => vccInfoList ← pinInfoList;
Rope.Equal[key, "-5.2"] => pinInfoList ← pinInfoList;
Rope.Equal[key, "V2"] => pinInfoList ← pinInfoList;
ENDCASE => [] ← SymTab.Insert[reducedPinTable, key, pinInfoList];
};
ComputeOrigin: SymTab.EachPairAction~ {
pos: PinPos;
part: ExpertPCBRead.Part ← NARROW[val];
IF NOT ExpertKeepRead.KeepRefDes[refDesTable, key] THEN RETURN;
FOR index:
NAT
IN [1..ExpertLibRead.PinNumber[libTable, part.libraryEntry]]
DO
pos ← AbsolutePinPosition[libTable, part, index];
origin.x ← MIN[origin.x, pos.x];
origin.y ← MIN[origin.y, pos.y];
ENDLOOP;
};
WrapNets: SymTab.EachPairAction~ {
pos: PinPos;
part: ExpertPCBRead.Part;
netNumber ← netNumber + 1;
FOR l: ExpertPinRead.PinInfoList ←
NARROW[val], l.rest
UNTIL l =
NIL
DO
part ← NARROW[SymTab.Fetch[pCBTable, l.first.refDes].val];
IF part =
NIL
THEN {
IO.PutF[cmd.out, "The part for symbol %g is not inside the library.\n", IO.rope[l.first.refDes]];
ERROR;
};
pos ← TranslateAndScale[AbsolutePinPosition[libTable, part, l.first.pinNumber]];
outputLines ← outputLines + 1;
IO.PutF[out, "2 NET%04g X%03gY%03g",
IO.card[netNumber],
IO.int[pos.x],
IO.int[pos.y]
];
IO.PutF[out2, "2 NET%04g X%03gY%03g",
IO.card[netNumber],
IO.int[pos.x],
IO.int[pos.y]
];
IO.PutF[out, " page %2g %4g pin %3g %g\n",
IO.card[l.first.pageNumber],
IO.rope [l.first.refDes],
IO.card[l.first.pinNumber],
IO.rope[key]
];
IO.PutF[out2, " %g pin %g\n\012",
IO.rope [l.first.refDes],
IO.card[l.first.pinNumber]
];
ENDLOOP;
};
pCBTable: ExpertPCBRead.PCBTable;
libTable: ExpertLibRead.LibTable;
gndInfoList, vccInfoList: ExpertPinRead.PinInfoList;
pinTable, reducedPinTable, gndPinTable, vccPinTable, newGndPinTable, newVccPinTable: ExpertPinRead.PinTable;
refDesTable: ExpertKeepRead.RefDesTable;
out, out2: IO.STREAM;
origin: PinPos;
outputLines: CARD ← 0;
netNumber: CARD ← 0;
stream: IO.STREAM ← IO.RIS[cmd.commandLine];
file: ROPE ← IO.GetTokenRope[stream].token;
pcbFile: ROPE ← Rope.Cat[file, ".pcb"];
libFile: ROPE ← Rope.Cat[file, ".lib"];
pinListFile: ROPE ← Rope.Cat[file, ".pinlist"];
keepFile: ROPE ← Rope.Cat[file, ".keep"];
wrapFile: ROPE ← Rope.Cat[file, ".wrap"];
wrapFile2: ROPE ← Rope.Cat[file, ".wrap.IBM"];
found: BOOLEAN ← FileExistence[pcbFile];
found ← FileExistence[libFile] AND found;
found ← FileExistence[pinListFile] AND found;
found ← FileExistence[keepFile] AND found;
IF NOT found THEN GO TO fail;
IO.PutF[cmd.out, "Reading %g\n", IO.rope[pcbFile]];
pCBTable ← ExpertPCBRead.ReadPCBFile[pcbFile];
IO.PutF[cmd.out, "Reading %g\n", IO.rope[libFile]];
libTable ← ExpertLibRead.ReadLibFile[libFile];
IO.PutF[cmd.out, "Reading %g\n", IO.rope[pinListFile]];
pinTable ← ExpertPinRead.ReadPinFile[pinListFile];
IO.PutF[cmd.out, "Reading %g\n", IO.rope[keepFile]];
refDesTable ← ExpertKeepRead.ReadKeepFile[keepFile];
IO.PutF[cmd.out, "Reducing the pin list (removing the unwanted parts)\n"];
reducedPinTable ← SymTab.Create[];
[] ← SymTab.Pairs[pinTable, ReducePinList];
IO.PutF[cmd.out, "Spliting the gnd and vcc nets\n"];
gndPinTable ← SplitPowerNet["GND", gndInfoList];
vccPinTable ← SplitPowerNet["VCC", vccInfoList];
IO.PutF[cmd.out, "Adding a gnd or vcc pin on each splited power net\n"];
newGndPinTable ← SymTab.Create[];
[] ← SymTab.Pairs[gndPinTable, AddGndPin];
newVccPinTable ← SymTab.Create[];
[] ← SymTab.Pairs[vccPinTable, AddVccPin];
IO.PutF[cmd.out, "Computing the origin\n"];
origin.x ← 32000; -- Starts at the top right
origin.y ← 0;
[] ← SymTab.Pairs[pCBTable, ComputeOrigin];
IO.PutF[cmd.out, "Writing %g and %g\n", IO.rope[wrapFile], IO.rope[wrapFile2]];
out ← FS.StreamOpen[wrapFile, $create];
out2 ← FS.StreamOpen[wrapFile2, $create];
[] ← SymTab.Pairs[reducedPinTable, WrapNets];
IO.PutF[out, "*****\n"];
[] ← SymTab.Pairs[newGndPinTable, WrapNets];
IO.PutF[out, "*****\n"];
[] ← SymTab.Pairs[newVccPinTable, WrapNets];
IO.Close[out];
IO.Close[out2];
IO.PutF[cmd.out, "\nNumber of nets: %g\n", IO.card[netNumber]];
IO.PutF[cmd.out, "Number of wrap points: %g\n", IO.card[2*(outputLines-netNumber)]];
IO.PutF[cmd.out, "Number of wires: %g\n\n", IO.card[outputLines-netNumber]];
EXITS fail => result ← $Failed;
END;