<> <> <> <> DIRECTORY Basics, CD, CDColors, CDIO, CDMenus, CDSequencer, CDViewer, Commander USING [CommandProc, Register], Convert, FS, IO, Rope, TerminalIO, UserProfile, ViewerOps; ChipmonkPatterns: CEDAR MONITOR IMPORTS Basics, CD, CDColors, CDIO, CDMenus, CDSequencer, CDViewer, Commander, Convert, IO, FS, Rope, TerminalIO, UserProfile, ViewerOps = BEGIN Brick: TYPE = CDColors.Brick; layer: TYPE = [0..15]; LayerTable: TYPE = ARRAY layer OF LIST OF CD.Layer; techList: LIST OF CD.Technology _ NIL; layerTable: REF LayerTable = NEW[LayerTable_ALL[NIL]]; InitPatternsFromProfile: PROC [comm: CDSequencer.Command] = <<--for this procedure comm is completely ignored and may be NIL>> BEGIN patNo: INT _ UserProfile.Number[key: "ChipNDale.ChipmonkColorPatternNum", default: 0]; IF patNo#0 THEN { ReadPatternFile[]; SetChipmonkPatterns[patNo] } END; colPatNum: CARDINAL=8; colPatRead: CARDINAL_0; colPatternTabs: ARRAY [0..colPatNum) OF ARRAY layer OF CARDINAL; colPatternBits: ARRAY [0..colPatNum) OF CARDINAL; orLTab: ARRAY layer OF CARDINAL _ [11B, 1, 4, 2, 76B, 8, 33B, 10, 9, 1, 10, 62B, 10, 8, 10, 10]; SetChipmonkPatterns: PROC [i: INT] = BEGIN done: BOOL _ FALSE; IF i<0 THEN { FOR j: NAT IN [0..colPatRead) DO IF colPatternBits[j]=(-i) THEN {i_j; EXIT} ENDLOOP }; IF i>=2 AND i EXIT].token; IF Rope.IsEmpty[token] THEN EXIT; IF Rope.Fetch[token, 0] IN ['0..'9] THEN { patNum _ Convert.IntFromRope[token ! Convert.Error => EXIT]; } ELSE IF Rope.Fetch[token, 0]='* THEN { InitPatternsFromProfile[NIL]; RETURN } ELSE patFile _ CDIO.MakeName[token, "CDColorPatterns"]; ENDLOOP; }; IF colPatRead=0 OR NOT Rope.IsEmpty[patFile] THEN ReadPatternFile[patFile]; IF patNum<0 THEN { TerminalIO.WriteRope["type color pattern; [ <="]; TerminalIO.WriteInt[colPatRead+1]; TerminalIO.WriteRope["]; (on default file often used: cmos: 3, nmos: 2) > "]; patNum _ TerminalIO.RequestInt["" ! TerminalIO.UserAbort => GOTO UserAbort]; }; SetChipmonkPatterns[patNum] EXITS UserAbort => {NULL}; END; ReadPatternFile: PROC[fileName: Rope.ROPE _ NIL] = BEGIN binfile: IO.STREAM; k, i, lv: CARDINAL; GetByte: PROC [] RETURNS[c: [0..255]] = INLINE { c _ LOOPHOLE[IO.GetChar[binfile], [0..255]]; }; Get2Bytes: PROC [] RETURNS [c: CARDINAL] = INLINE { h: [0..255] = GetByte[]; c _ h*256+GetByte[]; }; IF Rope.IsEmpty[fileName] THEN fileName _ UserProfile.Token[ key: "ChipNDale.ChipmonkColorPatterns", default: "default.CDColorPatterns" ]; fileName _ CDIO.MakeName[base: fileName, ext: "CDColorPatterns", wDir: CDIO.GetWorkingDirectory[NIL]]; binfile _ FS.StreamOpen[fileName ! FS.Error => IF error.group # bug THEN { TerminalIO.WriteRope[fileName]; TerminalIO.WriteRope[" not opened: "]; TerminalIO.WriteRope[error.explanation]; TerminalIO.WriteLn[]; GOTO FileName }]; k _ MIN[colPatNum, Get2Bytes[]]; colPatRead _ 0; FOR i IN [0..k) DO colPatternBits[i]_Get2Bytes[]; FOR lv IN layer DO colPatternTabs[i][lv]_Get2Bytes[]; ENDLOOP; ENDLOOP; colPatRead_k; IO.Close[binfile]; EXITS FileName => {NULL}; END; TeachColorCode: PROC[layers: LIST OF CD.Layer, code: CARDINAL] = <<--sets value into the default Color- and GreyTable >> BEGIN FOR list: LIST OF CD.Layer _ layers, list.rest WHILE list#NIL DO CDColors.DefineColor[list.first, NEW[Brick_GetChipmonkColor[code]], bit4]; <> ENDLOOP END; GetChipmonkColor: PROC [c: CARDINAL] RETURNS [Brick] = TRUSTED BEGIN IF c>255 THEN { --two colors in alteration combin: CARDINAL = Basics.BITAND[c, 255]; pat1: CARDINAL = combin+Basics.BITSHIFT[combin, 8]; pat2: CARDINAL = Basics.BITOR[Basics.BITSHIFT[pat1, 4], Basics.BITSHIFT[pat1, -4]]; RETURN [[pat1, pat2, pat1, pat2]] } ELSE { pixCol: CARDINAL = Basics.BITAND[15, c]; halfcw: CARDINAL = Basics.BITOR[Basics.BITSHIFT[pixCol, 4], pixCol]; cw: CARDINAL = Basics.BITOR[Basics.BITSHIFT[halfcw, 8], halfcw]; <<--pixCol replicated 4 times>> SELECT c-pixCol FROM 0 => RETURN[ALL[cw]]; -- every pixel set to pixCol ENDCASE => { m: Brick _ GetChipmonkMaskGrey[c]; FOR i: [0..4) IN [0..4) DO m[i] _ Basics.BITAND[m[i], cw] ENDLOOP; RETURN [m] } } END; GetChipmonkMaskGrey: PROC [c: CARDINAL] RETURNS [Brick] = TRUSTED BEGIN pixCol: [0..16) = Basics.BITAND[15, c]; RETURN [SELECT c-pixCol FROM 16 => [7400B, 7400B, 17B, 17B], <> <<-- .*..>> <<-- .*..>> <<-- ...*>> <<-- ...*>> 32 => [7417B, 170360B, 7417B, 170360B], <<-- .*.*>> <<-- *.*.>> <<-- .*.*>> <<-- *.*.>> 48 => [7400B, 7400B, 0, 0], <<-- .*..>> <<-- .*..>> <<-- ....>> <<-- ....>> 64 => [170377B, 177760B, 170377B, 177760B], <<-- *.**>> <<-- ***.>> <<-- *.**>> <<-- ***.>> ENDCASE => ALL[177777B] -- all bits --]; END; InitATechnology: ENTRY PROC [tech: CD.Technology] = BEGIN Entry: PROC[key: ATOM, number: NAT] = BEGIN lev: CD.Layer _ CD.FetchLayer[tech, key]; IF lev#CD.undefLayer THEN layerTable[number] _ CONS[lev, layerTable[number]] END; IF tech=NIL THEN RETURN; FOR tList: LIST OF CD.Technology _ techList, tList.rest WHILE tList#NIL DO IF tList.first=tech THEN RETURN ENDLOOP; techList _ CONS[tech, techList]; Entry[$cut, 0]; Entry[$dif, 1]; Entry[$ndif, 1]; Entry[$pol, 2]; Entry[$met, 3]; Entry[$imp, 4]; Entry[$imp0, 4]; Entry[$impWeak, 4]; Entry[$ovg, 5]; Entry[$bur, 6]; <> Entry[$cut2, 8]; Entry[$pdif, 9]; Entry[$pwelCont, 10]; Entry[$met2, 11]; Entry[$pwel, 12]; Entry[$nwel, 13]; Entry[$nwelCont, 14]; <> END; ColorPatterns: CDSequencer.CommandProc = {[] _ CMPatternCommand[NIL]}; Commander.Register[ key: "///Commands/CDPatterns", proc: CMPatternCommand, doc: "Read ChipNDale color patterns" ]; InitATechnology[CD.FetchTechnology[$nmos]]; InitATechnology[CD.FetchTechnology[$cmos]]; InitPatternsFromProfile[NIL]; CDSequencer.ImplementCommand[$InitColorPatternsFromProfile, InitPatternsFromProfile,, doQueue]; CDSequencer.ImplementCommand[$ColorPatterns, ColorPatterns,, doQueue]; CDMenus.CreateEntry[$DisplayMenu, "type cm pattern", $ColorPatterns]; CDMenus.CreateEntry[$DisplayMenu, "profile cm pattern", $InitColorPatternsFromProfile]; END.