File: NewPart.mesa
Christophe Cuenod March 20, 1987 3:45:02 pm PST
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];
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
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;
Entry number
WriteLong [lib: lib, index: index, value: parthandle.partinfo.entrynumber];
index ← index + 4;
Length not yet defined
lengthindex ← index;
index ← index + 2;
Type
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;
Length of name
WriteByte[lib: lib, index: index, value: namelength];
index ← index + 1;
Name
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;
Dummy
WriteShort [lib: lib, index: index, value: 1];
index ← index + 2;
Shape number
WriteLong [lib: lib, index: index, value: parthandle.partinfo.shapenumber];
index ← index + 4;
Shape number
WriteLong [lib: lib, index: index, value: parthandle.partinfo.shapenumber];
index ← index + 4;
Dummy
WriteLong [lib: lib, index: index, value: 0];
index ← index + 4;
Xmin
WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.xmin];
index ← index + 2;
Ymin
WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.ymin];
index ← index + 2;
Xmax
WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.xmax];
index ← index + 2;
Ymax
WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.ymax];
index ← index + 2;
Dummy
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;
Xprefix
WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.xprefix];
index ← index + 2;
Yprefix
WriteShortInt [lib: lib, index: index, value: parthandle.partinfo.yprefix];
index ← index + 2;
Prefix
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;
Number of pins Only one Byte!!!!
WriteByte[lib: lib, index: index, value: parthandle.partinfo.pinnumber];
index ← index + 1;
Dummy
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 each pin
FOR i
IN[0..parthandle.partinfo.pinnumber)
DO
Xpos
WriteShortInt [lib: lib, index: index, value: parthandle.pininfo[i].xpos];
index ← index + 2;
Ypos
WriteShortInt [lib: lib, index: index, value: parthandle.pininfo[i].ypos];
index ← index + 2;
Dummy
WriteByte[lib: lib, index: index, value: 0];
index ← index + 1;
Diameter
WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].dia];
index ← index + 1;
Site number
WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].site-1];
index ← index + 1;
Pad stack
WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].pad];
index ← index + 1;
Swap number
WriteByte[lib: lib, index: index, value: parthandle.pininfo[i].swap];
index ← index + 1;
Pin type and Length of pin name
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;
Pin Name
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;
Dummy
WriteByte[lib: lib, index: index, value: 0];
index ← index + 1;
Length of number
WriteByte[lib: lib, index: index, value: numberlength];
index ← index + 1;
Name
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;
Length of the entry
WriteShort [lib: lib, index: lengthindex, value: index - lengthindex - 2];
Clear next position
WriteByte[lib: lib, index: index, value: 0];
Adjust index to an even number
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];
InsertChecksum[lib];
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.