DIRECTORY
CD, CDAtomicObjects, CDBasics, CDCells, CDCurves, CDDefaultProcs, CDDirectory, CDEvents, CDImports, CDInstances, CDRects, CDRoutingObjects, CDSatellites, CDSymbolicObjects, CDTexts, CMosB, CMosBExtras, 
Imager, ImagerColor, ImagerTransformation, List,
Pipal, PipalCD, PipalInt, PipalMos, PipalPaint, 
Properties, PW, Real, RefTab, Saguaro;

PipalCDImpl: CEDAR PROGRAM
IMPORTS CD, CDAtomicObjects, CDBasics, CDCells, CDCurves, CDDefaultProcs, CDDirectory, CDEvents, CDImports, CDInstances, CDRects, CDRoutingObjects, CDSatellites, CDSymbolicObjects, CDTexts, CMosB, CMosBExtras, Imager, ImagerTransformation, List, Pipal, PipalInt, PipalMos, Properties, PW, Real, RefTab, Saguaro
EXPORTS PipalCD
SHARES CDCells, CDCurves, CDImports, CDRects, CDTexts =
BEGIN OPEN PipalCD;
cdlayers: REF ARRAY CD.Layer OF PipalMos.Layer _ NEW [ARRAY CD.Layer OF PipalMos.Layer];
layers: RefTab.Ref _ RefTab.Create[];

RegisterCDPLayer: PROC [cdlayer: CD.Layer, layer: PipalMos.Layer] = {
cdlayers[cdlayer] _ layer;
[] _ RefTab.Store[layers, layer, NEW [CD.Layer _ cdlayer]];
};

CDToPLayer: PROC [cdlayer: CD.Layer] RETURNS [layer: PipalMos.Layer] = {
layer _ cdlayers[cdlayer];
IF layer=NIL THEN ERROR;
};

PToCDLayer: PROC [layer: PipalMos.Layer] RETURNS [cdlayer: CD.Layer] = {
refCDL: REF CD.Layer _ NARROW [RefTab.Fetch[layers, layer].val];
IF refCDL=NIL THEN ERROR;
cdlayer _ refCDL^;
};
cdToPProcs: RefTab.Ref _ RefTab.Create[];
pToCDProcs: Pipal.ClassTable _ Pipal.CreateClassTable[];
pToCDInstanceProcs: Pipal.ClassTable _ Pipal.CreateClassTable[];

RegisterCDToPProc: PROC [class: CD.ObjectClass, proc: CDToPProc] = {
[] _ RefTab.Store[cdToPProcs, class, NEW [CDToPProc _ proc]];
};
RegisterPToCDProc: PROC [class: Pipal.Class, proc: PToCDProc] = {
[] _ Pipal.StoreInClassTable[pToCDProcs, class, NEW [PToCDProc _ proc]];
};

RegisterPToCDInstanceProc: PROC [class: Pipal.Class, proc: PToCDInstanceProc] = {
[] _ Pipal.StoreInClassTable[pToCDInstanceProcs, class, NEW [PToCDInstanceProc _ proc]];
};

CDOP: TYPE = RECORD [cdobj: CD.Object, cdprops: CD.PropList _ NIL];
cdToPObjects: RefTab.Ref _ RefTab.Create[]; -- [CD.Object -> Pipal.Object]
pToCDObjects: RefTab.Ref _ RefTab.Create[]; -- [Pipal.Object -> CDOP]

SomethingWeirdGoingOn: SIGNAL [] = CODE;

CheckAndStore: PROC [obj: Pipal.Object, cdobj: CD.Object, cdprops: CD.PropList] = {
IF obj=Pipal.void THEN RETURN;
IF cdobj.class=CDCells.pCellClass AND NARROW [cdobj.specific, CD.CellSpecific].dummyCell THEN RETURN;
IF CDToPRect[cdobj.bbox]#PipalInt.BBox[obj, []] THEN SIGNAL SomethingWeirdGoingOn[];
IF CDRectSize[cdobj.bbox]#PipalInt.ObjectSize[obj] THEN SIGNAL SomethingWeirdGoingOn[];
IF CDToPRect[CD.InterestRect[cdobj]]#PipalInt.AbutBox[obj] THEN SIGNAL SomethingWeirdGoingOn[];
[] _ RefTab.Store[cdToPObjects, cdobj, obj];
[] _ RefTab.Store[pToCDObjects, obj, NEW [CDOP _ [cdobj, cdprops]]];
};

CheckInstance: PROC [obj: Pipal.Object, cdobj: CD.Object, cdprops: CD.PropList, cdtrans: CD.Transformation, transformation: PipalInt.Transformation] = {
IF obj=Pipal.void THEN RETURN;
IF CDToPRect[CDBasics.MapRect[cdobj.bbox, cdtrans]]#PipalInt.BBox[obj, transformation] THEN SIGNAL SomethingWeirdGoingOn[];
IF CDToPRect[CDBasics.MapRect[CD.InterestRect[cdobj], cdtrans]]#PipalInt.TransformRectangle[transformation, PipalInt.AbutBox[obj]] THEN SIGNAL SomethingWeirdGoingOn[];
};

CDToPObject: PUBLIC CDToPProc = {
refProc: REF CDToPProc;
IF cdobj=NIL THEN ERROR;
obj _ RefTab.Fetch[cdToPObjects, cdobj].val;
IF obj#NIL THEN RETURN;
refProc _ NARROW [RefTab.Fetch[cdToPProcs, cdobj.class].val];
IF refProc=NIL THEN ERROR;
obj _ (refProc^)[cdobj];
obj _ AddCDProps[cdobj.properties, obj, FALSE];
CheckAndStore[obj, cdobj, NIL];
};

PToCDObject: PUBLIC PToCDProc = {
cdop: REF CDOP _ NARROW [RefTab.Fetch[pToCDObjects, obj].val];
refProc: REF PToCDProc;
IF cdop#NIL THEN RETURN [cdop.cdobj, cdop.cdprops];
refProc _ NARROW [Pipal.FetchFromClassTable[pToCDProcs, Pipal.ObjectClass[obj]]];
[cdobj, cdprops] _ (IF refProc=NIL THEN PToCDExpand ELSE (refProc^))[obj];
CheckAndStore[obj, cdobj, cdprops];
};

PToCDInstance: PUBLIC PToCDInstanceProc = {
refProc: REF PToCDInstanceProc _ NARROW [Pipal.FetchFromClassTable[pToCDInstanceProcs, Pipal.ObjectClass[obj]]];
[cdobj, cdprops, cdtrans] _ (IF refProc=NIL THEN PToCDInstanceFromObj ELSE (refProc^))[obj, transformation];
CheckInstance[obj, cdobj, cdprops, cdtrans, transformation];
};
CDToPSize: PROC [size: CD.Position] RETURNS [PipalInt.Size] =
INLINE { RETURN [[size.x, size.y]] };

CDRectSize: PROC [rect: CD.Rect] RETURNS [PipalInt.Size] =
INLINE { RETURN [CDToPSize[CDBasics.SizeOfRect[rect]]] };

CDRectBase: PROC [rect: CD.Rect] RETURNS [PipalInt.Position] =
INLINE { RETURN [[rect.x1, rect.y1]] };

CDToPRect: PROC [rect: CD.Rect] RETURNS [PipalInt.Rectangle] =
INLINE { RETURN [[base: CDRectBase[rect], size: CDRectSize[rect]]] };

BaseTranslate: PROC [rect: CD.Rect, obj: Pipal.Object] RETURNS [Pipal.Object] =
INLINE { RETURN [PipalInt.TransformObject[[CDRectBase[rect]], obj]] };

CDDrawListToP: PROC [drawList: CDAtomicObjects.DrawList] RETURNS [Pipal.Object] = {
children: Pipal.Objects _ NIL;
WHILE drawList#NIL DO
dr: CDAtomicObjects.DrawRec _ drawList.first;
children _ CONS [
PipalInt.TransformObject[
[CDRectBase[dr.r]], PipalMos.CreateBox[CDRectSize[dr.r], CDToPLayer[dr.layer]]
],
children
];
drawList _ drawList.rest;
ENDLOOP;
RETURN [Pipal.CreateOverlay[children]];
};

CDToPTrans: PUBLIC PROC [trans: CD.Transformation] RETURNS [PipalInt.Transformation] = {
RETURN [[[trans.off.x, trans.off.y], VAL [ORD [trans.orient]]]];
};

Transform: PROC [trans: CD.Transformation, obj: Pipal.Object] RETURNS [Pipal.Object] =
INLINE { RETURN [PipalInt.TransformObject[CDToPTrans[trans], obj]] };

IRAnnotate: PROC [ir: CD.Rect, obj: Pipal.Object] RETURNS [Pipal.Object] =
INLINE { RETURN [PipalInt.CreateAbutBoxAnnotation[obj, CDToPRect[ir]]] };

UnknownProp: SIGNAL [key: ATOM, val: REF] = CODE;

stupidCDProps: LIST OF REF _ LIST [$layerOfPin, $CDSatellitesGroupId, $CDBringoverLibraryName, $CDSatellitesOGroup, $OwnerDesign, $CDSatellitesComment];
extractProps: LIST OF REF _ LIST [$SinixPropertiesCache, $CMosBExtractProc, $RawCMosBExtractProc, $SinixSatellites, $SinixCMosBExtractProc, $SisyphExtractProc, $SisyphParmNames, $CodeFor, $IconFor, $SinixInstanceCache, $FlattenInstanceCache, $SinixObjectCache];
otherProps: LIST OF REF _ LIST [$X, $PinOrder, $InstanceName, $DontFlatten, $Export, $MintDiscardMe];

ProcessSchematicIconProps: PROC [props: CD.PropList, obj: Pipal.Object] RETURNS [CD.PropList, Pipal.Object] = {
type: PipalMos.SchematicIconType;
codeFor: Pipal.ROPE _ NARROW [Properties.GetProp[props, $CodeFor]];
iconFor: Pipal.ROPE _ NARROW [Properties.GetProp[props, $IconFor]];
IF (codeFor=NIL AND iconFor=NIL) OR (codeFor#NIL AND iconFor#NIL) THEN RETURN [props, obj];
SELECT Properties.GetProp[props, $SisyphExtractProc] FROM
$SisyphExtractCellIcon		=> type _ cell;
$SisyphExtractNamedWireIcon	=> type _ wire;
$SisyphExtractUnNamedWireIcon	=> type _ unnamedWire;
ENDCASE			=> RETURN [props, obj];
props _ Properties.PutProp[props, $CodeFor, NIL];
props _ Properties.PutProp[props, $IconFor, NIL];
props _ Properties.PutProp[props, $SisyphExtractProc, NIL];
obj _ PipalMos.CreateSchematicIcon[obj, IF codeFor=NIL THEN iconFor ELSE codeFor, codeFor#NIL, type];
RETURN [props, obj];
};

AddCDProps: PROC [props: CD.PropList, obj: Pipal.Object, inst: BOOL] RETURNS [new: Pipal.Object] = {
[props, new] _ ProcessSchematicIconProps[props, obj];
WHILE props#NIL DO
key: REF _ props.first.key;
val: REF _ props.first.val;
IF ISTYPE [key, ATOM] THEN SELECT TRUE FROM
key=$SignalName OR key=$Describe			=> new _ Pipal.CreateAnnotation[new, Pipal.nameProp, NARROW [val, Pipal.ROPE]];
key=$SisyphExpressions			=> new _ Pipal.CreateAnnotation[new, IF inst THEN $SisyphInstanceExpressions ELSE $SisyphObjectExpressions, NARROW [val, LIST OF Pipal.ROPE]]; -- hack hack hack!
List.Memb[key, stupidCDProps]	=> {};
List.Memb[key, extractProps]		=> {};
List.Memb[key, otherProps]		=> {};
ENDCASE	=> {
SIGNAL UnknownProp[NARROW [key], val];
otherProps_ CONS [key, otherProps];
};
props _ props.rest;
ENDLOOP;
};

CDToPInstance: PUBLIC PROC [instance: CD.Instance] RETURNS [obj: Pipal.Object] = {
properties: CD.PropList _ instance.properties;
SELECT TRUE FROM
CDSymbolicObjects.IsSymbolicOb[instance.ob]	=> {
obj _ PipalMos.CreateMarker[
CDRectSize[CDSymbolicObjects.Denotes[instance]], 
CDToPLayer[CDSymbolicObjects.GetLayer[instance]]
];
properties _ Properties.PutProp[properties, $layerOfPin, NIL];
};
instance.ob.class.newLayer#NIL AND instance.ob.layer=CD.commentLayer AND Properties.GetProp[properties, $SisyphExtractProc] = $ExtractNull	=> {
instance _ CDInstances.Copy[instance];
IF NOT instance.ob.class.newLayer[instance, CD.FetchLayer[NIL, $blue]] THEN ERROR;
obj _ CDToPObject[instance.ob];
properties _ Properties.PutProp[properties, $SisyphExtractProc, NIL];
};
ENDCASE	=> obj _ CDToPObject[instance.ob];
obj _ AddCDProps[properties, Transform[instance.trans, obj], TRUE];
};
CDToPBox: CDToPProc = {
obj _ PipalMos.CreateBox[CDRectSize[cdobj.bbox], CDToPLayer[cdobj.layer]];
};

CDToPAtomicAnnotation: CDToPProc = {
ov: Pipal.Object _ CDToPOverlay[CDDirectory.Expand1ByDraw[cdobj]];
obj _ Pipal.CreateAnnotation[
ov, 
IF PipalMos.ContainsWell[ov] THEN PipalMos.biAtomicProp ELSE PipalMos.atomicProp, 
cdobj.class.objectType
];
};

CDToPTransistorAnnotation: CDToPProc = {
obj _ Pipal.CreateAnnotation[
CDToPOverlay[CDDirectory.Expand1ByDraw[cdobj]], 
PipalMos.transistorProp, 
cdobj.class.objectType
];
};

CDToPOrient: CDToPProc = {
rs: PW.RotationSpecific _ NARROW [cdobj.specific];
obj _ PipalInt.CreateOrient[VAL [ORD [rs.orientation]], CDToPObject[rs.obj]];
};

CDToPRouting: CDToPProc = {
rs: CDRoutingObjects.RoutingSpecific _ NARROW [cdobj.specific];
nodes: Pipal.Objects _ NIL;
FOR i: NAT IN [0 .. rs.size) DO
node: CDRoutingObjects.Node _ rs[i];
subs: Pipal.Objects _ NIL;
FOR j: NAT IN [0 .. node.size) DO
po: CDRoutingObjects.PlacedObject = node[j];
position: CD.Position = po.position;
subs _ CONS [PipalInt.TransformObject[[[position.x, position.y]], CDToPObject[po.object]], subs];
ENDLOOP;
nodes _ CONS [AddCDProps[node.properties, Pipal.CreateOverlay[subs], TRUE], nodes];
ENDLOOP;
obj _ IRAnnotate[rs.ir, Pipal.CreateOverlay[nodes]];
};

CDXYTile: PipalMos.XYTileProc = {
RETURN [CDToPObject[PW.GetTile[NARROW [data], x, y]]];
};

CDToPTiling: CDToPProc = {
obj _ PipalMos.CreateTiling[PW.GetTilingSize[cdobj].sizeX, PW.GetTilingSize[cdobj].sizeY, CDXYTile, cdobj];
};

CDToPImport: CDToPProc = {
import: CDImports.ImportSpecific = NARROW [cdobj.specific];
IF import.boundOb=NIL THEN ERROR;
obj _ CDToPObject[import.boundOb];
};

CDToPIndirect: CDToPProc = {
obj _ Pipal.CreateAnnotation[
CDToPObject[CDDirectory.Expand1[cdobj].new], PipalMos.indirectProp, NIL
];
};

CDToPAbut: CDToPProc = {
EachInst: PW.EachSubObjectProc = {children _ CONS [CDToPObject[subObject], children]};
children: Pipal.Objects _ NIL;
[] _ PW.EnumerateSubObjects[cdobj, EachInst];
obj _ PipalInt.CreateAbut[cdobj.class=PW.abutXClass, Pipal.Reverse[children]];
};

CDToPText: CDToPProc = {
text: CDTexts.TextSpecific _ NARROW [cdobj.specific];
obj _ PipalMos.CreateText[text.text, text.cdFont.font]
};

ImagerObjectData: TYPE = REF ImagerObjectDataRec;
ImagerObjectDataRec: TYPE = RECORD [
cdImagerObject: Imager.Object,
color: ImagerColor.ConstantColor
];

DrawImagerObject: PROC [self: Imager.Object, context: Imager.Context] = {
iod: ImagerObjectData = NARROW [self.data];
Imager.SetColor[context, iod.color];
Imager.DrawObject[context: context, object: iod.cdImagerObject, interactive: TRUE];
};

CDToPCurve: CDToPProc = {
curve: CDCurves.CurveSpecific _ NARROW [cdobj.specific];
cdImagerObject: Imager.Object _ curve.imagerObject;
iod: ImagerObjectData _ NEW [ImagerObjectDataRec _ [
cdImagerObject: cdImagerObject, color: PipalMos.FetchLayerColor[CDToPLayer[cdobj.layer]]
]];
obj _ PipalMos.CreatePicture[
CDRectSize[cdobj.bbox], 
NEW [Imager.ObjectRep _ [draw: DrawImagerObject, clip: cdImagerObject.clip, data: iod]]
];
};

CDToPPicture: CDToPProc = {
obj _ PipalMos.CreatePicture[CDRectSize[cdobj.bbox], NARROW [cdobj.specific]]
};

CDToPOverlay: CDToPProc = {
cs: CD.CellSpecific = NARROW [cdobj.specific];
GetSatellites: PROC [from: REF] RETURNS [satellites: Pipal.Objects _ NIL] = {
FOR list: CD.InstanceList _ CDSatellites.GetSatellites[from], list.rest WHILE list#NIL DO
IF NOT RefTab.Store[seen, list.first, $TRUE] THEN ERROR; -- satellite of several!
satellites _ CONS [CDToPInstance[list.first], satellites];
ENDLOOP;
};
CreateStar: PROC [master: Pipal.Object, satellites: Pipal.Objects, overlayStar: BOOL] RETURNS [Pipal.Object] = {
IF satellites=NIL THEN RETURN [master];
RETURN [PipalMos.CreateStar[master, satellites, overlayStar]];
};
seen: RefTab.Ref _ RefTab.Create[];
EachNonText: CDCells.InstEnumerator = {
IF CDTexts.IsText[inst.ob] THEN RETURN;
children _ CONS [CreateStar[CDToPInstance[inst], GetSatellites[inst], FALSE], children];
};
EachText: CDCells.InstEnumerator = {
IF NOT CDTexts.IsText[inst.ob] OR RefTab.Fetch[seen, inst].found THEN RETURN;
children _ CONS [CDToPInstance[inst], children];
};
children: Pipal.Objects _ NIL;
objectSatellites: Pipal.Objects _ GetSatellites[cdobj];
[] _ CDCells.EnumerateInstances[cdobj, EachNonText];
[] _ CDCells.EnumerateInstances[cdobj, EachText];
obj _ Pipal.CreateOverlay[children];
obj _ CreateStar[obj, objectSatellites, TRUE];
IF cs.specifiedIr THEN obj _ IRAnnotate[cs.ir, obj];
};
PToCDVector: PROC [size: PipalInt.Size] RETURNS [CD.Position] =
INLINE { RETURN [[size.x, size.y]] };

PToCDRect: PROC [rect: PipalInt.Rectangle] RETURNS [CD.Rect] =
INLINE { RETURN [[x1: rect.base.x, y1: rect.base.y, x2: rect.base.x+rect.size.x, y2: rect.base.y+rect.size.y]] };

PToCDTrans: PUBLIC PROC [trans: PipalInt.Transformation] RETURNS [CD.Transformation] = { 
RETURN [[PToCDVector[trans.translation], VAL [ORD [trans.orientation]]]];
};
PToCDInstanceFromObj: PToCDInstanceProc = {
[cdobj, cdprops] _ PToCDObject[obj];
cdtrans _ PToCDTrans[transformation];
};

PToCDInstanceInternal: PROC [obj: Pipal.Object, transformation: PipalInt.Transformation] RETURNS [cdinst: CD.Instance] = {
cdobj: CD.Object; cdprops: CD.PropList; cdtrans: CD.Transformation;
[cdobj, cdprops, cdtrans] _ PToCDInstance[obj, transformation];
cdinst _ NEW [CD.InstanceRep _ [ob: cdobj, trans: cdtrans, properties: cdprops]];
};

PToCDAnnotation: PToCDProc = {
annotation: Pipal.Annotation _ NARROW [obj];
SELECT annotation.key FROM
PipalInt.abutBoxProp	=> {
refAbutBox: REF PipalInt.Rectangle _ NARROW [annotation.value];
cdobj _ PW.CreateCell[
LIST [PToCDInstanceInternal[annotation.child, []]],
PToCDRect[refAbutBox^]
];
};
ENDCASE	=> {
[cdobj, cdprops] _ PToCDObject[annotation.child];
cdprops _ Properties.PutProp[cdprops, annotation.key, annotation.value];
};
};

PToCDBox: PToCDProc = {
box: PipalMos.Box _ NARROW [obj];
cdobj _ CDRects.CreateRect[PToCDVector[box.size], PToCDLayer[box.layer]];
};

PToCDMarker: PToCDProc = {
marker: PipalMos.Marker _ NARROW [obj];
cdobj _ CDRects.CreateRect[PToCDVector[marker.size], PToCDLayer[marker.layer]];
};

PToCDText: PToCDProc = {
text: PipalMos.Text _ NARROW [obj];
trans: Imager.Transformation = text.font.charToClient;
scale: INT _ Real.Round[trans.a];
IF NOT ImagerTransformation.CloseEnough[ImagerTransformation.Scale[scale], trans] THEN SIGNAL SomethingWeirdGoingOn[];
cdobj _ CDTexts.Create[text.contents, CDTexts.MakeFont[PipalMos.GetTextFontName[text], scale]];
};

PToCDPicture: PToCDProc = {
picture: PipalMos.Picture _ NARROW [obj];
cdobj _ CreatePicture[PToCDVector[picture.size], picture.imagerObject];
};

PToCDExpand: PToCDProc = {
instances: CD.InstanceList _ NIL;
EachChild: PipalInt.EachChildProc = {
IF child=Pipal.void THEN RETURN;
instances _ CONS [PToCDInstanceInternal[child, transformation], instances];
};
[] _ PipalInt.Enumerate[obj, EachChild];
cdobj _ PW.CreateCell[instances];
IF cdobj.bbox = [0, 0, 1, 1] THEN cdobj.bbox _ [0, 0, 0, 0];
};
pictureClass: CD.ObjectClass _ PW.RegisterClass[
objectType: $PipalPicture, 
expand: NIL,
interestRect: CDDefaultProcs.InterestRect,
drawMe: DrawPicture,
quickDrawMe: DrawPicture,
showMeSelected: CDDefaultProcs.ShowMeSelected
];

CreatePicture: PROC [size: CD.Position, imagerObject: Imager.Object] RETURNS [ob: CD.Object] = {
ob _ NEW [CD.ObjectRep _ [
bbox: [0, 0, size.x, size.y], class: pictureClass, immutable: TRUE, specific: imagerObject
]];
};

DrawPicture: CD.DrawProc = {
PictureInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = {
Imager.DrawObject[context: context, object: NARROW [ob.specific], interactive: TRUE];
};
pr.drawContext[pr, PictureInContext, ob, trans, ob.layer]
}; 

ReadPicture: CD.InternalReadProc = {ERROR};

WritePicture: CD.InternalWriteProc = {ERROR};
AnnotationExtractTransistor: PipalMos.ExtractTransistorProc = {
SubstituteLayers: PROC [old: CDAtomicObjects.DrawList] RETURNS [new: CDAtomicObjects.DrawList _ NIL] = {
WHILE old#NIL DO
r: CD.Rect _ old.first.r;
layer: CD.Layer _ old.first.layer;
new _ CONS [
[r, SELECT layer FROM 
CMosB.wndif => CMosB.ndif, CMosB.wpdif => CMosB.pdif, 
Saguaro.gate => CMosB.pol,
ENDCASE => layer
], 
new];
old _ old.rest;
ENDLOOP;
};
EachRectangleLayer: PipalMos.EachRectangleLayerProc = {
SELECT layer FROM
$Ndif		=> {dif _ CMosB.ndif; wdif _ CMosB.wndif};
$Pdif		=> {dif _ CMosB.pdif; wdif _ CMosB.wpdif};
$Pwell, $Nwell	=> hasWell _ TRUE;
ENDCASE		=> {};
};
annotation: Pipal.Annotation = NARROW [object];
abutBox: PipalInt.Rectangle = PipalInt.AbutBox[object];
et: Saguaro.ExtractedTransistor;
dif, wdif: CD.Layer _ CD.errorLayer;
hasWell: BOOL _ FALSE;
IF annotation.key#PipalMos.transistorProp THEN ERROR;
[] _ PipalMos.EnumerateRectangleLayers[annotation, EachRectangleLayer];
IF dif=CD.errorLayer THEN ERROR;
et _ Saguaro.ExtractTransistor[CDAtomicObjects.CreateAtomicOb[NARROW [annotation.value], [abutBox.size.x, abutBox.size.y], CMosB.cmosB, IF hasWell THEN wdif ELSE dif]];
type _ SELECT et.type FROM nE => nE, pE => pE, ENDCASE => ERROR;
ch1 _ CDDrawListToP[SubstituteLayers[et.ch1.layout]];
ch2 _ CDDrawListToP[SubstituteLayers[et.ch2.layout]];
gate _ CDDrawListToP[SubstituteLayers[et.gate.layout]];
bulk _ CDDrawListToP[et.bulk.layout];
width _ et.width;
length _ et.length;
};
FlushCDO: PROC [cdobj: CD.Object] = {
object: Pipal.Object _ RefTab.Fetch[cdToPObjects, cdobj].val;
[] _ RefTab.Delete[cdToPObjects, cdobj];
IF object#NIL THEN [] _ RefTab.Delete[pToCDObjects, object];
};

AfterObjectChange: CDEvents.EventProc = {
WITH x SELECT FROM
cdobj: CD.Object => FlushCDO[cdobj];
ENDCASE => NULL;
};

RegisterPToCDInstanceProc[PipalMos.boxClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.markerClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.textClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.pictureClass, PToCDInstanceFromObj];

CDEvents.RegisterEventProc[$AfterChange, AfterObjectChange];
CDEvents.RegisterEventProc[$AfterCellReplacement, AfterObjectChange];

RegisterCDPLayer[CD.errorLayer, PipalMos.errorLayer];
RegisterCDPLayer[CD.commentLayer, PipalMos.commentLayer];
RegisterCDPLayer[CMosBExtras.bond, $Bond];
RegisterCDPLayer[CMosB.ndif, $Ndif];
RegisterCDPLayer[CMosB.pdif, $Pdif];
RegisterCDPLayer[CMosB.pwellCont, $PwellCont];
RegisterCDPLayer[CMosB.nwellCont, $NwellCont];
RegisterCDPLayer[CMosB.pwell, $Pwell];
RegisterCDPLayer[CMosB.nwell, $Nwell];
RegisterCDPLayer[CMosB.pol, $Pol];
RegisterCDPLayer[CMosB.met, $Met];
RegisterCDPLayer[CMosB.met2, $Met2];
RegisterCDPLayer[CMosB.ovg, $Ovg];
RegisterCDPLayer[CMosB.cut, $Cut];
RegisterCDPLayer[CMosB.cut2, $Cut2];
RegisterCDPLayer[CD.FetchLayer[NIL, $blue], PipalMos.blueCommentLayer];

RegisterCDToPProc[CDRects.bareRectClass, CDToPBox];
RegisterCDToPProc[CDRects.wellRectClass, CDToPAtomicAnnotation];
RegisterCDToPProc[CDCells.pCellClass, CDToPOverlay];
RegisterCDToPProc[PW.abutXClass, CDToPAbut];
RegisterCDToPProc[PW.abutYClass, CDToPAbut];
RegisterCDToPProc[PW.rotationClass, CDToPOrient];
RegisterCDToPProc[CDRoutingObjects.routingClass, CDToPRouting];
RegisterCDToPProc[PW.tilingClass, CDToPTiling];
RegisterCDToPProc[PW.indirectClass, CDToPIndirect];
RegisterCDToPProc[CDTexts.flipTextClass, CDToPText];
RegisterCDToPProc[CDTexts.rigidTextClass, CDToPText];
RegisterCDToPProc[CDCurves.splineClass, CDToPCurve];
RegisterCDToPProc[CDCurves.lineClass, CDToPCurve];
RegisterCDToPProc[CDCurves.polygonClass, CDToPCurve];
RegisterCDToPProc[CDCurves.filledCurveClass, CDToPCurve];
RegisterCDToPProc[pictureClass, CDToPPicture];
RegisterCDToPProc[CDImports.importsClass, CDToPImport];

FOR list: LIST OF ATOM _ LIST [$C2SimpleCon, $C2WellSimpleCon, $C2LargeSimpleCon, $C2LargeWellSimpleCon, $C2DifShortCon, $C2DiffShortCon, $C2WellDifShortCon, $C2Via, $C2LargeVia], list.rest WHILE list#NIL DO
RegisterCDToPProc[CD.FetchObjectClass[list.first, CMosB.cmosB], CDToPAtomicAnnotation];
ENDLOOP;

FOR list: LIST OF ATOM _ LIST [$C2Trans, $C2WellTrans, $C2LTrans, $C2LWellTrans], list.rest WHILE list#NIL DO
RegisterCDToPProc[CD.FetchObjectClass[list.first, CMosB.cmosB], CDToPTransistorAnnotation];
ENDLOOP;

Pipal.PutClassMethod[Pipal.annotationClass, PipalMos.extractTransistorMethod, NEW [PipalMos.ExtractTransistorProc _ AnnotationExtractTransistor]];


RegisterPToCDProc[Pipal.annotationClass, PToCDAnnotation];
RegisterPToCDProc[PipalMos.boxClass, PToCDBox];
RegisterPToCDProc[PipalMos.markerClass, PToCDMarker];
RegisterPToCDProc[PipalMos.textClass, PToCDText];
RegisterPToCDProc[PipalMos.pictureClass, PToCDPicture];

RegisterPToCDInstanceProc[PipalMos.boxClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.markerClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.textClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.pictureClass, PToCDInstanceFromObj];

END.

��ö��PipalCDImpl.mesa
Copyright Ó 1988 by Xerox Corporation.  All rights reserved.
Louis Monier January 18, 1988 10:05:47 am PST
Bertrand Serlet May 23, 1988 4:06:08 pm PDT

Layer Conversions
Top-Level Conversion
Basic CDToP Conversions
CDToP Conversions Utilities
Special hack for pins, first!
Hack for $SisyphExtractProc=$ExtractNull
Class-Specific CDToP Object Conversions
All the functions in that section assume that the properties of cdobj have been dealt with.

Basic PToCD Conversions
Class-Specific PToCD Object Conversions
CD Pictures
internalRead: ReadPicture,
internalWrite: WritePicture,
Transistors
Event Flushing
Initialization
Attention: wndif, wpdif, wpwellCont, wnwellCont do not appear in that table to avoid problems!
All Atomic classes
Ê��–
"cedar" style˜�codešœ™Kšœ<™<Kšœ*Ïk™-Kšœ+™+K™�—š	˜	KšœÈ˜ÊKšœ0˜0Kšœ0˜0Kšœœ˜&—K˜�•StartOfExpansion[]šÏnœœ˜Kšœœ“œ˜¶Kšœ˜Kšœ1˜7Kšœœ	˜—headšœ™Kšœ
œœœœœœœœ˜Xšœ%˜%K˜�—šžœœœ"˜EKšœ˜Kšœ!œœ˜;K˜K˜�—šž
œœœœ˜HKšœ˜Kšœœœœ˜K˜J˜�—šž
œœœœ˜HJšœœœ	œ#˜@Kšœœœœ˜Kšœ˜K˜——™Kšœ)˜)Kšœ8˜8šœ@˜@K˜�—šžœœ	œ"˜DKšœ%œ˜=K˜—šžœœ*˜AKšœ0œ˜HK˜K˜�—šžœœ2˜QKšœ8œ˜XK˜K˜�—Kšœœœ	œœœ˜CKšœ,Ïc˜Jšœ,Ÿ˜EK˜�—šžœœœ˜(K˜�—šž
œœœœ˜SKšœœœ˜Kšœ œœœœœ˜eKšœ.œœ˜TKšœ1œœ˜WKšœœ,œœ˜_Kšœ,˜,Kšœ%œœ˜DK˜K˜�—š
ž
œœœœœ=˜˜Kšœœœ˜KšœUœœ˜{Kšœœcœœ˜§K˜K˜�—šžœœ˜!Kšœ	œ˜Kšœœœœ˜Kšœ,˜,Kšœœœœ˜Kšœ
œ-˜=Kšœ	œœœ˜Kšœ˜Kšœ(œ˜/Kšœœ˜K˜K˜�—šžœœ˜!Kšœœœœ'˜>Kšœ	œ˜Kšœœœœ˜3Kšœ
œA˜QKš	œœ	œœ
œ˜JKšœ#˜#Kšœ˜K˜�—šž
œœ˜+Kšœ	œœI˜pKš	œœ	œœœ"˜lKšœ<˜<Kšœ˜——™šž	œœœœ˜=Kšœœ˜%K˜�—šž
œœœœ˜:Kšœœ*˜9K˜�—šž
œœœœ˜>Kšœœ˜'K˜�—šž	œœœœ˜>Kšœœ6˜EK˜�—šž
œœœœ˜OKšœœ7˜FK˜�—šž
œœ&œ˜SKšœœ˜šœ
œ˜Kšœ-˜-šœœ˜šœ˜KšœN˜NK˜—Kšœ˜K˜—Kšœ˜Kšœ˜—Kšœ!˜'K˜K˜�—š
ž
œœœ	œœ˜XKšœœœ˜@K˜K˜�—šž	œœ	œ$œ˜VKšœœ6˜EK˜�—šž
œœœœ˜JKšœœ:˜IK˜�——™š
žœœœœœ˜1K˜�—Kš	œœœœœw˜˜Kš	œœœœœå˜…š	œœœœœG˜eK˜�—š
žœœ	œœœ˜oKšœ!˜!Kšœœœ'˜CKšœœœ'˜CKšœ
œœ	œœ
œœ	œœœ˜[šœ/˜9Kšœ'˜'Kšœ+˜+Kšœ4˜4Kšœœ˜!—Kšœ,œ˜1Kšœ,œ˜1Kšœ6œ˜;Kšœ(œ	œœ	œœ˜eKšœ˜K˜K˜�—š
ž
œœ	œ$œœ˜dJšœ5˜5šœœ˜Jšœœ˜Jšœœ˜š
œœœœœœ˜+JšœœFœ
œ˜rJšœ>œœœœœœœŸ˜ºJ–)[ref: REF ANY, list: LIST OF REF ANY]šœ$˜$J–)[ref: REF ANY, list: LIST OF REF ANY]šœ$˜$J–)[ref: REF ANY, list: LIST OF REF ANY]šœ"˜"šœ˜Jšœ
œ
˜&Jšœœ˜#J˜——Kšœ˜Kšœ˜—K˜K˜�—š
ž
œœœœœ˜RKšœœ ˜.šœœ˜K™šœ0˜0šœ˜Kšœ1˜1Kšœ0˜0Kšœ˜—Kšœ9œ˜>K˜—Kšœ(™(š	œœœœœG˜Kšœ&˜&Kšœœ&œœ
œœ˜RKšœ˜Kšœ@œ˜EK˜—Kšœ#˜*—Kšœ=œ˜CK˜——™'bodyšœ[™[M™�—šžœ˜KšœJ˜JK˜K˜�—šžœ˜$KšœB˜Bšœ˜Kšœ˜Kšœœœ˜RKšœ˜K˜—K˜K˜�—šžœ˜(šœ˜Kšœ0˜0Kšœ˜Kšœ˜K˜—K˜K˜�—šžœ˜Kšœœœ˜2Kšœœœ)˜MK˜K˜�—šžœ˜Kšœ'œ˜?Kšœœ˜šœœœ˜Kšœ$˜$Kšœœ˜šœœœ˜!Kšœ,˜,Kšœ
œ˜$KšœœV˜aKšœ˜—Kšœœ9œ
˜SKšœ˜—Kšœ4˜4K˜K˜�—šžœ˜!Kšœœ	œ˜6K˜K˜�—šžœ˜Kšœœœ.˜kK˜K˜�—šžœ˜Kšœ#œ˜;Kšœœœœ˜!Kšœ"˜"K˜K˜�—šž
œ˜šœ˜KšœD˜GK˜—K˜K˜�—šž	œ˜Kšžœœ!œ%˜VKšœœ˜Kšœœ&˜-Kšœ&œ&˜NK˜K˜�—šž	œ˜Kšœœ˜5Jšœ6˜6K˜K˜�—Jšœœœ˜1šœœœ˜$Jšœ˜Jšœ ˜ J˜J˜�—šžœœ3˜IKšœœ
˜+Kšœ$˜$JšœMœ˜SK˜K˜�—šž
œ˜Kšœ œ˜8Jšœ3˜3šœœ˜4JšœX˜XJšœ˜—šœ˜Jšœ˜JšœT˜WJ˜—K˜K˜�—šžœ˜Jšœ5œ˜MK˜K˜�—šžœ˜Kšœœœ˜.š
ž
œœœœœ˜Mš	œœ<œœ˜YKš	œœ'œœŸ˜QKšœ
œ)˜:Kšœ˜—Jšœ˜—šž
œœ@œœ˜pKšœœœœ
˜'Kšœ8˜>K˜—K˜#šžœ˜'Kšœœœ˜'Kšœœ7œ
˜XKšœ˜—šžœ˜$Kš
œœœ œœ˜MKšœœ!˜0Kšœ˜—Kšœœ˜Kšœ7˜7Kšœ4˜4Kšœ1˜1Kšœ$˜$Kšœ(œ˜.Kšœœ˜4K˜——™šžœœœœ˜?Kšœœ˜%K˜�—šž	œœœœ˜>šœœb˜qK˜�——š
ž
œœœ"œœ˜YKšœ#œœ˜IKšœ˜——™'šžœ˜+Kšœ$˜$Kšœ%˜%K˜K˜�—šžœœ>œ
œ˜zKšœœœœ˜CKšœ?˜?Kšœ	œœA˜QK˜K˜�—šžœ˜Kšœœ˜,šœ˜šœ˜Kšœœœ˜?šœœ˜Kšœ/˜3Kšœ˜Kšœ˜—K˜—šœ˜Kšœ1˜1KšœH˜HK˜——K˜K˜�—šžœ˜Kšœœ˜!KšœI˜IK˜K˜�—šžœ˜Kšœœ˜'KšœO˜OK˜K˜�—šž	œ˜Kšœœ˜#Kšœ6˜6Kšœœ˜!KšœœLœœ˜vKšœ_˜_K˜K˜�—šžœ˜Kšœœ˜)KšœG˜GK˜K˜�—šžœ˜Kšœœœ˜!šž	œ˜%Kšœœœ˜ Kšœœ;˜KK˜—Kšœ(˜(Kšœœ˜!Kšœœ˜<K˜——šœ	™šœœœ˜0Kšœ˜Kšœœ˜Kšœ*˜*Kšœ˜Kšœ˜Kšœ-˜-KšÏb™Kš ™šœ˜K˜�——š
ž
œœœ(œœ˜`šœœœ˜Kšœ>œ˜ZKšœ˜—Kšœ˜K˜�—šžœœ
˜šžœœœœ˜TKšœ,œœ˜UKšœ˜—Kšœ9˜9Kšœ˜K˜�—šžœœœ˜+K˜�—Kšžœœœ˜-—™šžœ$˜?šžœœ!œ"œ˜hšœœ˜Kšœœ˜Kšœœ˜"šœœ˜šœœœ˜Kšœ6˜6Kšœ˜Kšœ	˜Kšœ˜—Kšœ˜—K˜Kšœ˜—K˜—šžœ%˜7šœ˜Kšœ1˜1Kšœ1˜1Kšœœ˜!Kšœ˜—K˜—Kšœœ
˜/Kšœ7˜7Kšœ ˜ Kšœœ	œ˜$Kšœ	œœ˜Kšœ(œœ˜5KšœG˜GKšœœœœ˜ Kš	œ>œDœ	œœ˜¨Kš	œœ	œœœ˜@Kšœ5˜5Kšœ5˜5Kšœ7˜7Kšœ%˜%Kšœ˜Kšœ˜K˜——™šžœœ	œ˜%Kšœ=˜=Kšœ(˜(Kšœœœ*˜<K˜K˜�—šžœ˜)šœœ˜Kšœœ˜$Kšœœ˜—K˜K˜�—KšœC˜CKšœF˜FKšœD˜DšœG˜GK˜�——™Kšœ<˜<šœE˜EK˜�—Kšœ^™^Kšœœ"˜5Kšœœ&˜9Kšœ*˜*Kšœ$˜$Kšœ$˜$Kšœ.˜.Kšœ.˜.Kšœ&˜&Kšœ&˜&Kšœ"˜"Kšœ"˜"Kšœ$˜$Kšœ"˜"Kšœ"˜"Kšœ$˜$šœœœ%˜GK˜�—Kšœ3˜3Kšœ@˜@Kšœ4˜4Kšœœ˜,Kšœœ˜,Kšœœ˜1Kšœ?˜?Kšœœ˜/Kšœœ˜3Kšœ4˜4Kšœ5˜5Kšœ4˜4Kšœ2˜2Kšœ5˜5Kšœ9˜9Kšœ.˜.Kšœ7˜7K˜�Kšœ™šœœœœœbÐblœ>œœ˜ÏKšœœC˜WKšœ˜K˜�—šœœœœœ?œœ˜mKšœœG˜[Kšœ˜K˜�—šœNœA˜’K˜�—K˜�Kšœ:˜:Kšœ/˜/Kšœ5˜5Kšœ1˜1šœ7˜7K˜�—KšœC˜CKšœF˜FKšœD˜DšœG˜GK˜�——Kšœ˜K˜�—�…—����UL��nÒ��