📄 cvt.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 + -