DIRECTORY Basics USING [bitsPerWord, BITAND, BITOR, BITSHIFT, LongDiv, LongDivMod, LongMult, LowHalf], ColorDisplayFace USING [Color, DisplayType, Mode], DeviceCleanup USING [Await, Item, Reason], DoradoInputOutput USING [InputNoPE, RWMufMan], PrincOps USING [PageCount, PageNumber, wordsPerPage], ProcessorFace USING [GetClockPulses, microsecondsPerHundredPulses]; ColorDisplayHeadDorado: PROGRAM IMPORTS Basics, DeviceCleanup, DoradoInputOutput, ProcessorFace EXPORTS ColorDisplayFace = { ErrorHalt: PROC = {ERROR}; Base: TYPE = LONG BASE POINTER; first64K: Base = LOOPHOLE[LONG[0]]; RPtr: TYPE = Base RELATIVE POINTER; -- relative to absolute address 0 rpNIL: RPtr = LOOPHOLE[0]; Mode: TYPE = ColorDisplayFace.Mode; Color: TYPE = ColorDisplayFace.Color; DisplayType: TYPE = ColorDisplayFace.DisplayType; CSBState: TYPE = MACHINE DEPENDENT RECORD [mcb: MCBPtr]; csb: LONG POINTER TO CSBState = LOOPHOLE[LONG[177414B]]; MCBPtr: TYPE = Base RELATIVE POINTER TO MCB; -- in first64k MCB: TYPE = MACHINE DEPENDENT RECORD [ seal: CARDINAL _ mcbSeal, flags: MCBFlags, achanCB: ChanCBPtr, bchanCB: ChanCBPtr, colorCB: ColorCBPtr ]; mcbSeal: CARDINAL = 177456B; Flag: TYPE = BOOLEAN _ FALSE; MCBFlags: TYPE = MACHINE DEPENDENT RECORD [ unused: [0..777B] _ 0, m: Flag, -- minimixer (unimplemented) vc: Flag, -- vertical control hc: Flag, -- horizontal control clk: Flag, -- clock a: Flag, -- A table b: Flag, -- B table c: Flag -- C table ]; ChanCBPtr: TYPE = Base RELATIVE POINTER TO ChanCB; -- in first64k ChanCB: TYPE = RECORD [ link: ChanCBPtr _ rpNIL, -- next ChanCB in chain, or NIL wordsPerLine: CARDINAL, -- words per bitmap scanline bitmap: LONG POINTER _ NIL, -- pointer to bitmap bits (must be even) linesPerField: CARDINAL, -- scan lines per field (bitmap height / 2) pixelsPerLine: CARDINAL, -- visible pixels/scanline + 377B leftMargin: CARDINAL, -- left margin + marginOffset[monitortype] scan: ScanControl -- scan control word (see below) ]; pplOffset: CARDINAL = 377B; -- offset for pixelsPerLine ScanControl: TYPE = MACHINE DEPENDENT RECORD [ unused: [0..77B] _ 0, mode24: BOOLEAN, -- 24 bit per pixel mode aChannelOnly: BOOLEAN, -- if TRUE, disable B channel bBypass: BOOLEAN, -- B channel bypassed to BTable a8b2: BOOLEAN, -- 8 bits from A, 2 bits from B (a6b4 if FALSE) res: ScanRes _ full, -- resolution size: [0..17B] _ 1 -- bits per pixel; must be 1, 2, 4, or 8 ]; ScanRes: TYPE = MACHINE DEPENDENT{quarter(0), half(2), full(3)}; ColorCBPtr: TYPE = Base RELATIVE POINTER TO ColorCB; -- in first64k ColorCB: TYPE = MACHINE DEPENDENT RECORD [ aTable(0:0..31): LONG POINTER TO ATableImage, -- pointer to color table A bTable(2:0..31): LONG POINTER TO BCTableImage, -- pointer to color table B cTable(4:0..31): LONG POINTER TO BCTableImage, -- pointer to color table C miniMixer(6:0..31): LONG POINTER TO MiniMixerImage _ NIL, -- pointer to MiniMixer table vcontrol(10B:0..47): VControl, -- vertical control hcontrol(13B:0..47): HControl, -- horizontal control ccontrol(16B:0..15): CControl, -- clock control reserved(17B:0..15): CARDINAL _ 0 ]; VControl: TYPE = MACHINE DEPENDENT RECORD [ VBtoVS: [0..377B], VStoVS: [0..377B], VStoVB: CARDINAL, VisibleLines: CARDINAL]; HControl: TYPE = MACHINE DEPENDENT RECORD [ HRamMaxAddr: CARDINAL, HBLeadLength: [0..377B], HSTrailAddr: [0..377B], HBTrailLength: CARDINAL]; CControl: TYPE = MACHINE DEPENDENT RECORD [ zero: [0..17B] _ 0, mul: [0..377B], div: [0..17B]]; ATableIndex: TYPE = [0..1024); ATableImage: TYPE = ARRAY ATableIndex OF ATableEntry; BCTableIndex: TYPE = [0..256); BCTableImage: TYPE = ARRAY BCTableIndex OF BCTableEntry; MiniMixerIndex: TYPE = [0..256); MiniMixerImage: TYPE = ARRAY MiniMixerIndex OF MiniMixerEntry; ATableEntry: TYPE = MACHINE DEPENDENT RECORD [ zeroL(0:0..3): [0..17B] _ 0, -- always zero redL(0:4..7): [0..17B], -- low order 4 bits of red value blue(0:8..15): [0..377B], -- blue value zeroH(1:0..3): [0..17B] _ 0, -- always zero green(1:4..11): [0..377B], -- green value redH(1:12..15): [0..17B] -- high order 4 bits of red value ]; BCTableEntry: TYPE = MACHINE DEPENDENT RECORD [ zero(0:0..7): [0..377B] _ 0, -- always zero value(0:8..15): [0..377B] -- table value ]; MiniMixerEntry: TYPE = MACHINE DEPENDENT RECORD [ address(0:0..7): [0..377B], data(0:8..15): [0..377B]]; globalStateSize: PUBLIC NAT _ SIZE[MCB]+3*SIZE[ChanCB]+SIZE[ColorCB]; -- for Initialize displayType: PUBLIC DisplayType _ none; -- display type; 0 means display not available oldRev: BOOLEAN _ FALSE; -- TRUE if color board has an old revision level (less than Cj) pixelsPerInch: PUBLIC NAT _ 0; -- Size of a pixel mixedRG: PUBLIC BOOLEAN _ TRUE; -- in fullmode, red and green alternate in A bitmap width,height: PUBLIC NAT _ 0; -- Dimensions of current raster in pixels baseA,baseB: PUBLIC LONG POINTER _ NIL; -- bitmap addresses bplA,bplB: PUBLIC NAT _ 0; -- bitmap bits per line screenwidth,screenheight: CARDINAL; -- screen dimensions in pixels 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 rpMCB: MCBPtr _ rpNIL; rpTChan: ChanCBPtr _ rpNIL; rpAChan: ChanCBPtr _ rpNIL; rpBChan: ChanCBPtr _ rpNIL; rpColor: ColorCBPtr _ rpNIL; mcb: LONG POINTER TO MCB _ NIL; tchan: LONG POINTER TO ChanCB _ NIL; achan: LONG POINTER TO ChanCB _ NIL; bchan: LONG POINTER TO ChanCB _ NIL; color: LONG POINTER TO ColorCB _ NIL; bppA,bppB: [0..LAST[INTEGER]] _ 0; -- bits per pixel showA,showB: BOOLEAN _ FALSE; -- to be shown atable: LONG POINTER TO ATableImage _ NIL; btable,ctable: LONG POINTER TO BCTableImage _ NIL; -- used only in fullmode ashift,bshift: INTEGER _ 0; amask,bmask: WORD _ 0; Initialize: PUBLIC PROC [globalState: LONG POINTER] = { alloc: RPtr _ LOOPHOLE[Basics.LowHalf[LOOPHOLE[globalState]]]; end: RPtr _ LOOPHOLE[Basics.LowHalf[LOOPHOLE[globalState+globalStateSize]]]; Alloc: PROC[words: CARDINAL] RETURNS[RPtr] = INLINE { p: RPtr _ alloc; alloc _ alloc + words; RETURN[p] }; IF initialized THEN ErrorHalt[]; mcb _ @first64K[rpMCB _ Alloc[SIZE[MCB]]]; tchan _ @first64K[rpTChan _ Alloc[SIZE[ChanCB]]]; achan _ @first64K[rpAChan _ Alloc[SIZE[ChanCB]]]; bchan _ @first64K[rpBChan _ Alloc[SIZE[ChanCB]]]; color _ @first64K[rpColor _ Alloc[SIZE[ColorCB]]]; IF LOOPHOLE[alloc,CARDINAL]>LOOPHOLE[end,CARDINAL] THEN ErrorHalt[]; tchan^ _ [link: rpNIL, wordsPerLine: 0, bitmap: NIL, linesPerField: 0, pixelsPerLine: pplOffset, leftMargin: 0, scan: ]; color^ _ [aTable: NIL, bTable: NIL, cTable: NIL, vcontrol: , hcontrol: , ccontrol: ]; mcb^ _ [flags: [], achanCB: rpNIL, bchanCB: rpNIL, colorCB: rpColor]; initialized _ TRUE; }; Lg: TYPE = [0..4); -- logarithm base 2 lg1: Lg = 0; lg2: Lg = 1; lg4: Lg = 2; lg8: Lg = 3; Exp: PROC[lg: Lg] RETURNS[CARDINAL] = INLINE { RETURN[Basics.BITSHIFT[1,lg]] }; -- 2^lg PagesForWords: PROC[words: LONG CARDINAL] RETURNS[CARDINAL] = INLINE { q,r: CARDINAL; [q,r] _ Basics.LongDivMod[words,PrincOps.wordsPerPage]; RETURN[IF r>0 THEN q+1 ELSE q] }; WordsForPages: PROC[pages: CARDINAL] RETURNS[LONG CARDINAL] = INLINE { RETURN[Basics.LongMult[pages,PrincOps.wordsPerPage]] }; LPFromPage: PROC[page: PrincOps.PageNumber] RETURNS[LONG POINTER] = INLINE { RETURN[LOOPHOLE[Basics.LongMult[page, PrincOps.wordsPerPage]]] }; Wpl: PROC[w: CARDINAL, lbpp: Lg] RETURNS[CARDINAL] = INLINE { bits: CARDINAL _ w*Exp[lbpp]; RETURN[((bits+31)/32)*2] }; WordsForBitmap: PROC[w,h: CARDINAL, lbpp: Lg] RETURNS[LONG CARDINAL] = INLINE { RETURN[Basics.LongMult[Wpl[w,lbpp],h]] }; HasMode: PUBLIC PROC[mode: Mode] RETURNS[BOOLEAN] = { IF displayType=none THEN RETURN[FALSE]; -- no display IF oldRev AND (mode.full OR (mode.useA AND mode.useB)) THEN RETURN[FALSE]; IF mode.full THEN { SELECT displayType FROM ramtek525 => RETURN[TRUE]; hitachi3619 => RETURN[FALSE]; ENDCASE; -- drop through } ELSE { a,b: CARDINAL _ 0; -- bits per pixel IF mode.useA THEN a _ Exp[mode.lgBitsPerPixelA]; IF mode.useB THEN b _ Exp[mode.lgBitsPerPixelB]; IF a>8 OR b>4 OR (a+b)>10 THEN RETURN[FALSE]; -- limits of Dorado hardware SELECT displayType FROM ramtek525 => RETURN[TRUE]; -- all possible modes supported hitachi3619 => RETURN[a<8 OR b=0]; -- can't use B channel if a=8 ENDCASE; -- drop through }; ErrorHalt[]; -- bogus displayType ("can't happen") RETURN[FALSE]; }; PagesForMode: PUBLIC PROC[mode: Mode] RETURNS[PrincOps.PageCount] = { a,b: CARDINAL _ 0; -- bits per pixel words: LONG CARDINAL _ 0; IF NOT HasMode[mode] THEN RETURN[0]; words _ SIZE[ATableImage]; -- atable always required IF mode.full THEN { a _ 16; b _ 8; -- bitmap A has double pixels words _ words + 2*SIZE[BCTableImage]; -- need 2 more color tables } ELSE { IF mode.useA THEN a _ Exp[mode.lgBitsPerPixelA]; -- bitmap A IF mode.useB THEN b _ Exp[mode.lgBitsPerPixelB]; -- bitmap B }; words _ words + Basics.LongMult[(a+b)*screenwidth/Basics.bitsPerWord,screenheight]; RETURN[PagesForWords[words]]; }; MapIndex: PROC[a,b: CARDINAL] RETURNS[ATableIndex] = INLINE { OPEN Basics; RETURN[BITOR[BITAND[BITSHIFT[a,ashift],amask],BITAND[BITSHIFT[b,bshift],bmask]]] }; SetSize: PROC[mode: Mode, pages: PrincOps.PageCount] RETURNS[BOOLEAN] = { w: CARDINAL _ screenwidth; h: CARDINAL _ screenheight; avail: LONG CARDINAL _ 0; extra: CARDINAL _ 0; IF pages>=PagesForMode[mode] THEN { width _ w; height _ h; RETURN[TRUE] }; IF NOT mode.full THEN RETURN[FALSE]; avail _ WordsForPages[pages]; -- available words extra _ SIZE[ATableImage] + 2*SIZE[BCTableImage]; -- overhead for tables IF avail>extra THEN avail _ avail - extra ELSE RETURN[FALSE]; w _ 4*Basics.LongDiv[avail,6*h]; IF w0 THEN { width _ w; height _ h; RETURN[TRUE] } ELSE RETURN[FALSE]; }; Connect: PUBLIC PROC [mode: Mode, firstPage: PrincOps.PageNumber, nPages: PrincOps.PageCount] = { allocBegin: LONG POINTER _ LPFromPage[firstPage]; -- beginning address allocLimit: LONG CARDINAL = WordsForPages[nPages]; -- maximum words available allocCount: LONG CARDINAL _ 0; -- words allocated so far Alloc: PROC[words: LONG CARDINAL] RETURNS[LONG POINTER] = INLINE { p: LONG POINTER _ allocBegin + allocCount; allocCount _ allocCount + words; IF allocCount>allocLimit THEN ErrorHalt[]; RETURN[p] }; AllocBitmap: PROC[bpl: CARDINAL] RETURNS [LONG POINTER] = INLINE { RETURN[Alloc[Basics.LongMult[bpl/Basics.bitsPerWord,height]]] }; IF NOT initialized OR NOT HasMode[mode] OR connected THEN ErrorHalt[]; IF NOT SetSize[mode,nPages] THEN ErrorHalt[]; SELECT displayType FROM ramtek525 => { color.vcontrol _ [VBtoVS: 3B, VStoVS: 3B, VStoVB: 20B, VisibleLines: 240]; color.hcontrol _ [HRamMaxAddr: 379, HBLeadLength: 6, HSTrailAddr: 28, HBTrailLength: 25]; color.ccontrol _ [mul: 130B, div: 14B]; tchan.leftMargin _ 65B }; hitachi3619 => { color.vcontrol _ [VBtoVS: 3B, VStoVS: 3B, VStoVB: 14B, VisibleLines: 512]; color.hcontrol _ [HRamMaxAddr: 629, HBLeadLength: 6, HSTrailAddr: 61, HBTrailLength: 49]; color.ccontrol _ [mul: 163B, div: 17B]; tchan.leftMargin _ 172 -- a guess -- }; ENDCASE => ErrorHalt[]; IF mode.full THEN { SELECT displayType FROM ramtek525 => color.ccontrol _ [mul: 130B, div: 16B]; ENDCASE => ErrorHalt[]; tchan.scan _ [mode24: TRUE, aChannelOnly: FALSE, bBypass: TRUE, a8b2: TRUE]; tchan.leftMargin _ 2*tchan.leftMargin + 40B--HWindow-- + 40B--marginCounter--; baseA _ AllocBitmap[bplA _ 2*8*width]; -- double pixels in bitmap A baseB _ AllocBitmap[bplB _ 8*width]; bppA _ bppB _ 8; showA _ showB _ TRUE; color.aTable _ atable _ Alloc[SIZE[ATableImage]]; color.bTable _ btable _ Alloc[SIZE[BCTableImage]]; color.cTable _ ctable _ Alloc[SIZE[BCTableImage]]; atable^ _ ALL[[redH: 0, redL: 0, blue: 0, green: 0]]; btable^ _ ALL[[value: 0]]; ctable^ _ ALL[[value: 0]]; fullmode _ TRUE } ELSE { tchan.scan _ [mode24: FALSE, aChannelOnly: ~mode.useB, bBypass: FALSE, a8b2: bppB<=2]; IF mode.useA THEN { bppA _ Exp[mode.lgBitsPerPixelA]; bplA _ width*bppA; baseA _ AllocBitmap[bplA]; showA _ TRUE }; IF mode.useB THEN { bppB _ Exp[mode.lgBitsPerPixelB]; bplB _ width*bppB; baseB _ AllocBitmap[bplB]; showB _ TRUE }; color.aTable _ atable _ Alloc[SIZE[ATableImage]]; atable^ _ ALL[[redH: 0, redL: 0, blue: 0, green: 0]]; mapmode _ TRUE }; IF tchan.scan.a8b2 THEN { ashift _ 10-bppA; amask _ 1774B; bshift _ 2-bppB; bmask _ 0003B } ELSE { -- a6b4 -- ashift _ 10-bppA; amask _ 1760B; bshift _ 4-bppB; bmask _ 0017B }; tchan.pixelsPerLine _ width+pplOffset; tchan.linesPerField _ height/2; IF bppA>0 THEN { achan^ _ tchan^; achan.bitmap _ baseA; achan.wordsPerLine _ bplA/Basics.bitsPerWord; achan.scan.size _ bppA }; IF bppB>0 THEN { bchan^ _ tchan^; bchan.bitmap _ baseB; bchan.wordsPerLine _ bplB/Basics.bitsPerWord; bchan.scan.size _ bppB }; tchan.pixelsPerLine _ 0 + pplOffset; -- now make tchan a dummy control block IF fullmode THEN { achan.pixelsPerLine _ bchan.pixelsPerLine _ 2*width+pplOffset; bchan.scan.res _ half; color.hcontrol.HRamMaxAddr _ 2*color.hcontrol.HRamMaxAddr; color.hcontrol.HBLeadLength _ 2*color.hcontrol.HBLeadLength; color.hcontrol.HSTrailAddr _ 2*color.hcontrol.HSTrailAddr; color.hcontrol.HBTrailLength _ 2*color.hcontrol.HBTrailLength; }; connected _ TRUE; }; Disconnect: PUBLIC PROC = { IF NOT connected THEN ErrorHalt[]; IF turnedon THEN TurnOff[]; color.aTable _ NIL; color.bTable _ color.cTable _ NIL; achan.bitmap _ bchan.bitmap _ NIL; width _ height _ 0; baseA _ baseB _ NIL; bplA _ bplB _ 0; bppA _ bppB _ 0; showA _ showB _ FALSE; atable _ NIL; btable _ ctable _ NIL; fullmode _ mapmode _ connected _ FALSE; }; TurnOn: PUBLIC PROC = { IF (NOT connected) OR turnedon THEN RETURN; mcb.flags _ [vc: TRUE, hc: TRUE, clk: TRUE, a: TRUE]; mcb.achanCB _ rpTChan; -- plug in dummy control block to establish scan mode csb.mcb _ rpMCB; WHILE mcb.flags.a DO ENDLOOP; -- wait for microcode to notice everything IF fullmode THEN mcb.flags _ [b: TRUE, c: TRUE]; mcb.achanCB _ (IF showA THEN rpAChan ELSE rpNIL); -- show bitmap A mcb.bchanCB _ (IF showB THEN rpBChan ELSE rpNIL); -- show bitmap B turnedon _ TRUE; }; TurnOff: PUBLIC PROC = { asave: ATableEntry; bsave,csave: BCTableEntry; IF NOT turnedon THEN RETURN; mcb.achanCB _ mcb.bchanCB _ rpNIL; -- disable bitmaps asave _ atable[0]; atable[0] _ [redH: 0, redL: 0, green: 0, blue: 0]; -- black mcb.flags.a _ TRUE; IF fullmode THEN { bsave _ btable[0]; csave _ ctable[0]; btable[0] _ ctable[0] _ [value: 0]; mcb.flags.b _ mcb.flags.c _ TRUE; }; Wait[]; -- be sure the microcode is no longer touching bitmaps or color tables csb.mcb _ rpNIL; atable[0] _ asave; IF fullmode THEN { btable[0] _ bsave; ctable[0] _ csave }; turnedon _ FALSE; }; Show: PUBLIC PROC[a,b: BOOLEAN] = { IF bppA>0 THEN showA _ a; IF bppB>0 THEN showB _ b; IF turnedon THEN { mcb.achanCB _ (IF showA THEN rpAChan ELSE rpNIL); mcb.bchanCB _ (IF showB THEN rpBChan ELSE rpNIL); }; }; GetColor: PUBLIC PROC[pixelA,pixelB: CARDINAL] RETURNS[r,g,b: Color] = { IF mapmode THEN { index: ATableIndex _ MapIndex[pixelA,pixelB]; entry: ATableEntry _ atable[index]; RETURN[r: entry.redH*16+entry.redL, g: entry.green, b: entry.blue]; } ELSE RETURN[0,0,0]; }; SetColor: PUBLIC PROC[pixelA,pixelB: CARDINAL, r,g,b: Color] = { IF mapmode THEN { index: ATableIndex _ MapIndex[pixelA,pixelB]; atable[index] _ [redH: r/16, redL: r MOD 16, blue: b, green: g]; IF turnedon THEN mcb.flags.a _ TRUE; }; }; GetRedMap: PUBLIC PROC[in: Color] RETURNS[out: Color] = { IF fullmode THEN { index: ATableIndex _ MapIndex[in,0]; entry: ATableEntry _ atable[index]; RETURN[entry.redH*16+entry.redL] } ELSE RETURN[0]; }; GetGreenMap: PUBLIC PROC[in: Color] RETURNS[out: Color] = { IF fullmode THEN RETURN[ctable[in].value] ELSE RETURN[0]; }; GetBlueMap: PUBLIC PROC[in: Color] RETURNS[out: Color] = { IF fullmode THEN RETURN[btable[in].value] ELSE RETURN[0]; }; SetRedMap: PUBLIC PROC[in,out: Color] = { IF fullmode THEN { index: ATableIndex _ MapIndex[in,0]; atable[index] _ [redH: out/16, redL: out MOD 16, green: 0, blue: 0]; IF turnedon THEN mcb.flags.a _ TRUE; }; }; SetGreenMap: PUBLIC PROC[in,out: Color] = { IF fullmode THEN { ctable[in] _ [value: out]; IF turnedon THEN mcb.flags.c _ TRUE; }; }; SetBlueMap: PUBLIC PROC[in,out: Color] = { IF fullmode THEN { btable[in] _ [value: out]; IF turnedon THEN mcb.flags.b _ TRUE; }; }; minFPS: CARDINAL = 30; -- minimum number of frames per second maxPulsesPerRefresh: LONG CARDINAL = 2* --for safety-- (LONG[100]* --pulsesPerHundredPulses-- 1000000 --microsecondsPerSecond--)/ (LONG[minFPS]*ProcessorFace.microsecondsPerHundredPulses); Wait: PROC = INLINE { timeDone: LONG CARDINAL _ ProcessorFace.GetClockPulses[]; WHILE ProcessorFace.GetClockPulses[] - timeDone < maxPulsesPerRefresh DO ENDLOOP }; InitializeCleanup: PUBLIC PROC = { OPEN DeviceCleanup; item: Item; reason: Reason; state: CSBState; DO reason _ Await[@item]; SELECT reason FROM turnOff => { state _ csb^; csb.mcb _ rpNIL; Wait[] }; turnOn => { csb^ _ state }; ENDCASE; ENDLOOP; }; { hasColorBoard: BOOLEAN _ (DoradoInputOutput.InputNoPE[360B] # 0); IF hasColorBoard THEN { device: MACHINE DEPENDENT RECORD[type: [0..17B], junk: [0..7777B]] _ DoradoInputOutput.InputNoPE[361B]; SELECT device.type FROM 17B => { displayType _ ramtek525; screenwidth _ 640; -- must be a multiple of 32 screenheight _ 480; -- must be a multiple of 2 pixelsPerInch _ 64; -- *** approximate *** }; 16B => { displayType _ hitachi3619; screenwidth _ 1024; -- must be a multiple of 32 screenheight _ 1024; -- must be a multiple of 2 pixelsPerInch _ 72; -- *** approximate *** }; ENDCASE => ErrorHalt[]; -- unknown display type oldRev _ (DoradoInputOutput.RWMufMan[[useDMD: FALSE, dMuxAddr: 3107B]].dMuxData # 0); }; csb^ _ [mcb: rpNIL]; }; }. ¨ColorDisplayHeadDorado.mesa Last edited by Doug Wyatt on December 8, 1983 2:00 pm Last edited by Andrew Birrell on December 20, 1983 2:10 pm Monitor control block Channel control block Margin offsets for various monitors AltoTerminal: 107B, Ramtek525: 66B, Ramtek1000: 0, ConracRQB525: 66B, ConracRQB875: 107B, ConracRQB1225: 0, Scan control word Color control block Vertical control information (loaded via vc flag) Horizontal control information (loaded via hc flag) Clock control information (loaded via clk flag) Interface variables The following are valid as soon as the module start code has run (see Start) ramtek525: CARDINAL = 1; -- displayType for Ramtek or Hitachi 525 line monitor hitachi3619: CARDINAL = 2; -- displayType for Hitachi UHR monitor Internal globals The following globals are valid when initialized=TRUE (see Initialize) first64k-relative pointers to global state: long pointers to same: The following globals are valid when connected=TRUE (see Connect) Allocate from globalState block: words per line, guaranteed to be even; resulting width in pixels >= w old revision boards can't run both channels at the same time Shrink the raster width, observing necessary constraints. Bitmaps must have an even number of words per line, so width must shrink in steps of 4 pixels. Each 4 pixels of width require 6*h words. Shrink the raster height. Bitmaps must have an even number of lines, so height must shrink in steps of 2. Each 2 lines require 3*w words. Allocate bitmaps first; they must begin at even addresses double the pixel clock rate adjust leftMargin to compensate for the faster pixel clock set up for MapIndex set up channel control blocks; use tchan for a template achan fetches two bitmap pixels per screen pixel bchan runs at half resolution: 2 pixel clocks for each pixel from the bitmap horizontal control is measured in pixel clock periods Initialization Start determine whether an old rev DispY board is installed Ê›˜Jšœ™Jšœ5™5Jšœ:™:J˜šÏk ˜ Jš œœœœœ*˜\Jšœœ˜2Jšœœ˜*Jšœœ˜.Jšœ œ'˜5Jšœœ0˜CJ˜—Jšœ˜Jšœ8˜?Jšœ˜J˜JšÏn œœœ˜J˜Jš œœœœœ˜Jšœœœ˜#JšœœœœÏc!˜EJšœœ˜J˜Jšœœ˜#Jšœœ˜%Jšœ œ ˜1J˜Jš œ œœ œœ˜8Jš œœœœ œœ ˜8J˜Jšœ™Jš œœœœœœŸ˜;š œœœ œœ˜&Jšœœ ˜J˜J˜J˜J˜J˜J˜—Jšœ œ ˜J˜Jšœœœœ˜J˜š œ œœ œœ˜+J˜Jšœ Ÿ˜&Jšœ Ÿ˜Jšœ Ÿ˜ Jšœ Ÿ˜Jšœ Ÿ ˜Jšœ Ÿ ˜Jšœ Ÿ ˜J˜J˜—Jšœ™J˜Jš œ œœœœ Ÿ˜Ašœœœ˜JšœŸ˜8JšœœŸ˜5JšœœœœŸ(˜EJšœœŸ+˜EJšœœŸ!˜;Jšœ œŸ*˜AJšœŸ ˜3J˜—Jšœ œ Ÿ˜7J˜Jšœ#™#Jšœ2™2Jšœ8™8J˜Jšœ™J˜š œ œœ œœ˜.J˜JšœœŸ˜)JšœœŸ˜4Jšœ œŸ˜1JšœœŸ/˜>JšœŸ ˜"JšœŸ(˜;J˜—Jšœ œœ œ˜@J˜Jšœ™J˜Jš œ œœœœ Ÿ˜Cš œ œœ œœ˜*JšœœœœŸ˜JJšœœœœŸ˜JJšœœœœŸ˜JJš œœœœœŸ˜WJšœŸ˜2JšœŸ˜4JšœŸ˜/Jšœœ˜!J˜J˜—Jšœ1™1š œ œœ œœ˜+J˜%Jšœœ˜Jšœœ˜—Jšœ3™3š œ œœ œœ˜+Jšœ œ˜J˜0Jšœœ˜—Jšœ/™/š œ œœ œœ˜+J˜3J˜—Jšœ œ ˜Jšœ œœ œ ˜5Jšœœ ˜Jšœœœœ˜8Jšœœ ˜ Jšœœœœ˜>J˜š œ œœ œœ˜.JšœŸ˜,JšœŸ ˜9JšœŸ ˜(JšœŸ˜,JšœŸ˜*JšœŸ!˜;J˜J˜—š œœœ œœ˜/JšœŸ˜,JšœŸ˜)J˜J˜—š œœœ œœ˜1J˜6J˜—Jšœ™J˜JšœL™LJ˜Jšœœœœœœ œ Ÿ˜WJšœ œŸ.˜VJšœœœŸ?˜XJ˜Jšœ œŸ5™NJšœ œŸ&™AJ˜JšœœœŸ˜1Jšœ œœœŸ3˜SJ˜JšœœœŸ)˜GJš œ œœœœŸ˜;Jšœ œœŸ˜2J˜Jšœ™J˜JšœœŸ˜BJ˜Jšœ œœŸ˜=Jšœ œœŸ4˜PJšœ œœŸ1˜LJšœ œœŸ%˜@Jšœ œœŸ˜7J˜JšœF™FJšœ+™+J˜J˜J˜J˜J˜Jšœ™Jš œœœœœœ˜Jš œœœœ œ˜$Jš œœœœ œ˜$Jš œœœœ œ˜$Jš œœœœ œ˜%J˜JšœA™AJ˜JšœœœŸ˜4Jšœ œœŸ˜,J˜Jš œœœœœ˜*Jš œœœœœŸ˜KJ˜Jšœœ˜Jšœ œ˜J˜š ž œœœœœ˜7Jšœœœ˜>Jšœ œœ ˜Lš žœœœœ œ˜5Jšœ(œ˜4—Jšœ œ ˜ Jšœ ™ Jšœœœ˜*Jšœ"œ ˜1Jšœ"œ ˜1Jšœ"œ ˜1Jšœ"œ ˜2Jš œœœœœœ ˜Dšœ0œ˜FJ˜1—Jšœœ œ œ&˜UJ˜EJšœœ˜J˜J˜—Jšœœ Ÿ˜&J˜3Jšžœœ œœœœœ Ÿ˜WJ˜šž œœœœœœœ˜FJšœœ9˜FJšœœœœ˜!J˜—šž œœœœœœœ˜FJšœ1˜7J˜—š ž œœœœœœ˜LJšœœ2˜AJ˜—JšœE™Eš žœœœ œœœ˜=Jšœœœ˜9J˜—šžœœœ œœœœ˜OJšœ#˜)J˜—š žœœœ œœ˜5Jš œœœœŸ ˜5Jšœ<™J˜Jšœ5™5J˜:J˜J˜—Jšœ œ˜J˜J˜—šž œœœ˜Jšœœ œ ˜"Jšœ œ ˜Jšœœ œ˜6Jšœœ˜"J˜Jšœœ#˜6Jšœœ˜Jšœ œœ˜$Jšœ!œ˜'J˜J˜—šžœœœ˜Jš œœ œ œœ˜+Jš œœœœœ˜5JšœŸ5˜LJ˜Jšœ œœŸ*˜HJšœ œœœ˜0Jšœœœ œ Ÿ˜BJšœœœ œ Ÿ˜BJšœ œ˜J˜J˜—šžœœœ˜J˜J˜Jšœœ œœ˜Jšœ#Ÿ˜5J˜Jšœ3Ÿ˜;Jšœœ˜šœ œ˜J˜%J˜#Jšœœ˜!J˜—JšœŸF˜NJ˜J˜Jšœ œ*˜:Jšœ œ˜J˜J˜J˜—šžœœœœ˜#Jšœœ ˜Jšœœ ˜šœ œ˜Jšœœœ œ˜1Jšœœœ œ˜1J˜—J˜J˜—š žœœœœœ˜Hšœ œ˜J˜-J˜#Jšœ=˜CJ˜—Jšœœ˜J˜J˜—šžœœœœ˜@šœ œ˜J˜-Jšœ%œ˜@Jšœ œœ˜$J˜—J˜J˜—šž œœœ œ˜9šœ œ˜J˜$J˜#Jšœ˜"—Jšœœ˜J˜—šž œœœ œ˜;Jš œ œœœœ˜9J˜—šž œœœ œ˜:Jš œ œœœœ˜9J˜J˜—šž œœœ˜)šœ œ˜J˜$Jšœ)œ˜DJšœ œœ˜'—J˜—šž œœœ˜+šœ œ˜-Jšœ œœ˜'—J˜—šž œœœ˜*šœ œ˜-Jšœ œœ˜'—J˜J˜—Jšœ™J˜JšœœŸ&˜=šœœœŸ˜7šœœŸœ Ÿœ˜KJšœœ5˜:J˜——š žœœœ œœ"˜OJšœAœœ˜SJ˜—šžœœœœ˜6J˜ J˜J˜š˜J˜šœ˜J˜5J˜Jšœ˜—Jšœ˜—J˜J˜—J™J˜šœ˜Jšœœ+˜Ašœœ˜šœœ œœ$˜DJ˜"—šœ ˜˜Jšœ˜JšœŸ˜.JšœŸ˜.JšœŸ˜*J˜—˜Jšœ˜JšœŸ˜/JšœŸ˜/JšœŸ˜*J˜—JšœŸ˜/—Jšœ5™5Jšœ.œ"˜UJ˜—J˜J˜J˜J˜—J˜J˜J˜J˜—…—E¦cé