ConvertCMosB.mesa (part of ChipNDale)
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, June 24, 1983 5:03 pm
last edited Christian Jacobi, December 4, 1985 4:59:07 pm PST
DIRECTORY
CD,
CDAtomicObjects,
CDBasics,
CDCells,
CDCommandOps,
CDDirectory,
CDExtras,
CDImports,
CDMarkObjects,
CDMenus,
CDOps,
CDOrient,
CDPolygons,
CDProperties,
CDRects,
CDSequencer,
CDTexts,
CDViewer,
CMos,
CMosB,
Rope,
TerminalIO;
ConvertCMosB:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDAtomicObjects, CDCells, CDCommandOps, CDDirectory, CDExtras, CDImports, CDMarkObjects, CDMenus, CDOps, CDOrient, CDPolygons, CDProperties, CDRects, CDTexts, CDViewer, CMos, CMosB, TerminalIO =
BEGIN
--must be protected
correspondKey: REF INT;
abortFlag: REF BOOL ← NEW[BOOL←FALSE];
design: CD.Design;
newDesign: CD.Design;
lambda: CD.Number;
newLambda: CD.Number;
oldTech: CD.Technology;
newTech: CD.Technology;
TRect:
PROC [rect:
CD.Rect]
RETURNS [r:
CD.Rect] =
BEGIN
r ← [x1: rect.x1*newLambda/lambda, x2: rect.x2*newLambda/lambda, y1: rect.y1*newLambda/lambda, y2: rect.y2*newLambda/lambda]
END;
TPos:
PROC [pos:
CD.Position]
RETURNS [p:
CD.Position] =
BEGIN
p ← [pos.x*newLambda/lambda, pos.y*newLambda/lambda]
END;
TNum:
PROC [n:
CD.Number]
RETURNS [
CD.Number] =
BEGIN
RETURN [n*newLambda/lambda]
END;
MustOffsetOrigin:
PROC [oldOb:
CD.Object]
RETURNS [off:
CD.Position ← [0, 0]] =
--off in old coord system
BEGIN
SELECT oldOb.class.objectType
FROM
$CTrans, $CWellTrans, $CLTrans, $CLWellTrans => RETURN [[0, -lambda]];
ENDCASE => RETURN [[0, 0]];
END;
OriginPos:
PROC [i:
CD.Instance, point:
CD.Position ← [0, 0]]
RETURNS [p:
CD.Position] =
--point in origin coordinates of object i.ob is returned in world coordinates
BEGIN
RETURN [CDOrient.MapPoint[
pointInCell: CDBasics.AddPoints[point, CD.ClientOrigin[i.ob]],
cellSize: i.ob.size,
cellInstOrient: i.orientation,
cellInstPos: i.location
]]
END;
CorrespondingLayer:
PROC [layer:
CD.Layer]
RETURNS [l:
CD.Layer] =
BEGIN
IF CD.LayerTechnology[layer]=NIL THEN RETURN [layer];
l ← CD.FetchLayer[newTech, CD.LayerKey[layer]]
END;
TransferAny:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object←
NIL] =
BEGIN
WITH CDProperties.GetProp[ob, correspondKey]
SELECT
FROM
ob1: CD.Object => RETURN [ob1];
ENDCASE => NULL;
IF CDAtomicObjects.IsAtomicOb[ob] THEN new ← TransferAtomicObject[ob]
ELSE IF CDCells.IsCell[ob] THEN new ← TransferCell[ob]
ELSE IF ob.class.wireTyped THEN new ← TransferWire[ob]
ELSE IF ob=CDMarkObjects.markOb THEN new ← CDMarkObjects.markOb
ELSE IF CDTexts.IsText[ob] THEN new ← TransferText[ob]
ELSE IF CDImports.IsImport[ob] THEN new ← TransferImport[ob]
ELSE IF CDPolygons.IsPolygon[ob] THEN new ← TransferPolygon[ob];
IF new=NIL THEN new ← TransferHard[ob];
IF new=NIL THEN TerminalIO.WriteRope["unknown object type\n"]
END;
--to be set using the interpreter; NIL would make a cell!
convertCViaTo: ATOM ← $C2Via; --or NIL
convertCTrans: ATOM ← $C2Trans; --or NIL
convertCLTrans: ATOM ← $C2LTrans; --or NIL
GetAtomKey:
PROC [a:
ATOM]
RETURNS [
ATOM] =
BEGIN
RETURN [
SELECT a
FROM
$CSimpleCon, $CWellSimpleCon => $C2SimpleCon,
$CDifShortCon, $CWellDifShortCon => $C2DifShortCon,
$CTrans, $CWellTrans => $C2Trans,
$CLTrans, $CLWellTrans => convertCLTrans,
$CVia => convertCViaTo,
ENDCASE => NIL]
END;
TransferAtomicObject:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object←
NIL] =
BEGIN
SpecialCases:
PROC [newKey:
ATOM] =
BEGIN
SELECT newKey
FROM
$C2Trans => {sz.y ← sz.y+2*newLambda};
$C2LTrans => {sz.y ← sz.y+newLambda; sz.x ← sz.x+newLambda};
ENDCASE => NULL;
END;
sz: CD.Position ← TPos[CD.InterestSize[ob]];
newKey: ATOM ← GetAtomKey[ob.class.objectType];
IF newKey#
NIL
THEN {
SpecialCases[newKey];
new ← CDAtomicObjects.CreateAtomicOb[newKey, sz, newTech, CorrespondingLayer[ob.layer]];
}
END;
TransferHard:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object←
NIL] =
BEGIN
ob1: CD.Object ← CDDirectory.ExpandHard[me: ob, from: design, to: NIL];
IF ob1#
NIL
THEN {
new ← TransferWithChildrenCheck[ob1]
}
END;
TransferWire:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] =
BEGIN
new ← CDRects.CreateRect[TPos[CD.InterestSize[ob]], CorrespondingLayer[ob.layer]]
END;
TransferText:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] =
BEGIN
tp: CDTexts.TextPtr ← NARROW[ob.specificRef];
font: CDTexts.CDFont;
font ← CDTexts.MakeFont[name: tp.cdFont.supposedName, scale: TNum[tp.cdFont.scaleI]];
new ← CDTexts.CreateText[text: tp.text, font: font, layer: CorrespondingLayer[ob.layer]];
END;
TransferImport:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] =
BEGIN
--dirty
ip: CDImports.ImportPtr ← NARROW[ob.specificRef];
newIp: CDImports.ImportPtr ← NEW[CDImports.ImportRep←[ir: TRect[ip.ir], objectName: ip.objectName, designName: ip.designName]];
new ← NEW[CD.ObjectRep←ob^];
new.properties ← NIL;
new.specificRef ← newIp;
new.size ← TPos[new.size];
[] ← CDDirectory.Include[newDesign, new, CDDirectory.Name[ob]]
END;
TransferPolygon:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] =
BEGIN
pp: CDPolygons.PolygonPtr ← NARROW[ob.specificRef];
newPl: LIST OF CD.Position←NIL;
FOR pl:
LIST
OF
CD.Position ← pp.points, pl.rest WHILE pl#
NIL
DO
newPl ← CONS[TPos[pl.first], newPl];
ENDLOOP;
new ← CDPolygons.CreatePolygon[newPl, CorrespondingLayer[ob.layer]].ob;
END;
TransferCell:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] =
BEGIN
newChild: CD.Object;
cp: CD.CellPtr ← NARROW[ob.specificRef];
new ← CDCells.CreateEmptyCell[];
FOR il:
CD.InstanceList ← cp.contents, il.rest
WHILE il#
NIL
DO
inst: CD.Instance;
position: CD.Position ← TPos[CDBasics.SubPoints[OriginPos[il.first, MustOffsetOrigin[il.first.ob]], cp.origin]];
newChild ← TransferAny[il.first.ob];
IF newChild=NIL THEN LOOP;
inst ← CDCells.IncludeOb[design: NIL, cell: new, position: position, ob: newChild, orientation: il.first.orientation, cellCSystem: originCoords, obCSystem: originCoords, mode: dontPropagate].newInst;
CDProperties.AppendProps[winner: inst.properties, looser: il.first.properties, putOnto: inst];
ENDLOOP;
IF ~cp.useDIr
THEN
CDCells.SetInterestRect[new,
TRect[CDBasics.MoveRect[cp.ir, CDBasics.NegOffset[CD.ClientOrigin[ob]]]]
];
[] ← CDCells.RepositionCell[new, NIL];
CDProperties.AppendProps[winner: new.properties, looser: ob.properties, putOnto: new];
[] ← CDDirectory.Include[newDesign, new, CDDirectory.Name[ob]]
END;
ReallyTransfer:
PROC [ob:
CD.Object]
RETURNS [ob1:
CD.Object] =
--all children of ob are already transfereed
BEGIN
ob1 ← TransferAny[ob]
END;
TransferWithChildrenCheck:
PROC [ob:
CD.Object]
RETURNS [ob1
: CD.Object] =
BEGIN
EachChild:
PROC [me:
CD.Object, x:
REF] = {
[] ← TransferWithChildrenCheck[me];
};
WITH CDProperties.GetProp[ob, correspondKey]
SELECT
FROM
obx: CD.Object => ob1 ← obx;
ENDCASE => {
CDDirectory.EnumerateChildObjects[ob, EachChild, NIL];
ob1 ← ReallyTransfer[ob];
CDProperties.PutProp[ob, correspondKey, ob1]
};
END;
Transfer:
PROC [from:
CD.Design, tech:
CD.Technology]
RETURNS [nD:
CD.Design] =
BEGIN
EachDirEl:
PROC [name: Rope.
ROPE, ob:
CD.Object]
RETURNS [quit:
BOOL←
FALSE] = {
[] ← TransferWithChildrenCheck[ob];
};
dummyOb, newDummyOb: CD.Object;
design ← from;
correspondKey ← NEW[INT];
oldTech ← from.technology;
newTech ← tech;
newDesign ← nD ← CDOps.CreateDesign[tech];
CDExtras.PopToTopLevel[from];
dummyOb ← CDExtras.CreateDummyObject[from];
lambda ← oldTech.lambda;
newLambda ← newTech.lambda;
[] ← CDDirectory.Enumerate[design: from, action: EachDirEl];
newDummyOb ← TransferWithChildrenCheck[dummyOb];
[] ← CDCells.IncludeOb[design: newDesign, ob: newDummyOb];
CDExtras.RemoveProperties[from, correspondKey];
END;
ProtectedTransferComm:
PROC [comm: CDSequencer.Command] =
BEGIN
d: CD.Design;
TerminalIO.WriteRope["transfer technology\n"];
IF comm.design.technology#CMos.cmos
THEN {
TerminalIO.WriteRope["not cmos\n"];
ERROR ABORTED
};
d ← Transfer[comm.design, CMosB.cmosB];
[] ← CDViewer.CreateViewer[d];
END;
TransferComm:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["transfer technology\n"];
abortFlag^ ← FALSE;
[] ← CDCommandOps.CallWithResource[
proc: ProtectedTransferComm,
comm: comm,
resource: $CDTransferTecnology,
abortFlag: abortFlag
];
END;
CDMenus.ImplementEntryCommand[menu: $ProgramMenu, entry: "convert to dragon cmos", p: TransferComm];
END.