⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modehandler.c

📁 GM5621原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (LocalIndex == 0xff)
			break;

		LocalTablePtr = &StandardModeTable[LocalIndex];

		// exit if indexing last element (used if StdModeArray == NULL_PTR)
		if(LocalTablePtr->StdHFreq == 0)
			break;
		if ((abs(LocalTablePtr->StdHFreq - gmvw_InputHFreqMain) <= LocalTablePtr->DeltaHFreq) &&
			(abs(LocalTablePtr->StdVTotal - gmvw_InputVTotalMain) <= LocalTablePtr->DeltaVTotal))
		{
			#if USE_OVERLAPPED_MODE
			if (LocalTablePtr->ModeType & gmd_OVERLAPPED_MASK)
			{	// if negative Vsync, then set it as 640/720x350 mode
				// otherwise set to 640/720x400 mode.
				if ((gmvw_InputFlagsMain & gmd_NEG_VSYNC) ==  gmd_NEG_VSYNC)
				{
					if ((LocalTablePtr->ModeType & gmd_OVERLAPPED350) == gmd_OVERLAPPED350) // Louis 0322
					{	// 640/720x350 mode with +/- H/V sync polarity
						if ((UserPrefOverlappedMode == DOS) && (LocalTablePtr->StdWidth != 720))
						{ // continue for next DOS. (720x350)
							continue;
						}
						else
						{// check NVRAM if mode exists, and if Htotals differ by
						 // less than 50.  If > 50 continue.  Only if we're in
						 // Default mode, otherwise go with the table.
							if((UserPrefOverlappedMode == Default) && (ReadModeDependentEntry() == gmd_OK))
							{
								if(abs(UserPrefHTotal - LocalTablePtr->StdHTotal) > 50)
									continue;
							}
						}
					}
					else
						continue;
				}
				else
				{// we're in the 640/720x400 modes
					if ((LocalTablePtr->ModeType & gmd_OVERLAPPED350) == gmd_OVERLAPPED350) // Louis 0322
						continue;

					// set to 640/720 x 400 modes
					if (UserPrefOverlappedMode == Default)
					{	// if default for 400 modes, detect 640/720 mode depending upon
						// the input vertical total with zero tolerance for 640x400x85hz.
						// VTotal for 640x400x85hz is 445, and 720x400x85 is 446.
						if ((LocalTablePtr->StdWidth == 640) && (gmvw_InputVFreqMain > 840))
						{
							if (LocalTablePtr->StdVTotal != gmvw_InputVTotalMain)
								continue;
						}
						else
						{// check NVRAM if mode exists, and if Htotals differ by
						 // less than 50.  if > 50 continue.
							if((UserPrefOverlappedMode == Default) && (ReadModeDependentEntry() == gmd_OK))
							{
								if(abs(UserPrefHTotal - LocalTablePtr->StdHTotal) > 50)
									continue;
							}
						}
					}
					else if ((UserPrefOverlappedMode == DOS) && (LocalTablePtr->StdWidth != 720))
					{// continue for next DOS. (720x400)
						continue;
					}
				}
				}

			#else
			// if positive Hsync and negative Vsync, then set it as 640x350 mode
			// otherwise set to 720x400 mode.
			if ((LocalTablePtr->ModeType == gmd_OVERLAPPED350) &&
				((gmvw_InputFlagsMain & gmd_SYNC_POL_MASK) !=  gmd_NEG_VSYNC))
            {
                continue;
            }
			#endif

			ModeTableIndex = LocalIndex;

			// update input window format from the standard mode table
			gmvw_StdHTotal   = LocalTablePtr->StdHTotal;
			gmvw_InputHTotalMain = LocalTablePtr->StdHTotal;
			gmvw_InputWidthMain  = LocalTablePtr->StdWidth;
			W_SrcModeWidth  = LocalTablePtr->StdWidth;
			gmvw_InputHeightMain = LocalTablePtr->StdHeight;

			UserPrefOverlappedMode = Default;

			// pdr#5720. add mask overlapped
			// pdr#5530. set Overlapped mode flag
			gmvw_InputFlagsMain |= LocalTablePtr->ModeType & gmd_OVERLAPPED_MASK;		// set flags for Overlapped mode

			// PDR#5333. H/V Start variables will be set later using sub function
			// to save the code space.
			// Refer SetupHVStartVariables() function.

			return LocalTablePtr; // return with pointer to mode that matches the input format
		}
	}
	return NULL_PTR; // no match for this table
}

//******************************************************************
// DESCRIPTION  : This function takes the input Vertical total values
//						and tries to find a match in the mode definition.
//						The estimated mode table should be in order.
//						If the input vertical total is greater than height but
//						less than the max value (normally height of next mode),
//						then it assumes as an estimated mode.
// SYNCTEX		:  EstSearchModeTable()
// PARAMETERS	:  void
// RETURN      :  Returns pointer to mode table entry if mode was succesfully
//					detected else NULL.
//******************************************************************
static EstimatedModeType ROM * __near EstSearchModeTable(void)
{
	BYTE i;
	BYTE LocalIndex;
	EstimatedModeType ROM * LocalTablePtr;

	// search the estimated mode table entries until it finds the matching mode
	// or the end of table.
	for (i=0; ;i++) //end of table is denoted by ModeTableIndex = 0xff
	{
		if(InputPortArray[gmvb_CurrentPortMain].EstModeArray != NULL_PTR)
			LocalIndex = InputPortArray[gmvb_CurrentPortMain].EstModeArray[i];
		else
			LocalIndex = i;

		// exit if end of table
		if (LocalIndex == 0xff)
			break;

	  LocalTablePtr = &EstimatedModeTable[LocalIndex];

		// exit if indexing last element (used if StdModeArray == NULL_PTR)
		if(LocalTablePtr->StdHeight == 0)
			break;

		// check the vertical total to find the estimated mode.
		// the estimated mode table should be in order of the vtotal.
		// If the input vertical total is bigger than mode height and
		// less than the max vtotal (next mode height + alpha), then
		// it assumes as a matching mode.
		if ((gmvw_InputVTotalMain > LocalTablePtr->StdHeight) &&
			(gmvw_InputVTotalMain <= LocalTablePtr->MaxVTotal) )
		{
			// Set unknown mode bit in input format flags indicating estimated mode
			gmvw_InputFlagsMain |= gmd_ESTIMATED;
			ModeTableIndex = LocalIndex;

			// set the standard input variables
			gmvw_StdHTotal   = LocalTablePtr->StdHTotal;
			gmvw_InputHTotalMain = LocalTablePtr->StdHTotal;
			gmvw_InputWidthMain  = LocalTablePtr->StdWidth;
			W_SrcModeWidth  = LocalTablePtr->StdWidth;

			// height for the interlaced mode is 1/2 of normal.
			if (gmvw_InputFlagsMain & gmd_INTERLACED)
			{
				gmvw_InputHeightMain = LocalTablePtr->StdHeight/2;
			}
			else
				gmvw_InputHeightMain = LocalTablePtr->StdHeight;

			return LocalTablePtr;
		}
	}
	return NULL_PTR;	// didn't find a match even using estimated search
}


//***************************************************************
// DESCRIPTION  : This function is called after a new stable mode
//						has been detected. First it will make sure that
//						the chip is awake and in normal functioning mode.
//						After that it will make sure that the AFR
//						(Auto Free Run) feature is disabled and will look
//						what type of input we have.
//						After that the user mode dependent
//						preferrences are loaded, the shrinking block is
//						set-up and finaly the panel is set to active.
//
//						If everything is gmd_OK gmd_TRUE will be returned if a
//						mode change is detected during this function
//						the function will abort returning gmd_FALSE.
//
//	SYNTAX     	:	gmt_RET_STAT ModeSetup()
//	PARAMETERS	:	none
//  RETURN		:	gmd_TRUE	The condition is present
//					gmd_FALSE	The condition is not present
//***************************************************************
static gmt_RET_STAT __near ModeSetup()
{

	msgx("Mode Setup",0);

	SetupHVStartVariables();

	// Add checking Input ADC clock.
	// check source ADC clock. If ADC clock is too fast for Genesis chip,
	// then it can be reduced by subsampling.
	CheckAdcClock();

	// setup SDDS/DDDS PLL & Divider, and ADC Clamp Width/Start, and AutoFreeRun State
	SetupInputConfig();

	// set input timing control registers
	gm_SetInputWindowMain();

	// check whether input timing is changed again.
	// if so, abort processing for new mode handler.
	if (gm_IsAfrSet() == gmd_TRUE)
	{
		msg("Abort Mode Setup 1",0);
		return gmd_ABORT;
	}

	// set input htotal as well as sclk
	if (InputPortArray[gmvb_CurrentPortMain].PowerDev == gmd_PCD_RGB)
		gm_SetupSclkMain();

	// setup display format / scaler
	if (InputPortArray[gmvb_CurrentPortMain].PowerDev == gmd_PCD_DVI)
	{   //For 1080i mode, the top and bottom display boarder is missing if DVI_HSVS_REGEN is enable.
		//Therefore, disable DVI_HSVS_REGEN for the case.
		if(gmvw_InputFlagsMain & gmd_INTERLACED)
			gm_ClearRegBitsByte(IP_CONTROL, DVI_HSVS_REGEN);
		else
			gm_SetRegBitsByte(IP_CONTROL, DVI_HSVS_REGEN);
	}

	SetupScaler();

	// now OutputFormat has been setup
	// setup hardware SDDS/DDDS, scaler, scale factors, output registers
	gm_SetScalerMain();

#if defined(UserPrefLBNCMode)
	LBNC_Adjust();
#endif
	#ifdef PHOENIX_U //Fixed for ramdon Modesetup failed when swith to Component port.
	    if (InputPortArray[gmvb_CurrentPortMain].Port==IP_COMPONENT)
			if(gm_ReadRegByte(IFM_STATUS) & 7)
			{
				msg("Abort Mode Setup : ifm =NO_HS or NO_VS",0);
				return gmd_ABORT;
			}
	#endif
	gm_SetDisplayGeometryMain();

#if 0 //def PHOENIX_U   //Fixed for ramdon Modesetup failed when swith to Component port.
	if(	gm_SetupDclk(gmvw_InputHTotalMain)!=gmd_TRUE)
		{
			gm_Print("Abort Mode Setup : SetupDclk failed",0);
			return gmd_ABORT;
		}
	
#else		
	#if defined(PHOENIX) || defined (TUCSON) || defined(PHOENIX_U) 
	if((!(gmvw_InputFlagsMain & gmd_VIDEO_SRC)) && (gmvw_InputWidthMain <= PanelWidth) && (B_InputSaveIndex != NonSavedModeLookUpIndex))
	{
		#ifdef UserPrefVFStartValue		
		if(!(UserPrefVFStartValue & UN_SAVE_VFSTART))
			{
				msg("Set VF_START_OFFSET 0x%x from NVRAM",UserPrefVFStartValue);
				gm_WriteRegWord(VF_START_OFFSET, UserPrefVFStartValue & 0x1fff);
			}
		else
		#endif	
			gm_SetupVFStartOffset();
	}
	else
		gm_SetupVFStartOffset();
	#endif
	gm_SetupDclk(gmvw_InputHTotalMain);
#endif	

#ifndef UserPrefVFStartValue

	#if defined(PHOENIX)
	// Special case that new formula can't cover.  Use hard-code value at this moment.
	if ((gmvw_InputWidthMain == 1280 && gmvw_InputHeightMain == 1024) && (gmvw_InputWidthMain == 1280 && gmvw_InputHeightMain == 960 && gmvw_InputVFreqMain > 800))
		gm_WriteRegWord(VF_START_OFFSET, 0x670); // 0x420 is not small enough with certain generator.
	#endif // defined(PHOENIX)

	#if defined(PHOENIX_U)
	// Special case that new formula can't cover.  Use hard-code value at this moment.
	if ((gmvw_InputWidthMain == 1280 && gmvw_InputHeightMain == 1024) && (gmvw_InputWidthMain == 1280 && gmvw_InputHeightMain == 960 && gmvw_InputVFreqMain > 800))
		gm_WriteRegWord(VF_START_OFFSET, 0x670); // 0x420 is not small enough with certain generator.
	if(gmvw_InputWidthMain == 1152) // && PanelHeight == 870)) 
		gm_WriteRegWord(VF_START_OFFSET, 0x670); // 0x420 is not small enough with certain generator.
	#endif // defined(PHOENIX_U)

#endif //UserPrefVFStartValue

	// setup sharpness
//	gm_SetFilterCoeff(UserPrefSharpness);

	// setup phase from ModeDependent data.
	//gmvb_InputPhase = UserPrefHSyncPhase;
#ifdef ZERO_K_MAIN		// gives cleaner display sometimes, but adds a phase skew
	gmvb_InputPhase = ((UserPrefHSyncPhase + KM0PhaseOffset) & 0x3f);
#else
	gmvb_InputPhase = UserPrefHSyncPhase;
#endif
#if USE_COMPONENT_INPUT_ON_RGB
	if ((InputPortArray[gmvb_CurrentPortMain].Port == IP_COMPONENT)&& (gmvw_InputFlagsMain & gmd_VIDEO_SRC))		
	{
		BYTE i=0;
		while(PREDEF_COMPONENT_TBL[i].ModeIndex!=0xff)
		{
			if(PREDEF_COMPONENT_TBL[i].ModeIndex==ModeTableIndex)
				{
						gmvb_InputPhase=PREDEF_COMPONENT_TBL[i].InputPhase;
						break;
				}
				i++;
		}
	}
	
#endif			
	gm_SetAdcPhaseMain(gmvb_InputPhase);

#if defined(FOUR_BIT_BW) && UPDATE_BW_BY_MODE
	if (InputPortArray[gmvb_CurrentPortMain].PowerDev==gmd_PCD_RGB)
	{
		const BYTE BWFilterTable[] = {20, 90, 100, 110, 125, 140, 155, 170, 185, 200, 215, 230, 245, 260, 275, 290};
		BYTE src_clk;
		src_clk=(((gmvw_InputHFreqMain/10)+1)*((gmvw_InputHTotalMain/10)+1))/100;
		for(gmvb_Input_ADC_BW=0;gmvb_Input_ADC_BW<16;gmvb_Input_ADC_BW++)
		{
			if(src_clk<BWFilterTable[gmvb_Input_ADC_BW])
				break;
		}
		gm_ClearAndSetBitsByte(ADC_B_PHASE, ADC_BW, gmvb_Input_ADC_BW<< 4);

	}
#endif



	// check whether input timing is changed again.
	// if so, abort processing for new mode handler.
	if (gm_IsAfrSet() == gmd_TRUE)
	{
		msg("Abort Mode setup 2",0);
		return gmd_ABORT;
	}

	// set up colr matrix, ADC cal settings etc.
	AdjustAllModeIndependentSettings();

	#if defined(PHOENIX) && (PANEL == LG_SXGA_LTM170E01)
	// LG panel fix to avoid jumpy image and line garbage at bottom of display
	// while adjusting VPosition
	gm_WriteRegWord(DP_FLAGLINE,	gmvw_OutputVTotalMain - Alt_DispLines - 1);
	#endif

	#if Enable_AOC		
		EnableAOCMain();
	#ifdef PHOENIX_U       
   	if (InputPortArray[gmvb_CurrentPortMain].YUV == gmd_TRUE)
   		EnableDontUpdateAOCMain();
   	else
   		DisableDontUpdateAOCMain();
	#endif   // PHOENIX_U
	#endif   // Enable_AOC

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -