DIRECTORY ColorDisplayHeadDorado, Real USING [RoundC, LargestNumber], WindowManager, Inline USING [LowByte]; MonitorToolOps: PROGRAM IMPORTS Real, Inline, WindowManager, ColorDisplayHeadDorado SHARES ColorDisplayHeadDorado = BEGIN OPEN ColorDisplayHeadDorado, WindowManager; 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: REAL; --desired pixel time in nanoseconds, rate in MHz truePixeltime, truePixelfreq: REAL; --actual pixel time in nanoseconds, rate in MHz lineTime, lineFreq: REAL; --desired line time in microseconds, rate in KHz trueLinetime, trueLinefreq: REAL; --actual line time in microseconds, rate in KHz fieldTime, fieldFreq: 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: CARDINAL; hBLeadLength: [0..377B]; hSTrailAddr: [0..377B]; hBTrailLength: CARDINAL; vbToVS: [0..377B]; defaultVBtoVS: [0..377B] _ 0; vsToVS: [0..377B]; defaultVStoVS: [0..377B] _ 3; vsToVB: CARDINAL; visibleLines: CARDINAL; refFreq, nextFreq, bestFreq, fDiff, bestDiff: REAL; trueMul, nextMul, bestMul: [0..377B]; trueZero, bestZero, trueDiv, nextDiv, bestDiv: [0..17B]; MonitorParam: TYPE = REF MonitorParamRec; MonitorParamRec: TYPE = RECORD [hRes: CARDINAL, vRes: CARDINAL, vc: VControl, hc: HControl, cc: CControl, lmarg: CARDINAL, truePixelFreq, truePixelTime: REAL]; mp: MonitorParam; sw: CARDINAL; sh: CARDINAL; rr: CARDINAL; hbt: REAL ; vbt: REAL ; DoMonitorParams: PROCEDURE [screenWidth, screenHeight, refreshRate: CARDINAL, hBlankTime, vBlankTime: REAL, NTSCBoard: BOOLEAN _ FALSE, interlace: BOOLEAN _ TRUE] RETURNS [MonitorParam] = { mp: MonitorParam _ NEW[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 _ Inline.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: PROCEDURE [bpp: CARDINAL _ 8, mp: MonitorParam] = { WindowManager.StopColorViewers[]; displayType _ IF bpp#24 THEN Hitachi3619 ELSE Standard525; screenwidth _ mp.hRes; -- must be a multiple of 32 screenheight _ mp.vRes; -- must be a multiple of 2 WindowManager.StartColorViewers[left,bpp]; ColorDisplayHeadDorado.TurnOff[]; color.vcontrol _ mp.vc; color.hcontrol _ mp.hc; color.ccontrol _ mp.cc; ColorDisplayHeadDorado.TurnOn[]; LMarg[mp.lmarg]; --only works if turned on }; StartMonitor: PROCEDURE [screenWidth, screenHeight, refreshRate, bitsPerPixel: CARDINAL, hBlankTime, vBlankTime: REAL, NTSCBoard: BOOLEAN _ FALSE, interlace: BOOLEAN _ TRUE] = { mp _ DoMonitorParams[screenWidth, screenHeight, refreshRate, hBlankTime*1E-6, vBlankTime*1E-6, NTSCBoard, interlace]; SetMonitorParams[bitsPerPixel, mp]; }; 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] = { IF mcb.achanCB#rpNIL THEN achan.leftMargin _ lmarg; IF mcb.bchanCB#rpNIL THEN bchan.leftMargin _ lmarg; }; END. ØMonitorToolOps.mesa Last Edited August 30, 1983 4:55 pm by Ken Pier Last Edited by: Sosinski, September 14, 1983 11:31 am --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 Ê}˜Jšœ™Jšœ/™/J™5šÏk ˜ Jšœ˜Jšœœ˜#J˜Jšœœ ˜J˜—šœœ˜Jšœ4˜;Jšœ˜&Jšœ'˜+J˜J™JšœœÏc)™JJšœ œž)™˜>Jšœ"ž5˜WJšœDž˜RJšœ2žR˜„Jšœ=ž˜\Jšœ-˜-J˜Jšœ^˜^J˜J˜J˜Jšœ8ž@˜xJ˜Jšœü˜üJ˜Jšœ˜ J˜—J˜šŸœ œ*˜EJ˜J˜!J˜:Jšœž˜2Jšœž˜2J˜*Jšœ!˜!Jšœ˜J˜J˜Jšœ ˜ Jšœž˜*J˜J˜—šŸ œ œ8œœ œœ œœ˜²J˜Jšœu˜uJšœ#˜#J˜J˜——˜š Ÿ œ œœ œœ8œ˜J˜Jšœ+˜+Jšœ œœ˜QJšœž˜>šœ(œ˜HJšœ#˜#šœ œ ˜šœ œ ˜Jšœ0˜0Jšœ˜Jšœ œ˜!šœœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜—Jšœ˜—Jšœ˜—Jšœ˜—Jšœ&˜,J˜—J˜šŸ œ œ5œœ˜dJ˜Jšœ˜Jšœ$˜$J˜—J˜šŸœ œ œ˜'Jšœ3˜3Jšœ3˜3J˜—J˜Jšœ˜——…—¬