DIRECTORY Commander USING [CommandProc, Register], Rope USING [ROPE, Length, Fetch, Equal], FS USING [StreamOpen], IO USING [ GetChar, PutChar, PutRope, EndOf, EndOfStream, GetInt, STREAM, RIS, GetTokenRope, TokenProc, BreakProc, Close]; NewPart: CEDAR PROGRAM IMPORTS IO, Commander, Rope, FS = BEGIN ROPE: TYPE = Rope.ROPE; offset: CARD = 186; -- Experimental constant. Everything is relatif to this offset. tablelocation: CARD = 256*2; --Experimental constant. First table location. tablelength: CARD = 256*3; --Experimental constant. Length of the table. Lib: TYPE = REF LibRep; LibarrayRep: TYPE = ARRAY[0..15000] OF BYTE; LibRep: TYPE = RECORD [ lib: REF LibarrayRep, length: CARD, tablelocation: CARD, tablelength: CARD, offset: CARD ]; Pininfo: TYPE = REF PininfoRep; PininfoRep: TYPE = ARRAY[0..255] OF RECORD [ xpos: INT, ypos: INT, name: ROPE, swap: CARD, dia: CARD, site: CARD, type: CARD, pad: CARD ]; Partinfo: TYPE = REF PartinfoRep; PartinfoRep: TYPE = RECORD [ entrynumber: CARD, shapenumber: CARD, xmin: INT, ymin: INT, xmax: INT, ymax: INT, xprefix: INT, yprefix: INT, pinnumber: CARD, name: ROPE, number: ROPE, prefix: ROPE ]; Parthandle: TYPE = REF ParthandleRep; ParthandleRep: TYPE = RECORD [ partinfo: Partinfo, pininfo: Pininfo ]; GetRope: PROC [stream: IO.STREAM, breakProc: IO.BreakProc _ TokenBreak] RETURNS [r:ROPE] = { r _ IO.GetTokenRope[stream, breakProc ! IO.EndOfStream => CONTINUE].token; }; TokenBreak: IO.BreakProc ~ { IF char = ' OR char = '\t OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; CmdTokenBreak: IO.BreakProc = { IF char = '_ THEN RETURN [break]; IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; ReadInitialLib: PROC [initiallibfile: ROPE] RETURNS [lib: Lib] = { in: IO.STREAM _ FS.StreamOpen[initiallibfile]; index: CARD _ 0; lib _ NEW [LibRep]; lib.lib _ NEW[LibarrayRep]; WHILE NOT IO.EndOf[in] DO lib.lib[index] _ ORD[CHAR[IO.GetChar[in]]]; index _ index + 1; ENDLOOP; lib.length _ index; }; ReadPartFile: PROC [initialpartfile: ROPE] RETURNS [parthandle: Parthandle] = { pinindex: CARD _ 0; in: IO.STREAM _ FS.StreamOpen[initialpartfile]; parthandle _ NEW[ParthandleRep]; parthandle.partinfo _ NEW[PartinfoRep]; parthandle.pininfo _ NEW[PininfoRep]; parthandle.partinfo.entrynumber _ IO.GetInt[in]; parthandle.partinfo.shapenumber _ IO.GetInt[in]; parthandle.partinfo.xmin _ IO.GetInt[in]; parthandle.partinfo.ymin _ IO.GetInt[in]; parthandle.partinfo.xmax _ IO.GetInt[in]; parthandle.partinfo.ymax _ IO.GetInt[in]; parthandle.partinfo.xprefix _ IO.GetInt[in]; parthandle.partinfo.yprefix _ IO.GetInt[in]; parthandle.partinfo.name _ GetRope[in]; parthandle.partinfo.number _ GetRope[in]; parthandle.partinfo.prefix _ GetRope[in]; WHILE TRUE DO parthandle.pininfo[pinindex].xpos _ IO.GetInt[in ! IO.EndOfStream => EXIT]; parthandle.pininfo[pinindex].ypos _ IO.GetInt[in]; parthandle.pininfo[pinindex].name _ GetRope[in]; parthandle.pininfo[pinindex].swap _ IO.GetInt[in]; parthandle.pininfo[pinindex].dia _ IO.GetInt[in]; parthandle.pininfo[pinindex].site _ IO.GetInt[in]; parthandle.pininfo[pinindex].type _ IO.GetInt[in]; parthandle.pininfo[pinindex].pad _ IO.GetInt[in]; pinindex _ pinindex + 1; ENDLOOP; parthandle.partinfo.pinnumber _ pinindex; }; VerifyTableLocation: PROC[lib: Lib] = { firstentrynumber: CARD _ ReadLong[lib, lib.tablelocation]; --First presumed entry number firstentrylocation: CARD _ ReadShort[lib, lib.tablelocation+4]; --Address of first entry IF ReadLong[lib, firstentrylocation] # firstentrynumber THEN ERROR; }; ReadShort: PROC[lib: Lib, index: CARD] RETURNS [value: CARD]= { value _ 256*lib.lib[lib.offset+index]; value _ value + lib.lib[lib.offset+index+1]; }; ReadLong: PROC[lib: Lib, index: CARD] RETURNS [value: CARD]= { value _ 256*ReadShort[lib,index+2]; value _ ReadShort[lib,index] + value*256; }; WriteByte: PROC [lib: Lib, index: CARD, value: CARD] ~ { lib.lib[lib.offset+index] _ value MOD 256; }; WriteShort: PROC [lib: Lib, index: CARD, value: CARD] ~ { WriteByte[lib: lib, index: index, value: value/256]; WriteByte[lib: lib, index: index+1, value: value - (value/256)*256]; }; WriteShortInt: PROC [lib: Lib, index: CARD, value: INTEGER] ~ { c: CARD; IF value >= 0 THEN { c _ value; } ELSE { c _ 128*256 + value + 128*256 }; WriteShort[lib, index, c]; }; WriteLong: PROC [lib: Lib, index: CARD, value: CARD] ~ { WriteShort[lib, index, value - ((value/256)/256)*256*256]; WriteShort[lib, index+2, (value/256)/256]; }; InsertEntryInTable: PROC[lib: Lib, entrynumber: CARD] RETURNS [ entryposition: CARD] = { index: INT _ lib.tablelength - 16; currententry: CARD _ ReadLong[lib, index]; WHILE currententry > entrynumber DO WriteLong[lib: lib, index: index+8, value: currententry]; WriteLong[lib: lib, index: index+12, value: ReadLong[lib, index+4]]; index _ index - 8; currententry _ ReadLong[lib, index]; ENDLOOP; IF currententry = entrynumber THEN ERROR; WriteLong[lib: lib, index: index+8, value: entrynumber]; entryposition _ lib.length-2-lib.offset; WriteLong[lib: lib, index: index+12, value: entryposition]; }; InsertPartInLib: PROC [lib: Lib, parthandle: Parthandle] ~ { b: BYTE; i,j: CARD; tempindex: CARD; lengthindex: CARD; pinnamelength: CARD; namelength: CARD _ Rope.Length[parthandle.partinfo.name]; prefixlength: CARD _ Rope.Length[parthandle.partinfo.prefix]; numberlength: CARD _ Rope.Length[parthandle.partinfo.number]; entryposition: CARD _ InsertEntryInTable[lib: lib, entrynumber: parthandle.partinfo.entrynumber]; index: CARD _ lib.length- lib.offset -2; WriteLong [lib: lib, index: index, value: parthandle.partinfo.entrynumber]; index _ index + 4; lengthindex _ index; index _ index + 2; WriteByte[lib: lib, index: index, value: 0]; index _ index + 1; WriteByte[lib: lib, index: index, value: 7]; index _ index + 1; WriteByte[lib: lib, index: index, value: 0]; index _ index + 1; WriteByte[lib: lib, index: index, value: namelength]; index _ index + 1; FOR i IN[0..namelength) DO b _ LOOPHOLE[Rope.Fetch[parthandle.partinfo.name,i]]; WriteByte[lib: lib, index: index, value: b]; index _ index + 1; ENDLOOP; WriteShort [lib: lib, index: index, value: 1]; index _ index + 2; WriteLong [lib: lib, index: index, value: parthandle.partinfo.shapenumber]; index _ index + 4; WriteLong [lib: lib, index: index, value: parthandle.partinfo.shapenumber]; index _ index + 4; WriteLong [lib: lib, index: index, value: 0]; index _ index + 4; WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.xmin]; index _ index + 2; WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.ymin]; index _ index + 2; WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.xmax]; index _ index + 2; WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.ymax]; index _ index + 2; WriteLong [lib: lib, index: index, value: 0]; index _ index + 4; WriteLong [lib: lib, index: index, value: 0]; index _ index + 4; WriteLong [lib: lib, index: index, value: 0]; index _ index + 4; WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.xprefix]; index _ index + 2; WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.yprefix]; index _ index + 2; tempindex _ index; WriteShort [lib: lib, index: index, value: 0]; FOR i IN[0..prefixlength) DO b _ LOOPHOLE[Rope.Fetch[parthandle.partinfo.prefix,i]]; WriteByte[lib: lib, index: index, value: b]; index _ index + 1; ENDLOOP; index _ tempindex + 2; WriteByte[lib: lib, index: index, value: parthandle.partinfo.pinnumber]; index _ index + 1; WriteByte[lib: lib, index: index, value: 1]; index _ index + 1; WriteShortInt [lib: lib, index: index, value: 0]; index _ index + 2; WriteShortInt [lib: lib, index: index, value: 0]; index _ index + 2; WriteShortInt [lib: lib, index: index, value: 0]; index _ index + 2; FOR i IN[0..parthandle.partinfo.pinnumber) DO WriteShortInt [lib: lib, index: index, value: parthandle.pininfo[i].xpos]; index _ index + 2; WriteShortInt [lib: lib, index: index, value: parthandle.pininfo[i].ypos]; index _ index + 2; WriteByte[lib: lib, index: index, value: 0]; index _ index + 1; WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].dia]; index _ index + 1; WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].site-1]; index _ index + 1; WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].pad]; index _ index + 1; WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].swap]; index _ index + 1; pinnamelength _ Rope.Length[parthandle.pininfo[i].name]; IF pinnamelength>15 THEN ERROR; WriteByte[lib: lib, index: index, value: 16*parthandle.pininfo[i].type+pinnamelength]; index _ index + 1; FOR j IN[0..pinnamelength) DO b _ LOOPHOLE[Rope.Fetch[parthandle.pininfo[i].name,j]]; WriteByte[lib: lib, index: index, value: b]; index _ index + 1; ENDLOOP; ENDLOOP; WriteByte[lib: lib, index: index, value: 0]; index _ index + 1; WriteByte[lib: lib, index: index, value: numberlength]; index _ index + 1; FOR i IN[0..numberlength) DO b _ LOOPHOLE[Rope.Fetch[parthandle.partinfo.number,i]]; WriteByte[lib: lib, index: index, value: b]; index _ index + 1; ENDLOOP; WriteShort [lib: lib, index: lengthindex, value: index - lengthindex - 2]; WriteByte[lib: lib, index: index, value: 0]; index _ index + index - (index/2)*2; WriteShort [lib: lib, index: index, value: 255*256-3]; index _ index + 2; lib.length _ index + lib.offset; }; InsertChecksum: PROC [lib: Lib] ~ { index: CARD _ 0; checksum: CARD _ 0; WHILE index < lib.length - 2 DO checksum _ checksum + ReadShort[lib, index]; index _ index + 2; ENDLOOP; WriteShort [lib: lib, index: index-lib.offset, value: checksum-(((checksum/256)/256)*256)*256] }; WriteNewLib: PROC[lib: Lib, outputfile: ROPE] = { i: CARD; out: IO.STREAM _ FS.StreamOpen[outputfile,$create]; FOR i IN [0..lib.length) DO IO.PutChar[out,VAL[lib.lib[i]]]; ENDLOOP; IO.Close[out]; }; NewPartProc: Commander.CommandProc = BEGIN parthandle: Parthandle; lib: Lib; stream: IO.STREAM _ IO.RIS[cmd.commandLine]; outputfile: ROPE _ GetRope[stream, CmdTokenBreak]; gets: ROPE _ GetRope[stream, CmdTokenBreak]; initiallibfile: ROPE _ GetRope[stream, CmdTokenBreak]; initialpartfile: ROPE _ GetRope[stream, CmdTokenBreak]; IF NOT Rope.Equal[gets,"_"] OR outputfile = NIL OR initiallibfile = NIL OR initialpartfile = NIL THEN { cmd.out.PutRope["\nUsage:\nNewPart NewLibFile _ OldLibFile PartFile\n"]; } ELSE { lib _ ReadInitialLib[initiallibfile]; parthandle _ ReadPartFile[initialpartfile]; lib.offset _ offset; lib.tablelocation _ tablelocation; lib.tablelength _ tablelength; VerifyTableLocation[lib]; InsertPartInLib[lib, parthandle]; WriteNewLib[lib, outputfile]; }; END; Commander.Register[ key: "NewPart", proc: NewPartProc, doc: "Adds a new Part and a new Shape to an Expert 2.5 library.\n"]; END. RFile: NewPart.mesa Christophe Cuenod March 20, 1987 3:45:02 pm PST The part file is a text file containing exactly: entry number new part entry number shape assossiated xmin part outline ymin part outline xmax part outline ymax part outline xprefix yprefix location of the prefix part name part number (inventory number) prefi and for each pin: x y name swap dia site type pad Entry number Length not yet defined Type Length of name Name Dummy Shape number Shape number Dummy Xmin Ymin Xmax Ymax Dummy Xprefix Yprefix Prefix Number of pins Only one Byte!!!! Dummy For each pin Xpos Ypos Dummy Diameter Site number Pad stack Swap number Pin type and Length of pin name Pin Name Dummy Length of number Name Length of the entry Clear next position Adjust index to an even number InsertChecksum[lib]; Κ>–i(firstHeadersAfterPage) {1} .cvx .def (firstPageNumber) {1} .cvx .def (oneSidedFormat) {.false} .cvx .def– "Cedar" style˜– "Cedar" stylešœ™J™/—codešΟk ˜ Kšœ œ˜(Kšœœœ˜(Kšœœ˜Kšœœ:œœ-˜z—K˜K™0K™K™ K™K™K™K™K™+K™ K™!K™K™K™K™K™K™K™K™K™K™ K™K˜šΟnœœ˜Kšœœœ˜"—Kš˜Kšœœœ˜KšœœΟc@˜TKšœœ Ÿ/˜LKšœ œ Ÿ.˜IK– "cedar" stylešœœœ˜K– "cedar" styleš œ œœ œœ˜,– "cedar" stylešœœœ˜K– "cedar" stylešœœ ˜K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜K– "cedar" stylešœ œ˜K– "cedar" stylešœ˜ K– "cedar" stylešœ˜—K– "cedar" stylešœ œœ ˜– "cedar" styleš œ œœ œœ˜,K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœ˜ K– "cedar" stylešœ˜—K– "cedar" stylešœ œœ ˜"– "cedar" stylešœ œœ˜K– "cedar" stylešœ œ˜K– "cedar" stylešœ œ˜K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœ œ˜ K– "cedar" stylešœ œ˜ K– "cedar" stylešœ œ˜K– "cedar" stylešœœ˜ K– "cedar" stylešœœ˜ K– "cedar" stylešœ˜ K– "cedar" stylešœ˜—K– "cedar" style˜K– "cedar" stylešœ œœ˜%– "cedar" stylešœœœ˜K– "cedar" stylešœ˜K– "cedar" stylešœ˜K– "cedar" style˜—– "cedar" stylešžœœ œœ œœœ˜\Kšœœ"œœ˜JK– "cedar" style˜—K– "cedar" style˜šž œœ˜Kš œ œ œ œœ˜Kšœ#˜#Kšœ)˜)K˜—šž œœœ œ˜9Kšœ"œ˜*K˜—šž œœœ œ˜:Kšœ4˜4KšœD˜DK˜—šž œœœ œ˜@Kšœœ˜šœ œ˜K˜ K˜—šœ˜K˜K˜—Kšœ˜Kšœ˜—šž œœœ œ˜9Kšœ:˜:Kšœ*˜*K˜—š žœœœœœ˜XKšœœ˜"Kšœœ˜*šœ˜#Kšœ9˜9KšœD˜DK˜Kšœ$˜$Kšœ˜—Kšœœœ˜)Kšœ8˜8Kšœ(˜(Kšœ;˜;K˜—šžœœ(˜=Kšœœ˜Kšœœ˜ Kšœ œ˜Kšœ œ˜Kšœœ˜Kšœ œ)˜9Kšœœ+˜=Kšœœ+˜=KšœœN˜aKšœœ˜(Kšœ ™ KšœK˜KK˜Kšœ™Kšœ˜K˜Kšœ™Kšœ,˜,Kšœ˜Kšœ,˜,Kšœ˜Kšœ,˜,Kšœ˜K™Kšœ5˜5Kšœ˜K™šœœ˜Kšœœ)˜5Kšœ,˜,Kšœ˜Kšœ˜—K™Kšœ.˜.K˜K™ KšœK˜KK˜K™ KšœK˜KK˜K™Kšœ-˜-K˜K™KšœH˜HK˜K™KšœH˜HK˜K™KšœH˜HK˜K™KšœH˜HK˜K™Kšœ-˜-K˜Kšœ-˜-K˜Kšœ-˜-K˜K™KšœK˜KK˜K™KšœK˜KK˜K™Kšœ˜Kšœ.˜.šœœ˜Kšœœ+˜7Kšœ,˜,Kšœ˜Kšœ˜—Kšœ˜K™$K˜KšœH˜HK˜Kšœ˜K™Kšœ,˜,Kšœ˜Kšœ1˜1K˜Kšœ1˜1K˜Kšœ1˜1K˜K™ šœœ#˜-K™KšœJ˜JK˜K™KšœJ˜JK˜K™Kšœ,˜,Kšœ˜K™KšœD˜DKšœ˜K™ KšœG˜GKšœ˜K™ KšœD˜DKšœ˜K™ KšœE˜EKšœ˜K™Kšœ8˜8Kšœœœ˜KšœV˜VKšœ˜K™šœœ˜Kšœœ+˜7Kšœ,˜,Kšœ˜Kšœ˜—Kšœ˜—K™Kšœ,˜,Kšœ˜K™Kšœ7˜7Kšœ˜K™šœœ˜Kšœœ+˜7Kšœ,˜,Kšœ˜Kšœ˜—K™KšœJ˜JK™Kšœ,˜,K™K˜$Kšœ6˜6K˜Kšœ ˜ K˜—šžœœ˜$Kšœœ˜Kšœ œ˜šœ˜Kšœ,˜,K˜Kšœ˜ —Kšœ^˜^Kšœ˜—šž œœœ˜1Kšœœ˜Kšœœœœ ˜3šœœ˜Kšœ œ˜ Kšœ˜—Kšœ ˜K˜—šž œ˜*Kšœ˜Kšœ ˜ Kš œœœœœ˜,Kšœ œ"˜2Kšœœ"˜,Kšœœ"˜6Kšœœ"˜7šœœœœœœœœœ˜gKšœH˜HK˜—šœ˜Kšœ%˜%Kšœ+˜+K˜Kšœ"˜"Kšœ˜Kšœ˜Kšœ!˜!Kšœ™Kšœ˜K˜—Kšœ˜—šœ˜Kšœg˜g—Kšœ˜—…—*=