-- 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