ChipmonkPatterns.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
by Ch. Jacobi, October 22, 1984 12:22:09 pm PDT
last edited Christian Jacobi, May 28, 1985 5:06:22 pm PDT
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 =
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𡤀
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<colPatRead+2
THEN {
FOR j: [0..15]
IN [0..15]
DO
TeachColorCode[layerTable[j], colPatternTabs[i-2][j]]
ENDLOOP;
done ← TRUE
}
ELSE
IF i=1
THEN {
FOR j: [0..15]
IN [0..15]
DO
TeachColorCode[layerTable[j], orLTab[j]];
ENDLOOP;
done ← TRUE
}
ELSE IF i=0 THEN TerminalIO.WriteRope["Resetting default not with this command\n"]
ELSE TerminalIO.WriteRope["pattern not found\n"];
IF done
THEN {
RepaintViewers[];
};
END;
RepaintViewers:
PROC [] =
BEGIN
FOR tList:
LIST
OF
CD.Technology ← techList, tList.rest
WHILE tList#
NIL
DO
FOR l: CDViewer.ViewerList ← CDViewer.ViewersOf[tList.first], l.rest
WHILE l#
NIL
DO
IF l.first.column=color THEN ViewerOps.PaintViewer[l.first, client]
ENDLOOP;
ENDLOOP
END;
CMPatternCommand: Commander.CommandProc =
BEGIN
patNum: INT ← -1;
patFile: Rope.ROPE ← NIL;
InitATechnology[CD.FetchTechnology[$nmos]];
InitATechnology[CD.FetchTechnology[$cmos]];
IF cmd#
NIL
THEN {
s: IO.STREAM ~ IO.RIS[cmd.commandLine];
DO
token: Rope.ROPE ← IO.GetTokenRope[s ! IO.EndOfStream => 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];
CDColors.DefineColor[list.first, NEW[Brick←GetChipmonkMaskGrey[code]], bit4, grey];
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],
The pattern
-- .*..
-- .*..
-- ...*
-- ...*
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.combined 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[$snerd, 7];
Entry[$cut2, 8];
Entry[$pdif, 9];
Entry[$pwelCont, 10];
Entry[$met2, 11];
Entry[$pwel, 12];
Entry[$nwel, 13];
Entry[$nwelCont, 14];
Entry[$NOcOL, 15];
END;
ColorPatterns: CDSequencer.CommandProc = {[] ← CMPatternCommand[NIL]};
Commander.Register[
key: "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.