DIRECTORY Commander USING [CommandProc, Register], ExpertPCBRead USING [PCBTable, ReadPCBFile, Part], ExpertLibRead USING [FirstPinOfThisType, LibTable, ReadLibFile, RelativePinPosition, PinPos, PinNumber], ExpertPinRead USING [PinTable, PinInfo, ReadPinFile, PinInfoList], ExpertKeepRead USING [RefDesTable, ReadKeepFile, KeepRefDes], FS USING [Error, FileInfo, StreamOpen], IO USING [card, Close, GetTokenRope, int, PutF, RIS, rope, STREAM], Rope USING [Cat, Equal, ROPE], SymTab USING [Create, EachPairAction, Insert, Pairs, Fetch, Store]; ExpertWrap: CEDAR PROGRAM IMPORTS Commander, ExpertPCBRead, ExpertLibRead, ExpertPinRead, ExpertKeepRead, FS, IO, Rope, SymTab ~ BEGIN PinPos: TYPE ~ ExpertLibRead.PinPos; ROPE: TYPE ~ Rope.ROPE; SplitPowerNet: PROC [prefix: ROPE, powerInfo: ExpertPinRead.PinInfoList] RETURNS [splitedTable: ExpertPinRead.PinTable] ~ { pinList: ExpertPinRead.PinInfoList; key: ROPE; splitedTable _ SymTab.Create[]; FOR l: ExpertPinRead.PinInfoList _ powerInfo, l.rest UNTIL l = NIL DO key _ Rope.Cat[prefix, ".", l.first.refDes]; pinList _ NIL; IF SymTab.Fetch[splitedTable, key].found THEN { pinList _ NARROW[SymTab.Fetch[splitedTable, key].val]; }; pinList _ CONS[l.first, pinList]; [] _ SymTab.Store[splitedTable, key, pinList]; ENDLOOP; }; AbsolutePinPosition: PROC [libTable: ExpertLibRead.LibTable, part: ExpertPCBRead.Part, i: NAT] RETURNS [absolutePos: PinPos] ~ { relativePos: PinPos _ ExpertLibRead.RelativePinPosition[libTable, part.libraryEntry, i]; SELECT part.orientation FROM = 0 => { absolutePos.x _ part.x + relativePos.x; absolutePos.y _ part.y + relativePos.y; }; = 90 => { absolutePos.x _ part.x - relativePos.y; absolutePos.y _ part.y + relativePos.x; }; = 180 => { absolutePos.x _ part.x - relativePos.x; absolutePos.y _ part.y - relativePos.y; }; = 270 => { absolutePos.x _ part.x + relativePos.y; absolutePos.y _ part.y - relativePos.x; }; ENDCASE => ERROR; }; 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; Commander.Register[ key: "ExpertWrap", proc: ExpertWrapProc, doc: "Takes 4 expert files ( .pcb .lib .pinlist .keep) and generates a .wrap file.\n"]; END. „ExpertWrap.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Christophe Cuenod October 3, 1988 3:04:14 pm PDT Reads a set of .pcb .lib .pinlist and .keep files comming from expert and generates a .wrap file contening all the absolute information for the wirewrap machine. Removes from the nets the pins belonging to a part not mentionned inside the .keep file. Κ /˜code•Mark outsideHeaderšœ™Kšœ<™