DIRECTORY Basics USING [LowByte], ColorDisplayDorado USING [RNIL], ColorDisplayHeadDorado, MonitorToolDefs USING [MonitorParam, MonitorParamRec], Real USING [LargestNumber, RoundC], Terminal USING [Current, TurnOffColorDisplay], WindowManager USING [ScreenPos, StartColorViewers, StopColorViewers]; MonitorToolOps: CEDAR PROGRAM IMPORTS Real, Basics, WindowManager, Terminal, ColorDisplayHeadDorado EXPORTS MonitorToolDefs SHARES ColorDisplayHeadDorado = { OPEN ColorDisplayHeadDorado ; hWindowPixels: INTEGER _ 32; --hardware counts 32 pixel clocks before counting out margin mCounterOverflow: INTEGER _ 32; --hardware counts 32 pixel clocks after margin counter overflows before channel ON marginPipelineLength: INTEGER _ 5; --there are 5 pixel clocks in the pipeline from margin counter overflow to video. hBlankEarly: [0..377B] _ 4; --number of pixels before HSync which will be blanked. Must be even!! pixelTime, pixelFreq: PUBLIC REAL; --desired pixel time in nanoseconds, rate in MHz truePixeltime, truePixelfreq: PUBLIC REAL; --actual pixel time in nanoseconds, rate in MHz lineTime, lineFreq: PUBLIC REAL; --desired line time in microseconds, rate in KHz trueLinetime, trueLinefreq: PUBLIC REAL; --actual line time in microseconds, rate in KHz fieldTime, fieldFreq: PUBLIC REAL; --desired time in microseconds for one field; rate in Hz leftMarginOffset: NAT; --this is added to the desired left margin for the microcode. Usually, the left margin is = 0. hBlankPixels, hSyncPixels: INTEGER; truePixels: INTEGER; hRamMaxAddr: PUBLIC CARDINAL; hBLeadLength: PUBLIC [0..377B]; hSTrailAddr: PUBLIC [0..377B]; hBTrailLength: PUBLIC CARDINAL; vbToVS: PUBLIC [0..377B]; defaultVBtoVS: [0..377B] _ 0; vsToVS: PUBLIC [0..377B]; defaultVStoVS: [0..377B] _ 3; vsToVB: PUBLIC CARDINAL; visibleLines: PUBLIC CARDINAL; refFreq, nextFreq, bestFreq, fDiff, bestDiff: PUBLIC REAL; trueMul, nextMul, bestMul: PUBLIC [0..377B]; trueZero, bestZero, trueDiv, nextDiv, bestDiv: PUBLIC [0..17B]; mp: MonitorToolDefs.MonitorParam; sw: CARDINAL; sh: CARDINAL; rr: CARDINAL; hbt: REAL ; vbt: REAL ; DoMonitorParams: PUBLIC PROCEDURE [screenWidth, screenHeight, refreshRate: CARDINAL, hBlankTime, vBlankTime: REAL, NTSCBoard: BOOLEAN _ FALSE, interlace: BOOLEAN _ TRUE] RETURNS [MonitorToolDefs.MonitorParam] = { mp: MonitorToolDefs.MonitorParam _ NEW[MonitorToolDefs.MonitorParamRec]; sw _ screenWidth; sh _ screenHeight; rr _ refreshRate; hbt _ hBlankTime; vbt _ vBlankTime; visibleLines _ Real.RoundC[IF interlace THEN screenHeight/2 ELSE screenHeight]; fieldFreq _ IF interlace THEN refreshRate*2 ELSE refreshRate; fieldTime _ 1.0/fieldFreq; lineTime _ (fieldTime - vBlankTime)/visibleLines; --assumes VBtoVS = 0 lineFreq _ 1.0/lineTime; truePixels _ screenWidth+hBlankEarly; --line is "longer" by hBlankEarly pixels pixelTime _ (lineTime - hBlankTime)/truePixels; pixelFreq _ 1.0/pixelTime; [zero: trueZero, mul: trueMul, div: trueDiv, bestF: truePixelfreq] _ FreqToMulDiv[pixelFreq, NTSCBoard]; truePixeltime _ 1.0/truePixelfreq; trueLinetime _ truePixeltime*truePixels+hBlankTime; trueLinefreq _ 1.0/trueLinetime; hRamMaxAddr _ Real.RoundC[(trueLinetime/truePixeltime)/2] - 1; hBLeadLength _ (hBlankEarly/2)+1; -- +1 for one cycle of pipelined delay forming HBlank hSyncPixels _ (Real.RoundC[(hBlankTime * 0.60)/truePixeltime]/2)*2; --make it even hSTrailAddr _ Basics.LowByte[(hSyncPixels/2)- 2]; -- -2 for pipeline advance of HSync by two HRam ticks (maxAddress and addressZero) hBlankPixels _ (Real.RoundC[hBlankTime/truePixeltime]/2)*2; --make it even number of pixels hBTrailLength _ (hBlankPixels-hSyncPixels)/2; leftMarginOffset_hBlankPixels+hBlankEarly-hWindowPixels-mCounterOverflow-marginPipelineLength; vbToVS _ defaultVBtoVS; vsToVS _ defaultVStoVS; vsToVB _ Real.RoundC[vBlankTime/trueLinetime] - vsToVS; --monitor specs call for VBlank to begin simultaneous with VSync mp^ _ [hRes: screenWidth, vRes: screenHeight, vc: [VBtoVS: vbToVS, VStoVS: vsToVS, VStoVB: vsToVB, VisibleLines: visibleLines], hc: [HRamMaxAddr: hRamMaxAddr, HBLeadLength: hBLeadLength, HSTrailAddr: hSTrailAddr, HBTrailLength: hBTrailLength], cc: [zero: trueZero, mul: trueMul, div: trueDiv], lmarg: leftMarginOffset, truePixelFreq: truePixelfreq, truePixelTime: truePixeltime]; RETURN[mp]; }; SetMonitorParams: PUBLIC PROCEDURE [bpp: CARDINAL _ 8, pos: WindowManager.ScreenPos _ left, mp: MonitorToolDefs.MonitorParam] = TRUSTED { WindowManager.StopColorViewers[]; width _ mp.hRes; -- must be a multiple of 32 height _ mp.vRes; -- must be a multiple of 2 WindowManager.StartColorViewers[pos,bpp]; ColorDisplayHeadDorado.TurnOff[]; IF bpp=24 THEN { --mimic what the DisplayHead does in full color mode lmul, ldiv: [0..377B]; [ , lmul, ldiv, ] _ FreqToMulDiv[freq: mp.truePixelFreq*2, NTSCBoard: FALSE]; --run the clock twice as fast mp.cc _ [0, lmul, ldiv]; mp.lmarg _ 2*mp.lmarg+40B--HWindow-- + 40B--marginCounter--; --adjust leftMargin mp.hc.HRamMaxAddr _ 2*mp.hc.HRamMaxAddr; -- double all HRam parameters mp.hc.HBLeadLength _ 2*mp.hc.HBLeadLength; mp.hc.HSTrailAddr _ 2*mp.hc.HSTrailAddr; mp.hc.HBTrailLength _ 2*mp.hc.HBTrailLength; }; color.vc _ mp.vc; color.hc _ mp.hc; color.clk _ mp.cc; ColorDisplayHeadDorado.TurnOn[]; LMarg[mp.lmarg]; --only works if turned on }; StartMonitor: PUBLIC PROCEDURE [screenWidth, screenHeight, refreshRate, bitsPerPixel: CARDINAL, hBlankTime, vBlankTime: REAL, pos: WindowManager.ScreenPos _ left, NTSCBoard: BOOLEAN _ FALSE, interlace: BOOLEAN _ TRUE] = { mp _ DoMonitorParams[screenWidth, screenHeight, refreshRate, hBlankTime*1E-6, vBlankTime*1E-6, NTSCBoard, interlace]; SetMonitorParams[bitsPerPixel, pos, mp]; }; Start640Monitor: PUBLIC PROCEDURE [bitsPerPixel: CARDINAL _ 8, pos: WindowManager.ScreenPos _ left] = { WindowManager.StopColorViewers[]; ColorDisplayHeadDorado.displayType _ standard; --approx. 640 by 480 pixels ColorDisplayHeadDorado.width _ 640; -- must be a multiple of 32 ColorDisplayHeadDorado.height _ 480; -- must be a multiple of 2 Terminal.TurnOffColorDisplay[Terminal.Current[]]; -- must force a disconnect WindowManager.StartColorViewers[pos,bitsPerPixel]; }; Start1024Monitor: PUBLIC PROCEDURE [bitsPerPixel: CARDINAL _ 8, pos: WindowManager.ScreenPos _ left] = { Terminal.TurnOffColorDisplay[Terminal.Current[]]; -- must force a disconnect ColorDisplayHeadDorado.displayType _ highResolution; --approx. 1024 by 768 pixels WindowManager.StartColorViewers[pos,bitsPerPixel]; StartMonitor[1024, 768, 30, bitsPerPixel, 6, 850, pos]; }; FreqToMulDiv: PROCEDURE [freq: REAL, NTSCBoard: BOOLEAN] RETURNS [zero: [0..17B], mul: [0..377B], div: [0..17B], bestF: REAL] = { firstZero, lastZero, currentZero: [0..17B]; IF NTSCBoard THEN {firstZero_1; lastZero _ 16B} ELSE {firstZero_0; lastZero _ 0}; bestDiff _ Real.LargestNumber; --start with maximum difference FOR currentZero _ firstZero, currentZero+2 UNTIL currentZero>lastZero DO refFreq _ 5002750/(16-currentZero); FOR nextMul IN [0..121] DO FOR nextDiv IN [0..15] DO nextFreq _ refFreq*(241 - nextMul)/(16-nextDiv); fDiff _ nextFreq-freq; IF fDiff < 0 THEN fDiff _ -fDiff; IF fDiff < bestDiff THEN { bestDiff _ fDiff; bestZero _ currentZero; bestMul _ nextMul; bestDiv _ nextDiv; bestFreq _ nextFreq; }; ENDLOOP; ENDLOOP; ENDLOOP; RETURN [bestZero, bestMul,bestDiv,bestFreq]; }; MulDivToFreq: PROCEDURE [zero: [0..17B] _ 0, mul: [0..377B], div: [0..17B]] RETURNS [freq: REAL] = { refFreq _ 5002750/(16-zero); freq _ refFreq*(241 - mul)/(16-div); }; LMarg: PROCEDURE [lmarg: CARDINAL] = TRUSTED { IF mcb.channelA#ColorDisplayDorado.RNIL THEN channelA.leftMargin _ lmarg; IF mcb.channelB#ColorDisplayDorado.RNIL THEN channelB.leftMargin _ lmarg; }; }. ΚMonitorToolOps.mesa Last Edited July 30, 1985 5:35:21 pm PDT by Ken Pier Diebert, April 30, 1985 12:40:19 pm PDT parameters supplied as input -- screenWidth, screenHeight: REAL; --visible pixels, visible lines per frame -- refreshRate: REAL; --field refresh rate in frames per second -- interlace: BOOLEAN _ TRUE; --monitor to scan interlaced ?? -- hBlankTime, vBlankTime: REAL; --blanking time in microseconds constant values from hardware calculated values horizontal values needed by microcode vertical values needed by microcode parameters for mul/div calculation calculate mul, div parameters for nearest achieveable pixel frequency calculate true values of parameters based on best frequency available Κ?˜Icodešœ™Kšœ4™4Kšœ'™'K˜šΟk ˜ Kšœœ ˜Kšœœœ˜ K˜Kšœœ!˜6Kšœœ˜#Kšœ œ ˜.Kšœœ2˜E—K˜šΟbœœœ˜Kšœ>˜Ešœœ˜:Kšœ˜—K˜Kšœ™KšΟc&œ'™MKšŸœ'™?KšŸ œ™=KšŸ#œ™@K˜Kšœ™KšœœŸ<˜ZKšœœŸR˜sKšœœŸQ˜uKšœŸE˜aK˜Kšœ™KšœœœŸ0˜SKšœœœŸ/˜ZKšœœœŸ0˜QKšœœœŸ/˜XKšœœœŸ8˜[K˜KšœœŸ^˜uKšœœ˜#Kšœ œ˜K˜Kšœ%™%Kšœ œœ˜Kšœœ ˜Kšœ œ ˜Kšœœœ˜K˜Kšœ#™#Kšœœ ˜K˜Kšœœ ˜K˜Kšœœœ˜Kšœœœ˜K˜Kšœ"™"Kšœ.œœ˜:Kšœœ ˜,Kšœ/œ ˜?K˜K˜!Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ K˜K˜šΟnœœ œ*œœ œœ œœœ#˜ΥK˜Kšœ#œ"˜HK˜K˜K˜K˜K˜K˜Kšœœ œœ˜OKšœ œ œœ ˜=K˜Kšœ2Ÿ˜FK˜Kšœ&Ÿ(˜NK˜/K˜K˜KšœE™EK˜K˜hK˜KšœE™EK˜K˜"K˜3K˜ K˜K˜>Kšœ"Ÿ5˜WKšœDŸ˜RKšœ2ŸR˜„Kšœ=Ÿ˜\K˜-K˜K˜^K˜K˜K˜Kšœ8Ÿ@˜xK˜K˜ϋK˜Kšœ˜ K˜—K˜š  œœ œœOœ˜‰K˜K˜!KšœŸ˜,KšœŸ˜,K˜)K˜!šœœŸ4˜EK˜KšœFœŸ˜kK˜KšœŸ œŸœŸ˜PKšœ)Ÿ˜FK˜*K˜(K˜,K˜—K˜K˜K˜K˜ KšœŸ˜*K˜—K˜š  œœ œ8œœ2œœ œœ˜ήK˜K˜uK˜(K˜K˜—š œœ œœ.˜gK˜!Kšœ/Ÿ˜JKšœ$Ÿ˜?Kšœ%Ÿ˜?Kšœ2Ÿ˜LK˜2K˜—K˜š œœ œœ.˜hKšœ2Ÿ˜LKšœ5Ÿ˜QK˜2K˜7K˜—K˜š   œ œœ œœ8œ˜K˜K˜+Kšœ œœ˜QKšœŸ˜>šœ(œ˜HK˜#šœ œ ˜šœ œ ˜K˜0K˜Kšœ œ˜!šœœ˜K˜K˜K˜K˜K˜K˜—Kšœ˜—Kšœ˜—Kšœ˜—Kšœ&˜,K˜—K˜š  œ œ5œœ˜dK˜K˜K˜$K˜—K˜š œ œ œœ˜/Kšœ!œœ˜IKšœ!œœ˜IK˜—K˜K˜——…—'