<> <> 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]; <> <> <> <> <> <> <> <> <> <> <> << and for each pin:>> <> <> <> <> <> <> <> <> << >> 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.