ColorDisplayHeadD0.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Doug Wyatt, May 2, 1985 5:22:59 pm PDT
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 };
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.
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)<waitPulses DO ENDLOOP;
};
HardwareOn:
PROC =
INLINE {
D0InputOutput.Output[datum: 6, register: [controller: colorControllerNumber, register: 0]] };
HardwareOff:
PROC =
INLINE {
D0InputOutput.Output[datum: 0, register: [controller: colorControllerNumber, register: 0]] };
InitializeCleanup:
PUBLIC
PROC ~ {
item: DeviceCleanup.Item;
state: ColorCSB;
IF csb=NIL THEN RETURN;
DO
reason: DeviceCleanup.Reason ~ DeviceCleanup.Await[@item];
SELECT reason
FROM
turnOff, kill => {
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[];
Note: both baseA and map must be multiples of 16.
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[] };
};
};
Start code
{
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.