-- ColorDisplayImpl.mesa
-- Last edited by Stone on June 9, 1982 4:02 pm
DIRECTORY
ColorDisplay USING [disconnected, Mode, NotifyCursor],
ColorDisplayFace USING [baseA, baseB, baseC, bplA, bplB, bplC, Connect, Disconnect,
displayType, GetBlueMap, GetColor, GetGreenMap, GetRedMap, globalStateSize, HasMode,
height, Initialize, InitializeCleanup, mixedRG, Mode, PagesForMode, pixelsPerInch,
SetBlueMap, SetColor, SetGreenMap, SetRedMap, Show, TurnOff, TurnOn, width],
DriverStartChain USING [Start],
Environment USING [Base, bitsPerWord, PageCount, PageNumber, PageOffset],
ResidentHeap USING [MakeNode],
Runtime USING [CallDebugger],
Space USING [Create, defaultBase, defaultWindow, Delete, Handle, Map,
nullHandle, PageCount, PageNumber, virtualMemory, VMPageNumber],
SpecialSpace USING [MakeResident, MakeSwappable, realMemorySize],
Transaction USING [Handle, nullHandle],
Zone USING [Base, Status];
ColorDisplayImpl: MONITOR
IMPORTS
ColorDisplayFace, OtherDrivers: DriverStartChain, ResidentHeap, Runtime,
Space, SpecialSpace, Transaction, ColorDisplay
EXPORTS DriverStartChain, ColorDisplay = {
Mode: TYPE = ColorDisplay.Mode;
disconnected: Mode = ColorDisplay.disconnected;
-- Interface variables
pixelsPerInch: PUBLIC CARDINAL ← 0;
displayType: PUBLIC CARDINAL ← 0;
mixedRG: PUBLIC BOOLEAN ← FALSE;
curmode: PUBLIC Mode ← disconnected;
width,height: PUBLIC CARDINAL ← 0;
baseA,baseB,baseC: PUBLIC LONG POINTER ← NIL;
wplA,wplB,wplC: PUBLIC CARDINAL ← 0;
ValidMode: PROC[m: Mode] RETURNS[BOOLEAN] = {
Ok: PROC[b: [0..8]] RETURNS[BOOLEAN] = INLINE {
RETURN[SELECT b FROM 0,1,2,4,8 => TRUE, ENDCASE => FALSE] };
RETURN[m.full OR (Ok[m.bitsPerPixelA] AND Ok[m.bitsPerPixelB])] };
FMode: PROC[m: Mode] RETURNS[ColorDisplayFace.Mode] = {
Log: PROC[b: [0..8]] RETURNS[[0..4)] = INLINE {
RETURN[SELECT b FROM 1=>0, 2=>1, 4=>2, 8=>3, ENDCASE => 0] };
fm: ColorDisplayFace.Mode ← [full: FALSE,
useA: FALSE, useB: FALSE, lgBitsPerPixelA: 0, lgBitsPerPixelB: 0];
IF m.full THEN fm.full ← TRUE
ELSE {
IF m.bitsPerPixelA>0 THEN { fm.useA ← TRUE; fm.lgBitsPerPixelA ← Log[m.bitsPerPixelA] };
IF m.bitsPerPixelB>0 THEN { fm.useB ← TRUE; fm.lgBitsPerPixelB ← Log[m.bitsPerPixelB] };
};
RETURN[fm];
};
HasMode: PUBLIC ENTRY PROC[mode: Mode] RETURNS [BOOLEAN] = {
RETURN[SELECT TRUE FROM
(mode=disconnected) => TRUE,
(displayType=0) => FALSE,
ValidMode[mode] => ColorDisplayFace.HasMode[FMode[mode]],
ENDCASE => FALSE] };
space: Space.Handle ← Space.nullHandle;
workingSet: Space.PageCount = 750; -- a guess
SetMode: PUBLIC ENTRY PROC [mode: Mode] RETURNS [BOOLEAN] = {
IF mode=curmode THEN RETURN[TRUE];
IF displayType=0 THEN RETURN[FALSE];
IF curmode#disconnected THEN { -- disconnect
IF state=on THEN InternalTurnOff[];
curmode ← disconnected;
width ← height ← 0;
baseA ← baseB ← baseC ← NIL;
wplA ← wplB ← wplC ← 0;
ColorDisplayFace.Disconnect[];
Space.Delete[space];
space ← Space.nullHandle;
};
IF NOT ValidMode[mode] THEN RETURN[FALSE];
IF mode#disconnected THEN { -- connect
fmode: ColorDisplayFace.Mode ← FMode[mode];
pages: Environment.PageCount;
swapUnitSize: CARDINAL = 50;
IF NOT ColorDisplayFace.HasMode[fmode] THEN RETURN[FALSE];
pages ← ColorDisplayFace.PagesForMode[fmode];
IF mode.full THEN pages ← MIN[pages,SpecialSpace.realMemorySize-workingSet];
space ← Space.Create[size: pages,
parent: Space.virtualMemory, base: Space.defaultBase];
FOR offset: CARDINAL ← 0, offset + swapUnitSize
WHILE offset + swapUnitSize <= pages DO
[] ← Space.Create[size: swapUnitSize, parent: space, base: offset]
ENDLOOP;
Space.Map[space: space, window: Space.defaultWindow];
ColorDisplayFace.Connect[fmode,Space.VMPageNumber[space],pages];
baseA ← ColorDisplayFace.baseA;
baseB ← ColorDisplayFace.baseB;
baseC ← ColorDisplayFace.baseC;
IF ColorDisplayFace.bplA MOD Environment.bitsPerWord # 0 THEN ERROR;
IF ColorDisplayFace.bplB MOD Environment.bitsPerWord # 0 THEN ERROR;
IF ColorDisplayFace.bplC MOD Environment.bitsPerWord # 0 THEN ERROR;
wplA ← ColorDisplayFace.bplA/Environment.bitsPerWord;
wplB ← ColorDisplayFace.bplB/Environment.bitsPerWord;
wplC ← ColorDisplayFace.bplC/Environment.bitsPerWord;
width ← ColorDisplayFace.width;
height ← ColorDisplayFace.height;
};
IF mode.full THEN FOR i: [0..256) IN [0..256) DO
ColorDisplayFace.SetRedMap[i,i];
ColorDisplayFace.SetGreenMap[i,i];
ColorDisplayFace.SetBlueMap[i,i];
ENDLOOP;
curmode ← mode; ColorDisplay.NotifyCursor[]; RETURN[TRUE];
};
state: {off, on} ← off;
TurnOn: PUBLIC ENTRY PROC = {
IF curmode=disconnected OR state=on THEN RETURN;
SpecialSpace.MakeResident[space];
ColorDisplayFace.TurnOn[];
state ← on;
};
TurnOff: PUBLIC ENTRY PROC = {
IF curmode=disconnected OR state=off THEN RETURN;
InternalTurnOff[];
};
InternalTurnOff: INTERNAL PROC = INLINE {
ColorDisplayFace.TurnOff[];
SpecialSpace.MakeSwappable[space];
state ← off;
};
Show: PUBLIC ENTRY PROC[a,b,c: BOOLEAN] = {
IF curmode=disconnected THEN RETURN;
ColorDisplayFace.Show[a,b,c];
};
GetColor: PUBLIC ENTRY PROC [pixelA,pixelB: CARDINAL] RETURNS[r,g,b: [0..256)] = {
IF curmode=disconnected OR curmode.full THEN RETURN[0,0,0];
[r: r, g: g, b: b] ← ColorDisplayFace.GetColor[pixelA,pixelB];
};
SetColor: PUBLIC ENTRY PROC [pixelA,pixelB: CARDINAL, r,g,b: [0..256)] = {
IF curmode=disconnected OR curmode.full THEN RETURN;
ColorDisplayFace.SetColor[pixelA: pixelA, pixelB: pixelB, r: r, g: g, b: b];
};
-- Procedures for 24 bit per pixel mode
GetRedMap: PUBLIC ENTRY PROC[in: [0..256)] RETURNS[out: [0..256)] = {
IF curmode=disconnected OR NOT curmode.full THEN RETURN[0];
RETURN[ColorDisplayFace.GetRedMap[in]];
};
GetGreenMap: PUBLIC ENTRY PROC[in: [0..256)] RETURNS[out: [0..256)] = {
IF curmode=disconnected OR NOT curmode.full THEN RETURN[0];
RETURN[ColorDisplayFace.GetGreenMap[in]];
};
GetBlueMap: PUBLIC ENTRY PROC[in: [0..256)] RETURNS[out: [0..256)] = {
IF curmode=disconnected OR NOT curmode.full THEN RETURN[0];
RETURN[ColorDisplayFace.GetBlueMap[in]];
};
SetRedMap: PUBLIC ENTRY PROC[in,out: [0..256)] = {
IF curmode=disconnected OR NOT curmode.full THEN RETURN;
ColorDisplayFace.SetRedMap[in: in, out: out];
};
SetGreenMap: PUBLIC ENTRY PROC[in,out: [0..256)] = {
IF curmode=disconnected OR NOT curmode.full THEN RETURN;
ColorDisplayFace.SetGreenMap[in: in, out: out];
};
SetBlueMap: PUBLIC ENTRY PROC[in,out: [0..256)] = {
IF curmode=disconnected OR NOT curmode.full THEN RETURN;
ColorDisplayFace.SetBlueMap[in: in, out: out];
};
-- Initialization
Start: PUBLIC PROCEDURE = {OtherDrivers.Start[]};
StartHead: PROCEDURE = {
headGlobalP: Zone.Base RELATIVE POINTER;
s: Zone.Status;
[headGlobalP, s] ← ResidentHeap.MakeNode[ColorDisplayFace.globalStateSize];
IF s # okay THEN Runtime.CallDebugger["Zone error in ColorDisplayImpl"L];
ColorDisplayFace.Initialize[headGlobalP];
ColorDisplayFace.InitializeCleanup[]};
displayType ← ColorDisplayFace.displayType;
-- dont't initialize the head if there's no color display!
IF displayType#0 THEN {
StartHead[];
pixelsPerInch ← ColorDisplayFace.pixelsPerInch;
mixedRG ← ColorDisplayFace.mixedRG;
};
}.
Wyatt 25-Aug-81 17:39:01
increase workingSet from 512 to 750
Wyatt 4-Mar-82 14:55:41
prevent disaster when color display was absent (blush!)
Levin 22-Mar-82 12:40:43
change start logic to conform to normal driver conventions
Stone June 9, 1982 4:03 pm
change SetMode to notify the color cursor implimentation