<> <> <> <> DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDCommandOps, CDCleanUp, CDDirectory, CDExtras, CDImports, CDMenus, CDOps, CDOrient, CDPolygons, CDProperties, CDRects, CDSequencer, CDSymbolicObjects, CDTexts, CDViewer, CMosB, Rope, TerminalIO; ConvertCMosB: CEDAR PROGRAM IMPORTS CD, CDBasics, CDAtomicObjects, CDCleanUp, CDCells, CDCommandOps, CDDirectory, CDExtras, CDImports, CDMenus, CDOps, CDOrient, CDPolygons, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CDViewer, 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 CDSymbolicObjects.IsMark[ob] THEN new _ CDSymbolicObjects.CreateMark[] 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.Expand[ob, design, NIL].new; IF ob1=NIL OR ob1=ob THEN ob1 _ CDDirectory.ExpandByDraw[ob]; IF ob1#NIL THEN { new _ TransferWithChildrenCheck[ob1]; CDProperties.PutProp[ob, correspondKey, CDProperties.GetProp[ob1, correspondKey]]; } 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]; CDCleanUp.RemoveProperties[from, correspondKey]; END; ProtectedTransferComm: PROC [comm: CDSequencer.Command] = BEGIN d: CD.Design; TerminalIO.WriteRope["transfer technology\n"]; IF comm.design.technology.key#$cmos THEN { TerminalIO.WriteRope["not cmos\n"]; ERROR ABORTED }; [] _ CDCleanUp.CleanUp[comm.design]; 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.