DIRECTORY Basics USING [LongDiv, LongMult], ColorDisplayD0 USING [ColorCSB, colorDisplayController, ColorTable], ColorDisplayDefs USING [ChannelsVisible, ChannelValue, ColorDisplayType, ColorMode, ColorValue], ColorDisplayFace USING [nullMode], D0InputOutput USING [ControllerNumber, GetNextController, IOPage, nullControllerNumber, Output], DeviceCleanup USING [Await, Item, Reason], ProcessorFace USING [GetClockPulses, microsecondsPerHundredPulses]; ColorDisplayHeadD0: PROGRAM IMPORTS Basics, D0InputOutput, DeviceCleanup, ProcessorFace EXPORTS ColorDisplayFace = BEGIN OPEN ColorDisplayFace, ColorDisplayDefs, ColorDisplayD0; ErrorHalt: PROC = {ERROR}; displayType: PUBLIC ColorDisplayType _ none; -- display type, "none" if display not available width: PUBLIC NAT _ 0; -- raster width in pixels height: PUBLIC NAT _ 0; -- raster height in pixels pixelsPerInch: PUBLIC NAT _ 0; -- approximate pixel size colorControllerNumber: D0InputOutput.ControllerNumber _ D0InputOutput.nullControllerNumber; csb: LONG POINTER TO ColorCSB _ NIL; bitmap: LONG POINTER _ NIL; show: BOOL _ TRUE; state: {uninitialized, disconnected, connected, displayed} _ uninitialized; globalStateSize: PUBLIC NAT _ 0; -- number of words required by Initialize Initialize: PUBLIC PROC [globalState: LONG POINTER] = { state _ disconnected }; hundredPulsesPerSecond: CARDINAL ~ Basics.LongDiv[ 1000000, -- microsecondsPerSecond ProcessorFace.microsecondsPerHundredPulses -- (assumed >15) ]; pulsesPerField: CARDINAL ~ Basics.LongDiv[ Basics.LongMult[hundredPulsesPerSecond, 100], -- pulsesPerSecond (assumed <3932160) 60 -- fieldsPerSecond (approximate) ]; waitPulses: LONG CARDINAL ~ Basics.LongMult[pulsesPerField, 3]; -- 3 fields, just to be sure Wait: PROC ~ INLINE { -- inline, because device cleanup must not do procedure call startPulses: LONG CARDINAL ~ ProcessorFace.GetClockPulses[]; WHILE (ProcessorFace.GetClockPulses[]-startPulses) { state _ csb^; IF state.bitmap#NIL THEN { csb.bitmap _ NIL; Wait[]; HardwareOff[] }; }; turnOn => { csb^ _ state; IF state.bitmap#NIL THEN HardwareOn[]; }; ENDCASE; ENDLOOP; }; SetDisplayType: PUBLIC SAFE PROC [type: ColorDisplayType] RETURNS [ok: BOOL] ~ CHECKED { RETURN[type=displayType]; }; mode4: ColorMode ~ [full: FALSE, bitsPerPixelChannelA: 4, bitsPerPixelChannelB: 0]; HasMode: PUBLIC SAFE PROC[mode: ColorMode] RETURNS[BOOL] = CHECKED { RETURN[displayType#none AND mode=mode4]; }; NextMode: PUBLIC SAFE PROC [mode: ColorMode] RETURNS [ColorMode] = CHECKED { IF mode=nullMode THEN RETURN[mode4]; RETURN[nullMode]; }; ColorMap: TYPE ~ LONG POINTER TO ColorMapRep; ColorMapRep: PUBLIC TYPE ~ ColorTable; wordsForColorMap: PUBLIC NAT _ SIZE[ColorMapRep]; InitializeColorMap: PUBLIC PROC [mode: ColorMode, pointer: LONG POINTER] RETURNS [ColorMap] ~ { map: ColorMap ~ LOOPHOLE[pointer]; map^ _ [front: ALL[0], array: , back: ALL[0]]; FOR i: [0..16) IN [0..16) DO map.array[i].r _ [addr: i, r: TRUE, data: 255]; map.array[i].g _ [addr: i, g: TRUE, data: 255]; map.array[i].b _ [addr: i, b: TRUE, data: 255]; ENDLOOP; RETURN[map]; }; SetColor: PUBLIC PROC [map: ColorMap, pixelA, pixelB: ChannelValue, r, g, b: ColorValue] ~ { index: [0..16) ~ pixelA MOD 16; map.array[index].r.data _ 255 - r; map.array[index].g.data _ 255 - g; map.array[index].b.data _ 255 - b; }; GetColor: PUBLIC SAFE PROC[map: ColorMap, pixelA, pixelB: ChannelValue] RETURNS [r, g, b: ColorValue _ 0] ~ TRUSTED { index: [0..16) ~ pixelA MOD 16; r _ 255 - map.array[index].r.data; g _ 255 - map.array[index].g.data; b _ 255 - map.array[index].b.data; }; SetR: PUBLIC PROC [map: ColorMap, in: ChannelValue, out: ColorValue] ~ { }; SetG: PUBLIC PROC [map: ColorMap, in: ChannelValue, out: ColorValue] ~ { }; SetB: PUBLIC PROC [map: ColorMap, in: ChannelValue, out: ColorValue] ~ { }; GetR: PUBLIC SAFE PROC [map: ColorMap, in: ChannelValue] RETURNS [out: ColorValue _ 0] ~ CHECKED { }; GetG: PUBLIC SAFE PROC [map: ColorMap, in: ChannelValue] RETURNS [out: ColorValue _ 0] ~ CHECKED { }; GetB: PUBLIC SAFE PROC [map: ColorMap, in: ChannelValue] RETURNS [out: ColorValue _ 0] ~ CHECKED { }; Connect: PUBLIC PROC [mode: ColorMode, baseA, baseB: LONG POINTER, map: ColorMap] = { IF NOT mode=mode4 THEN ErrorHalt[]; bitmap _ baseA; csb.table _ map; state _ connected; }; Disconnect: PUBLIC SAFE PROC ~ TRUSTED { IF state=displayed THEN TurnOff[]; IF state#connected THEN RETURN; bitmap _ NIL; csb.table _ NIL; state _ disconnected; }; TurnOn: PUBLIC PROC ~ { IF state#connected THEN RETURN; IF show THEN { csb.bitmap _ bitmap; HardwareOn[] }; state _ displayed; }; TurnOff: PUBLIC SAFE PROC ~ TRUSTED { IF state#displayed THEN RETURN; IF show THEN { csb.bitmap _ NIL; Wait[]; HardwareOff[] }; state _ connected; }; SetVisibility: PUBLIC SAFE PROC[visibility: ChannelsVisible] ~ TRUSTED { prev: BOOL ~ show; SELECT visibility FROM none => { show _ FALSE }; aOnly => { show _ TRUE }; bOnly => { show _ FALSE }; all => { show _ TRUE }; ENDCASE; IF show=prev THEN RETURN; IF state=displayed THEN { IF prev THEN { csb.bitmap _ NIL; Wait[]; HardwareOff[] }; IF show THEN { csb.bitmap _ bitmap; HardwareOn[] }; }; }; { OPEN D0InputOutput; colorControllerNumber _ GetNextController[colorDisplayController, nullControllerNumber]; IF colorControllerNumber#nullControllerNumber THEN { displayType _ standard; width _ 640; height _ 481; -- (only part of last line is visible) pixelsPerInch _ 42; csb _ LOOPHOLE[@IOPage[colorControllerNumber]]; csb^ _ [bitmap: NIL, table: NIL]; }; }; END. jColorDisplayHeadD0.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Doug Wyatt, May 2, 1985 5:22:59 pm PDT Since the runtime support may be in a delicate state when the heads are started, this code avoids software-implemented operations like long integer multiply or divide. Note: both baseA and map must be multiples of 16. Start code ΚΛ˜codešœ™Kšœ Οmœ1™