<> <> <> DIRECTORY CD, CDCommandOps, CDDirectory, CDInstances, CDLayers, CDOps, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDSequencer, CDTexts, CDViewer, Core, CoreCreate, CoreOps, CoreProperties, PopUpMenus, IO, PW, REFBit, Rope, Sisyph, TerminalIO, ViewerClasses, ViewerOps, WireIconExtras; WireIconExtrasImpl: CEDAR PROGRAM IMPORTS CD, CDCommandOps, CDDirectory, CDInstances, CDLayers, CDOps, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDTexts, CDViewer, CoreCreate, CoreProperties, CoreOps, IO, PW, REFBit, Rope, Sisyph, TerminalIO, ViewerOps EXPORTS WireIconExtras = BEGIN ROPE: TYPE = Rope.ROPE; Wire: TYPE = Core.Wire; <> RecWire: PUBLIC PROC[rec: ROPE, dual: BOOL _ FALSE] RETURNS[wire: Wire] = {RETURN[RefWire[REFBit.NEWFromName[rec], rec.Substr[rec.Index[0,"."]+1]]]}; RefWire: PUBLIC PROC[ref: REF, name: ROPE, dual: BOOL _ FALSE] RETURNS[wire: Wire] = { ZeroIfOne: PROC[s: INT] RETURNS[INT] = {RETURN[IF s=1 THEN 0 ELSE s]}; fieldForm: REFBit.Format _ REFBit.Desc[ref].fieldForm; wires: LIST OF Wire _ NIL; temp: LIST OF Wire _ NIL; FOR field: INT IN[0..fieldForm.size) DO fieldName: ROPE _ BitRopeToSigRope[fieldForm[field].name]; SELECT fieldForm[field].bitSize FROM 1 => {wires _ CONS[CoreCreate.Seq[fieldName, IF dual THEN 2 ELSE 0], wires]}; >1 => { fieldWire: Wire _ CoreOps.CreateWires[fieldForm[field].bitSize, fieldName]; wires _ CONS[fieldWire, wires]; FOR bit: INT IN[0..fieldWire.size) DO fieldWire[bit] _ CoreCreate.Seq[NIL, IF dual THEN 2 ELSE 0] ENDLOOP}; ENDCASE => ERROR; ENDLOOP; temp _ wires; wires _ NIL; FOR temp _ temp, temp.rest WHILE temp#NIL DO wires _ CONS[temp.first, wires] ENDLOOP; wire _ CoreOps.CreateWire[wires, name]}; <<>> ETWire: PUBLIC PROC[prefix, suffix, type: ROPE] RETURNS[wire: Wire] = { bitName, bitNameInv: ROPE; refREF: REF _ REFBit.NEWFromName[type]; format: REFBit.Format _ REFBit.Desc[refREF].bitForm; wire _ CoreOps.CreateWires[MAX[2, format.size], prefix.Cat[suffix]]; FOR i: INT IN[0..format.size) DO bitName _ BitRopeToSigRope[format[i].name]; bitNameInv _ BitRopeToSigRope[format[i].nameInv]; IF ((format.size#1) = (i+1=format.size)) = (bitName#NIL) THEN ERROR; IF ((format.size#1) = (bitNameInv#NIL)) = (bitName#NIL) THEN ERROR; IF bitName=NIL THEN bitName _ bitNameInv; wire[i] _ CoreOps.CreateWires[0, prefix.Cat[bitName, suffix]]; IF format.size=1 THEN wire[1] _ CoreOps.CreateWires[0, prefix.Cat[bitNameInv, suffix]]; ENDLOOP}; BitRopeToSigRope: PROC [name: ROPE] RETURNS [ROPE] ~ { Cap: PROC[rope: ROPE, idx: INT] RETURNS[ROPE] = { char: CHAR _ rope.Fetch[idx+1]; IF char IN ['a..'z] THEN char _ char + LOOPHOLE['A - 'a]; RETURN[IO.PutFR["%g", IO.char[char]]]}; IF name = NIL THEN RETURN[NIL]; name _ Rope.Cat[Cap[name, -1], name.Substr[1]]; DO -- remove peiods and Capitalize next letters until end or next char is number index: INT _ name.Index[0, "."]; IF index+1 >= name.Length[] OR name.Fetch[index+1] IN ['0..'9] THEN RETURN[name]; name _ Rope.Cat[name.Substr[0,index], Cap[name, index], name.Substr[index+2]]; ENDLOOP }; <> ConstructRecWireIconCommand: PROC [comm: CDSequencer.Command] ~ { type: ROPE _ TerminalIO.RequestRope["Type (eg. Def.Record): "]; wire: Core.Wire _ RecWire[type]; name: ROPE _ type.Substr[type.Index[0,"."]+1]; icon: CD.Object _ ConstructWireIcon[comm, wire, name.Cat[".icon"]]; CDProperties.PutObjectProp[icon, $CodeFor, Rope.Cat["WireIconExtras.RecWire[\"", type, "\"]" ]]; CDProperties.PutObjectProp[icon, Sisyph.mode.extractProcProp, $SisyphExtractNamedWireIcon]}; ConstructDETWireIconCommand: PROC [comm: CDSequencer.Command] ~ { type: ROPE _ TerminalIO.RequestRope["Type (eg. Def.Enumerated): "]; pre: ROPE _ TerminalIO.RequestRope["Prefix:"]; suf: ROPE _ TerminalIO.RequestRope["Suffix:"]; wire: Core.Wire _ ETWire[pre, suf, type]; icon: CD.Object _ ConstructWireIcon[comm, wire, Rope.Cat[pre, suf, ".icon"]]; CDProperties.PutObjectProp [icon, $CodeFor, IO.PutFR["WireIconExtras.ETWire[\"%g\", \"%g\", \"%g\"]", IO.rope[pre], IO.rope[suf], IO.rope[type] ]]; CDProperties.PutObjectProp[icon, Sisyph.mode.extractProcProp, $SisyphExtractNamedWireIcon]}; ConstructWireIcon: PROC [comm: CDSequencer.Command, wire: Core.Wire, name: ROPE] RETURNS[icon: CD.Object] ~ { font: CDTexts.CDFont _ CDPanelFonts.CurrentFont[comm.design]; w: INT _ CDLayers.LayerWidth[comm.design, CD.commentLayer]; fw2: INT _ font.height/2 - w - font.origin.y; grid: CD.Number _ Grid[comm.design, font]; insts: CD.InstanceList _ NIL; pinObject: CD.Object _ CDRects.CreateRect[size: [grid/2, w], l: CD.commentLayer]; text: CD.Object; sat: CD.Instance; pin: CD.Instance; maxX: INT _ 0; FOR i: INT IN [0..wire.size) DO text _ CDTexts.Create[CoreOps.GetShortWireName[wire[i]], font]; maxX _ MAX[ maxX, CD.InterestSize[text].x]; sat _ CDInstances.NewInst[text, [[x: grid, y: grid*(i+2)-fw2 ]]]; pin _ CDInstances.NewInst[pinObject, [[x: 0, y: grid*(i+2) ]]]; insts _ CONS[sat, CONS[pin, insts]]; CDSatellites.Associate[master: pin, text: sat] ENDLOOP; text _ CDTexts.Create[CoreOps.GetShortWireName[wire], font]; maxX _ ((MAX[ maxX, CD.InterestSize[text].x] + 3*grid-1)/grid)*grid; sat _ CDInstances.NewInst[text, [[x: maxX-grid-CD.InterestSize[text].x, y: grid-fw2 ]]]; pin _ CDInstances.NewInst[pinObject, [[x: maxX-grid/2, y: grid ]]]; insts _ CONS[sat, CONS[pin, insts]]; CDSatellites.Associate[master: pin, text: sat]; icon _ PW.CreateCell[instances: insts, ir: [0, 0, maxX, grid*(wire.size+2)+w]]; IF NOT CDDirectory.Include[comm.design, icon, name] THEN {TerminalIO.PutF["*** Directory insertion of %g failed.\n", IO.rope[name]]; ERROR}; <> []_CDOps.IncludeObjectI[comm.design, icon, comm.pos]}; <<>> Grid: PROC[design: CD.Design, font: CDTexts.CDFont _ NIL] RETURNS[grid: NAT] = { viewers: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; IF viewers#NIL THEN WITH ViewerOps.GetViewer[viewers.first, $Grid] SELECT FROM rgrid: REF CD.Number => grid _ rgrid^; ENDCASE => NULL ELSE grid _ design.technology.lambda*2; IF font#NIL THEN WHILE font.height > (grid*4)/3 DO grid _ grid*2 ENDLOOP}; <> <> <> <> <> <> <> <> <> <> <<[selected, multiple] _ CDOps.SelectedInstance[comm.design];>> <> <> <> <<{TerminalIO.PutF["*** Selected schematic has no name.\n"]; RETURN};>> <> <> <> <> <> <> <> <> <> <> <> <<{TerminalIO.PutF["No name provided, no default from schematic.\n"]; RETURN};>> <> <> <> <> <<$ConstructIconCommand => FALSE,>> <<$ConstructIconCommandSort => TRUE,>> < ERROR;>> <> <> <> <<[]_CDOps.IncludeObjectI[comm.design, icon, comm.pos]};>> <<>> mark: ATOM _ CoreProperties.RegisterProperty[$TemporaryMark]; <> <> <> <> <> <> <> <> <<{XX: INT _ design.technology.lambda*16; RETURN[((in+XX-1)/XX)*XX]};>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[] _ CoreGeometry.EnumerateSortedSides[schDeco, schCT, side, eachSortedPin];>> <<[]_CoreOps.VisitWire[schCT.public, clearMark];>> <> <> <> <> <> <> <> <> < {>> <> <> < {>> <> <> < {>> <> <> < {>> <> <> < ERROR;>> <> <> <<>> <> <> <> <> <> <> <> <> <<>> <> <> <> <<{TerminalIO.PutF["*** Directory insertion of %g failed.\n", IO.rope[iconFullName]]; ERROR};>> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<{TerminalIO.PutF["Can't handle pushed in cell\n"]; RETURN};>> <> <> <> <> <> <<{TerminalIO.PutF["%g is not an icon.\n", IO.rope[objName]]; LOOP};>> <> <> <<{TerminalIO.PutF["%g does not extract as a cell.\n", IO.rope[objName]]; LOOP};>> <> <> <> < {errorType _ type; errorMsg _ message; CONTINUE}];>> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[]_CDDebug.Draw[directOb, comm.design.technology, objName];>> <> <> <> <> <> <> <> <<>> <> <> <<{TerminalIO.PutF["*** No current selection--can't do it.\n"]; RETURN[FALSE]};>> <> <<{TerminalIO.PutF["*** Multiple instances selected--can't do it.\n"]; RETURN[FALSE]};>> <> <> <> <> <<{TerminalIO.PutF["*** Selected instance is not a cellcan't do it.\n"]; RETURN[FALSE]};>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> CDCommandOps.RegisterWithMenu[ menu: $SisyphIconMenu, entry: "Create Wire Icon from Cedar Record Type", doc: "RECORDs with field types such as: RECORD, INT, BOOL, enumerated, subranges", key: $ConstructRecWireIconCommand, proc: ConstructRecWireIconCommand ]; CDCommandOps.RegisterWithMenu[ menu: $SisyphIconMenu, entry: "Create Wire Icon from Cedar Enumerated Type", doc: "Decoded Enumerated types encoded as: 0, 3, 5, 9, 17 etc.", key: $ConstructDETWireIconCommand, proc: ConstructDETWireIconCommand ]; END.