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

📄 cvt.c

📁 GM5621原代码
💻 C
字号:
/*
	$Workfile:   cvt.c  $
	$Revision:   1.10  $
	$Date:   Jan 12 2006 04:45:54  $
*/

//******************************************************************
//
//          Copyright (C) 2002. GENESIS MICROCHIP INC.
//  All rights reserved.  No part of this program may be reproduced.
//
//	Genesis Microchip Corp., 2150 Gold Street
//			Alviso, CA 95002	USA
//  Genesis Microchip Inc., 165 Commerce Valley Dr. West
//          Thornhill, Ontario, Canada, L3T 7V8
//
//================================================================
//
//  MODULE: cvt.c
//
//******************************************************************
#include "inc\all.h"

#if (SUPPORT_VESA_CVT_MODES)

#define	DEBUG_CVT    			0
#define  DEBUG_CVT_EXTENDED	0

#define  USE_VBP_CHECK			0


#if DEBUG_CVT && DEBUG_MSG
	#define	msg(a,b)	gm_Print((const char far *)a,b)
#else
	#define msg(a,b)
#endif
#if DEBUG_CVT_EXTENDED && DEBUG_MSG
	#define	msgx(a,b)	gm_Print((const char far *)a,b)
#else
	#define msgx(a,b)
#endif



//**************************************************************
//	         G L O B A L   V A R I A B L E S
//**************************************************************

//**************************************************************
//	         L O C A L   V A R I A B L E S
//**************************************************************
typedef struct cvt_aspect_ratio_struct
{
	BYTE	VsyncWidth;
	BYTE  Width;
	BYTE  Height;
}cvt_aspect_ratio_type;

cvt_aspect_ratio_type ROM cvt_aspect[] = {
{ 4, 4,3 }, // vsync == 4,  4:3
{ 5,16,9 }, // vsync == 5, 16:9
{ 6,16,10}, // vsync == 6, 16:10
{ 7, 5,4 }, // vsync == 7 & VTotal > 1000  5:4
{ 7, 15,9}}; // vsync == 7 & Vtotal < 1000 15:9

//**************************************************************
//	         L O C A L   D E F I N I T I O N S
//**************************************************************
#define MIN_VERT_BP		7
#define VERT_FP			3

#define RB_MIN_V_BLANK_PERIOD 		460	// 460 ms.
#define NORM_MIN_V_BLANK_PERIOD 		550	// 500 ms.
#define RB_MIN_V_BLANK_LINES			13

#define RB_H_BLANK						160

#define C_PRIME				30
#define M_PRIME				300

#define MAKE_DIV8(a)		((a) & 0xfff8)

//**************************************************************
//	         LOCAL  FUNCTION   PROTOTYPES
//**************************************************************
WORD cvt_getVBP(void);
WORD cvt_getVsyncWidth(void);

static WORD __near getVBI(void);
static BYTE __near isReducedBlanking(void);
static WORD __near getVActive(void);



//***************************************************************
//	DESCRIPTION	:	Determine if mode is a CVT mode.
//
//	SYNTAX     	:	gmt_RET_STAT cvt_IsCVT(void)
//	PARAMETERS	:	none
//  RETURN		:	gmd_NORMAL, gmd_CVT_MODE, CVT_REDUCED_BLANKING
//
//***************************************************************
gmt_MODE_TYPE cvt_IsCVT(void)
{
	WORD VsyncWidth;

// 1) only perform CVT check on DSS sync, all other sync types will always
//    have sync polarities opposite.
	if(InputPortSyncArray[gmvb_CurrentPortMain].B_SyncType != gmd_DSS_SYNC)
	{
		msgx("cvt: Not gmd_DSS_SYNC",0);
		return gmd_FALSE;
	}

// 2) check sync polarity, if Hsync an Vsynd the same polarity, then it's
//    not a CVT mode.
	if((gmvw_InputFlagsMain & gmd_NEG_VSYNC) && (gmvw_InputFlagsMain & gmd_NEG_HSYNC))
	{
		msgx("cvt: both NEG sync",0);
		return gmd_FALSE;
	}
	if(!(gmvw_InputFlagsMain & gmd_NEG_VSYNC) && !(gmvw_InputFlagsMain & gmd_NEG_HSYNC))
	{
		msgx("cvt: both POS sync",0);
		return gmd_FALSE;
	}
// 3) if 3 < Vpulse < 6 then could be CVT...
	VsyncWidth = cvt_getVsyncWidth();

	if(VsyncWidth < 4 || VsyncWidth > 7)
	{
		msgx("cvt: 4 <= VsyncWidth <=7 width %d",VsyncWidth);
		return gmd_FALSE;
	}
#if USE_VBP_CHECK
// 4) if Vsync_bp >= 6, then CVT mode.
	if(cvt_getVBP() <= 6)
	{
		msgx("cvt: VsyncBP < 6 %d", cvt_getVBP());
		return gmd_FALSE;
	}
#endif
	if(isReducedBlanking())
	{
		msgx("cvt: is CVT RB mode",0);
		gmvw_InputFlagsMain |= gmd_CVT_MODE_RB;
	}
	else
	{
		msgx("cvt: is CVT mode",0);
		gmvw_InputFlagsMain |= gmd_CVT_MODE;
	}

	return gmd_TRUE;
}
//***************************************************************
//	DESCRIPTION	:	Calculates HTotal
//
//	SYNTAX     	:	WORD cvt_CalcHTotal(void)
//	PARAMETERS	:	none
//  RETURN		:	void
//
//***************************************************************
void cvt_CalcTiming(void)
{
	BYTE i;
	WORD HTotal, HActive, idealDC, HBlanking;
	WORD VActive;
	WORD VsyncWidth;
	WORD roundup;

	VActive = getVActive();
	VsyncWidth = cvt_getVsyncWidth();

	msg("cvt: VActive %d",VActive);
	msg("cvt: VsyncWidth %d",VsyncWidth);

	for(i=0;i<(sizeof(cvt_aspect)/sizeof(cvt_aspect[0]));i++)
	{
		if(cvt_aspect[i].VsyncWidth == VsyncWidth)
			break;
	}
	// one more check, if vsync width is 7, and VTotal > 1000, then 15:9 mode.
	if((VsyncWidth == 7) && (gmvw_InputVTotalMain < 1000) )
	{
		msg("vsync == 7 and Vtotal < 1000",0);
		i++;
	}

	msg("cvt: Width %d",cvt_aspect[i].Width);
	msg("cvt: Height %d",cvt_aspect[i].Height);

	roundup = cvt_aspect[i].Height / 2;
	HActive = (WORD)((((DWORD)VActive * cvt_aspect[i].Width) + roundup) / cvt_aspect[i].Height);
	HActive = MAKE_DIV8(HActive); // divisable by 8.

	msg("cvt: HActive %d",HActive);

	if(isReducedBlanking())
	{
		HTotal = RB_H_BLANK + HActive;

	}
	else
	{// Standard CVT timing.
		roundup = gmvw_InputHFreqMain / 2;
		idealDC = C_PRIME - ((( M_PRIME * 10) + roundup) / gmvw_InputHFreqMain );
		msg("cvt: idealDC %d",idealDC);
		if(idealDC < 20) // < 20%
		{
			roundup = 40;
			HBlanking = MAKE_DIV8(((HActive * 20) + roundup) / 80);
			msg("cvt idealDC < 20: HBlanking %d",HBlanking);
		}
		else
		{
			roundup = (100 - idealDC) / 2;
			HBlanking = MAKE_DIV8(((HActive * idealDC) + roundup)/(100 - idealDC));
			msg("cvt ideal DC > 20: HBlanking %d",HBlanking);
		}
		HTotal = MAKE_DIV8(HBlanking + HActive);
		msg("cvt: HTotal %d",HTotal);
	}

	gmvw_StdHTotal   = HTotal;
	gmvw_InputHTotalMain = HTotal;
	gmvw_InputWidthMain  = HActive;
	W_SrcModeWidth  = HActive;
	gmvw_InputHeightMain = VActive;
}

//***************************************************************
//	DESCRIPTION	:	Calculates Vactive
//
//	SYNTAX     	:	WORD getVActive(void)
//	PARAMETERS	:	none
//  RETURN		:	Vertical Active lines.
//
//***************************************************************
static WORD __near getVActive(void)
{
	WORD vbi, Vactive;

	vbi = getVBI();

	Vactive = (gmvw_InputVTotalMain - vbi) & 0xfffe; // make even.

	return Vactive;
}
//***************************************************************
//	DESCRIPTION	:	Calculates Vsync back porch
//
//	SYNTAX     	:	WORD cvt_getVBP(void)
//	PARAMETERS	:	none
//  RETURN		:	Vsync back porch
//
//***************************************************************
WORD cvt_getVBP(void)
{
	WORD verticalBlank, VsyncBP, VsyncWidth;

	VsyncWidth = cvt_getVsyncWidth();
	verticalBlank = getVBI();

	VsyncBP = verticalBlank - VERT_FP - VsyncWidth;
	msg("cvt_getVBP: verticalBlank %d",verticalBlank);
	msg("cvt_getVBP: VERT_FP %d",(WORD)VERT_FP);
	msg("cvt_getVBP: VsyncWidth %d",VsyncWidth);
	return VsyncBP;
}
//***************************************************************
//	DESCRIPTION	:	Calculates Vertical blanking interval
//
//	SYNTAX     	:	WORD getVBI(void)
//	PARAMETERS	:	none
//  RETURN		:	Vsync back porch
//
//***************************************************************
static WORD __near getVBI(void)
{
	WORD verticalBlank;

	if(isReducedBlanking())
	{
		verticalBlank = (WORD)(((DWORD)RB_MIN_V_BLANK_PERIOD * gmvw_InputHFreqMain) / 10000) + 1;

		if(verticalBlank < RB_MIN_V_BLANK_LINES)
			verticalBlank = RB_MIN_V_BLANK_LINES;

		msg("getVBI rb: verticalBlank %d",verticalBlank);
	}
	else
	{// Standard CVT timing.
		verticalBlank = (WORD)(((DWORD)NORM_MIN_V_BLANK_PERIOD * gmvw_InputHFreqMain) / 10000) + 1 + VERT_FP;
		msgx("getVBI std: gmvw_InputHFreqMain %d",gmvw_InputHFreqMain);
		msg("getVBI std: verticalBlank %d",verticalBlank);
	}
	return verticalBlank;
}
//***************************************************************
//	DESCRIPTION	:	Calculates Vsync width
//
//	SYNTAX     	:	WORD cvt_getVsyncWidth(void)
//	PARAMETERS	:	none
//  RETURN		:	Vsync width
//
//***************************************************************
WORD cvt_getVsyncWidth(void)
{
	if (gmvw_InputFlagsMain & gmd_NEG_VSYNC)
		return(gmvw_InputVTotalMain - gmvw_InputVPulse);
	return(gmvw_InputVPulse);
}

//***************************************************************
//	DESCRIPTION	:	determines standard blanking or reduced blanking
//
//	SYNTAX     	:	BYTE isReducedBlanking(void)
//	PARAMETERS	:	none
//  RETURN		:	gmd_TRUE/gmd_FALSE
//
//***************************************************************
static BYTE __near isReducedBlanking(void)
{
// if H+ and V- then reduced blanking
	if(gmvw_InputFlagsMain & gmd_NEG_VSYNC)
		return gmd_TRUE;
	return gmd_FALSE;
}

#endif //SUPPORT_VESA_CVT_MODES

⌨️ 快捷键说明

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