<> <> <> <> <> <> DIRECTORY Basics USING [bytesPerWord], CD USING [Design, Error, ErrorCode, Instance, InterestSize, Layer, Object, LayerKey, Position, Rect, Technology], CDCells USING [CreateEmptyCell, EnumerateInstances, IncludeMode, IncludeOb, InstEnumerator, SetInterestRect], CDDirectory USING [Another, DMode, FixChildren, Include], CDImports USING [Load, CreateImport], CDIO USING [MakeName, ReadDesign, DesignInReadOperation, WriteDesign], CDOps USING [CreateDesign], CDProperties USING [PutObjectProp, RegisterProperty], CDRects USING [CreateRect], CDSil USING [cdsil, xaqua, xbrown, xcyan, xgreen, xlime, xmagenta, xneutral, xorange, xpink, xred, xsmoke, xturquise, xultraviolet, xviolet, xwhite, xyellow], CDSilConversion, CDTexts USING [Create, FontRec, IsText, MakeFont], CDViewer USING [CreateViewer], Commander USING [CommandProc, Register], CommandTool USING [ParseToList], FileNames USING [CurrentWorkingDirectory], FS USING [ComponentPositions, Error, ExpandName, Position, StreamOpen], ImagerFont USING [Extents, Font, RopeBoundingBox], IO USING [atom, char, Close, EndOf, EndOfStream, GetChar, int, PutFR, STREAM, UnsafeGetBlock], Real USING [Round], Rope USING [ActionType, Cat, Concat, FromChar, FromProc, Length, Map, Replace, ROPE, SkipTo, Substr], TerminalIO USING [PutRope, UserAbort, Confirm], TokenIO USING [Handle], UserProfile USING [CallWhenProfileChanges, ProfileChangedProc, ProfileChangeReason, Token]; CDSilConversionImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDDirectory, CDImports, CDIO, CDOps, CDProperties, CDRects, CDSil, CDTexts, CDViewer, Commander, CommandTool, FileNames, FS, ImagerFont, IO, Real, Rope, TerminalIO, UserProfile EXPORTS CDSilConversion = BEGIN OPEN CDSilConversion; fileNotFound: ERROR [reason: Rope.ROPE] = CODE; <> convLibEachTime: BOOL _ FALSE; -- convert all library files for each model verbose: BOOL = FALSE; -- Asks the user whether he wants to write the converted model and libraries <> debug0: BOOL _ FALSE; -- reading file debug1: BOOL _ FALSE; -- converting debug2: BOOL _ FALSE; -- integration of macro files debug3: BOOL _ FALSE; -- main Sil model debug4: BOOL _ FALSE; -- translation of font names debugAll: BOOL _ debug0 OR debug1 OR debug2 OR debug3 OR debug4; <> <> <> <> <> <> <> <> <> <> <> <> <<00: Neutral 08: Brown 01: Red 09: Orange 02: Yellow 10: Lime 03: Green 11: Turquise 04: Cyan 12: Aqua 05: Violet 13: UltraViolet 06: Magenta 14: Pink 07: White 15: Smoke>> <> <> <> <<00: Font 0 01: Font 0 with "boldness" opposite to default value in profile 02: Font 1 03: Font 1 with "boldness" opposite to default value in profile 04: Font 2 05: Font 2 with "boldness" opposite to default value in profile 06: Font 3 07: Font 3 with "boldness" opposite to default value in profile 08: Font 4 macro 09: Font 5 macro 10: Font 6 macro 11: Font 7 macro 12: Font 8 macro 13: Font 9 macro 14: A line with lingth and width indicated by preceeding coordinates 15: A background with area indicated by preceeding coordinates>> <> <> <> <> <> <> <> FourBits: TYPE ~ [0..17B]; SevenBits: TYPE ~ [0..177B]; TwelveBits: TYPE ~ [0..7777B]; SixteenBits: TYPE ~ [0..177777B]; OneBit: TYPE ~ [0..1]; ElevenBits: TYPE ~ [0..3777B]; mainElementName: CHAR ~ 377C; -- this as name of silobject means it's part of main picture checkCodeByte1: CHAR ~ '9; -- check code indicating Sil format unbuiltCheckCodeByte2: CHAR ~ 'r; builtCheckCodeByte2: CHAR ~ 's; largeFormatFileByte2: CHAR ~ 'l; -- new password for large format files SilBlockRef: TYPE ~ REF SilBlock; LargeSilBlockRef: TYPE ~ REF LargeSilBlock; --new format for large format files SilBlock: TYPE ~ MACHINE DEPENDENT RECORD [ leftChar, rightChar: CHAR, state : FourBits, xMin : TwelveBits, yMin : SixteenBits, color : FourBits, xMax : TwelveBits, font : FourBits, italic : OneBit, yMax : ElevenBits ]; LargeSilBlock: TYPE ~ MACHINE DEPENDENT RECORD [ leftChar, rightChar: CHAR, xMin: INTEGER, yMin: INTEGER, xMax: INTEGER, yMax: INTEGER, color: FourBits, font: FourBits, italic: OneBit, pad: SevenBits _ 0 ]; <> TrueFonts: TYPE ~ [0..3]; MainFile: TYPE ~ [4..4]; <> SilFile: TYPE ~ [4..9]; InternalFonts: TYPE ~ [0..15]; <> InternalFileMacroFonts: TYPE ~ [8..8]; InternalTrueFonts: TYPE ~ [0..7]; InternalLibraryFile: TYPE ~ [9..13]; InternalRopeFonts: TYPE ~ [0..13]; -- those fonts which do not denote boxes. See below <> InternalForegroundBoxFonts: TYPE ~ [14..14]; InternalBackgroundBoxFonts: TYPE ~ [15..15]; mainFile: MainFile ~ 4; <> <> <> Color: TYPE ~ [0..15]; colorTable: ARRAY Color OF CD.Layer ~ [CDSil.xneutral, CDSil.xred, CDSil.xyellow, CDSil.xgreen, CDSil.xcyan, CDSil.xviolet, CDSil.xmagenta, CDSil.xwhite, CDSil.xbrown, CDSil.xorange, CDSil.xlime, CDSil.xturquise, CDSil.xaqua, CDSil.xultraviolet, CDSil.xpink, CDSil.xsmoke]; neutralColor: Color ~ 0; <> Font: TYPE ~ RECORD [ name: Rope.ROPE, descr: REF CDTexts.FontRec _ NIL ]; cellFonts: ARRAY InternalTrueFonts OF ARRAY BOOL OF Font; <> ObjectName: TYPE ~ CHAR[' .. '~]; -- Only printing characters are used MacroName: TYPE ~ CHAR['! .. '~]; -- All but mainObject: ObjectName ~ ' ; -- object whose name is SilObject: TYPE ~ RECORD [ xMin, yMin: INTEGER, -- Upper Left boundary of box or string xMax, yMax: INTEGER, -- Lower right boundary of box, guess for lower right of string color: Color, -- Color used to display or print silobject font: InternalFonts, italic: BOOL, -- Only interesting for Ropes (fonts 0-13), TRUE for italic strings value: Rope.ROPE _ NIL ]; SilObjectList: TYPE ~ LIST OF SilObject; Macro: TYPE ~ RECORD [ xMin, yMin: INTEGER _ 32767, -- Upper Left boundary of macro definition xMax, yMax: INTEGER _ -1, -- Lower right boundary of macro definition << note: coordinates are Alto screen absolute, hence -1 is OK.>> objects: SilObjectList _ NIL, cdCellPtr: CD.Object _ NIL -- This field used to generate recursion if a cell includes a cell not known yet. ]; LibraryDesign: TYPE ~ RECORD [ data: CD.Design _ NIL, imported: BOOL _ FALSE, -- Chipndale wants only a single import of the same library written: BOOL _ FALSE -- libraries are written only once per run ]; MacroPtr: TYPE ~ REF Macro _ NIL; MacroFile: TYPE ~ ARRAY ObjectName OF MacroPtr; allMacros: REF MacroFile _ NIL; coloredMacros: ARRAY Color OF CD.Object; -- the other stuff is in the neutral macro record silDesigns: ARRAY SilFile OF LibraryDesign; -- need all because of imports background: ATOM = $SilBackground; silProfilePrefix: Rope.ROPE ~ "Sil.Font"; cdSilProfilePrefix: Rope.ROPE ~ "Chipndale.chipnsil.Library"; lambda: INTEGER = CDSil.cdsil.lambda; -- Sil uses integers throughout lambdaAltoScreenHeights: INTEGER ~ lambda * 808; <> CrackNames: PROC [genericName: Rope.ROPE] RETURNS [fullSilName: Rope.ROPE, properName: Rope.ROPE] ~ { <> namePos: FS.ComponentPositions; silExtension: Rope.ROPE ~ "Sil"; dummy: Rope.ROPE; -- in Cedar 5.2 FS.ExpandName does not work as documented fullSilName _ CDIO.MakeName [base: genericName, ext: silExtension, wDir: FileNames.CurrentWorkingDirectory[]]; [fullFName: dummy, cp: namePos] _ FS.ExpandName [name: fullSilName]; properName _ Rope.Substr [base: dummy, start: namePos.base.start, len: namePos.base.length] }; -- end CrackNames <> FlushLibraries: UserProfile.ProfileChangedProc ~ BEGIN <> FOR lib: LibraryFile IN LibraryFile DO silDesigns[lib].data _ NIL; silDesigns[lib].imported _ FALSE ENDLOOP END; -- FlushLibraries <> TechnologyIsCdsil: PROC [d: TokenIO.Handle] RETURNS [BOOL] ~ { IF d = NIL THEN CD.Error [explanation: "Programming error in ReadSilLibrary"]; RETURN [CDIO.DesignInReadOperation[d].technology = CDSil.cdsil] }; -- end TechnologyIsCdsil <> ReadSilModel: PUBLIC PROC [name: Rope.ROPE] RETURNS [design: CD.Design _ NIL] ~ { <> designName: Rope.ROPE; write: BOOL _ NOT verbose; [fullSilName: name, properName: designName] _ CrackNames [name]; IF convLibEachTime THEN FlushLibraries [edit]; design _ CDOps.CreateDesign [technology: CDSil.cdsil]; design.name _ designName; silDesigns[mainFile].data _ design; ReadSilFile [fileName: name]; ConvertSilFile [file: mainFile]; IF verbose THEN write _ TerminalIO.Confirm [text: "CDSilConversion", help: Rope.Cat["Write ", designName, " to disk ?"]]; IF write THEN IF NOT CDIO.WriteDesign [design: design, to: designName] THEN TerminalIO.PutRope [Rope.Cat["Warning: The design ", designName, " cannot be written. Proceeding anyway.\n"]]; [] _ CDViewer.CreateViewer [design: design]; }; -- end ReadSilModel <> ReadSilLibrary: PUBLIC PROC [library: LibraryFile] RETURNS [cells: CD.Design _ NIL] ~ { <> libraryPrefix: Rope.ROPE ~ "sil.lb"; -- Cedar Sil designPrefix: Rope.ROPE ~ "SilLib"; -- Chipnsil macroFileName, cdFileName, defaultName, designName: Rope.ROPE; key: Rope.ROPE; -- Access key for the User Profile. write: BOOL _ NOT verbose; <> IF silDesigns[library].data # NIL THEN RETURN [silDesigns[library].data]; <> key _ Rope.Concat [cdSilProfilePrefix, Rope.FromChar['0 + library]]; defaultName _ Rope.Cat [designPrefix, Rope.FromChar['0 + library], ".dale"]; cdFileName _ UserProfile.Token [key: key, default: defaultName]; designName _ CrackNames [cdFileName].properName; <> key _ Rope.Concat [silProfilePrefix, Rope.FromChar['0 + library]]; defaultName _ Rope.Concat [libraryPrefix, Rope.FromChar['0 + library]]; macroFileName _ UserProfile.Token [key: key, default: defaultName]; IF NOT convLibEachTime THEN BEGIN <> cells _ CDIO.ReadDesign [from: cdFileName, check: TechnologyIsCdsil]; IF cells # NIL THEN {silDesigns[library].data _ cells; RETURN [cells]} ELSE TerminalIO.PutRope [Rope.Cat["The library file ", cdFileName, " is not available. It is being converted from ", macroFileName, "\n"]]; END; -- NOT convLibEachTime <> ReadSilFile [fileName: macroFileName]; cells _ CDOps.CreateDesign[technology: CDSil.cdsil]; cells.name _ designName; silDesigns[library].data _ cells; ConvertSilFile [file: library]; <> IF verbose THEN write _ TerminalIO.Confirm [text: "CDSilConversion", help: Rope.Cat ["Write ", designName, " to disk ?"]]; IF write THEN { IF NOT silDesigns[library].written THEN { silDesigns[library].written _ CDIO.WriteDesign [design: cells, to: cdFileName]; IF NOT silDesigns[library].written THEN TerminalIO.PutRope [Rope.Cat["Warning: The design ", designName, " cannot be written. Proceeding anyway.\n"]] } }; -- IF write RETURN [cells] }; -- end ReadSilLibrary SetFonts: UserProfile.ProfileChangedProc ~ { <> key: Rope.ROPE; -- Access key for the User Profile. TrueFontsDefaults: TYPE ~ ARRAY TrueFonts OF Rope.ROPE; trueFontsDefaults: TrueFontsDefaults ~ ["Helvetica10", "Helvetica7", "Template64", "Gates32"]; italic: BOOL ~ TRUE; FixAttibutes: PROC [coarseName: Rope.ROPE] RETURNS [notBold, italic, both: Rope.ROPE] ~ { <> properName, dummy, attributes, notBAttr: Rope.ROPE; namePos: FS.ComponentPositions; attributePos, bPos: INTEGER; alreadyItalic: BOOL; [fullFName: dummy, cp: namePos] _ FS.ExpandName [name: coarseName]; properName _ Rope.Substr [base: dummy, start: namePos.base.start, len: namePos.base.length]; attributePos _ properName.SkipTo [0, "0123456789"]; attributes _ properName.Substr [attributePos, properName.Length[]-attributePos]; <> bPos _ attributes.SkipTo [0, "bB"]; IF bPos = attributes.Length[] THEN notBAttr _ Rope.Concat [attributes, "B"] ELSE notBAttr _ Rope.Replace [base: attributes, start: bPos, len: 1]; <> alreadyItalic _ (attributes.SkipTo [0, "iI"] # attributes.Length []); IF NOT alreadyItalic THEN attributes _ Rope.Concat [attributes, "I"]; <> notBold _ Rope.Replace [base: properName, start: attributePos, len: properName.Length[]-attributePos, with: notBAttr]; italic _ Rope.Replace [base: properName, start: attributePos, len: properName.Length[]-attributePos, with: attributes]; IF alreadyItalic THEN both _ notBold ELSE { notBAttr _ Rope.Concat [notBAttr, "I"]; both _ Rope.Replace [base: properName, start: attributePos, len: properName.Length[]-attributePos, with: notBAttr] }; IF debug4 THEN { TerminalIO.PutRope [Rope.Cat["Original font: ", coarseName, ", notBold: "]]; TerminalIO.PutRope [Rope.Cat[notBold, ", italic: ", italic]]; TerminalIO.PutRope [Rope.Cat[", both: ", both, "\n"]]; } }; -- end FixAttibutes FOR i: TrueFonts IN TrueFonts DO <> key _ Rope.Concat [silProfilePrefix, Rope.FromChar ['0 + i]]; cellFonts[2*i][~italic].name _ UserProfile.Token [key: key, default: trueFontsDefaults[i]]; [cellFonts[2*i+1][~italic].name, cellFonts[2*i][italic].name, cellFonts[2*i+1][italic].name] _ FixAttibutes [cellFonts[2*i][~italic].name] ENDLOOP }; -- end SetFonts MakeCDFont: PROC [nr: InternalTrueFonts, italic: BOOL] ~ { fullName: Rope.ROPE; fullName _ Rope.Cat ["Xerox/TiogaFonts/", cellFonts[nr][italic].name]; <> cellFonts[nr][italic].descr _ CDTexts.MakeFont [name: fullName, scale: lambda]; IF cellFonts[nr][italic].descr = NIL THEN { TerminalIO.PutRope [Rope.Cat["CDTexts.MakeFont returns not found on ", fullName, ". Fatal error.\n"]]; ERROR ABORTED } }; -- end MakeCDFont ConvertSilFile: PROC [file: SilFile] ~ { <> MacroToObject: PROC [sil: MacroPtr, name: ObjectName] RETURNS [object: CD.Object _ NIL] ~ { <> size, position: CD.Position _ [0, 0]; topLeftPos: CD.Position _ [0, 0]; cdObPtr: CD.Object _ NIL; -- object before it is either a cell or an application cell: CD.Object _ NIL; -- NIL when object is not a cell boundingBox: CD.Rect; -- interesting rectangle height: INTEGER _ 0; -- height of cell or main object import, workingOnMainObject: BOOL; impName: Rope.ROPE; -- global importee name assigned in FOR loop and used in the recursion ColoredMacro: PROC [name: ObjectName, color: Color _ neutralColor] RETURNS [colored: CD.Object] ~ BEGIN <> <> <> <> ColorContents: CDCells.InstEnumerator = BEGIN <> IF ((inst.ob.class.objectType = $Rect) OR (CDTexts.IsText [inst.ob])) THEN [] _ inst.ob.class.newLayer [inst, colorTable[color]] END; -- ColorContents IF (color = neutralColor) THEN BEGIN IF (allMacros[name].cdCellPtr = NIL) THEN BEGIN IF debug1 THEN TerminalIO.PutRope [IO.PutFR [" will prepone macro %g\n", IO.char[name]]]; RETURN [MacroToObject [allMacros[name], name]] END ELSE RETURN [allMacros[name].cdCellPtr] END; IF (coloredMacros[color] # NIL) THEN colored _ coloredMacros[color] ELSE BEGIN -- This is the real stuff design: CD.Design ~ silDesigns[mainFile].data; topMode, childMode: CDDirectory.DMode; coloredName: Rope.ROPE ~ IO.PutFR [format: "%g-%g", v1: IO.char[name], v2: IO.atom[CD.LayerKey[colorTable[color]]]]; IF (allMacros[name].cdCellPtr = NIL) THEN BEGIN IF debug1 THEN TerminalIO.PutRope [IO.PutFR [" will prepone macro %g\n", IO.char[name]]]; [] _ MacroToObject [allMacros[name], name] <> END; <> [colored, topMode, childMode] _ CDDirectory.Another [me: allMacros[name].cdCellPtr, fromOrNil: design, into: design, friendly: TRUE]; <> IF ((colored = NIL) OR (topMode # ready) OR (colored = allMacros[name].cdCellPtr) OR (NOT CDDirectory.Include [design, colored, coloredName]) OR ((childMode = immutable) AND (NOT CDDirectory.FixChildren [colored, design]))) THEN BEGIN TerminalIO.PutRope [IO.PutFR ["Failed to color macro %g\n", IO.char[name]]]; colored _ allMacros[name].cdCellPtr END ELSE BEGIN <> [] _ CDCells.EnumerateInstances [colored, ColorContents]; coloredMacros[color] _ colored END END END; -- ColoredMacro ExpansionWrapping: PROC [rope: Rope.ROPE, color: Color _ neutralColor] = BEGIN <> ExpandRope: PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] ~ { <> cdObPtr: CD.Object; -- object before it is either a cell or an instance sz, pos: CD.Position; IF import THEN BEGIN <> cdObPtr _ CDImports.CreateImport [into: silDesigns[file].data, objectName: Rope.FromChar[c], importeeName: impName]; IF cdObPtr = NIL THEN CD.Error [ec: other, explanation: "CDImports.CreateImport failed"]; <> END ELSE -- not import: file macro <> cdObPtr _ ColoredMacro [c, color]; sz _ CD.InterestSize [cdObPtr]; pos _ [topLeftPos.x, topLeftPos.y-sz.y]; topLeftPos.x _ topLeftPos.x + sz.x; [] _ CDCells.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, trans: [pos], mode: dontNotify]; }; -- end ExpandRope [] _ Rope.Map [base: rope, action: ExpandRope] END; -- ExpansionWrapping workingOnMainObject _ (name = ' ); height _ IF workingOnMainObject THEN lambdaAltoScreenHeights ELSE lambda * (sil.yMax - sil.yMin); boundingBox _ [x1: lambda*sil.xMin, y1: height - lambda*sil.yMax, x2: lambda*sil.xMax, y2: height - lambda*sil.yMin]; IF workingOnMainObject THEN cell _ NIL ELSE { ir: CD.Rect _ [x1: lambda*sil.xMin, y1: height - lambda*sil.yMax, x2: lambda*sil.xMax, y2: height - lambda*sil.yMin]; cell _ CDCells.CreateEmptyCell []; CDCells.SetInterestRect [silDesigns[file].data, cell, ir]; <> <> }; FOR silObj: SilObjectList _ sil.objects, silObj.rest WHILE silObj # NIL DO size.x _ lambda * (silObj.first.xMax - silObj.first.xMin); size.y _ lambda * (silObj.first.yMax - silObj.first.yMin); topLeftPos.x _ position.x _ lambda * silObj.first.xMin; position.y _ height - lambda * silObj.first.yMax; topLeftPos.y _ height - lambda * silObj.first.yMin; SELECT silObj.first.font FROM IN InternalTrueFonts => { cdFont: REF CDTexts.FontRec; er: ImagerFont.Extents; IF (cellFonts[silObj.first.font][silObj.first.italic].descr = NIL) THEN MakeCDFont [silObj.first.font, silObj.first.italic]; cdFont _ cellFonts[silObj.first.font][silObj.first.italic].descr; cdObPtr _ CDTexts.Create [text: silObj.first.value, font: cdFont, layer: colorTable[silObj.first.color]]; IF cdObPtr = NIL THEN CD.Error [ec: other, explanation: "Cannot create text"]; <> <> er _ ImagerFont.RopeBoundingBox [cdFont.font, silObj.first.value]; position.y _ height - lambda * silObj.first.yMin - Real.Round[er.ascent] - cdFont.origin.y; [] _ CDCells.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, trans: [position], mode: dontNotify] }; IN InternalFileMacroFonts => { IF debug1 THEN TerminalIO.PutRope [IO.PutFR ["%g calls a cell in the same design:\n", IO.char [name]]]; import _ FALSE; ExpansionWrapping [rope: silObj.first.value, color: silObj.first.color] }; IN InternalLibraryFile => { <> externalFileNr: LibraryFile; -- Since the exported procedure works with the external library file numbering, we cannot use the internal Sil numbering when we call our procedures. IF debug1 THEN TerminalIO.PutRope ["Import of a cell in another design.\n"]; externalFileNr _ silObj.first.font - mainFile; IF (silDesigns[externalFileNr].data = NIL) THEN [] _ ReadSilLibrary [externalFileNr]; IF NOT silDesigns[externalFileNr].imported THEN { silDesigns[externalFileNr].imported _ CDImports.Load[into: silDesigns[file].data, importeeName: silDesigns[externalFileNr].data.name]; IF NOT silDesigns[externalFileNr].imported THEN IF file IN MainFile THEN CD.Error [ec: other, explanation: "Cannot import library"] ELSE CD.Error [ec: other, explanation: "Library tried to import other library"] }; impName _ silDesigns[externalFileNr].data.name; -- assigned to a global variable, so that it can be used in the recursion import _ TRUE; ExpansionWrapping [rope: silObj.first.value, color: silObj.first.color] }; IN InternalForegroundBoxFonts => { cdObPtr _ CDRects.CreateRect [size: size, l: colorTable[silObj.first.color]]; [] _ CDCells.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, trans: [position], mode: dontNotify] }; IN InternalBackgroundBoxFonts => { <> cdObPtr _ CDRects.CreateRect [size: size, l: colorTable[silObj.first.color]]; CDProperties.PutObjectProp [onto: cdObPtr, prop: background, val: background]; [] _ CDCells.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, trans: [position], mode: dontNotify] }; ENDCASE => CD.Error [explanation: "Invalid case in CDSilConversionImpl.MacroToObject"] ENDLOOP; IF NOT workingOnMainObject THEN { CDCells.SetInterestRect [silDesigns[file].data, cell]; [] _ CDDirectory.Include [design: silDesigns[file].data, object: cell, alternateName: Rope.FromChar[name]]; }; object _ IF workingOnMainObject THEN cdObPtr ELSE cell; sil.cdCellPtr _ object; sil.objects _ NIL; -- dispose obsolete space IF debug1 THEN TerminalIO.PutRope [IO.PutFR ["Converted object: %g\n", IO.char[name]]]; RETURN [object] }; -- end MacroToObject <> FOR obj: MacroName IN MacroName DO IF ((allMacros[obj] # NIL) AND (allMacros[obj].cdCellPtr = NIL)) THEN <> [] _ MacroToObject [allMacros[obj], obj] ENDLOOP; IF ((allMacros[mainObject] # NIL) AND (allMacros[mainObject].cdCellPtr = NIL)) THEN <> [] _ MacroToObject [allMacros[mainObject], mainObject]; IF debugAll THEN TerminalIO.PutRope ["Sil macro file converted to Chipndale model.\n"] }; -- end ConvertSilFile ReadSilFile: PROC [fileName: Rope.ROPE] ~ { <> sBlock: SilBlockRef _ NEW [SilBlock]; largesBlock: LargeSilBlockRef _ NEW [LargeSilBlock]; largeFormat: BOOL _ FALSE; block: LONG POINTER _ NIL; -- either sBlock or largesBlock bytesInSilItemBlock: INTEGER; -- depends on above AddItemBlockToMacro: PROC [itemBlock: SilObject, name: CHAR] ~ { m: MacroPtr _ allMacros[name]; IF m = NIL THEN m _ NEW [Macro]; <> m.xMin _ MIN [m.xMin, itemBlock.xMin]; m.yMin _ MIN [m.yMin, itemBlock.yMin]; m.xMax _ MAX [m.xMax, itemBlock.yMax]; m.yMax _ MAX [m.yMax, itemBlock.yMax]; <> m.objects _ CONS [itemBlock, m.objects]; allMacros[name] _ m }; -- end AddItemBlockToMacro ReadItemBlock: PROC [s: IO.STREAM] RETURNS [name: CHAR, itemBlock: SilObject] ~ { <> ENABLE IO.EndOfStream => CD.Error [ec: other, explanation: "Unexpected End Of Stream"]; ReadChar: PROC[] RETURNS [c: CHAR] ~ { <> RETURN [s.GetChar[] ]; }; -- end ReadChar <<>> <
> maxRecLen: INTEGER ~ 256; --the longest a record can be (1 byte for its length) len: INTEGER; TRUSTED BEGIN bytesGot: INT _ s.UnsafeGetBlock [ [base: block, startIndex: 0, count: bytesInSilItemBlock]]; IF bytesGot # bytesInSilItemBlock THEN CD.Error [ec: other, explanation: "Macro file corrupted"] END; IF largeFormat THEN BEGIN name _ IF largesBlock.leftChar = mainElementName THEN ' ELSE largesBlock.rightChar; <> <> itemBlock.xMin _ largesBlock.xMin; itemBlock.yMin _ largesBlock.yMin; itemBlock.xMax _ largesBlock.xMax; itemBlock.yMax _ largesBlock.yMax; itemBlock.color _ largesBlock.color; itemBlock.font _ largesBlock.font; itemBlock.italic _ (largesBlock.italic = 1) END ELSE BEGIN name _ IF sBlock.leftChar = mainElementName THEN ' ELSE sBlock.rightChar; <> <> itemBlock.xMin _ sBlock.xMin; itemBlock.yMin _ sBlock.yMin; itemBlock.xMax _ sBlock.xMax; itemBlock.yMax _ sBlock.yMax; itemBlock.color _ sBlock.color; itemBlock.font _ sBlock.font; itemBlock.italic _ (sBlock.italic = 1) END; IF debug0 THEN { TerminalIO.PutRope [IO.PutFR ["\n%g%g", IO.char[name], IO.int[ORD[name]]]]; {OPEN itemBlock; TerminalIO.PutRope [IO.PutFR [": xMin = %g, yMin = %g, xMax = %g, yMax = %g. ", IO.int[xMin], IO.int[yMin], IO.int[xMax], IO.int[yMax]]]; TerminalIO.PutRope [IO.PutFR ["Color = %g. Font = %g", IO.int[color], IO.int[font]]]; IF color # 0 THEN TerminalIO.PutRope ["***"]; IF NOT italic THEN TerminalIO.PutRope [", not"]; TerminalIO.PutRope [" italic "] } }; IF itemBlock.font IN InternalRopeFonts THEN { len _ s.GetChar[] - 0C; itemBlock.value _ Rope.FromProc [len, ReadChar, maxRecLen]; IF debug0 THEN TerminalIO.PutRope [itemBlock.value]; IF len MOD 2 = 0 THEN --Make sure to start next item block on a word boundary [] _ s.GetChar[]; --Flush the extra slot for a Char } }; -- end ReadItemBlock BEGIN header1, header2: CHAR; name: CHAR; itemBlock: SilObject; s: IO.STREAM _ FS.StreamOpen [fileName ! FS.Error => IF error.group#bug THEN ERROR fileNotFound [error.explanation]]; IF debugAll THEN {TerminalIO.PutRope [fileName]; TerminalIO.PutRope ["\n"]}; header1 _ s.GetChar[]; header2 _ s.GetChar[]; IF (header1 # checkCodeByte1) THEN ERROR fileNotFound ["File not in Sil format"]; SELECT header2 FROM unbuiltCheckCodeByte2 => IF debugAll THEN TerminalIO.PutRope ["Sil file format OK.\n"]; builtCheckCodeByte2 => TerminalIO.PutRope ["Sil schematic file has been 'build' into a wire-list file via the Build process.\n"]; largeFormatFileByte2 => largeFormat _ TRUE; ENDCASE => ERROR fileNotFound ["File not in Sil format"]; TRUSTED {block _ IF largeFormat THEN LOOPHOLE [largesBlock] ELSE LOOPHOLE [sBlock]}; bytesInSilItemBlock _ IF largeFormat THEN SIZE [LargeSilBlock] * Basics.bytesPerWord ELSE SIZE [SilBlock] * Basics.bytesPerWord; allMacros _ NEW [MacroFile]; WHILE NOT s.EndOf[] DO [name, itemBlock] _ ReadItemBlock [s]; <> AddItemBlockToMacro [itemBlock, name] <> ENDLOOP; IO.Close[s] END }; -- end ReadSilFile ReadModel: Commander.CommandProc = BEGIN ENABLE BEGIN TerminalIO.UserAbort => {msg _ "user abort"; GOTO failure}; fileNotFound => {msg _ reason; GOTO failure} END; list: LIST OF Rope.ROPE; length: NAT; name: Rope.ROPE; [list, length] _ CommandTool.ParseToList [cmd]; IF length = 1 THEN name _ list.first ELSE BEGIN result _ $Failure; msg _ "unknown arguments"; TerminalIO.PutRope [msg.Cat ["\n"]]; RETURN END; IF convLibEachTime THEN TerminalIO.PutRope ["\nAll libraries will be converted as they are referenced.\n"] ELSE TerminalIO.PutRope ["\nIf they exist, the libraries specified in the user profile entries 'ChipNDale.ChipNSil.Library%' will be used. Delete them to force the creation of new ones.\n"]; [] _ ReadSilModel [name]; msg _ name.Concat [" converted to ChipNDale"]; <> FOR color: Color IN Color DO coloredMacros[color] _ NIL ENDLOOP; <> <> <<[] _ CDViewer.CreateViewer [design: synopsis]; CDOps.Redraw [synopsis] -- optional>> EXITS failure => {result _ $Failure; TerminalIO.PutRope [msg.Concat ["\n"]]} END; <> UserProfile.CallWhenProfileChanges [SetFonts]; UserProfile.CallWhenProfileChanges [FlushLibraries]; IF NOT CDProperties.RegisterProperty [prop: background, registrationKey: $GBB] THEN TerminalIO.PutRope ["CDSilConversionImpl re-executed"]; -- somebody is already using it Commander.Register [key: "CDReadSil", proc: ReadModel, doc: "Read a SIL model into ChipNSil and save it."] END. <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>>