-- ColorDisplayHeadD0.mesa -- Last edit by Doug Wyatt on 21-Dec-81 9:40:49 -- Last edit by Levin on 26-Feb-82 13:12:24 DIRECTORY ColorDisplayFace USING [Color, Mode], DeviceCleanup USING [Await, Item, Reason], D0InputOutput USING [ControllerNumber, ControllerType, GetNextController, IOPage, nullControllerNumber, Output], Environment USING [Base, PageCount, PageNumber, wordsPerPage], HeadStartChain USING [Start], Inline USING [LongDivMod, LongMult], ProcessorFace USING [GetClockPulses, microsecondsPerHundredPulses], RuntimeInternal USING [WorryCallDebugger]; ColorDisplayHeadD0: PROGRAM IMPORTS DeviceCleanup, D0InputOutput, RemainingHeads: HeadStartChain, Inline, ProcessorFace, RuntimeInternal EXPORTS ColorDisplayFace, HeadStartChain = { ErrorHalt: PROC = {RuntimeInternal.WorryCallDebugger["Error in ColorDisplayHeadD0"L]}; RPtr: TYPE = Environment.Base RELATIVE POINTER; -- relative to absolute address 0 rpNIL: RPtr = LOOPHOLE[0]; Mode: TYPE = ColorDisplayFace.Mode; Color: TYPE = ColorDisplayFace.Color; screenwidth: CARDINAL = 640; -- pixels per line screenheight: CARDINAL = 481; -- scan lines (part of last line is not visible) wordsPerLine: CARDINAL = screenwidth/4; screenSize: LONG CARDINAL = Inline.LongMult[wordsPerLine,screenheight]; ColorData: TYPE = MACHINE DEPENDENT RECORD [ addr: [0..17B], r,g,b,unused: BOOLEAN _ FALSE, data: [0..377B]]; ColorEntry: TYPE = MACHINE DEPENDENT RECORD [r,g,b: ColorData]; ColorTable: TYPE = MACHINE DEPENDENT RECORD [ front: ARRAY [0..2) OF CARDINAL _ ALL[0], array: ARRAY [0..16) OF ColorEntry, back: ARRAY [0..10) OF CARDINAL _ ALL[0] ]; tableSize: CARDINAL = ((SIZE[ColorTable]+15)/16)*16; -- round up to multiple of 16 CSBState: TYPE = MACHINE DEPENDENT RECORD [ bitmap: LONG POINTER, -- must be a multiple of 16 table: LONG POINTER TO ColorTable -- must be a multiple of 16 ]; colorControllerType: D0InputOutput.ControllerType = 257B; colorControllerNumber: D0InputOutput.ControllerNumber _ D0InputOutput.nullControllerNumber; csb: LONG POINTER TO CSBState _ NIL; -- Interface variables -- The following are valid as soon as the module start code has run (see Start) globalStateSize: PUBLIC CARDINAL _ 0; -- for Initialize displayType: PUBLIC CARDINAL _ 0; -- display type; 0 means display not available Ramtek525: CARDINAL = 1; -- displayType for Ramtek 525 line monitor pixelsPerInch: PUBLIC CARDINAL _ 0; -- Size of a pixel mixedRG: PUBLIC BOOLEAN _ FALSE; -- in fullmode, red and green alternate in A bitmap width,height: PUBLIC CARDINAL _ 0; -- Dimensions of current raster in pixels baseA,baseB,baseC: PUBLIC LONG POINTER _ NIL; -- bitmap addresses bplA,bplB,bplC: PUBLIC CARDINAL _ 0; -- bitmap bits per line -- Internal globals initialized: BOOLEAN _ FALSE; -- control blocks are allocated connected: BOOLEAN _ FALSE; -- bitmaps and tables are allocated, globals are set turnedon: BOOLEAN _ FALSE; -- display is on, bitmaps and tables are resident fullmode: BOOLEAN _ FALSE; -- connected in 24 bit per pixel mode mapmode: BOOLEAN _ FALSE; -- connected in a mapped mode -- The following globals are valid when initialized=TRUE (see Initialize) -- (none for D0) -- -- The following globals are valid when connected=TRUE (see Connect) showA: BOOLEAN _ FALSE; -- to be shown table: LONG POINTER TO ColorTable _ NIL; Initialize: PUBLIC PROC [globalState: RPtr] = { initialized _ TRUE; }; Lg: TYPE = [0..4); -- logarithm base 2 lg1: Lg = 0; lg2: Lg = 1; lg4: Lg = 2; lg8: Lg = 3; PagesForWords: PROC[words: LONG CARDINAL] RETURNS[CARDINAL] = INLINE { q,r: CARDINAL; [q,r] _ Inline.LongDivMod[words,Environment.wordsPerPage]; RETURN[IF r>0 THEN q+1 ELSE q] }; WordsForPages: PROC[pages: CARDINAL] RETURNS[LONG CARDINAL] = INLINE { RETURN[Inline.LongMult[pages,Environment.wordsPerPage]] }; LPFromPage: PROC[page: Environment.PageNumber] RETURNS[LONG POINTER] = INLINE { RETURN[LOOPHOLE[Inline.LongMult[page, Environment.wordsPerPage]]] }; HasMode: PUBLIC PROC[mode: Mode] RETURNS[BOOLEAN] = { IF displayType=0 THEN RETURN[FALSE]; IF mode.full OR mode.useB THEN RETURN[FALSE]; RETURN[mode.useA AND mode.lgBitsPerPixelA=lg4]; }; PagesForMode: PUBLIC PROC[mode: Mode] RETURNS[Environment.PageCount] = { RETURN[PagesForWords[tableSize + screenSize]]; }; Connect: PUBLIC PROC [mode: Mode, firstPage: Environment.PageNumber, nPages: Environment.PageCount] = { alloc: LONG POINTER _ LPFromPage[firstPage]; -- next available word Alloc: PROC[words: LONG CARDINAL] RETURNS[LONG POINTER] = INLINE { p: LONG POINTER _ alloc; alloc _ alloc + words; RETURN[p] }; wpl: CARDINAL = screenwidth/4; -- words per scan line IF NOT initialized OR NOT HasMode[mode] OR connected THEN ErrorHalt[]; IF nPages { state _ csb^; IF state.bitmap#NIL THEN { csb.bitmap _ NIL; Wait[]; HardwareOff[] }; }; turnOn => { csb^ _ state; IF state.bitmap#NIL THEN HardwareOn[]; }; ENDCASE; ENDLOOP; }; -- HeadStartChain Start: PUBLIC PROC = { OPEN D0InputOutput; colorControllerNumber _ GetNextController[colorControllerType,nullControllerNumber]; IF colorControllerNumber#nullControllerNumber THEN { displayType _ Ramtek525; pixelsPerInch _ 72; -- *** Is this right? *** csb _ LOOPHOLE[@IOPage[colorControllerNumber]]; csb^ _ [bitmap: NIL, table: NIL]; }; RemainingHeads.Start[]; }; }.