[PATCH 844/961] staging: xgifb: vb_setmode: move functions to avoid forward declarations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Aaro Koskinen <aaro.koskinen@xxxxxx>

Move functions to avoid forward declarations.

Signed-off-by: Aaro Koskinen <aaro.koskinen@xxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/staging/xgifb/vb_setmode.c |12469 ++++++++++++++++++------------------
 1 files changed, 6178 insertions(+), 6291 deletions(-)

diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
index 5423524..693be07 100644
--- a/drivers/staging/xgifb/vb_setmode.c
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -19,118 +19,6 @@
 #define XGI_MASK_DUAL_CHIP	  0x04  /* SR3A */
 #endif
 
-
-
-static unsigned char  XGI_AjustCRT2Rate(unsigned short ModeNo,
-			unsigned short ModeIdIndex,
-			unsigned short RefreshRateTableIndex,
-			unsigned short *i, struct vb_device_info *pVBInfo);
-static unsigned char  XGI_GetModePtr(unsigned short ModeNo,
-			unsigned short ModeIdIndex,
-			struct vb_device_info *pVBInfo);
-static unsigned short XGI_GetOffset(unsigned short ModeNo,
-			unsigned short ModeIdIndex,
-			unsigned short RefreshRateTableIndex,
-			struct xgi_hw_device_info *HwDeviceExtension,
-			struct vb_device_info *pVBInfo);
-static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
-			unsigned short ModeIdIndex,
-			struct vb_device_info *pVBInfo);
-static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo);
-static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
-			unsigned short ModeIdIndex,
-			unsigned short RefreshRateTableIndex,
-			struct xgi_hw_device_info *HwDeviceExtension,
-			struct vb_device_info *pVBInfo);
-static void XGI_VBLongWait(struct vb_device_info *pVBInfo);
-static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo);
-static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
-static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
-static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void *XGI_GetLcdPtr(unsigned short BX,  unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_AutoThreshold(struct vb_device_info *pVBInfo);
-static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo);
-
-static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo);
-static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo);
-static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex);
-static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short StandTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo);
-
-static void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension);
-static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension);
-static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, struct vb_device_info *pVBInfo);
-static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetCRT1FIFO(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
-static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-
-static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh, struct vb_device_info *pVBInfo);
-/*void     XGI_ClearBuffer(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, struct vb_device_info *pVBInfo);*/
-static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
-static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
-			struct vb_device_info *pVBInfo);
-static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
-			unsigned short RefreshRateTableIndex,
-			struct xgi_hw_device_info *HwDeviceExtension,
-			struct vb_device_info *pVBInfo);
-static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
-static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, struct vb_device_info *pVBInfo);
-static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetDelayComp(struct vb_device_info *pVBInfo);
-static void XGI_SetLCDCap(struct vb_device_info *pVBInfo);
-static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo);
-static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo);
-static void SetSpectrum(struct vb_device_info *pVBInfo);
-static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo);
-static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char* tempcl,
-			unsigned char *tempch, struct vb_device_info *pVBInfo);
-static void XGI_CloseCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
-static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
-static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo);
-static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
-static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
-			struct vb_device_info *pVBInfo);
-static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
-			unsigned short ModeNo,
-			unsigned short ModeIdIndex,
-			struct vb_device_info *pVBInfo);
-static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
-			unsigned char *di_1, struct vb_device_info *pVBInfo);
-static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo);
-static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo);
-static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo);
-static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo);
-static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo);
-static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo);
-
 static unsigned short XGINew_MDA_DAC[] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
@@ -312,1486 +200,1233 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
 
 }
 
-unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
-			unsigned short ModeNo)
+static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
 {
-	unsigned short ModeIdIndex;
-	/* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; */
-	struct vb_device_info VBINF;
-	struct vb_device_info *pVBInfo = &VBINF;
-	pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
-	pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
-	pVBInfo->IF_DEF_LVDS = 0;
-	pVBInfo->IF_DEF_CH7005 = 0;
-	pVBInfo->IF_DEF_LCDA = 1;
-	pVBInfo->IF_DEF_CH7017 = 0;
-	pVBInfo->IF_DEF_CH7007 = 0; /* [Billy] 2007/05/14 */
-	pVBInfo->IF_DEF_VideoCapture = 0;
-	pVBInfo->IF_DEF_ScaleLCD = 0;
-	pVBInfo->IF_DEF_OEMUtil = 0;
-	pVBInfo->IF_DEF_PWD = 0;
+	unsigned char index;
 
-	if (HwDeviceExtension->jChipType >= XG20) { /* kuku 2004/06/25 */
-		pVBInfo->IF_DEF_YPbPr = 0;
-		pVBInfo->IF_DEF_HiVision = 0;
-		pVBInfo->IF_DEF_CRT2Monitor = 0;
-		pVBInfo->VBType = 0; /*set VBType default 0*/
-	} else if (HwDeviceExtension->jChipType >= XG40) {
-		pVBInfo->IF_DEF_YPbPr = 1;
-		pVBInfo->IF_DEF_HiVision = 1;
-		pVBInfo->IF_DEF_CRT2Monitor = 1;
-	} else {
-		pVBInfo->IF_DEF_YPbPr = 1;
-		pVBInfo->IF_DEF_HiVision = 1;
-		pVBInfo->IF_DEF_CRT2Monitor = 0;
+	if (ModeNo <= 0x13)
+		index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex;
+	else {
+		if (pVBInfo->ModeType <= 0x02)
+			index = 0x1B; /* 02 -> ModeEGA */
+		else
+			index = 0x0F;
 	}
+	return index; /* Get pVBInfo->StandTable index */
+}
 
-	pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
-	pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
-	pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
-	pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
-	pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
-	pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C;
-	pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
-	pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
-	pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
-	pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
-	pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
-	pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
-	pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
-	pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
-	pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
-	pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
-	pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
-	pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+/*
+unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) {
+	return (0);
+}
+*/
 
-	if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */
-		if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
-			pVBInfo->IF_DEF_LVDS = 1;
-	}
-	if (HwDeviceExtension->jChipType == XG27) {
-		if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
-			if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20)
-				pVBInfo->IF_DEF_LVDS = 1;
+/* unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex) {
+	return( 0 ) ;
+}
+*/
+
+static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex,
+		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+	unsigned char tempah, SRdata;
+
+	unsigned short i, modeflag;
+
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+	XGINew_SetReg1(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
+	tempah = pVBInfo->StandTable[StandTableIndex].SR[0];
+
+	i = SetCRT2ToLCDA;
+	if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+		tempah |= 0x01;
+	} else {
+		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
+			if (pVBInfo->VBInfo & SetInSlaveMode)
+				tempah |= 0x01;
 		}
 	}
 
-	if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
-		XGI_GetVBType(pVBInfo);
+	tempah |= 0x20; /* screen off */
+	XGINew_SetReg1(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
 
-	InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
-	if (ModeNo & 0x80) {
-		ModeNo = ModeNo & 0x7F;
-		/* XGINew_flag_clearbuffer = 0; */
+	for (i = 02; i <= 04; i++) {
+		SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */
+		XGINew_SetReg1(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
 	}
-	/* else {
-		XGINew_flag_clearbuffer = 1;
+}
+
+static void XGI_SetMiscRegs(unsigned short StandTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned char Miscdata;
+
+	Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
+	/*
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+			Miscdata |= 0x0C;
+		}
 	}
 	*/
-	XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
 
-	if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */
-		XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
+	XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
+}
 
-	XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
+static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
+{
+	unsigned char CRTCdata;
+	unsigned short i;
 
-	XGI_GetVGAType(HwDeviceExtension, pVBInfo);
+	CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+	CRTCdata &= 0x7f;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
 
-	if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
-		XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
-		XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
-		XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
-		XGI_DisableBridge(HwDeviceExtension, pVBInfo);
-		/* XGI_OpenCRTC(HwDeviceExtension, pVBInfo); */
+	for (i = 0; i <= 0x18; i++) {
+		CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */
+		XGINew_SetReg1(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
+	}
+	/*
+	if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) {
+		if (pVBInfo->VBInfo & SetInSlaveMode) {
+			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+				XGINew_SetReg1(pVBInfo->P3d4, 0x18, 0xFE);
+			}
+		}
+	}
+	*/
+}
 
-		if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
-			XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
-					ModeIdIndex, pVBInfo);
+static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex,
+		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+	unsigned char ARdata;
+	unsigned short i, modeflag;
 
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-				XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
-						HwDeviceExtension, pVBInfo);
-			}
-		} else {
-			if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
-				XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
-						ModeIdIndex, pVBInfo);
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+	for (i = 0; i <= 0x13; i++) {
+		ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
+		if (modeflag & Charx8Dot) { /* ifndef Dot9 */
+			if (i == 0x13) {
 				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-					XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
-							HwDeviceExtension,
-							pVBInfo);
+					ARdata = 0;
+				} else {
+					if (pVBInfo->VBInfo & (SetCRT2ToTV
+							| SetCRT2ToLCD)) {
+						if (pVBInfo->VBInfo
+								& SetInSlaveMode)
+							ARdata = 0;
+					}
 				}
 			}
 		}
 
-		if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
-			switch (HwDeviceExtension->ujVBChipID) {
-			case VB_CHIP_301:
-				XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
-						pVBInfo); /*add for CRT2 */
-				break;
+		XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+		XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */
+		XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */
+	}
 
-			case VB_CHIP_302:
-				XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
-						pVBInfo); /*add for CRT2 */
-				break;
+	XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+	XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */
+	XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */
+	XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
+	XGINew_SetReg3(pVBInfo->P3c0, 0x20);
+}
 
-			default:
-				break;
-			}
-		}
+static void XGI_SetGRCRegs(unsigned short StandTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned char GRdata;
+	unsigned short i;
 
-		XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
-		XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
-		XGI_CloseCRTC(HwDeviceExtension, pVBInfo);
-		XGI_EnableBridge(HwDeviceExtension, pVBInfo);
-	} /* !XG20 */
-	else {
-		if (pVBInfo->IF_DEF_LVDS == 1)
-			if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
-				return 0;
+	for (i = 0; i <= 0x08; i++) {
+		GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */
+		XGINew_SetReg1(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
+	}
 
-		if (ModeNo <= 0x13) {
-			pVBInfo->ModeType
-					= pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
-							& ModeInfoFlag;
-		} else {
-			pVBInfo->ModeType
-					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag
-							& ModeInfoFlag;
-		}
-
-		pVBInfo->SetFlag = 0;
-		if (pVBInfo->IF_DEF_CH7007 != 1)
-			pVBInfo->VBInfo = DisableCRT2Display;
-
-		XGI_DisplayOff(HwDeviceExtension, pVBInfo);
-
-		XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
-				pVBInfo);
-
-		XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-		/*
-		if (HwDeviceExtension->jChipType == XG21)
-			XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80);
-		*/
+	if (pVBInfo->ModeType > ModeVGA) {
+		GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05);
+		GRdata &= 0xBF; /* 256 color disable */
+		XGINew_SetReg1(pVBInfo->P3ce, 0x05, GRdata);
 	}
+}
 
-	/*
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-	pVBInfo->ModeType = modeflag&ModeInfoFlag;
-	pVBInfo->SetFlag = 0x00;
-	pVBInfo->VBInfo = DisableCRT2Display;
-	temp = XGINew_CheckMemorySize(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
+{
+	unsigned short i;
 
-	if (temp == 0)
-		return (0);
+	for (i = 0x0A; i <= 0x0E; i++)
+		XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
+}
 
-	XGI_DisplayOff(HwDeviceExtension, pVBInfo) ;
-	XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
-	XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-	*/
+static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
+{
 
-	XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
+	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
 
-	if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
-		XGI_LockCRT2(HwDeviceExtension, pVBInfo);
-	}
+	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
 
-	return 1;
+	XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30);
+	return 0;
 }
 
-static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short ModeNo, unsigned short ModeIdIndex,
+static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
+		unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex, unsigned short *i,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp;
-
-	unsigned short XGINew_P3cc = pVBInfo->P3cc;
+	unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
 
-	/* XGINew_CRT1Mode = ModeNo; // SaveModeID */
-	StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
-	/* XGI_SetBIOSData(ModeNo, ModeIdIndex); */
-	/* XGI_ClearBankRegs(ModeNo, ModeIdIndex); */
-	XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
-	XGI_SetMiscRegs(StandTableIndex, pVBInfo);
-	XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo);
-	XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
-	XGI_SetGRCRegs(StandTableIndex, pVBInfo);
-	XGI_ClearExt1Regs(pVBInfo);
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	/* if (pVBInfo->IF_DEF_ExpLink) */
-	if (HwDeviceExtension->jChipType == XG27) {
-		if (pVBInfo->IF_DEF_LVDS == 0)
-			XGI_SetDefaultVCLK(pVBInfo);
-	}
+	resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+	tempax = 0;
 
-	temp = ~ProgrammingCRT2;
-	pVBInfo->SetFlag &= temp;
-	pVBInfo->SelectCRT2Rate = 0;
+	if (pVBInfo->IF_DEF_LVDS == 0) {
+		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+			tempax |= SupportRAMDAC2;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA
-				| SetInSlaveMode)) {
-			pVBInfo->SetFlag |= ProgrammingCRT2;
+			if (pVBInfo->VBType & VB_XGI301C)
+				tempax |= SupportCRT2in301C;
 		}
-	}
 
-	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
-			ModeIdIndex, pVBInfo);
-	if (RefreshRateTableIndex != 0xFFFF) {
-		XGI_SetSync(RefreshRateTableIndex, pVBInfo);
-		XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-				pVBInfo, HwDeviceExtension);
-		XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, pVBInfo);
-		XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-				HwDeviceExtension, pVBInfo);
-		XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
-				RefreshRateTableIndex, pVBInfo);
-	}
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
+			tempax |= SupportLCD;
 
-	if ((HwDeviceExtension->jChipType >= XG20)
-			&& (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */
-		if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9);
-			b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
-			XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
-		} else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo
-				== 0x0D)) {
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3);
-			b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
-			XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
+			if (pVBInfo->LCDResInfo != Panel1280x1024) {
+				if (pVBInfo->LCDResInfo != Panel1280x960) {
+					if (pVBInfo->LCDInfo & LCDNonExpanding) {
+						if (resinfo >= 9) {
+							tempax = 0;
+							return 0;
+						}
+					}
+				}
+			}
 		}
-	}
 
-	if (HwDeviceExtension->jChipType >= XG21) {
-		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
-		if (temp & 0xA0) {
+		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
+			if ((pVBInfo->VBType & VB_XGI301LV)
+					&& (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
+				tempax |= SupportYPbPr;
+				if (pVBInfo->VBInfo & SetInSlaveMode) {
+					if (resinfo == 4)
+						return 0;
 
-			/* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */
-			/* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */
-			/* XG21 CRT1 Timing */
-			if (HwDeviceExtension->jChipType == XG27)
-				XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
-						RefreshRateTableIndex, pVBInfo);
-			else
-				XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
-						RefreshRateTableIndex, pVBInfo);
+					if (resinfo == 3)
+						return 0;
 
-			XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
-					RefreshRateTableIndex);
+					if (resinfo > 7)
+						return 0;
+				}
+			} else {
+				tempax |= SupportHiVisionTV;
+				if (pVBInfo->VBInfo & SetInSlaveMode) {
+					if (resinfo == 4)
+						return 0;
 
-			if (HwDeviceExtension->jChipType == XG27)
-				XGI_SetXG27LCD(pVBInfo, RefreshRateTableIndex,
-						ModeNo);
-			else
-				XGI_SetXG21LCD(pVBInfo, RefreshRateTableIndex,
-						ModeNo);
+					if (resinfo == 3) {
+						if (pVBInfo->SetFlag
+								& TVSimuMode)
+							return 0;
+					}
 
-			if (pVBInfo->IF_DEF_LVDS == 1) {
-				if (HwDeviceExtension->jChipType == XG27)
-					XGI_SetXG27LVDSPara(ModeNo,
-							ModeIdIndex, pVBInfo);
-				else
-					XGI_SetXG21LVDSPara(ModeNo,
-							ModeIdIndex, pVBInfo);
+					if (resinfo > 7)
+						return 0;
+				}
 			}
-			/* XGINew_SetRegOR(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */
-		}
-	}
+		} else {
+			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+					| SetCRT2ToSVIDEO | SetCRT2ToSCART
+					| SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
+				tempax |= SupportTV;
 
-	pVBInfo->SetFlag &= (~ProgrammingCRT2);
-	XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
-	XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
-			RefreshRateTableIndex, pVBInfo);
+				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+						| VB_XGI301LV | VB_XGI302LV
+						| VB_XGI301C)) {
+					tempax |= SupportTV1024;
+				}
 
-	/* XGI_LoadCharacter(); //dif ifdef TVFont */
+				if (!(pVBInfo->VBInfo & SetPALTV)) {
+					if (modeflag & NoSupportSimuTV) {
+						if (pVBInfo->VBInfo
+								& SetInSlaveMode) {
+							if (!(pVBInfo->VBInfo
+									& SetNotSimuMode)) {
+								return 0;
+							}
+						}
+					}
+				}
+			}
+		}
+	} else { /* for LVDS */
+		if (pVBInfo->IF_DEF_CH7005 == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToTV)
+				tempax |= SupportCHTV;
+		}
 
-	XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
-	/* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */
-}
+		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+			tempax |= SupportLCD;
 
-static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned char index;
+			if (resinfo > 0x08)
+				return 0; /* 1024x768 */
 
-	if (ModeNo <= 0x13)
-		index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex;
-	else {
-		if (pVBInfo->ModeType <= 0x02)
-			index = 0x1B; /* 02 -> ModeEGA */
-		else
-			index = 0x0F;
-	}
-	return index; /* Get pVBInfo->StandTable index */
-}
+			if (pVBInfo->LCDResInfo < Panel1024x768) {
+				if (resinfo > 0x07)
+					return 0; /* 800x600 */
 
-/*
-unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) {
-	return (0);
-}
-*/
-
-/* unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex) {
-	return( 0 ) ;
-}
-*/
-
-static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	unsigned char tempah, SRdata;
-
-	unsigned short i, modeflag;
-
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+				if (resinfo == 0x04)
+					return 0; /* 512x384 */
+			}
+		}
+	}
 
-	XGINew_SetReg1(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
-	tempah = pVBInfo->StandTable[StandTableIndex].SR[0];
+	for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) {
+		infoflag
+				= pVBInfo->RefIndex[RefreshRateTableIndex
+						+ (*i)].Ext_InfoFlag;
+		if (infoflag & tempax)
+			return 1;
 
-	i = SetCRT2ToLCDA;
-	if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-		tempah |= 0x01;
-	} else {
-		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
-			if (pVBInfo->VBInfo & SetInSlaveMode)
-				tempah |= 0x01;
-		}
+		if ((*i) == 0)
+			break;
 	}
 
-	tempah |= 0x20; /* screen off */
-	XGINew_SetReg1(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
+	for ((*i) = 0;; (*i)++) {
+		infoflag
+				= pVBInfo->RefIndex[RefreshRateTableIndex
+						+ (*i)].Ext_InfoFlag;
+		if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
+				!= tempbx) {
+			return 0;
+		}
 
-	for (i = 02; i <= 04; i++) {
-		SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */
-		XGINew_SetReg1(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
+		if (infoflag & tempax)
+			return 1;
 	}
+	return 1;
 }
 
-static void XGI_SetMiscRegs(unsigned short StandTableIndex,
+static void XGI_SetSync(unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned char Miscdata;
-
-	Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
-	/*
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-			Miscdata |= 0x0C;
-		}
-	}
-	*/
+	unsigned short sync, temp;
 
-	XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
+	sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; /* di+0x00 */
+	sync &= 0xC0;
+	temp = 0x2F;
+	temp |= sync;
+	XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */
 }
 
-static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
+static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
+		struct xgi_hw_device_info *HwDeviceExtension)
 {
-	unsigned char CRTCdata;
-	unsigned short i;
+	unsigned char data, data1, pushax;
+	unsigned short i, j;
 
-	CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
-	CRTCdata &= 0x7f;
-	XGINew_SetReg1(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
+	/* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
+	/* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
+	/* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
 
-	for (i = 0; i <= 0x18; i++) {
-		CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */
-		XGINew_SetReg1(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
-	}
-	/*
-	if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) {
-		if (pVBInfo->VBInfo & SetInSlaveMode) {
-			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-				XGINew_SetReg1(pVBInfo->P3d4, 0x18, 0xFE);
-			}
-		}
+	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
+	data &= 0x7F;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x11, data);
+
+	data = pVBInfo->TimingH[0].data[0];
+	XGINew_SetReg1(pVBInfo->P3d4, 0, data);
+
+	for (i = 0x01; i <= 0x04; i++) {
+		data = pVBInfo->TimingH[0].data[i];
+		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 1), data);
 	}
-	*/
-}
 
-static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	unsigned char ARdata;
-	unsigned short i, modeflag;
+	for (i = 0x05; i <= 0x06; i++) {
+		data = pVBInfo->TimingH[0].data[i];
+		XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i + 6), data);
+	}
 
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
+	j &= 0x1F;
+	data = pVBInfo->TimingH[0].data[7];
+	data &= 0xE0;
+	data |= j;
+	XGINew_SetReg1(pVBInfo->P3c4, 0x0e, data);
 
-	for (i = 0; i <= 0x13; i++) {
-		ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
-		if (modeflag & Charx8Dot) { /* ifndef Dot9 */
-			if (i == 0x13) {
-				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-					ARdata = 0;
-				} else {
-					if (pVBInfo->VBInfo & (SetCRT2ToTV
-							| SetCRT2ToLCD)) {
-						if (pVBInfo->VBInfo
-								& SetInSlaveMode)
-							ARdata = 0;
-					}
-				}
-			}
+	if (HwDeviceExtension->jChipType >= XG20) {
+		data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04);
+		data = data - 1;
+		XGINew_SetReg1(pVBInfo->P3d4, 0x04, data);
+		data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05);
+		data1 = data;
+		data1 &= 0xE0;
+		data &= 0x1F;
+		if (data == 0) {
+			pushax = data;
+			data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4,
+					0x0c);
+			data &= 0xFB;
+			XGINew_SetReg1(pVBInfo->P3c4, 0x0c, data);
+			data = pushax;
 		}
-
-		XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
-		XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */
-		XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */
+		data = data - 1;
+		data |= data1;
+		XGINew_SetReg1(pVBInfo->P3d4, 0x05, data);
+		data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
+		data = data >> 5;
+		data = data + 3;
+		if (data > 7)
+			data = data - 7;
+		data = data << 5;
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0e, ~0xE0, data);
 	}
-
-	XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
-	XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */
-	XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */
-	XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
-	XGINew_SetReg3(pVBInfo->P3c0, 0x20);
 }
 
-static void XGI_SetGRCRegs(unsigned short StandTableIndex,
+static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned char GRdata;
-	unsigned short i;
+	unsigned char data;
+	unsigned short i, j;
 
-	for (i = 0; i <= 0x08; i++) {
-		GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */
-		XGINew_SetReg1(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
+	/* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
+	/* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
+	/* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
+
+	for (i = 0x00; i <= 0x01; i++) {
+		data = pVBInfo->TimingV[0].data[i];
+		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 6), data);
 	}
 
-	if (pVBInfo->ModeType > ModeVGA) {
-		GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05);
-		GRdata &= 0xBF; /* 256 color disable */
-		XGINew_SetReg1(pVBInfo->P3ce, 0x05, GRdata);
+	for (i = 0x02; i <= 0x03; i++) {
+		data = pVBInfo->TimingV[0].data[i];
+		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
 	}
-}
 
-static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
-{
-	unsigned short i;
+	for (i = 0x04; i <= 0x05; i++) {
+		data = pVBInfo->TimingV[0].data[i];
+		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
+	}
 
-	for (i = 0x0A; i <= 0x0E; i++)
-		XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
-}
+	j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a);
+	j &= 0xC0;
+	data = pVBInfo->TimingV[0].data[6];
+	data &= 0x3F;
+	data |= j;
+	XGINew_SetReg1(pVBInfo->P3c4, 0x0a, data);
 
-static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
-{
+	data = pVBInfo->TimingV[0].data[6];
+	data &= 0x80;
+	data = data >> 2;
 
-	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
+	if (ModeNo <= 0x13)
+		i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+	else
+		i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
+	i &= DoubleScanMode;
+	if (i)
+		data |= 0x80;
 
-	XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30);
-	return 0;
+	j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09);
+	j &= 0x5F;
+	data |= j;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x09, data);
 }
 
-unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
-		unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo,
+		struct xgi_hw_device_info *HwDeviceExtension)
 {
-	short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 },
-			LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01,
-					0x01, 0x01 };
-
-	unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
-
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
-	if (pVBInfo->IF_DEF_CH7005 == 1) {
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			if (modeflag & HalfDCLK)
-				return 0;
-		}
-	}
-
-	if (ModeNo < 0x14)
-		return 0xFFFF;
-
-	index = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
-	index = index >> pVBInfo->SelectCRT2Rate;
-	index &= 0x0F;
-
-	if (pVBInfo->LCDInfo & LCDNonExpanding)
-		index = 0;
+	unsigned char index, data;
+	unsigned short i;
 
-	if (index > 0)
-		index--;
+	index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
+	index = index & IndexMask;
 
-	if (pVBInfo->SetFlag & ProgrammingCRT2) {
-		if (pVBInfo->IF_DEF_CH7005 == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToTV)
-				index = 0;
-		}
+	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+	data &= 0x7F;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
 
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			if (pVBInfo->IF_DEF_LVDS == 0) {
-				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-						| VB_XGI301LV | VB_XGI302LV
-						| VB_XGI301C))
-					temp
-							= LCDARefreshIndex[pVBInfo->LCDResInfo
-									& 0x0F]; /* 301b */
-				else
-					temp
-							= LCDRefreshIndex[pVBInfo->LCDResInfo
-									& 0x0F];
+	for (i = 0; i < 8; i++)
+		pVBInfo->TimingH[0].data[i]
+				= pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
 
-				if (index > temp)
-					index = temp;
-			} else {
-				index = 0;
-			}
-		}
-	}
+	for (i = 0; i < 7; i++)
+		pVBInfo->TimingV[0].data[i]
+				= pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
 
-	RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
-	ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
-	if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
-		/*
-		if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & XG2xNotSupport) {
-			index++;
-		}
-		*/
-		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800)
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
-						== 600)) {
-			index++;
-		}
-		/* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */
-		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024)
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
-						== 768)) {
-			index++;
-		}
-		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280)
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
-						== 1024)) {
-			index++;
-		}
-	}
+	XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
 
-	i = 0;
-	do {
-		if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID
-				!= ModeNo)
-			break;
-		temp
-				= pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
-		temp &= ModeInfoFlag;
-		if (temp < pVBInfo->ModeType)
-			break;
-		i++;
-		index--;
+	XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
 
-	} while (index != 0xFFFF);
-	if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
-		if (pVBInfo->VBInfo & SetInSlaveMode) {
-			temp
-					= pVBInfo->RefIndex[RefreshRateTableIndex
-							+ i - 1].Ext_InfoFlag;
-			if (temp & InterlaceMode)
-				i++;
-		}
-	}
-	i--;
-	if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
-		temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
-				RefreshRateTableIndex, &i, pVBInfo);
-	}
-	return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */
+	if (pVBInfo->ModeType > 0x03)
+		XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F);
 }
 
-static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
-		unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex, unsigned short *i,
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetXG21CRTC */
+/* Input : Stand or enhance CRTC table */
+/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
+/* Description : Set LCD timing */
+/* --------------------------------------------------------------------- */
+static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
-
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
+	unsigned short Temp1, Temp2, Temp3;
 
-	resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
-	tempax = 0;
+	if (ModeNo <= 0x13) {
+		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
+		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
+		Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
+		Tempcx = Tempax;
+		Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
+		Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
+		if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
+			Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
+		Tempdx <<= 2; /* Tempdx << 2 */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-	if (pVBInfo->IF_DEF_LVDS == 0) {
-		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
-			tempax |= SupportRAMDAC2;
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */
+		Tempbx = Tempax; /* Tempbx=Tempax */
+		Tempax &= 0x01; /* Tempax: VRS[0] */
+		XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */
+		Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */
+		Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */
+		Tempcx <<= 5; /* Tempcx[7]: VRS[8] */
+		Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */
 
-			if (pVBInfo->VBType & VB_XGI301C)
-				tempax |= SupportCRT2in301C;
-		}
+		Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */
+		Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
+		Tempax &= 0x80; /* Tempax[7]: CR7[7] */
+		Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
+		Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
 
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
-			tempax |= SupportLCD;
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR16 VRE */
+		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+		Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */
+		Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */
+		Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */
+		if (Tempax < Temp3) /* VRE[3:0]<VRS[3:0] */
+			Temp2 |= 0x10; /* Temp2: VRE + 0x10 */
+		Temp2 &= 0xFF; /* Temp2[7:0]: VRE[7:0] */
+		Tempax = (unsigned char) Temp2; /* Tempax[7:0]: VRE[7:0] */
+		Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
+		Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
+		Temp1 >>= 9; /* [10:9]->[1:0] */
+		Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */
+		Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */
+		Tempax &= 0x7F;
+		XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
+	} else {
+		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+		Tempcx = Tempax; /* Tempcx: HRS */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
 
-			if (pVBInfo->LCDResInfo != Panel1280x1024) {
-				if (pVBInfo->LCDResInfo != Panel1280x960) {
-					if (pVBInfo->LCDInfo & LCDNonExpanding) {
-						if (resinfo >= 9) {
-							tempax = 0;
-							return 0;
-						}
-					}
-				}
-			}
-		}
+		Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
+		Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
+		Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
+		Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
+		Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
 
-		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
-			if ((pVBInfo->VBType & VB_XGI301LV)
-					&& (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
-				tempax |= SupportYPbPr;
-				if (pVBInfo->VBInfo & SetInSlaveMode) {
-					if (resinfo == 4)
-						return 0;
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
+		Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
 
-					if (resinfo == 3)
-						return 0;
+		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
+		Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
+		Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
+		Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
 
-					if (resinfo > 7)
-						return 0;
-				}
-			} else {
-				tempax |= SupportHiVisionTV;
-				if (pVBInfo->VBInfo & SetInSlaveMode) {
-					if (resinfo == 4)
-						return 0;
+		Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
+		Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
 
-					if (resinfo == 3) {
-						if (pVBInfo->SetFlag
-								& TVSimuMode)
-							return 0;
-					}
+		Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
+		if (Tempax < Tempcx) /* HRE < HRS */
+			Temp2 |= 0x40; /* Temp2 + 0x40 */
 
-					if (resinfo > 7)
-						return 0;
-				}
-			}
-		} else {
-			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
-					| SetCRT2ToSVIDEO | SetCRT2ToSCART
-					| SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
-				tempax |= SupportTV;
-
-				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-						| VB_XGI301LV | VB_XGI302LV
-						| VB_XGI301C)) {
-					tempax |= SupportTV1024;
-				}
-
-				if (!(pVBInfo->VBInfo & SetPALTV)) {
-					if (modeflag & NoSupportSimuTV) {
-						if (pVBInfo->VBInfo
-								& SetInSlaveMode) {
-							if (!(pVBInfo->VBInfo
-									& SetNotSimuMode)) {
-								return 0;
-							}
-						}
-					}
-				}
-			}
-		}
-	} else { /* for LVDS */
-		if (pVBInfo->IF_DEF_CH7005 == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToTV)
-				tempax |= SupportCHTV;
-		}
-
-		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
-			tempax |= SupportLCD;
-
-			if (resinfo > 0x08)
-				return 0; /* 1024x768 */
-
-			if (pVBInfo->LCDResInfo < Panel1024x768) {
-				if (resinfo > 0x07)
-					return 0; /* 800x600 */
+		Temp2 &= 0xFF;
+		Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
+		Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
+		Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
+		Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-				if (resinfo == 0x04)
-					return 0; /* 512x384 */
-			}
-		}
-	}
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
+		Tempbx = Tempax; /* Tempbx: VRS */
+		Tempax &= 0x01; /* Tempax[0]: VRS[0] */
+		XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */
+		Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
+		Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
+		Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
+		Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
 
-	for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) {
-		infoflag
-				= pVBInfo->RefIndex[RefreshRateTableIndex
-						+ (*i)].Ext_InfoFlag;
-		if (infoflag & tempax)
-			return 1;
+		Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
+		Temp1 <<= 1; /* Temp1[8]: VRS[8] */
+		Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
+		Tempax &= 0x80;
+		Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
+		Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SRA */
+		Tempax &= 0x08; /* Tempax[3]: VRS[3] */
+		Temp2 = Tempax;
+		Temp2 <<= 7; /* Temp2[10]: VRS[10] */
+		Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
 
-		if ((*i) == 0)
-			break;
-	}
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
+		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SRA */
+		Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
+		Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
+		Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
+		Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
+		Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
 
-	for ((*i) = 0;; (*i)++) {
-		infoflag
-				= pVBInfo->RefIndex[RefreshRateTableIndex
-						+ (*i)].Ext_InfoFlag;
-		if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
-				!= tempbx) {
-			return 0;
-		}
+		Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
+		if (Tempax < Temp3) /* VRE < VRS */
+			Temp2 |= 0x20; /* VRE + 0x20 */
 
-		if (infoflag & tempax)
-			return 1;
+		Temp2 &= 0xFF;
+		Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
+		Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
+		Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
+		Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
+		Tempbx = (unsigned char) Temp1;
+		Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
+		Tempax &= 0x7F;
+		XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
 	}
-	return 1;
 }
 
-static void XGI_SetSync(unsigned short RefreshRateTableIndex,
+static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short sync, temp;
+	unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
 
-	sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; /* di+0x00 */
-	sync &= 0xC0;
-	temp = 0x2F;
-	temp |= sync;
-	XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */
-}
+	if (ModeNo <= 0x13) {
+		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
+		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
+		Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
+		Tempcx = Tempax;
+		Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
+		Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
+		if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
+			Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
+		Tempdx <<= 2; /* Tempdx << 2 */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo,
-		struct xgi_hw_device_info *HwDeviceExtension)
-{
-	unsigned char index, data;
-	unsigned short i;
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */
+		Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
+		Tempbx = Tempax; /* Tempbx=CR07 */
+		Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */
+		Tempax >>= 2;
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */
+		Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */
+		Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */
 
-	index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
-	index = index & IndexMask;
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR11 VRE */
+		Tempax &= 0x0F; /* Tempax: VRE[3:0] */
+		Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */
+		Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */
+		Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */
+		if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */
+			Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */
+		Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
+		Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
+		Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */
+	} else {
+		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+		Tempbx = Tempax; /* Tempbx: HRS[7:0] */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
 
-	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
-	data &= 0x7F;
-	XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
+		Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+		Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
 
-	for (i = 0; i < 8; i++)
-		pVBInfo->TimingH[0].data[i]
-				= pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
+		Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
+		Tempcx = Tempax; /* Tempcx: HRE[4:0] */
 
-	for (i = 0; i < 7; i++)
-		pVBInfo->TimingV[0].data[i]
-				= pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
+		Tempax &= 0x04; /* Tempax[2]: HRE[5] */
+		Tempax <<= 3; /* Tempax[5]: HRE[5] */
+		Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
 
-	XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+		Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
+		Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
 
-	XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+		Tempax &= 0x3F; /* Tempax: HRS[5:0] */
+		if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
+			Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
 
-	if (pVBInfo->ModeType > 0x03)
-		XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F);
-}
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
+		Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+		Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
+		Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
-		struct xgi_hw_device_info *HwDeviceExtension)
-{
-	unsigned char data, data1, pushax;
-	unsigned short i, j;
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
+		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */
 
-	/* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
-	/* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
-	/* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
+		Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */
+		Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
+		Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
+		Tempax >>= 2; /* Tempax[0]: VRS[8] */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */
+		Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
+		Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */
+		Tempax &= 0x08; /* SR0A[3] VRS[10] */
+		Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
 
-	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
-	data &= 0x7F;
-	XGINew_SetReg1(pVBInfo->P3d4, 0x11, data);
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
+		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SR0A */
+		Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
+		Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
+		Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
+		Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
+		Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
+		Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
 
-	data = pVBInfo->TimingH[0].data[0];
-	XGINew_SetReg1(pVBInfo->P3d4, 0, data);
+		if (Tempbx <= Tempcx) /* VRE <= VRS */
+			Tempbx |= 0x20; /* VRE + 0x20 */
 
-	for (i = 0x01; i <= 0x04; i++) {
-		data = pVBInfo->TimingH[0].data[i];
-		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 1), data);
+		Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */
+		Tempax = Tempcx >> 8;
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */
 	}
+}
 
-	for (i = 0x05; i <= 0x06; i++) {
-		data = pVBInfo->TimingH[0].data[i];
-		XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i + 6), data);
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetXG21LCD */
+/* Input : */
+/* Output : FCLK duty cycle, FCLK delay compensation */
+/* Description : All values set zero */
+/* --------------------------------------------------------------------- */
+static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo,
+		unsigned short RefreshRateTableIndex, unsigned short ModeNo)
+{
+	unsigned short Data, Temp, b3CC;
+	unsigned short XGI_P3cc;
+
+	XGI_P3cc = pVBInfo->P3cc;
+
+	XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
+	if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
+		XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
 	}
 
-	j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
-	j &= 0x1F;
-	data = pVBInfo->TimingH[0].data[7];
-	data &= 0xE0;
-	data |= j;
-	XGINew_SetReg1(pVBInfo->P3c4, 0x0e, data);
+	Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
 
-	if (HwDeviceExtension->jChipType >= XG20) {
-		data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04);
-		data = data - 1;
-		XGINew_SetReg1(pVBInfo->P3d4, 0x04, data);
-		data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05);
-		data1 = data;
-		data1 &= 0xE0;
-		data &= 0x1F;
-		if (data == 0) {
-			pushax = data;
-			data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4,
-					0x0c);
-			data &= 0xFB;
-			XGINew_SetReg1(pVBInfo->P3c4, 0x0c, data);
-			data = pushax;
-		}
-		data = data - 1;
-		data |= data1;
-		XGINew_SetReg1(pVBInfo->P3d4, 0x05, data);
-		data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
-		data = data >> 5;
-		data = data + 3;
-		if (data > 7)
-			data = data - 7;
-		data = data << 5;
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0e, ~0xE0, data);
+	if (Temp & 0x01) {
+		XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */
+		XGINew_SetRegOR(pVBInfo->P3c4, 0x09, 0x40);
+	}
+
+	XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
+
+	XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20);
+	XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80);
+
+	if (ModeNo <= 0x13) {
+		b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
+		if (b3CC & 0x40)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+		if (b3CC & 0x80)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+	} else {
+		Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+		if (Data & 0x4000)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+		if (Data & 0x8000)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
 	}
 }
 
-static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo,
+		unsigned short RefreshRateTableIndex, unsigned short ModeNo)
 {
-	unsigned char data;
-	unsigned short i, j;
+	unsigned short Data, Temp, b3CC;
+	unsigned short XGI_P3cc;
 
-	/* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
-	/* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
-	/* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
+	XGI_P3cc = pVBInfo->P3cc;
 
-	for (i = 0x00; i <= 0x01; i++) {
-		data = pVBInfo->TimingV[0].data[i];
-		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 6), data);
-	}
+	XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
 
-	for (i = 0x02; i <= 0x03; i++) {
-		data = pVBInfo->TimingV[0].data[i];
-		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
+	Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
+	if ((Temp & 0x03) == 0) { /* dual 12 */
+		XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x13);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x13);
 	}
 
-	for (i = 0x04; i <= 0x05; i++) {
-		data = pVBInfo->TimingV[0].data[i];
-		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
+	if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
+		XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
 	}
 
-	j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a);
-	j &= 0xC0;
-	data = pVBInfo->TimingV[0].data[6];
-	data &= 0x3F;
-	data |= j;
-	XGINew_SetReg1(pVBInfo->P3c4, 0x0a, data);
-
-	data = pVBInfo->TimingV[0].data[6];
-	data &= 0x80;
-	data = data >> 2;
+	XGI_SetXG27FPBits(pVBInfo);
 
-	if (ModeNo <= 0x13)
-		i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
 
-	i &= DoubleScanMode;
-	if (i)
-		data |= 0x80;
+	XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
+	XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
 
-	j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09);
-	j &= 0x5F;
-	data |= j;
-	XGINew_SetReg1(pVBInfo->P3d4, 0x09, data);
+	if (ModeNo <= 0x13) {
+		b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
+		if (b3CC & 0x40)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+		if (b3CC & 0x80)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+	} else {
+		Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+		if (Data & 0x4000)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+		if (Data & 0x8000)
+			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+	}
 }
 
 /* --------------------------------------------------------------------- */
-/* Function : XGI_SetXG21CRTC */
-/* Input : Stand or enhance CRTC table */
-/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
-/* Description : Set LCD timing */
+/* Function : XGI_UpdateXG21CRTC */
+/* Input : */
+/* Output : CRT1 CRTC */
+/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
 /* --------------------------------------------------------------------- */
-static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo,
+		unsigned short RefreshRateTableIndex)
+{
+	int i, index = -1;
+
+	XGINew_SetRegAND(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
+	if (ModeNo <= 0x13) {
+		for (i = 0; i < 12; i++) {
+			if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID)
+				index = i;
+		}
+	} else {
+		if (ModeNo == 0x2E
+				&& (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
+						== RES640x480x60))
+			index = 12;
+		else if (ModeNo == 0x2E
+				&& (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
+						== RES640x480x72))
+			index = 13;
+		else if (ModeNo == 0x2F)
+			index = 14;
+		else if (ModeNo == 0x50)
+			index = 15;
+		else if (ModeNo == 0x59)
+			index = 16;
+	}
+
+	if (index != -1) {
+		XGINew_SetReg1(pVBInfo->P3d4, 0x02,
+				pVBInfo->UpdateCRT1[index].CR02);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x03,
+				pVBInfo->UpdateCRT1[index].CR03);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x15,
+				pVBInfo->UpdateCRT1[index].CR15);
+		XGINew_SetReg1(pVBInfo->P3d4, 0x16,
+				pVBInfo->UpdateCRT1[index].CR16);
+	}
+}
+
+static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short ModeNo, unsigned short ModeIdIndex,
 		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
-	unsigned short Temp1, Temp2, Temp3;
+	unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
+
+	unsigned char data;
+
+	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
 
 	if (ModeNo <= 0x13) {
-		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
-		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
-		Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
-		Tempcx = Tempax;
-		Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
-		Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
-		if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
-			Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
-		Tempdx <<= 2; /* Tempdx << 2 */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+		tempax = pVBInfo->StResInfo[resindex].HTotal;
+		tempbx = pVBInfo->StResInfo[resindex].VTotal;
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		tempax = pVBInfo->ModeResInfo[resindex].HTotal;
+		tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
+	}
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */
-		Tempbx = Tempax; /* Tempbx=Tempax */
-		Tempax &= 0x01; /* Tempax: VRS[0] */
-		XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */
-		Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */
-		Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */
-		Tempcx <<= 5; /* Tempcx[7]: VRS[8] */
-		Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */
+	if (modeflag & HalfDCLK)
+		tempax = tempax >> 1;
 
-		Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */
-		Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
-		Tempax &= 0x80; /* Tempax[7]: CR7[7] */
-		Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
-		Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
+	if (ModeNo > 0x13) {
+		if (modeflag & HalfDCLK)
+			tempax = tempax << 1;
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR16 VRE */
-		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
-		Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */
-		Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */
-		Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */
-		if (Tempax < Temp3) /* VRE[3:0]<VRS[3:0] */
-			Temp2 |= 0x10; /* Temp2: VRE + 0x10 */
-		Temp2 &= 0xFF; /* Temp2[7:0]: VRE[7:0] */
-		Tempax = (unsigned char) Temp2; /* Tempax[7:0]: VRE[7:0] */
-		Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
-		Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
-		Temp1 >>= 9; /* [10:9]->[1:0] */
-		Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */
-		Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */
-		Tempax &= 0x7F;
-		XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
-	} else {
-		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
-		Tempcx = Tempax; /* Tempcx: HRS */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
+		temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 
-		Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
-		Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
-		Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
-		Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
-		Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
+		if (temp & InterlaceMode)
+			tempbx = tempbx >> 1;
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
-		Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
+		if (modeflag & DoubleScanMode)
+			tempbx = tempbx << 1;
+	}
 
-		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
-		Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
-		Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
-		Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
+	tempcx = 8;
 
-		Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
-		Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
+	/* if (!(modeflag & Charx8Dot)) */
+	/* tempcx = 9; */
 
-		Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
-		if (Tempax < Tempcx) /* HRE < HRS */
-			Temp2 |= 0x40; /* Temp2 + 0x40 */
+	tempax /= tempcx;
+	tempax -= 1;
+	tempbx -= 1;
+	tempcx = tempax;
+	temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+	data &= 0x7F;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+	XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
+	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c,
+			(unsigned short) ((tempcx & 0x0ff00) >> 10));
+	XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
+	tempax = 0;
+	tempbx = tempbx >> 8;
 
-		Temp2 &= 0xFF;
-		Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
-		Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
-		Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
-		Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+	if (tempbx & 0x01)
+		tempax |= 0x02;
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
-		Tempbx = Tempax; /* Tempbx: VRS */
-		Tempax &= 0x01; /* Tempax[0]: VRS[0] */
-		XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */
-		Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
-		Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
-		Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
-		Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
+	if (tempbx & 0x02)
+		tempax |= 0x40;
 
-		Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
-		Temp1 <<= 1; /* Temp1[8]: VRS[8] */
-		Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
-		Tempax &= 0x80;
-		Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
-		Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SRA */
-		Tempax &= 0x08; /* Tempax[3]: VRS[3] */
-		Temp2 = Tempax;
-		Temp2 <<= 7; /* Temp2[10]: VRS[10] */
-		Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
+	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax);
+	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x07);
+	data &= 0xFF;
+	tempax = 0;
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
-		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
-		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SRA */
-		Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
-		Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
-		Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
-		Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
-		Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
+	if (tempbx & 0x04)
+		tempax |= 0x02;
 
-		Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
-		if (Tempax < Temp3) /* VRE < VRS */
-			Temp2 |= 0x20; /* VRE + 0x20 */
+	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp);
+}
 
-		Temp2 &= 0xFF;
-		Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
-		Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
-		Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
-		Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
-		Tempbx = (unsigned char) Temp1;
-		Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
-		Tempax &= 0x7F;
-		XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
-	}
+unsigned short XGI_GetResInfo(unsigned short ModeNo,
+		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+	unsigned short resindex;
+
+	if (ModeNo <= 0x13)
+		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+	else
+		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+	return resindex;
 }
 
-static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex,
 		unsigned short RefreshRateTableIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
-
-	if (ModeNo <= 0x13) {
-		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
-		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
-		Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
-		Tempcx = Tempax;
-		Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
-		Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
-		if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
-			Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
-		Tempdx <<= 2; /* Tempdx << 2 */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+	unsigned short temp, ah, al, temp2, i, DisplayUnit;
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */
-		Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
-		Tempbx = Tempax; /* Tempbx=CR07 */
-		Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */
-		Tempax >>= 2;
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */
-		Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */
-		Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */
+	/* GetOffset */
+	temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+	temp = temp >> 8;
+	temp = pVBInfo->ScreenOffset[temp];
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR11 VRE */
-		Tempax &= 0x0F; /* Tempax: VRE[3:0] */
-		Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */
-		Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */
-		Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */
-		if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */
-			Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */
-		Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
-		Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
-		Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */
-	} else {
-		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
-		Tempbx = Tempax; /* Tempbx: HRS[7:0] */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
+	temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+	temp2 &= InterlaceMode;
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
-		Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
-		Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
+	if (temp2)
+		temp = temp << 1;
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
-		Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
-		Tempcx = Tempax; /* Tempcx: HRE[4:0] */
+	temp2 = pVBInfo->ModeType - ModeEGA;
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
-		Tempax &= 0x04; /* Tempax[2]: HRE[5] */
-		Tempax <<= 3; /* Tempax[5]: HRE[5] */
-		Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
+	switch (temp2) {
+	case 0:
+		temp2 = 1;
+		break;
+	case 1:
+		temp2 = 2;
+		break;
+	case 2:
+		temp2 = 4;
+		break;
+	case 3:
+		temp2 = 4;
+		break;
+	case 4:
+		temp2 = 6;
+		break;
+	case 5:
+		temp2 = 8;
+		break;
+	default:
+		break;
+	}
 
-		Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
-		Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
+	if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
+		temp = temp * temp2 + temp2 / 2;
+	else
+		temp *= temp2;
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
-		Tempax &= 0x3F; /* Tempax: HRS[5:0] */
-		if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
-			Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
+	/* SetOffset */
+	DisplayUnit = temp;
+	temp2 = temp;
+	temp = temp >> 8; /* ah */
+	temp &= 0x0F;
+	i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E);
+	i &= 0xF0;
+	i |= temp;
+	XGINew_SetReg1(pVBInfo->P3c4, 0x0E, i);
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
-		Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
-		Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
-		Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+	temp = (unsigned char) temp2;
+	temp &= 0xFF; /* al */
+	XGINew_SetReg1(pVBInfo->P3d4, 0x13, temp);
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
-		XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */
+	/* SetDisplayUnit */
+	temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+	temp2 &= InterlaceMode;
+	if (temp2)
+		DisplayUnit >>= 1;
 
-		Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */
-		Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
-		Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
-		Tempax >>= 2; /* Tempax[0]: VRS[8] */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */
-		Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
-		Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */
-		Tempax &= 0x08; /* SR0A[3] VRS[10] */
-		Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
-
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
-		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
-		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SR0A */
-		Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
-		Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
-		Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
-		Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
-		Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
-		Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
+	DisplayUnit = DisplayUnit << 5;
+	ah = (DisplayUnit & 0xff00) >> 8;
+	al = DisplayUnit & 0x00ff;
+	if (al == 0)
+		ah += 1;
+	else
+		ah += 2;
 
-		if (Tempbx <= Tempcx) /* VRE <= VRS */
-			Tempbx |= 0x20; /* VRE + 0x20 */
+	if (HwDeviceExtension->jChipType >= XG20)
+		if ((ModeNo == 0x4A) | (ModeNo == 0x49))
+			ah -= 1;
 
-		Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */
-		Tempax = Tempcx >> 8;
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */
-	}
+	XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah);
 }
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetXG21LCD */
-/* Input : */
-/* Output : FCLK duty cycle, FCLK delay compensation */
-/* Description : All values set zero */
-/* --------------------------------------------------------------------- */
-static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo,
-		unsigned short RefreshRateTableIndex, unsigned short ModeNo)
+static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
+		unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
 {
-	unsigned short Data, Temp, b3CC;
-	unsigned short XGI_P3cc;
-
-	XGI_P3cc = pVBInfo->P3cc;
-
-	XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
-	if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
-		XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
-	}
-
-	Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
-
-	if (Temp & 0x01) {
-		XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */
-		XGINew_SetRegOR(pVBInfo->P3c4, 0x09, 0x40);
-	}
+	unsigned short tempbx;
 
-	XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
+	unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
+			VCLK65 + 2 };
+	unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, VCLK108_2 + 5,
+			VCLK108_2 + 5, VCLK108_2 + 5 };
+	unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
+	unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
+			VCLK65 + 2 };
+	unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
+			VCLK65 + 2 };
 
-	XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20);
-	XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80);
+	unsigned short CRT2Index, VCLKIndex;
+	unsigned short modeflag, resinfo;
+	unsigned char *CHTVVCLKPtr = NULL;
 
 	if (ModeNo <= 0x13) {
-		b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
-		if (b3CC & 0x40)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
-		if (b3CC & 0x80)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+		CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 	} else {
-		Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-		if (Data & 0x4000)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
-		if (Data & 0x8000)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+		CRT2Index
+				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 	}
-}
-
-static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo,
-		unsigned short RefreshRateTableIndex, unsigned short ModeNo)
-{
-	unsigned short Data, Temp, b3CC;
-	unsigned short XGI_P3cc;
 
-	XGI_P3cc = pVBInfo->P3cc;
+	if (pVBInfo->IF_DEF_LVDS == 0) {
+		CRT2Index = CRT2Index >> 6; /*  for LCD */
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/
+			if (pVBInfo->LCDResInfo != Panel1024x768)
+				VCLKIndex = LCDXlat2VCLK[CRT2Index];
+			else
+				VCLKIndex = LCDXlat1VCLK[CRT2Index];
+		} else { /* for TV */
+			if (pVBInfo->VBInfo & SetCRT2ToTV) {
+				if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+					if (pVBInfo->SetFlag & RPLLDIV2XO) {
+						VCLKIndex = HiTVVCLKDIV2;
 
-	XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
+						VCLKIndex += 25;
 
-	Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
-	if ((Temp & 0x03) == 0) { /* dual 12 */
-		XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x13);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x13);
-	}
+					} else {
+						VCLKIndex = HiTVVCLK;
 
-	if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
-		XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
-	}
+						VCLKIndex += 25;
 
-	XGI_SetXG27FPBits(pVBInfo);
+					}
 
-	XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
+					if (pVBInfo->SetFlag & TVSimuMode) {
+						if (modeflag & Charx8Dot) {
+							VCLKIndex
+									= HiTVSimuVCLK;
 
-	XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
-	XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
+							VCLKIndex += 25;
 
-	if (ModeNo <= 0x13) {
-		b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
-		if (b3CC & 0x40)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
-		if (b3CC & 0x80)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
-	} else {
-		Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-		if (Data & 0x4000)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
-		if (Data & 0x8000)
-			XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
-	}
-}
+						} else {
+							VCLKIndex
+									= HiTVTextVCLK;
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_UpdateXG21CRTC */
-/* Input : */
-/* Output : CRT1 CRTC */
-/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
-/* --------------------------------------------------------------------- */
-static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo,
-		unsigned short RefreshRateTableIndex)
-{
-	int i, index = -1;
+							VCLKIndex += 25;
 
-	XGINew_SetRegAND(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
-	if (ModeNo <= 0x13) {
-		for (i = 0; i < 12; i++) {
-			if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID)
-				index = i;
-		}
-	} else {
-		if (ModeNo == 0x2E
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
-						== RES640x480x60))
-			index = 12;
-		else if (ModeNo == 0x2E
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
-						== RES640x480x72))
-			index = 13;
-		else if (ModeNo == 0x2F)
-			index = 14;
-		else if (ModeNo == 0x50)
-			index = 15;
-		else if (ModeNo == 0x59)
-			index = 16;
-	}
+						}
+					}
 
-	if (index != -1) {
-		XGINew_SetReg1(pVBInfo->P3d4, 0x02,
-				pVBInfo->UpdateCRT1[index].CR02);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x03,
-				pVBInfo->UpdateCRT1[index].CR03);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x15,
-				pVBInfo->UpdateCRT1[index].CR15);
-		XGINew_SetReg1(pVBInfo->P3d4, 0x16,
-				pVBInfo->UpdateCRT1[index].CR16);
-	}
-}
+					if (pVBInfo->VBType & VB_XGI301LV) { /* 301lv */
+						if (!(pVBInfo->VBExtInfo
+								== VB_YPbPr1080i)) {
+							VCLKIndex
+									= YPbPr750pVCLK;
+							if (!(pVBInfo->VBExtInfo
+									== VB_YPbPr750p)) {
+								VCLKIndex
+										= YPbPr525pVCLK;
+								if (!(pVBInfo->VBExtInfo
+										== VB_YPbPr525p)) {
+									VCLKIndex
+											= YPbPr525iVCLK_2;
+									if (!(pVBInfo->SetFlag
+											& RPLLDIV2XO))
+										VCLKIndex
+												= YPbPr525iVCLK;
+								}
+							}
+						}
+					}
+				} else {
+					if (pVBInfo->VBInfo & SetCRT2ToTV) {
+						if (pVBInfo->SetFlag
+								& RPLLDIV2XO) {
+							VCLKIndex = TVVCLKDIV2;
 
-static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
+							VCLKIndex += 25;
 
-	unsigned char data;
+						} else {
+							VCLKIndex = TVVCLK;
 
-	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+							VCLKIndex += 25;
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-		tempax = pVBInfo->StResInfo[resindex].HTotal;
-		tempbx = pVBInfo->StResInfo[resindex].VTotal;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		tempax = pVBInfo->ModeResInfo[resindex].HTotal;
-		tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
-	}
-
-	if (modeflag & HalfDCLK)
-		tempax = tempax >> 1;
-
-	if (ModeNo > 0x13) {
-		if (modeflag & HalfDCLK)
-			tempax = tempax << 1;
-
-		temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-
-		if (temp & InterlaceMode)
-			tempbx = tempbx >> 1;
-
-		if (modeflag & DoubleScanMode)
-			tempbx = tempbx << 1;
-	}
-
-	tempcx = 8;
-
-	/* if (!(modeflag & Charx8Dot)) */
-	/* tempcx = 9; */
-
-	tempax /= tempcx;
-	tempax -= 1;
-	tempbx -= 1;
-	tempcx = tempax;
-	temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
-	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
-	data &= 0x7F;
-	XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
-	XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
-	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c,
-			(unsigned short) ((tempcx & 0x0ff00) >> 10));
-	XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
-	tempax = 0;
-	tempbx = tempbx >> 8;
-
-	if (tempbx & 0x01)
-		tempax |= 0x02;
-
-	if (tempbx & 0x02)
-		tempax |= 0x40;
-
-	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax);
-	data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x07);
-	data &= 0xFF;
-	tempax = 0;
-
-	if (tempbx & 0x04)
-		tempax |= 0x02;
-
-	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp);
-}
-
-unsigned short XGI_GetResInfo(unsigned short ModeNo,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	unsigned short resindex;
-
-	if (ModeNo <= 0x13)
-		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
-	else
-		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
-	return resindex;
-}
-
-static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short temp, ah, al, temp2, i, DisplayUnit;
+						}
+					}
+				}
+			} else { /* for CRT2 */
+				VCLKIndex = (unsigned char) XGINew_GetReg2(
+						(pVBInfo->P3ca + 0x02)); /* Port 3cch */
+				VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+				if (ModeNo > 0x13) {
+					VCLKIndex
+							= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; /* di+Ext_CRTVCLK */
+					VCLKIndex &= IndexMask;
+				}
+			}
+		}
+	} else { /* LVDS */
+		if (ModeNo <= 0x13)
+			VCLKIndex = CRT2Index;
+		else
+			VCLKIndex = CRT2Index;
 
-	/* GetOffset */
-	temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-	temp = temp >> 8;
-	temp = pVBInfo->ScreenOffset[temp];
+		if (pVBInfo->IF_DEF_CH7005 == 1) {
+			if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
+				VCLKIndex &= 0x1f;
+				tempbx = 0;
 
-	temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	temp2 &= InterlaceMode;
+				if (pVBInfo->VBInfo & SetPALTV)
+					tempbx += 2;
 
-	if (temp2)
-		temp = temp << 1;
+				if (pVBInfo->VBInfo & SetCHTVOverScan)
+					tempbx += 1;
 
-	temp2 = pVBInfo->ModeType - ModeEGA;
+				switch (tempbx) {
+				case 0:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
+					break;
+				case 1:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
+					break;
+				case 2:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
+					break;
+				case 3:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
+					break;
+				default:
+					break;
+				}
 
-	switch (temp2) {
-	case 0:
-		temp2 = 1;
-		break;
-	case 1:
-		temp2 = 2;
-		break;
-	case 2:
-		temp2 = 4;
-		break;
-	case 3:
-		temp2 = 4;
-		break;
-	case 4:
-		temp2 = 6;
-		break;
-	case 5:
-		temp2 = 8;
-		break;
-	default:
-		break;
+				VCLKIndex = CHTVVCLKPtr[VCLKIndex];
+			}
+		} else {
+			VCLKIndex = VCLKIndex >> 6;
+			if ((pVBInfo->LCDResInfo == Panel800x600)
+					|| (pVBInfo->LCDResInfo == Panel320x480))
+				VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
+			else if ((pVBInfo->LCDResInfo == Panel1024x768)
+					|| (pVBInfo->LCDResInfo
+							== Panel1024x768x75))
+				VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
+			else
+				VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
+		}
 	}
+	/* VCLKIndex = VCLKIndex&IndexMask; */
 
-	if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
-		temp = temp * temp2 + temp2 / 2;
-	else
-		temp *= temp2;
-
-	/* SetOffset */
-	DisplayUnit = temp;
-	temp2 = temp;
-	temp = temp >> 8; /* ah */
-	temp &= 0x0F;
-	i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E);
-	i &= 0xF0;
-	i |= temp;
-	XGINew_SetReg1(pVBInfo->P3c4, 0x0E, i);
-
-	temp = (unsigned char) temp2;
-	temp &= 0xFF; /* al */
-	XGINew_SetReg1(pVBInfo->P3d4, 0x13, temp);
-
-	/* SetDisplayUnit */
-	temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	temp2 &= InterlaceMode;
-	if (temp2)
-		DisplayUnit >>= 1;
-
-	DisplayUnit = DisplayUnit << 5;
-	ah = (DisplayUnit & 0xff00) >> 8;
-	al = DisplayUnit & 0x00ff;
-	if (al == 0)
-		ah += 1;
-	else
-		ah += 2;
-
-	if (HwDeviceExtension->jChipType >= XG20)
-		if ((ModeNo == 0x4A) | (ModeNo == 0x49))
-			ah -= 1;
-
-	XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah);
+	return VCLKIndex;
 }
 
 static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
@@ -1887,38 +1522,91 @@ static void XGI_SetCRT1FIFO(unsigned short ModeNo,
 		XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
 }
 
-static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
+static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short ModeNo, unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
-			xres;
+	unsigned short data, data2 = 0;
+	short VCLK;
 
-	if (ModeNo > 0x13) {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		infoflag
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-	} else
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+	unsigned char index;
 
-	if (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & 0x01)
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
+	if (ModeNo <= 0x13)
+		VCLK = 0;
+	else {
+		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+		index &= IndexMask;
+		VCLK = pVBInfo->VCLKData[index].CLOCK;
+	}
 
-	if (ModeNo > 0x13)
-		data = infoflag;
-	else
-		data = 0;
+	data = XGINew_GetReg1(pVBInfo->P3c4, 0x32);
+	data &= 0xf3;
+	if (VCLK >= 200)
+		data |= 0x0c; /* VCLK > 200 */
 
-	data2 = 0;
+	if (HwDeviceExtension->jChipType >= XG20)
+		data &= ~0x04; /* 2 pixel mode */
 
-	if (ModeNo > 0x13) {
-		if (pVBInfo->ModeType > 0x02) {
-			data2 |= 0x02;
-			data3 = pVBInfo->ModeType - ModeVGA;
-			data3 = data3 << 2;
-			data2 |= data3;
-		}
+	XGINew_SetReg1(pVBInfo->P3c4, 0x32, data);
+
+	if (HwDeviceExtension->jChipType < XG20) {
+		data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
+		data &= 0xE7;
+		if (VCLK < 200)
+			data |= 0x10;
+		XGINew_SetReg1(pVBInfo->P3c4, 0x1F, data);
+	}
+
+	/*  Jong for Adavantech LCD ripple issue
+	if ((VCLK >= 0) && (VCLK < 135))
+		data2 = 0x03;
+	else if ((VCLK >= 135) && (VCLK < 160))
+		data2 = 0x02;
+	else if ((VCLK >= 160) && (VCLK < 260))
+		data2 = 0x01;
+	else if (VCLK > 260)
+		data2 = 0x00;
+	*/
+	data2 = 0x00;
+
+	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x07, 0xFC, data2);
+	if (HwDeviceExtension->jChipType >= XG27)
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
+
+}
+
+static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
+			xres;
+
+	if (ModeNo > 0x13) {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		infoflag
+				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+	} else
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+
+	if (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & 0x01)
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
+
+	if (ModeNo > 0x13)
+		data = infoflag;
+	else
+		data = 0;
+
+	data2 = 0;
+
+	if (ModeNo > 0x13) {
+		if (pVBInfo->ModeType > 0x02) {
+			data2 |= 0x02;
+			data3 = pVBInfo->ModeType - ModeVGA;
+			data3 = data3 << 2;
+			data2 |= data3;
+		}
 	}
 
 	data &= InterlaceMode;
@@ -2002,60 +1690,6 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
 
 }
 
-static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short ModeNo, unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short data, data2 = 0;
-	short VCLK;
-
-	unsigned char index;
-
-	if (ModeNo <= 0x13)
-		VCLK = 0;
-	else {
-		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		index &= IndexMask;
-		VCLK = pVBInfo->VCLKData[index].CLOCK;
-	}
-
-	data = XGINew_GetReg1(pVBInfo->P3c4, 0x32);
-	data &= 0xf3;
-	if (VCLK >= 200)
-		data |= 0x0c; /* VCLK > 200 */
-
-	if (HwDeviceExtension->jChipType >= XG20)
-		data &= ~0x04; /* 2 pixel mode */
-
-	XGINew_SetReg1(pVBInfo->P3c4, 0x32, data);
-
-	if (HwDeviceExtension->jChipType < XG20) {
-		data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
-		data &= 0xE7;
-		if (VCLK < 200)
-			data |= 0x10;
-		XGINew_SetReg1(pVBInfo->P3c4, 0x1F, data);
-	}
-
-	/*  Jong for Adavantech LCD ripple issue
-	if ((VCLK >= 0) && (VCLK < 135))
-		data2 = 0x03;
-	else if ((VCLK >= 135) && (VCLK < 160))
-		data2 = 0x02;
-	else if ((VCLK >= 160) && (VCLK < 260))
-		data2 = 0x01;
-	else if (VCLK > 260)
-		data2 = 0x00;
-	*/
-	data2 = 0x00;
-
-	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x07, 0xFC, data2);
-	if (HwDeviceExtension->jChipType >= XG27)
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
-
-}
-
-
 /*
 void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
@@ -2088,6 +1722,33 @@ void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, st
 }
 */
 
+static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al,
+		unsigned short dh, struct vb_device_info *pVBInfo)
+{
+	unsigned short temp, bh, bl;
+
+	bh = ah;
+	bl = al;
+
+	if (dl != 0) {
+		temp = bh;
+		bh = dh;
+		dh = temp;
+		if (dl == 1) {
+			temp = bl;
+			bl = dh;
+			dh = temp;
+		} else {
+			temp = bl;
+			bl = bh;
+			bh = temp;
+		}
+	}
+	XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) dh);
+	XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bh);
+	XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl);
+}
+
 static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
@@ -2180,53 +1841,6 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
 	}
 }
 
-static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al,
-		unsigned short dh, struct vb_device_info *pVBInfo)
-{
-	unsigned short temp, bh, bl;
-
-	bh = ah;
-	bl = al;
-
-	if (dl != 0) {
-		temp = bh;
-		bh = dh;
-		dh = temp;
-		if (dl == 1) {
-			temp = bl;
-			bl = dh;
-			dh = temp;
-		} else {
-			temp = bl;
-			bl = bh;
-			bh = temp;
-		}
-	}
-	XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) dh);
-	XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bh);
-	XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl);
-}
-
-static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short RefreshRateTableIndex;
-	/* unsigned short temp ; */
-
-	/* pVBInfo->SelectCRT2Rate = 0; */
-
-	pVBInfo->SetFlag |= ProgrammingCRT2;
-	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
-			ModeIdIndex, pVBInfo);
-	XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
-	XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-	XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-			HwDeviceExtension, pVBInfo);
-	XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-	XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-}
-
 static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
@@ -2276,4312 +1890,4394 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex
 	pVBInfo->VDE = yres;
 }
 
-static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
+		unsigned short ModeIdIndex,
 		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbx;
-	struct XGI330_LVDSDataStruct *LCDPtr = NULL;
-	struct XGI330_CHTVDataStruct *TVPtr = NULL;
+	unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table;
 
-	tempbx = 2;
+	struct XGI330_LCDDataTablStruct *tempdi = NULL;
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-		LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx,
-				ModeNo, ModeIdIndex, RefreshRateTableIndex,
-				pVBInfo);
-		pVBInfo->VGAHT = LCDPtr->VGAHT;
-		pVBInfo->VGAVT = LCDPtr->VGAVT;
-		pVBInfo->HT = LCDPtr->LCDHT;
-		pVBInfo->VT = LCDPtr->LCDVT;
+	tempbx = BX;
+
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+		tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 	}
-	if (pVBInfo->IF_DEF_CH7017 == 1) {
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			TVPtr = (struct XGI330_CHTVDataStruct *) XGI_GetTVPtr(
-					tempbx, ModeNo, ModeIdIndex,
-					RefreshRateTableIndex, pVBInfo);
-			pVBInfo->VGAHT = TVPtr->VGAHT;
-			pVBInfo->VGAVT = TVPtr->VGAVT;
-			pVBInfo->HT = TVPtr->LCDHT;
-			pVBInfo->VT = TVPtr->LCDVT;
+
+	tempal = tempal & 0x0f;
+
+	if (tempbx <= 1) { /* ExpLink */
+		if (ModeNo <= 0x13) {
+			tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
+		} else {
+			tempal
+					= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 		}
-	}
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-		if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
-				| EnableScalingLCD))) {
-			if ((pVBInfo->LCDResInfo == Panel1024x768)
-					|| (pVBInfo->LCDResInfo
-							== Panel1024x768x75)) {
-				pVBInfo->HDE = 1024;
-				pVBInfo->VDE = 768;
-			} else if ((pVBInfo->LCDResInfo == Panel1280x1024)
-					|| (pVBInfo->LCDResInfo
-							== Panel1280x1024x75)) {
-				pVBInfo->HDE = 1280;
-				pVBInfo->VDE = 1024;
-			} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
-				pVBInfo->HDE = 1400;
-				pVBInfo->VDE = 1050;
-			} else {
-				pVBInfo->HDE = 1600;
-				pVBInfo->VDE = 1200;
-			}
+		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+			if (ModeNo <= 0x13)
+				tempal
+						= pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
+			else
+				tempal
+						= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
 		}
-	}
-}
 
-static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned char index;
-	unsigned short tempbx, i;
-	struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
-	struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
-	/* struct XGI330_CHTVDataStruct *TVPtr = NULL; */
-	struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
-	struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
+		if (tempbx & 0x01)
+			tempal = (tempal >> 4);
 
-	if (ModeNo <= 0x13)
-		index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	else
-		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+		tempal = (tempal & 0x0f);
+	}
 
-	index = index & IndexMask;
+	tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
 
-	if ((pVBInfo->IF_DEF_ScaleLCD == 0) || ((pVBInfo->IF_DEF_ScaleLCD == 1)
-			&& (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
-		tempbx = 0;
+	if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
+		if ((tempbx == 5) || (tempbx) == 7)
+			tempcx = LCDDesDataLen2;
+		else if ((tempbx == 3) || (tempbx == 8))
+			tempcx = LVDSDesDataLen2;
+	}
+	/* mov di, word ptr cs:LCDDataList[bx] */
+	/* tempdi = pVideoMemory[LCDDataList + tempbx * 2] | (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
 
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			LCDPtr
-					= (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(
-							tempbx, ModeNo,
-							ModeIdIndex,
-							RefreshRateTableIndex,
-							pVBInfo);
+	switch (tempbx) {
+	case 0:
+		tempdi = XGI_EPLLCDCRT1Ptr_H;
+		break;
+	case 1:
+		tempdi = XGI_EPLLCDCRT1Ptr_V;
+		break;
+	case 2:
+		tempdi = XGI_EPLLCDDataPtr;
+		break;
+	case 3:
+		tempdi = XGI_EPLLCDDesDataPtr;
+		break;
+	case 4:
+		tempdi = XGI_LCDDataTable;
+		break;
+	case 5:
+		tempdi = XGI_LCDDesDataTable;
+		break;
+	case 6:
+		tempdi = XGI_EPLCHLCDRegPtr;
+		break;
+	case 7:
+	case 8:
+	case 9:
+		tempdi = NULL;
+		break;
+	default:
+		break;
+	}
 
-			for (i = 0; i < 8; i++)
-				pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
-		}
+	if (tempdi == NULL) /* OEMUtil */
+		return NULL;
 
-		if (pVBInfo->IF_DEF_CH7007 == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToTV) {
-				CH7007TV_TimingHPtr
-						= (struct XGI_CH7007TV_TimingHStruct *) XGI_GetTVPtr(
-								tempbx,
-								ModeNo,
-								ModeIdIndex,
-								RefreshRateTableIndex,
-								pVBInfo);
+	table = tempbx;
+	i = 0;
 
-				for (i = 0; i < 8; i++)
-					pVBInfo->TimingH[0].data[i]
-							= CH7007TV_TimingHPtr[0].data[i];
-			}
+	while (tempdi[i].PANELID != 0xff) {
+		tempdx = pVBInfo->LCDResInfo;
+		if (tempbx & 0x0080) { /* OEMUtil */
+			tempbx &= (~0x0080);
+			tempdx = pVBInfo->LCDTypeInfo;
 		}
 
-		/* if (pVBInfo->IF_DEF_CH7017 == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToTV)
-				TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-		}
-		*/
+		if (pVBInfo->LCDInfo & EnableScalingLCD)
+			tempdx &= (~PanelResInfo);
 
-		XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+		if (tempdi[i].PANELID == tempdx) {
+			tempbx = tempdi[i].MASK;
+			tempdx = pVBInfo->LCDInfo;
 
-		if (pVBInfo->IF_DEF_CH7007 == 1) {
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2E,
-					CH7007TV_TimingHPtr[0].data[8]);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2F,
-					CH7007TV_TimingHPtr[0].data[9]);
-		}
+			if (ModeNo <= 0x13) /* alan 09/10/2003 */
+				tempdx |= SetLCDStdMode;
 
-		tempbx = 1;
+			if (modeflag & HalfDCLK)
+				tempdx |= SetLCDLowResolution;
 
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			LCDPtr1
-					= (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(
-							tempbx, ModeNo,
-							ModeIdIndex,
-							RefreshRateTableIndex,
-							pVBInfo);
-			for (i = 0; i < 7; i++)
-				pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
+			tempbx &= tempdx;
+			if (tempbx == tempdi[i].CAP)
+				break;
 		}
+		i++;
+	}
 
-		if (pVBInfo->IF_DEF_CH7007 == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToTV) {
-				CH7007TV_TimingVPtr
-						= (struct XGI_CH7007TV_TimingVStruct *) XGI_GetTVPtr(
-								tempbx,
-								ModeNo,
-								ModeIdIndex,
-								RefreshRateTableIndex,
-								pVBInfo);
-
-				for (i = 0; i < 7; i++)
-					pVBInfo->TimingV[0].data[i]
-							= CH7007TV_TimingVPtr[0].data[i];
-			}
-		}
-		/* if (pVBInfo->IF_DEF_CH7017 == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToTV)
-				TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+	if (table == 0) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_LVDSCRT11024x768_1_H[tempal];
+			break;
+		case 1:
+			return &XGI_LVDSCRT11024x768_2_H[tempal];
+			break;
+		case 2:
+			return &XGI_LVDSCRT11280x1024_1_H[tempal];
+			break;
+		case 3:
+			return &XGI_LVDSCRT11280x1024_2_H[tempal];
+			break;
+		case 4:
+			return &XGI_LVDSCRT11400x1050_1_H[tempal];
+			break;
+		case 5:
+			return &XGI_LVDSCRT11400x1050_2_H[tempal];
+			break;
+		case 6:
+			return &XGI_LVDSCRT11600x1200_1_H[tempal];
+			break;
+		case 7:
+			return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
+			break;
+		case 8:
+			return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
+			break;
+		case 9:
+			return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
+			break;
+		case 10:
+			return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
+			break;
+		default:
+			break;
 		}
-		*/
-
-		XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
-
-		if (pVBInfo->IF_DEF_CH7007 == 1) {
-			XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01,
-					CH7007TV_TimingVPtr[0].data[7] & 0x01);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x34,
-					CH7007TV_TimingVPtr[0].data[8]);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x3F,
-					CH7007TV_TimingVPtr[0].data[9]);
-
+	} else if (table == 1) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_LVDSCRT11024x768_1_V[tempal];
+			break;
+		case 1:
+			return &XGI_LVDSCRT11024x768_2_V[tempal];
+			break;
+		case 2:
+			return &XGI_LVDSCRT11280x1024_1_V[tempal];
+			break;
+		case 3:
+			return &XGI_LVDSCRT11280x1024_2_V[tempal];
+			break;
+		case 4:
+			return &XGI_LVDSCRT11400x1050_1_V[tempal];
+			break;
+		case 5:
+			return &XGI_LVDSCRT11400x1050_2_V[tempal];
+			break;
+		case 6:
+			return &XGI_LVDSCRT11600x1200_1_V[tempal];
+			break;
+		case 7:
+			return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
+			break;
+		case 8:
+			return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
+			break;
+		case 9:
+			return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
+			break;
+		case 10:
+			return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
+			break;
+		default:
+			break;
 		}
-	}
-}
-
-static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
-	unsigned long temp, temp1, temp2, temp3, push3;
-	struct XGI330_LCDDataDesStruct *LCDPtr = NULL;
-	struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
-
-	if (ModeNo > 0x13)
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	else
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-
-	if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
-		if ((pVBInfo->IF_DEF_CH7017 == 0) || (pVBInfo->VBInfo
-				& (SetCRT2ToLCD | SetCRT2ToLCDA))) {
-			if (pVBInfo->IF_DEF_OEMUtil == 1) {
-				tempbx = 8;
-				LCDPtr
-						= (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
-								tempbx,
-								ModeNo,
-								ModeIdIndex,
-								RefreshRateTableIndex,
-								pVBInfo);
-			}
-
-			if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == NULL)) {
-				tempbx = 3;
-				if (pVBInfo->LCDInfo & EnableScalingLCD)
-					LCDPtr1
-							= (struct XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(
-									tempbx,
-									ModeNo,
-									ModeIdIndex,
-									RefreshRateTableIndex,
-									pVBInfo);
-				else
-					LCDPtr
-							= (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
-									tempbx,
-									ModeNo,
-									ModeIdIndex,
-									RefreshRateTableIndex,
-									pVBInfo);
-			}
-
-			XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
-			push1 = tempbx;
-			push2 = tempax;
-
-			/* GetLCDResInfo */
-			if ((pVBInfo->LCDResInfo == Panel1024x768)
-					|| (pVBInfo->LCDResInfo
-							== Panel1024x768x75)) {
-				tempax = 1024;
-				tempbx = 768;
-			} else if ((pVBInfo->LCDResInfo == Panel1280x1024)
-					|| (pVBInfo->LCDResInfo
-							== Panel1280x1024x75)) {
-				tempax = 1280;
-				tempbx = 1024;
-			} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
-				tempax = 1400;
-				tempbx = 1050;
-			} else {
-				tempax = 1600;
-				tempbx = 1200;
-			}
-
-			if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
-				pVBInfo->HDE = tempax;
-				pVBInfo->VDE = tempbx;
-				pVBInfo->VGAHDE = tempax;
-				pVBInfo->VGAVDE = tempbx;
-			}
-
-			if ((pVBInfo->IF_DEF_ScaleLCD == 1)
-					&& (pVBInfo->LCDInfo & EnableScalingLCD)) {
-				tempax = pVBInfo->HDE;
-				tempbx = pVBInfo->VDE;
-			}
-
-			tempax = pVBInfo->HT;
-
-			if (pVBInfo->LCDInfo & EnableScalingLCD)
-				tempbx = LCDPtr1->LCDHDES;
+	} else if (table == 2) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_LVDS1024x768Data_1[tempal];
+			break;
+		case 1:
+			return &XGI_LVDS1024x768Data_2[tempal];
+			break;
+		case 2:
+			return &XGI_LVDS1280x1024Data_1[tempal];
+			break;
+		case 3:
+			return &XGI_LVDS1280x1024Data_2[tempal];
+			break;
+		case 4:
+			return &XGI_LVDS1400x1050Data_1[tempal];
+			break;
+		case 5:
+			return &XGI_LVDS1400x1050Data_2[tempal];
+			break;
+		case 6:
+			return &XGI_LVDS1600x1200Data_1[tempal];
+			break;
+		case 7:
+			return &XGI_LVDSNoScalingData[tempal];
+			break;
+		case 8:
+			return &XGI_LVDS1024x768Data_1x75[tempal];
+			break;
+		case 9:
+			return &XGI_LVDS1024x768Data_2x75[tempal];
+			break;
+		case 10:
+			return &XGI_LVDS1280x1024Data_1x75[tempal];
+			break;
+		case 11:
+			return &XGI_LVDS1280x1024Data_2x75[tempal];
+			break;
+		case 12:
+			return &XGI_LVDSNoScalingDatax75[tempal];
+			break;
+		default:
+			break;
+		}
+	} else if (table == 3) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_LVDS1024x768Des_1[tempal];
+			break;
+		case 1:
+			return &XGI_LVDS1024x768Des_3[tempal];
+			break;
+		case 2:
+			return &XGI_LVDS1024x768Des_2[tempal];
+			break;
+		case 3:
+			return &XGI_LVDS1280x1024Des_1[tempal];
+			break;
+		case 4:
+			return &XGI_LVDS1280x1024Des_2[tempal];
+			break;
+		case 5:
+			return &XGI_LVDS1400x1050Des_1[tempal];
+			break;
+		case 6:
+			return &XGI_LVDS1400x1050Des_2[tempal];
+			break;
+		case 7:
+			return &XGI_LVDS1600x1200Des_1[tempal];
+			break;
+		case 8:
+			return &XGI_LVDSNoScalingDesData[tempal];
+			break;
+		case 9:
+			return &XGI_LVDS1024x768Des_1x75[tempal];
+			break;
+		case 10:
+			return &XGI_LVDS1024x768Des_3x75[tempal];
+			break;
+		case 11:
+			return &XGI_LVDS1024x768Des_2x75[tempal];
+			break;
+		case 12:
+			return &XGI_LVDS1280x1024Des_1x75[tempal];
+			break;
+		case 13:
+			return &XGI_LVDS1280x1024Des_2x75[tempal];
+			break;
+		case 14:
+			return &XGI_LVDSNoScalingDesDatax75[tempal];
+			break;
+		default:
+			break;
+		}
+	} else if (table == 4) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_ExtLCD1024x768Data[tempal];
+			break;
+		case 1:
+			return &XGI_StLCD1024x768Data[tempal];
+			break;
+		case 2:
+			return &XGI_CetLCD1024x768Data[tempal];
+			break;
+		case 3:
+			return &XGI_ExtLCD1280x1024Data[tempal];
+			break;
+		case 4:
+			return &XGI_StLCD1280x1024Data[tempal];
+			break;
+		case 5:
+			return &XGI_CetLCD1280x1024Data[tempal];
+			break;
+		case 6:
+			return &XGI_ExtLCD1400x1050Data[tempal];
+			break;
+		case 7:
+			return &XGI_StLCD1400x1050Data[tempal];
+			break;
+		case 8:
+			return &XGI_CetLCD1400x1050Data[tempal];
+			break;
+		case 9:
+			return &XGI_ExtLCD1600x1200Data[tempal];
+			break;
+		case 10:
+			return &XGI_StLCD1600x1200Data[tempal];
+			break;
+		case 11:
+			return &XGI_NoScalingData[tempal];
+			break;
+		case 12:
+			return &XGI_ExtLCD1024x768x75Data[tempal];
+			break;
+		case 13:
+			return &XGI_ExtLCD1024x768x75Data[tempal];
+			break;
+		case 14:
+			return &XGI_CetLCD1024x768x75Data[tempal];
+			break;
+		case 15:
+			return &XGI_ExtLCD1280x1024x75Data[tempal];
+			break;
+		case 16:
+			return &XGI_StLCD1280x1024x75Data[tempal];
+			break;
+		case 17:
+			return &XGI_CetLCD1280x1024x75Data[tempal];
+			break;
+		case 18:
+			return &XGI_NoScalingDatax75[tempal];
+			break;
+		default:
+			break;
+		}
+	} else if (table == 5) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_ExtLCDDes1024x768Data[tempal];
+			break;
+		case 1:
+			return &XGI_StLCDDes1024x768Data[tempal];
+			break;
+		case 2:
+			return &XGI_CetLCDDes1024x768Data[tempal];
+			break;
+		case 3:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_ExtLCDDLDes1280x1024Data[tempal];
 			else
-				tempbx = LCDPtr->LCDHDES;
-
-			tempcx = pVBInfo->HDE;
-			tempbx = tempbx & 0x0fff;
-			tempcx += tempbx;
-
-			if (tempcx >= tempax)
-				tempcx -= tempax;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
-
-			tempcx = tempcx >> 3;
-			tempbx = tempbx >> 3;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x16,
-					(unsigned short) (tempbx & 0xff));
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x17,
-					(unsigned short) (tempcx & 0xff));
-
-			tempax = pVBInfo->HT;
-
-			if (pVBInfo->LCDInfo & EnableScalingLCD)
-				tempbx = LCDPtr1->LCDHRS;
+				return &XGI_ExtLCDDes1280x1024Data[tempal];
+			break;
+		case 4:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_StLCDDLDes1280x1024Data[tempal];
 			else
-				tempbx = LCDPtr->LCDHRS;
-
-			tempcx = push2;
-
-			if (pVBInfo->LCDInfo & EnableScalingLCD)
-				tempcx = LCDPtr1->LCDHSync;
-
-			tempcx += tempbx;
-
-			if (tempcx >= tempax)
-				tempcx -= tempax;
-
-			tempax = tempbx & 0x07;
-			tempax = tempax >> 5;
-			tempcx = tempcx >> 3;
-			tempbx = tempbx >> 3;
-
-			tempcx &= 0x1f;
-			tempax |= tempcx;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x15, tempax);
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x14,
-					(unsigned short) (tempbx & 0xff));
-
-			tempax = pVBInfo->VT;
-			if (pVBInfo->LCDInfo & EnableScalingLCD)
-				tempbx = LCDPtr1->LCDVDES;
+				return &XGI_StLCDDes1280x1024Data[tempal];
+			break;
+		case 5:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_CetLCDDLDes1280x1024Data[tempal];
+			else
+				return &XGI_CetLCDDes1280x1024Data[tempal];
+			break;
+		case 6:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_ExtLCDDLDes1400x1050Data[tempal];
+			else
+				return &XGI_ExtLCDDes1400x1050Data[tempal];
+			break;
+		case 7:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_StLCDDLDes1400x1050Data[tempal];
+			else
+				return &XGI_StLCDDes1400x1050Data[tempal];
+			break;
+		case 8:
+			return &XGI_CetLCDDes1400x1050Data[tempal];
+			break;
+		case 9:
+			return &XGI_CetLCDDes1400x1050Data2[tempal];
+			break;
+		case 10:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_ExtLCDDLDes1600x1200Data[tempal];
+			else
+				return &XGI_ExtLCDDes1600x1200Data[tempal];
+			break;
+		case 11:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_StLCDDLDes1600x1200Data[tempal];
+			else
+				return &XGI_StLCDDes1600x1200Data[tempal];
+			break;
+		case 12:
+			return &XGI_NoScalingDesData[tempal];
+			break;
+		case 13:
+			return &XGI_ExtLCDDes1024x768x75Data[tempal];
+			break;
+		case 14:
+			return &XGI_StLCDDes1024x768x75Data[tempal];
+			break;
+		case 15:
+			return &XGI_CetLCDDes1024x768x75Data[tempal];
+			break;
+		case 16:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
 			else
-				tempbx = LCDPtr->LCDVDES;
-			tempcx = pVBInfo->VDE;
-
-			tempbx = tempbx & 0x0fff;
-			tempcx += tempbx;
-			if (tempcx >= tempax)
-				tempcx -= tempax;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x1b,
-					(unsigned short) (tempbx & 0xff));
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x1c,
-					(unsigned short) (tempcx & 0xff));
-
-			tempbx = (tempbx >> 8) & 0x07;
-			tempcx = (tempcx >> 8) & 0x07;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x1d,
-					(unsigned short) ((tempcx << 3)
-							| tempbx));
-
-			tempax = pVBInfo->VT;
-			if (pVBInfo->LCDInfo & EnableScalingLCD)
-				tempbx = LCDPtr1->LCDVRS;
+				return &XGI_ExtLCDDes1280x1024x75Data[tempal];
+			break;
+		case 17:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_StLCDDLDes1280x1024x75Data[tempal];
 			else
-				tempbx = LCDPtr->LCDVRS;
-
-			/* tempbx = tempbx >> 4; */
-			tempcx = push1;
-
-			if (pVBInfo->LCDInfo & EnableScalingLCD)
-				tempcx = LCDPtr1->LCDVSync;
-
-			tempcx += tempbx;
-			if (tempcx >= tempax)
-				tempcx -= tempax;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x18,
-					(unsigned short) (tempbx & 0xff));
-			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f,
-					(unsigned short) (tempcx & 0x0f));
-
-			tempax = ((tempbx >> 8) & 0x07) << 3;
-
-			tempbx = pVBInfo->VGAVDE;
-			if (tempbx != pVBInfo->VDE)
-				tempax |= 0x40;
-
-			if (pVBInfo->LCDInfo & EnableLVDSDDA)
-				tempax |= 0x40;
-
-			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1a, 0x07,
-					tempax);
-
-			tempcx = pVBInfo->VGAVT;
-			tempbx = pVBInfo->VDE;
-			tempax = pVBInfo->VGAVDE;
-			tempcx -= tempax;
-
-			temp = tempax; /* 0430 ylshieh */
-			temp1 = (temp << 18) / tempbx;
-
-			tempdx = (unsigned short) ((temp << 18) % tempbx);
-
-			if (tempdx != 0)
-				temp1 += 1;
-
-			temp2 = temp1;
-			push3 = temp2;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x37,
-					(unsigned short) (temp2 & 0xff));
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x36,
-					(unsigned short) ((temp2 >> 8) & 0xff));
-
-			tempbx = (unsigned short) (temp2 >> 16);
-			tempax = tempbx & 0x03;
-
-			tempbx = pVBInfo->VGAVDE;
-			if (tempbx == pVBInfo->VDE)
-				tempax |= 0x04;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x35, tempax);
-
-			if (pVBInfo->VBType & VB_XGI301C) {
-				temp2 = push3;
-				XGINew_SetReg1(pVBInfo->Part4Port, 0x3c,
-						(unsigned short) (temp2 & 0xff));
-				XGINew_SetReg1(pVBInfo->Part4Port, 0x3b,
-						(unsigned short) ((temp2 >> 8)
-								& 0xff));
-				tempbx = (unsigned short) (temp2 >> 16);
-				XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a,
-						~0xc0,
-						(unsigned short) ((tempbx
-								& 0xff) << 6));
-
-				tempcx = pVBInfo->VGAVDE;
-				if (tempcx == pVBInfo->VDE)
-					XGINew_SetRegANDOR(pVBInfo->Part4Port,
-							0x30, ~0x0c, 0x00);
-				else
-					XGINew_SetRegANDOR(pVBInfo->Part4Port,
-							0x30, ~0x0c, 0x08);
-			}
-
-			tempcx = pVBInfo->VGAHDE;
-			tempbx = pVBInfo->HDE;
-
-			temp1 = tempcx << 16;
-
-			tempax = (unsigned short) (temp1 / tempbx);
-
-			if ((tempbx & 0xffff) == (tempcx & 0xffff))
-				tempax = 65535;
-
-			temp3 = tempax;
-			temp1 = pVBInfo->VGAHDE << 16;
-
-			temp1 /= temp3;
-			temp3 = temp3 << 16;
-			temp1 -= 1;
-
-			temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
-
-			tempax = (unsigned short) (temp3 & 0xff);
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x1f, tempax);
-
-			temp1 = pVBInfo->VGAVDE << 18;
-			temp1 = temp1 / push3;
-			tempbx = (unsigned short) (temp1 & 0xffff);
-
-			if (pVBInfo->LCDResInfo == Panel1024x768)
-				tempbx -= 1;
-
-			tempax = ((tempbx >> 8) & 0xff) << 3;
-			tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x20,
-					(unsigned short) (tempax & 0xff));
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x21,
-					(unsigned short) (tempbx & 0xff));
-
-			temp3 = temp3 >> 16;
-
-			if (modeflag & HalfDCLK)
-				temp3 = temp3 >> 1;
-
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x22,
-					(unsigned short) ((temp3 >> 8) & 0xff));
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x23,
-					(unsigned short) (temp3 & 0xff));
+				return &XGI_StLCDDes1280x1024x75Data[tempal];
+			break;
+		case 18:
+			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV))
+				return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
+			else
+				return &XGI_CetLCDDes1280x1024x75Data[tempal];
+			break;
+		case 19:
+			return &XGI_NoScalingDesDatax75[tempal];
+			break;
+		default:
+			break;
 		}
-	}
-}
-
-static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned char di_0, di_1, tempal;
-	int i;
-
-	tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
-			pVBInfo);
-	XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
-	XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
-
-	for (i = 0; i < 4; i++) {
-		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30,
-				(unsigned short) (0x10 * i));
-		if (pVBInfo->IF_DEF_CH7007 == 1) {
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
-		} else if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-				&& (!(pVBInfo->VBInfo & SetInSlaveMode))) {
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2e, di_0);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2f, di_1);
-		} else {
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
-			XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
+	} else if (table == 6) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_CH7017LV1024x768[tempal];
+			break;
+		case 1:
+			return &XGI_CH7017LV1400x1050[tempal];
+			break;
+		default:
+			break;
 		}
 	}
+	return NULL;
 }
 
-static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
+static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
+		unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempcl, tempch, temp, tempbl, tempax;
-
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		tempcl = 0;
-		tempch = 0;
-		temp = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
-
-		if (!(temp & 0x20)) {
-			temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17);
-			if (temp & 0x80) {
-				if ((HwDeviceExtension->jChipType >= XG20)
-						|| (HwDeviceExtension->jChipType
-								>= XG40))
-					temp = XGINew_GetReg1(pVBInfo->P3d4,
-							0x53);
-				else
-					temp = XGINew_GetReg1(pVBInfo->P3d4,
-							0x63);
-
-				if (!(temp & 0x40))
-					tempcl |= ActiveCRT1;
-			}
-		}
+	unsigned short i, tempdx, tempbx, tempal, modeflag, table;
+	struct XGI330_TVDataTablStruct *tempdi = NULL;
 
-		temp = XGINew_GetReg1(pVBInfo->Part1Port, 0x2e);
-		temp &= 0x0f;
+	tempbx = BX;
 
-		if (!(temp == 0x08)) {
-			tempax = XGINew_GetReg1(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
-			if (tempax & 0x04)
-				tempcl = tempcl | ActiveLCD;
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+		tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+	}
 
-			temp &= 0x05;
+	tempal = tempal & 0x3f;
+	table = tempbx;
 
-			if (!(tempcl & ActiveLCD))
-				if (temp == 0x01)
-					tempcl |= ActiveCRT2;
+	switch (tempbx) {
+	case 0:
+		tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/
+		if (pVBInfo->IF_DEF_CH7007 == 1)
+			tempdi = XGI_EPLCHTVCRT1Ptr;
 
-			if (temp == 0x04)
-				tempcl |= ActiveLCD;
+		break;
+	case 1:
+		tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/
+		if (pVBInfo->IF_DEF_CH7007 == 1)
+			tempdi = XGI_EPLCHTVCRT1Ptr;
 
-			if (temp == 0x05) {
-				temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x00);
+		break;
+	case 2:
+		tempdi = XGI_EPLCHTVDataPtr;
+		break;
+	case 3:
+		tempdi = NULL;
+		break;
+	case 4:
+		tempdi = XGI_TVDataTable;
+		break;
+	case 5:
+		tempdi = NULL;
+		break;
+	case 6:
+		tempdi = XGI_EPLCHTVRegPtr;
+		break;
+	default:
+		break;
+	}
 
-				if (!(temp & 0x08))
-					tempch |= ActiveAVideo;
+	if (tempdi == NULL) /* OEMUtil */
+		return NULL;
 
-				if (!(temp & 0x04))
-					tempch |= ActiveSVideo;
+	tempdx = pVBInfo->TVInfo;
 
-				if (temp & 0x02)
-					tempch |= ActiveSCART;
+	if (pVBInfo->VBInfo & SetInSlaveMode)
+		tempdx = tempdx | SetTVLockMode;
 
-				if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-					if (temp & 0x01)
-						tempch |= ActiveHiTV;
-				}
+	if (modeflag & HalfDCLK)
+		tempdx = tempdx | SetTVLowResolution;
 
-				if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-					temp = XGINew_GetReg1(
-							pVBInfo->Part2Port,
-							0x4d);
+	i = 0;
 
-					if (temp & 0x10)
-						tempch |= ActiveYPbPr;
-				}
+	while (tempdi[i].MASK != 0xffff) {
+		if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
+			break;
+		i++;
+	}
 
-				if (tempch != 0)
-					tempcl |= ActiveTV;
-			}
+	if (table == 0x00) { /* 07/05/22 */
+	} else if (table == 0x01) {
+	} else if (table == 0x04) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_ExtPALData[tempal];
+			break;
+		case 1:
+			return &XGI_ExtNTSCData[tempal];
+			break;
+		case 2:
+			return &XGI_StPALData[tempal];
+			break;
+		case 3:
+			return &XGI_StNTSCData[tempal];
+			break;
+		case 4:
+			return &XGI_ExtHiTVData[tempal];
+			break;
+		case 5:
+			return &XGI_St2HiTVData[tempal];
+			break;
+		case 6:
+			return &XGI_ExtYPbPr525iData[tempal];
+			break;
+		case 7:
+			return &XGI_ExtYPbPr525pData[tempal];
+			break;
+		case 8:
+			return &XGI_ExtYPbPr750pData[tempal];
+			break;
+		case 9:
+			return &XGI_StYPbPr525iData[tempal];
+			break;
+		case 10:
+			return &XGI_StYPbPr525pData[tempal];
+			break;
+		case 11:
+			return &XGI_StYPbPr750pData[tempal];
+			break;
+		case 12: /* avoid system hang */
+			return &XGI_ExtNTSCData[tempal];
+			break;
+		case 13:
+			return &XGI_St1HiTVData[tempal];
+			break;
+		default:
+			break;
 		}
-
-		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
-		if (tempcl & ActiveLCD) {
-			if ((pVBInfo->SetFlag & ReserveTVOption)) {
-				if (temp & ActiveTV)
-					tempcl |= ActiveTV;
-			}
+	} else if (table == 0x02) {
+		switch (tempdi[i].DATAPTR) {
+		case 0:
+			return &XGI_CHTVUNTSCData[tempal];
+			break;
+		case 1:
+			return &XGI_CHTVONTSCData[tempal];
+			break;
+		case 2:
+			return &XGI_CHTVUPALData[tempal];
+			break;
+		case 3:
+			return &XGI_CHTVOPALData[tempal];
+			break;
+		default:
+			break;
 		}
-		temp = tempcl;
-		tempbl = ~ModeSwitchStatus;
-		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp);
-
-		if (!(pVBInfo->SetFlag & ReserveTVOption))
-			XGINew_SetReg1(pVBInfo->P3d4, 0x3e, tempch);
-	} else {
-		return;
+	} else if (table == 0x06) {
 	}
+	return NULL;
 }
 
-void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension,
+static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	/*
-	if ( HwDeviceExtension->jChipType >= XG20 ) {
-		pVBInfo->Set_VGAType = XG20;
-	} else if (HwDeviceExtension->jChipType >= XG40) {
-		pVBInfo->Set_VGAType = VGA_XGI340;
-	}
-	*/
-	pVBInfo->Set_VGAType = HwDeviceExtension->jChipType;
-}
+	unsigned short tempbx;
+	struct XGI330_LVDSDataStruct *LCDPtr = NULL;
+	struct XGI330_CHTVDataStruct *TVPtr = NULL;
 
-void XGI_GetVBType(struct vb_device_info *pVBInfo)
-{
-	unsigned short flag, tempbx, tempah;
+	tempbx = 2;
 
-	if (pVBInfo->IF_DEF_CH7007 == 1) {
-		pVBInfo->VBType = VB_CH7007;
-		return;
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+		LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx,
+				ModeNo, ModeIdIndex, RefreshRateTableIndex,
+				pVBInfo);
+		pVBInfo->VGAHT = LCDPtr->VGAHT;
+		pVBInfo->VGAVT = LCDPtr->VGAVT;
+		pVBInfo->HT = LCDPtr->LCDHT;
+		pVBInfo->VT = LCDPtr->LCDVT;
+	}
+	if (pVBInfo->IF_DEF_CH7017 == 1) {
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			TVPtr = (struct XGI330_CHTVDataStruct *) XGI_GetTVPtr(
+					tempbx, ModeNo, ModeIdIndex,
+					RefreshRateTableIndex, pVBInfo);
+			pVBInfo->VGAHT = TVPtr->VGAHT;
+			pVBInfo->VGAVT = TVPtr->VGAVT;
+			pVBInfo->HT = TVPtr->LCDHT;
+			pVBInfo->VT = TVPtr->LCDVT;
+		}
 	}
-	if (pVBInfo->IF_DEF_LVDS == 0) {
-		tempbx = VB_XGI302B;
-		flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
-		if (flag != 0x02) {
-			tempbx = VB_XGI301;
-			flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01);
-			if (flag >= 0xB0) {
-				tempbx = VB_XGI301B;
-				if (flag >= 0xC0) {
-					tempbx = VB_XGI301C;
-					if (flag >= 0xD0) {
-						tempbx = VB_XGI301LV;
-						if (flag >= 0xE0) {
-							tempbx = VB_XGI302LV;
-							tempah
-									= XGINew_GetReg1(
-											pVBInfo->Part4Port,
-											0x39);
-							if (tempah != 0xFF)
-								tempbx
-										= VB_XGI301C;
-						}
-					}
-				}
-
-				if (tempbx & (VB_XGI301B | VB_XGI302B)) {
-					flag = XGINew_GetReg1(
-							pVBInfo->Part4Port,
-							0x23);
 
-					if (!(flag & 0x02))
-						tempbx = tempbx | VB_NoLCD;
-				}
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+		if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
+				| EnableScalingLCD))) {
+			if ((pVBInfo->LCDResInfo == Panel1024x768)
+					|| (pVBInfo->LCDResInfo
+							== Panel1024x768x75)) {
+				pVBInfo->HDE = 1024;
+				pVBInfo->VDE = 768;
+			} else if ((pVBInfo->LCDResInfo == Panel1280x1024)
+					|| (pVBInfo->LCDResInfo
+							== Panel1280x1024x75)) {
+				pVBInfo->HDE = 1280;
+				pVBInfo->VDE = 1024;
+			} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+				pVBInfo->HDE = 1400;
+				pVBInfo->VDE = 1050;
+			} else {
+				pVBInfo->HDE = 1600;
+				pVBInfo->VDE = 1200;
 			}
 		}
-		pVBInfo->VBType = tempbx;
 	}
-	/*
-	else if (pVBInfo->IF_DEF_CH7017 == 1)
-		pVBInfo->VBType = VB_CH7017;
-	else //LVDS
-		pVBInfo->VBType = VB_LVDS_NS;
-	 */
-
 }
 
-void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempax, push, tempbx, temp, modeflag;
+	unsigned char index;
+	unsigned short tempbx, i;
+	struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
+	struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
+	/* struct XGI330_CHTVDataStruct *TVPtr = NULL; */
+	struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
+	struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
 
 	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+		index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
-	pVBInfo->SetFlag = 0;
-	pVBInfo->ModeType = modeflag & ModeInfoFlag;
-	tempbx = 0;
+		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-	if (pVBInfo->VBType & 0xFFFF) {
-		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x30); /* Check Display Device */
-		tempbx = tempbx | temp;
-		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
-		push = temp;
-		push = push << 8;
-		tempax = temp << 8;
-		tempbx = tempbx | tempax;
-		temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA
-				| SetInSlaveMode | DisableCRT2Display);
-		temp = 0xFFFF ^ temp;
-		tempbx &= temp;
+	index = index & IndexMask;
 
-		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+	if ((pVBInfo->IF_DEF_ScaleLCD == 0) || ((pVBInfo->IF_DEF_ScaleLCD == 1)
+			&& (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
+		tempbx = 0;
 
-		if (pVBInfo->IF_DEF_LCDA == 1) {
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+			LCDPtr
+					= (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(
+							tempbx, ModeNo,
+							ModeIdIndex,
+							RefreshRateTableIndex,
+							pVBInfo);
 
-			if ((pVBInfo->Set_VGAType >= XG20)
-					|| (pVBInfo->Set_VGAType >= XG40)) {
-				if (pVBInfo->IF_DEF_LVDS == 0) {
-					/* if ((pVBInfo->VBType & VB_XGI302B) || (pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C)) */
-					if (pVBInfo->VBType & (VB_XGI302B
-							| VB_XGI301LV
-							| VB_XGI302LV
-							| VB_XGI301C)) {
-						if (temp & EnableDualEdge) {
-							tempbx
-									|= SetCRT2ToDualEdge;
+			for (i = 0; i < 8; i++)
+				pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
+		}
 
-							if (temp & SetToLCDA)
-								tempbx
-										|= SetCRT2ToLCDA;
-						}
-					}
-				} else if (pVBInfo->IF_DEF_CH7017 == 1) {
-					if (pVBInfo->VBType & VB_CH7017) {
-						if (temp & EnableDualEdge) {
-							tempbx
-									|= SetCRT2ToDualEdge;
+		if (pVBInfo->IF_DEF_CH7007 == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToTV) {
+				CH7007TV_TimingHPtr
+						= (struct XGI_CH7007TV_TimingHStruct *) XGI_GetTVPtr(
+								tempbx,
+								ModeNo,
+								ModeIdIndex,
+								RefreshRateTableIndex,
+								pVBInfo);
 
-							if (temp & SetToLCDA)
-								tempbx
-										|= SetCRT2ToLCDA;
-						}
-					}
-				}
+				for (i = 0; i < 8; i++)
+					pVBInfo->TimingH[0].data[i]
+							= CH7007TV_TimingHPtr[0].data[i];
 			}
 		}
 
-		if (pVBInfo->IF_DEF_YPbPr == 1) {
-			if (((pVBInfo->IF_DEF_LVDS == 0) && ((pVBInfo->VBType
-					& VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV) || (pVBInfo->VBType
-					& VB_XGI301C)))
-					|| ((pVBInfo->IF_DEF_CH7017 == 1)
-							&& (pVBInfo->VBType
-									& VB_CH7017))
-					|| ((pVBInfo->IF_DEF_CH7007 == 1)
-							&& (pVBInfo->VBType
-									& VB_CH7007))) { /* [Billy] 07/05/04 */
-				if (temp & SetYPbPr) { /* temp = CR38 */
-					if (pVBInfo->IF_DEF_HiVision == 1) {
-						temp = XGINew_GetReg1(
-								pVBInfo->P3d4,
-								0x35); /* shampoo add for new scratch */
-						temp &= YPbPrMode;
-						tempbx |= SetCRT2ToHiVisionTV;
+		/* if (pVBInfo->IF_DEF_CH7017 == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToTV)
+				TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+		}
+		*/
 
-						if (temp != YPbPrMode1080i) {
-							tempbx
-									&= (~SetCRT2ToHiVisionTV);
-							tempbx
-									|= SetCRT2ToYPbPr;
-						}
-					}
+		XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
 
-					/* tempbx |= SetCRT2ToYPbPr; */
-				}
-			}
+		if (pVBInfo->IF_DEF_CH7007 == 1) {
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2E,
+					CH7007TV_TimingHPtr[0].data[8]);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2F,
+					CH7007TV_TimingHPtr[0].data[9]);
 		}
 
-		tempax = push; /* restore CR31 */
+		tempbx = 1;
 
-		if (pVBInfo->IF_DEF_LVDS == 0) {
-			if (pVBInfo->IF_DEF_YPbPr == 1) {
-				if (pVBInfo->IF_DEF_HiVision == 1)
-					temp = 0x09FC;
-				else
-					temp = 0x097C;
-			} else {
-				if (pVBInfo->IF_DEF_HiVision == 1)
-					temp = 0x01FC;
-				else
-					temp = 0x017C;
-			}
-		} else { /* 3nd party chip */
-			if (pVBInfo->IF_DEF_CH7017 == 1)
-				temp = (SetCRT2ToTV | SetCRT2ToLCD
-						| SetCRT2ToLCDA);
-			else if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/03 */
-				temp = SetCRT2ToTV;
-			} else
-				temp = SetCRT2ToLCD;
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+			LCDPtr1
+					= (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(
+							tempbx, ModeNo,
+							ModeIdIndex,
+							RefreshRateTableIndex,
+							pVBInfo);
+			for (i = 0; i < 7; i++)
+				pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
 		}
 
-		if (!(tempbx & temp)) {
-			tempax |= DisableCRT2Display;
-			tempbx = 0;
-		}
+		if (pVBInfo->IF_DEF_CH7007 == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToTV) {
+				CH7007TV_TimingVPtr
+						= (struct XGI_CH7007TV_TimingVStruct *) XGI_GetTVPtr(
+								tempbx,
+								ModeNo,
+								ModeIdIndex,
+								RefreshRateTableIndex,
+								pVBInfo);
 
-		if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
-			if (!(pVBInfo->VBType & VB_NoLCD)) {
-				if (tempbx & SetCRT2ToLCDA) {
-					if (tempbx & SetSimuScanMode)
-						tempbx
-								&= (~(SetCRT2ToLCD
-										| SetCRT2ToRAMDAC
-										| SwitchToCRT2));
-					else
-						tempbx
-								&= (~(SetCRT2ToLCD
-										| SetCRT2ToRAMDAC
-										| SetCRT2ToTV
-										| SwitchToCRT2));
-				}
+				for (i = 0; i < 7; i++)
+					pVBInfo->TimingV[0].data[i]
+							= CH7007TV_TimingVPtr[0].data[i];
 			}
 		}
-
-		/* shampoo add */
-		if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
-			if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
-				if (tempbx & SetCRT2ToRAMDAC) {
-					tempbx &= (0xFF00 | SetCRT2ToRAMDAC
-							| SwitchToCRT2
-							| SetSimuScanMode);
-					tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
-				}
-			} else {
-				tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD
-						| SetCRT2ToTV));
-			}
+		/* if (pVBInfo->IF_DEF_CH7017 == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToTV)
+				TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 		}
+		*/
 
-		if (!(pVBInfo->VBType & VB_NoLCD)) {
-			if (tempbx & SetCRT2ToLCD) {
-				tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchToCRT2
-						| SetSimuScanMode);
-				tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
-			}
-		}
+		XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
 
-		if (tempbx & SetCRT2ToSCART) {
-			tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchToCRT2
-					| SetSimuScanMode);
-			tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
-		}
+		if (pVBInfo->IF_DEF_CH7007 == 1) {
+			XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01,
+					CH7007TV_TimingVPtr[0].data[7] & 0x01);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x34,
+					CH7007TV_TimingVPtr[0].data[8]);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x3F,
+					CH7007TV_TimingVPtr[0].data[9]);
 
-		if (pVBInfo->IF_DEF_YPbPr == 1) {
-			if (tempbx & SetCRT2ToYPbPr)
-				tempbx &= (0xFF00 | SwitchToCRT2
-						| SetSimuScanMode);
 		}
+	}
+}
 
-		if (pVBInfo->IF_DEF_HiVision == 1) {
-			if (tempbx & SetCRT2ToHiVisionTV)
-				tempbx &= (0xFF00 | SetCRT2ToHiVisionTV
-						| SwitchToCRT2
-						| SetSimuScanMode);
-		}
+static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
+{
+	unsigned char tempal, tempah, tempbl, i;
+
+	tempah = XGINew_GetReg1(pVBInfo->P3d4, 0x36);
+	tempal = tempah & 0x0F;
+	tempah = tempah & 0xF0;
+	i = 0;
+	tempbl = pVBInfo->LCDCapList[i].LCD_ID;
 
-		if (tempax & DisableCRT2Display) { /* Set Display Device Info */
-			if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
-				tempbx = DisableCRT2Display;
+	while (tempbl != 0xFF) {
+		if (tempbl & 0x80) { /* OEMUtil */
+			tempal = tempah;
+			tempbl = tempbl & ~(0x80);
 		}
 
-		if (!(tempbx & DisableCRT2Display)) {
-			if ((!(tempbx & DriverMode))
-					|| (!(modeflag & CRT2Mode))) {
-				if (pVBInfo->IF_DEF_LCDA == 1) {
-					if (!(tempbx & SetCRT2ToLCDA))
-						tempbx
-								|= (SetInSlaveMode
-										| SetSimuScanMode);
-				}
+		if (tempal == tempbl)
+			break;
 
-				if (pVBInfo->IF_DEF_VideoCapture == 1) {
-					if (((HwDeviceExtension->jChipType
-							== XG40)
-							&& (pVBInfo->Set_VGAType
-									== XG40))
-							|| ((HwDeviceExtension->jChipType
-									== XG41)
-									&& (pVBInfo->Set_VGAType
-											== XG41))
-							|| ((HwDeviceExtension->jChipType
-									== XG42)
-									&& (pVBInfo->Set_VGAType
-											== XG42))
-							|| ((HwDeviceExtension->jChipType
-									== XG45)
-									&& (pVBInfo->Set_VGAType
-											== XG45))) {
-						if (ModeNo <= 13) {
-							if (!(tempbx
-									& SetCRT2ToRAMDAC)) { /*CRT2 not need to support*/
-								tempbx
-										&= (0x00FF
-												| (~SetInSlaveMode));
-								pVBInfo->SetFlag
-										|= EnableVCMode;
-							}
-						}
-					}
-				}
-			}
+		i++;
 
-			/* LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
-			if ((tempbx & SetInSlaveMode) && (tempbx
-					& SetCRT2ToLCDA)) {
-				tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA
-						| SetCRT2ToDualEdge);
-				pVBInfo->SetFlag |= ReserveTVOption;
-			}
-		}
+		tempbl = pVBInfo->LCDCapList[i].LCD_ID;
 	}
 
-	pVBInfo->VBInfo = tempbx;
+	return i;
 }
 
-void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
 {
-	unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1;
+	unsigned short tempah, tempal, tempbl, i;
 
-	tempbx = 0;
-	resinfo = 0;
+	tempal = pVBInfo->LCDResInfo;
+	tempah = pVBInfo->LCDTypeInfo;
 
-	if (pVBInfo->VBInfo & SetCRT2ToTV) {
-		if (ModeNo <= 0x13) {
-			modeflag
-					= pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
-			resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
-		} else {
-			modeflag
-					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-			resinfo
-					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
-		}
+	i = 0;
+	tempbl = pVBInfo->LCDCapList[i].LCD_ID;
 
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			temp = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
-			tempbx = temp;
-			if (tempbx & SetPALTV) {
-				tempbx &= (SetCHTVOverScan | SetPALMTV
-						| SetPALNTV | SetPALTV);
-				if (tempbx & SetPALMTV)
-					tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
-			} else
-				tempbx &= (SetCHTVOverScan | SetNTSCJ
-						| SetPALTV);
-			/*
-			if (pVBInfo->IF_DEF_LVDS == 0) {
-				index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info
-				temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N
-				tempbx |= temp2;
-				if (temp2 & 0x02)          //PAL-M
-					tempbx &= (~SetPALTV);
-			}
-			*/
+	while (tempbl != 0xFF) {
+		if ((tempbl & 0x80) && (tempbl != 0x80)) {
+			tempal = tempah;
+			tempbl &= ~0x80;
 		}
 
-		if (pVBInfo->IF_DEF_CH7017 == 1) {
-			tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+		if (tempal == tempbl)
+			break;
 
-			if (tempbx & TVOverScan)
-				tempbx |= SetCHTVOverScan;
-		}
+		i++;
+		tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+	}
 
-		if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/04 */
-			tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+	if (tempbl == 0xFF) {
+		pVBInfo->LCDResInfo = Panel1024x768;
+		pVBInfo->LCDTypeInfo = 0;
+		i = 0;
+	}
 
-			if (tempbx & TVOverScan)
-				tempbx |= SetCHTVOverScan;
-		}
+	return i;
+}
 
-		if (pVBInfo->IF_DEF_LVDS == 0) {
-			if (pVBInfo->VBInfo & SetCRT2ToSCART)
-				tempbx |= SetPALTV;
-		}
+static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short Index;
 
-		if (pVBInfo->IF_DEF_YPbPr == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-				index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
-				index1 &= YPbPrMode;
+	Index = XGI_GetLCDCapPtr(pVBInfo);
+	*HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
+	*VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
 
-				if (index1 == YPbPrMode525i)
-					tempbx |= SetYPbPrMode525i;
+	return;
+}
 
-				if (index1 == YPbPrMode525p)
-					tempbx = tempbx | SetYPbPrMode525p;
-				if (index1 == YPbPrMode750p)
-					tempbx = tempbx | SetYPbPrMode750p;
-			}
-		}
+static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
+	unsigned long temp, temp1, temp2, temp3, push3;
+	struct XGI330_LCDDataDesStruct *LCDPtr = NULL;
+	struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
 
-		if (pVBInfo->IF_DEF_HiVision == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
-				tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
-		}
+	if (ModeNo > 0x13)
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	else
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 
-		if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
-			if ((pVBInfo->VBInfo & SetInSlaveMode)
-					&& (!(pVBInfo->VBInfo & SetNotSimuMode)))
-				tempbx |= TVSimuMode;
+	if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
+		if ((pVBInfo->IF_DEF_CH7017 == 0) || (pVBInfo->VBInfo
+				& (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+			if (pVBInfo->IF_DEF_OEMUtil == 1) {
+				tempbx = 8;
+				LCDPtr
+						= (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
+								tempbx,
+								ModeNo,
+								ModeIdIndex,
+								RefreshRateTableIndex,
+								pVBInfo);
+			}
 
-			if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo
-					== 8)) /* NTSC 1024x768, */
-				tempbx |= NTSC1024x768;
+			if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == NULL)) {
+				tempbx = 3;
+				if (pVBInfo->LCDInfo & EnableScalingLCD)
+					LCDPtr1
+							= (struct XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(
+									tempbx,
+									ModeNo,
+									ModeIdIndex,
+									RefreshRateTableIndex,
+									pVBInfo);
+				else
+					LCDPtr
+							= (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
+									tempbx,
+									ModeNo,
+									ModeIdIndex,
+									RefreshRateTableIndex,
+									pVBInfo);
+			}
 
-			tempbx |= RPLLDIV2XO;
+			XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+			push1 = tempbx;
+			push2 = tempax;
 
-			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-				if (pVBInfo->VBInfo & SetInSlaveMode)
-					tempbx &= (~RPLLDIV2XO);
+			/* GetLCDResInfo */
+			if ((pVBInfo->LCDResInfo == Panel1024x768)
+					|| (pVBInfo->LCDResInfo
+							== Panel1024x768x75)) {
+				tempax = 1024;
+				tempbx = 768;
+			} else if ((pVBInfo->LCDResInfo == Panel1280x1024)
+					|| (pVBInfo->LCDResInfo
+							== Panel1280x1024x75)) {
+				tempax = 1280;
+				tempbx = 1024;
+			} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+				tempax = 1400;
+				tempbx = 1050;
 			} else {
-				if (tempbx & (SetYPbPrMode525p
-						| SetYPbPrMode750p))
-					tempbx &= (~RPLLDIV2XO);
-				else if (!(pVBInfo->VBType & (VB_XGI301B
-						| VB_XGI302B | VB_XGI301LV
-						| VB_XGI302LV | VB_XGI301C))) {
-					if (tempbx & TVSimuMode)
-						tempbx &= (~RPLLDIV2XO);
-				}
+				tempax = 1600;
+				tempbx = 1200;
+			}
+
+			if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
+				pVBInfo->HDE = tempax;
+				pVBInfo->VDE = tempbx;
+				pVBInfo->VGAHDE = tempax;
+				pVBInfo->VGAVDE = tempbx;
+			}
+
+			if ((pVBInfo->IF_DEF_ScaleLCD == 1)
+					&& (pVBInfo->LCDInfo & EnableScalingLCD)) {
+				tempax = pVBInfo->HDE;
+				tempbx = pVBInfo->VDE;
 			}
-		}
-	}
-	pVBInfo->TVInfo = tempbx;
-}
 
-unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
+			tempax = pVBInfo->HT;
 
-	pVBInfo->LCDResInfo = 0;
-	pVBInfo->LCDTypeInfo = 0;
-	pVBInfo->LCDInfo = 0;
+			if (pVBInfo->LCDInfo & EnableScalingLCD)
+				tempbx = LCDPtr1->LCDHDES;
+			else
+				tempbx = LCDPtr->LCDHDES;
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */
-	}
+			tempcx = pVBInfo->HDE;
+			tempbx = tempbx & 0x0fff;
+			tempcx += tempbx;
 
-	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
-	tempbx = temp & 0x0F;
+			if (tempcx >= tempax)
+				tempcx -= tempax;
 
-	if (tempbx == 0)
-		tempbx = Panel1024x768; /* default */
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
 
-	/* LCD75 [2003/8/22] Vicent */
-	if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
-		if (pVBInfo->VBInfo & DriverMode) {
-			tempax = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA)
-				tempax &= 0x0F;
+			tempcx = tempcx >> 3;
+			tempbx = tempbx >> 3;
+
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x16,
+					(unsigned short) (tempbx & 0xff));
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x17,
+					(unsigned short) (tempcx & 0xff));
+
+			tempax = pVBInfo->HT;
+
+			if (pVBInfo->LCDInfo & EnableScalingLCD)
+				tempbx = LCDPtr1->LCDHRS;
 			else
-				tempax = tempax >> 4;
+				tempbx = LCDPtr->LCDHRS;
 
-			if ((resinfo == 6) || (resinfo == 9)) {
-				if (tempax >= 3)
-					tempbx |= PanelRef75Hz;
-			} else if ((resinfo == 7) || (resinfo == 8)) {
-				if (tempax >= 4)
-					tempbx |= PanelRef75Hz;
-			}
-		}
-	}
+			tempcx = push2;
 
-	pVBInfo->LCDResInfo = tempbx;
+			if (pVBInfo->LCDInfo & EnableScalingLCD)
+				tempcx = LCDPtr1->LCDHSync;
 
-	/* End of LCD75 */
+			tempcx += tempbx;
 
-	if (pVBInfo->IF_DEF_OEMUtil == 1)
-		pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
+			if (tempcx >= tempax)
+				tempcx -= tempax;
 
-	if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
-		return 0;
+			tempax = tempbx & 0x07;
+			tempax = tempax >> 5;
+			tempcx = tempcx >> 3;
+			tempbx = tempbx >> 3;
 
-	tempbx = 0;
+			tempcx &= 0x1f;
+			tempax |= tempcx;
 
-	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x15, tempax);
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x14,
+					(unsigned short) (tempbx & 0xff));
 
-	temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
+			tempax = pVBInfo->VT;
+			if (pVBInfo->LCDInfo & EnableScalingLCD)
+				tempbx = LCDPtr1->LCDVDES;
+			else
+				tempbx = LCDPtr->LCDVDES;
+			tempcx = pVBInfo->VDE;
 
-	if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
-		temp &= ~EnableScalingLCD;
+			tempbx = tempbx & 0x0fff;
+			tempcx += tempbx;
+			if (tempcx >= tempax)
+				tempcx -= tempax;
 
-	tempbx |= temp;
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x1b,
+					(unsigned short) (tempbx & 0xff));
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x1c,
+					(unsigned short) (tempcx & 0xff));
 
-	LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
+			tempbx = (tempbx >> 8) & 0x07;
+			tempcx = (tempcx >> 8) & 0x07;
 
-	tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x1d,
+					(unsigned short) ((tempcx << 3)
+							| tempbx));
 
-	if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
-		if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
-				& VB_XGI301C)) && (tempax & LCDDualLink)) {
-			tempbx |= SetLCDDualLink;
-		}
-	}
+			tempax = pVBInfo->VT;
+			if (pVBInfo->LCDInfo & EnableScalingLCD)
+				tempbx = LCDPtr1->LCDVRS;
+			else
+				tempbx = LCDPtr->LCDVRS;
 
-	if (pVBInfo->IF_DEF_CH7017 == 1) {
-		if (tempax & LCDDualLink)
-			tempbx |= SetLCDDualLink;
-	}
+			/* tempbx = tempbx >> 4; */
+			tempcx = push1;
 
-	if (pVBInfo->IF_DEF_LVDS == 0) {
-		if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo
-				& SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo
-				== 9) && (!(tempbx & EnableScalingLCD)))
-			tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
-	}
+			if (pVBInfo->LCDInfo & EnableScalingLCD)
+				tempcx = LCDPtr1->LCDVSync;
 
-	/*
-	if (tempax & LCDBToA) {
-		tempbx |= SetLCDBToA;
-	}
-	*/
+			tempcx += tempbx;
+			if (tempcx >= tempax)
+				tempcx -= tempax;
 
-	if (pVBInfo->IF_DEF_ExpLink == 1) {
-		if (modeflag & HalfDCLK) {
-			/* if (!(pVBInfo->LCDInfo&LCDNonExpanding)) */
-			if (!(tempbx & SetLCDtoNonExpanding)) {
-				tempbx |= EnableLVDSDDA;
-			} else {
-				if (ModeNo > 0x13) {
-					if (pVBInfo->LCDResInfo
-							== Panel1024x768) {
-						if (resinfo == 4) { /* 512x384  */
-							tempbx |= EnableLVDSDDA;
-						}
-					}
-				}
-			}
-		}
-	}
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x18,
+					(unsigned short) (tempbx & 0xff));
+			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f,
+					(unsigned short) (tempcx & 0x0f));
 
-	if (pVBInfo->VBInfo & SetInSlaveMode) {
-		if (pVBInfo->VBInfo & SetNotSimuMode)
-			tempbx |= LCDVESATiming;
-	} else {
-		tempbx |= LCDVESATiming;
-	}
+			tempax = ((tempbx >> 8) & 0x07) << 3;
 
-	pVBInfo->LCDInfo = tempbx;
+			tempbx = pVBInfo->VGAVDE;
+			if (tempbx != pVBInfo->VDE)
+				tempax |= 0x40;
 
-	if (pVBInfo->IF_DEF_PWD == 1) {
-		if (pVBInfo->LCDInfo & SetPWDEnable) {
-			if ((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
-					& VB_XGI301C)) {
-				if (!(tempax & PWDEnable))
-					pVBInfo->LCDInfo &= ~SetPWDEnable;
-			}
-		}
-	}
+			if (pVBInfo->LCDInfo & EnableLVDSDDA)
+				tempax |= 0x40;
 
-	if (pVBInfo->IF_DEF_LVDS == 0) {
-		if (tempax & (LockLCDBToA | StLCDBToA)) {
-			if (pVBInfo->VBInfo & SetInSlaveMode) {
-				if (!(tempax & LockLCDBToA)) {
-					if (ModeNo <= 0x13) {
-						pVBInfo->VBInfo
-								&= ~(SetSimuScanMode
-										| SetInSlaveMode
-										| SetCRT2ToLCD);
-						pVBInfo->VBInfo
-								|= SetCRT2ToLCDA
-										| SetCRT2ToDualEdge;
-					}
-				}
-			}
-		}
-	}
+			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1a, 0x07,
+					tempax);
 
-	/*
-	if (pVBInfo->IF_DEF_LVDS == 0) {
-		if (tempax & (LockLCDBToA | StLCDBToA)) {
-			if (pVBInfo->VBInfo & SetInSlaveMode) {
-				if (!((!(tempax & LockLCDBToA)) && (ModeNo > 0x13))) {
-					pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD);
-					pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge;
-				}
-			}
-		}
-	}
-	*/
+			tempcx = pVBInfo->VGAVT;
+			tempbx = pVBInfo->VDE;
+			tempax = pVBInfo->VGAVDE;
+			tempcx -= tempax;
 
-	return 1;
-}
+			temp = tempax; /* 0430 ylshieh */
+			temp1 = (temp << 18) / tempbx;
 
-unsigned char XGI_SearchModeID(unsigned short ModeNo,
-		unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	if (ModeNo <= 5)
-		ModeNo |= 1;
-	if (ModeNo <= 0x13) {
-		/* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->SModeIDTable) / sizeof(struct XGI_StStruct); (*ModeIdIndex)++) */
-		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
-				break;
-			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
-				return 0;
-		}
+			tempdx = (unsigned short) ((temp << 18) % tempbx);
 
-		if (ModeNo == 0x07)
-			(*ModeIdIndex)++; /* 400 lines */
-		if (ModeNo <= 3)
-			(*ModeIdIndex) += 2; /* 400 lines */
-		/* else 350 lines */
-	} else {
-		/* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->EModeIDTable) / sizeof(struct XGI_ExtStruct); (*ModeIdIndex)++) */
-		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
-				break;
-			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
-				return 0;
-		}
-	}
+			if (tempdx != 0)
+				temp1 += 1;
+
+			temp2 = temp1;
+			push3 = temp2;
+
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x37,
+					(unsigned short) (temp2 & 0xff));
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x36,
+					(unsigned short) ((temp2 >> 8) & 0xff));
 
-	return 1;
-}
+			tempbx = (unsigned short) (temp2 >> 16);
+			tempax = tempbx & 0x03;
 
-/* win2000 MM adapter not support standard mode! */
+			tempbx = pVBInfo->VGAVDE;
+			if (tempbx == pVBInfo->VDE)
+				tempax |= 0x04;
 
-#if 0
-static unsigned char XGINew_CheckMemorySize(
-		struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short ModeNo,
-		unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short memorysize, modeflag, temp, temp1, tmp;
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x35, tempax);
 
-	/*
-	if ((HwDeviceExtension->jChipType == XGI_650) ||
-	(HwDeviceExtension->jChipType == XGI_650M)) {
-		return 1;
-	}
-	*/
+			if (pVBInfo->VBType & VB_XGI301C) {
+				temp2 = push3;
+				XGINew_SetReg1(pVBInfo->Part4Port, 0x3c,
+						(unsigned short) (temp2 & 0xff));
+				XGINew_SetReg1(pVBInfo->Part4Port, 0x3b,
+						(unsigned short) ((temp2 >> 8)
+								& 0xff));
+				tempbx = (unsigned short) (temp2 >> 16);
+				XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a,
+						~0xc0,
+						(unsigned short) ((tempbx
+								& 0xff) << 6));
 
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+				tempcx = pVBInfo->VGAVDE;
+				if (tempcx == pVBInfo->VDE)
+					XGINew_SetRegANDOR(pVBInfo->Part4Port,
+							0x30, ~0x0c, 0x00);
+				else
+					XGINew_SetRegANDOR(pVBInfo->Part4Port,
+							0x30, ~0x0c, 0x08);
+			}
 
-	/* ModeType = modeflag&ModeInfoFlag; // Get mode type */
+			tempcx = pVBInfo->VGAHDE;
+			tempbx = pVBInfo->HDE;
 
-	memorysize = modeflag & MemoryInfoFlag;
-	memorysize = memorysize > MemorySizeShift;
-	memorysize++; /* Get memory size */
+			temp1 = tempcx << 16;
 
-	temp = XGINew_GetReg1(pVBInfo->P3c4, 0x14); /* Get DRAM Size */
-	tmp = temp;
+			tempax = (unsigned short) (temp1 / tempbx);
 
-	if (HwDeviceExtension->jChipType == XG40) {
-		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
-		if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
-			temp <<= 2;
-		} else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
-			temp <<= 1;
-		}
-	} else if (HwDeviceExtension->jChipType == XG42) {
-		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
-		if ((tmp & 0x04) == 0x04) { /* Dual channels */
-			temp <<= 1;
-		}
-	} else if (HwDeviceExtension->jChipType == XG45) {
-		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
-		if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
-			temp <<= 2;
-		} else if ((tmp & 0x0c) == 0x08) { /* triple channels */
-			temp1 = temp;
-			temp <<= 1;
-			temp += temp1;
-		} else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
-			temp <<= 1;
-		}
-	}
-	if (temp < memorysize)
-		return 0;
-	else
-		return 1;
-}
-#endif
+			if ((tempbx & 0xffff) == (tempcx & 0xffff))
+				tempax = 65535;
 
-/*
-void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	unsigned short data ;
-	unsigned short ModeFlag ;
+			temp3 = tempax;
+			temp1 = pVBInfo->VGAHDE << 16;
 
-	data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
-	data &= 0x7F;
-	XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
+			temp1 /= temp3;
+			temp3 = temp3 << 16;
+			temp1 -= 1;
 
-	if (ModeNo > 0x13) {
-		ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
-			data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
-			data |= 0x80;
-			XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
-			data = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
-			data &= 0xF7;
-			XGINew_SetReg1(pVBInfo->P3c4, 0x01, data);
-		}
-	}
-}
-*/
+			temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
 
-void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE,
-		struct vb_device_info *pVBInfo)
-{
+			tempax = (unsigned short) (temp3 & 0xff);
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x1f, tempax);
 
-	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
-	if (pXGIHWDE->jChipType == XG21) {
-		if (pVBInfo->IF_DEF_LVDS == 1) {
-			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
-				XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
-				XGI_XG21SetPanelDelay(2, pVBInfo);
-			}
-			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
-				XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
-			XGI_XG21SetPanelDelay(3, pVBInfo);
-			XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
-		} else {
-			XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
-		}
+			temp1 = pVBInfo->VGAVDE << 18;
+			temp1 = temp1 / push3;
+			tempbx = (unsigned short) (temp1 & 0xffff);
 
-	}
+			if (pVBInfo->LCDResInfo == Panel1024x768)
+				tempbx -= 1;
 
-	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
+			tempax = ((tempbx >> 8) & 0xff) << 3;
+			tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x20,
+					(unsigned short) (tempax & 0xff));
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x21,
+					(unsigned short) (tempbx & 0xff));
 
-	}
+			temp3 = temp3 >> 16;
 
-	if (pXGIHWDE->jChipType == XG27) {
-		if (pVBInfo->IF_DEF_LVDS == 1) {
-			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
-				XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
-				XGI_XG21SetPanelDelay(2, pVBInfo);
-			}
-			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
-				XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
-			XGI_XG21SetPanelDelay(3, pVBInfo);
-			XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
-		} else {
-			XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
-		}
+			if (modeflag & HalfDCLK)
+				temp3 = temp3 >> 1;
 
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x22,
+					(unsigned short) ((temp3 >> 8) & 0xff));
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x23,
+					(unsigned short) (temp3 & 0xff));
+		}
 	}
 }
 
-void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE,
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GETLCDVCLKPtr */
+/* Input : */
+/* Output : al -> VCLK Index */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
 		struct vb_device_info *pVBInfo)
 {
+	unsigned short index;
 
-	if (pXGIHWDE->jChipType == XG21) {
-		if (pVBInfo->IF_DEF_LVDS == 1) {
-			XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
-			XGI_XG21SetPanelDelay(3, pVBInfo);
-		} else {
-			XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+		if (pVBInfo->IF_DEF_ScaleLCD == 1) {
+			if (pVBInfo->LCDInfo & EnableScalingLCD)
+				return;
 		}
-	}
 
-	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
-		/* if (IsCH7007TVMode(pVBInfo) == 0) */
-		{
-		}
-	}
+		/* index = XGI_GetLCDCapPtr(pVBInfo); */
+		index = XGI_GetLCDCapPtr1(pVBInfo);
 
-	if (pXGIHWDE->jChipType == XG27) {
-		if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
-			XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
-			XGI_XG21SetPanelDelay(3, pVBInfo);
+		if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
+			*di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
+			*di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
+		} else { /* LCDA */
+			*di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
+			*di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
 		}
-
-		if (pVBInfo->IF_DEF_LVDS == 0)
-			XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
 	}
-
-	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
-}
-
-static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
-{
-	while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01))
-		break;
-
-	while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01))
-		break;
+	return;
 }
 
-void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
+static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
+		unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
 {
-	unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
-			0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
-			0x05, 0x00 };
-
-	unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
-
-	unsigned char CR17, CR63, SR31;
-	unsigned short temp;
-	unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
-
-	int i;
-	XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
-
-	/* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
-	XGINew_SetReg1(pVBInfo->P3d4, 0x57, 0x4A);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
-			pVBInfo->P3d4, 0x53) | 0x02));
 
-	SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31);
-	CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63);
-	SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01);
+	unsigned short index, modeflag;
+	unsigned short tempbx;
+	unsigned char tempal;
+	unsigned char *CHTVVCLKPtr = NULL;
 
-	XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
-	XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
 
-	CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
+	if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo
+			& EnableScalingLCD))) { /* {LCDA/LCDB} */
+		index = XGI_GetLCDCapPtr(pVBInfo);
+		tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
 
-	SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+			return tempal;
 
-	SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
-	SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
+		/* {TV} */
+		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+				| VB_XGI302LV | VB_XGI301C)) {
+			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+				tempal = HiTVVCLKDIV2;
+				if (!(pVBInfo->TVInfo & RPLLDIV2XO))
+					tempal = HiTVVCLK;
+				if (pVBInfo->TVInfo & TVSimuMode) {
+					tempal = HiTVSimuVCLK;
+					if (!(modeflag & Charx8Dot))
+						tempal = HiTVTextVCLK;
 
-	XGINew_SetReg1(pVBInfo->P3d4, 0x11, 0x00);
+				}
+				return tempal;
+			}
 
-	for (i = 0; i < 8; i++)
-		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
+			if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+				tempal = YPbPr750pVCLK;
+				return tempal;
+			}
 
-	for (i = 8; i < 11; i++)
-		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 8),
-				CRTCData[i]);
+			if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+				tempal = YPbPr525pVCLK;
+				return tempal;
+			}
 
-	for (i = 11; i < 13; i++)
-		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 4),
-				CRTCData[i]);
+			tempal = NTSC1024VCLK;
 
-	for (i = 13; i < 16; i++)
-		XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i - 3),
-				CRTCData[i]);
+			if (!(pVBInfo->TVInfo & NTSC1024x768)) {
+				tempal = TVVCLKDIV2;
+				if (!(pVBInfo->TVInfo & RPLLDIV2XO))
+					tempal = TVVCLK;
+			}
 
-	XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
-			& 0xE0));
+			if (pVBInfo->VBInfo & SetCRT2ToTV)
+				return tempal;
+		}
+		/* else if ((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017)) {
+			if (ModeNo<=0x13)
+				*tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+			else
+				*tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+			*tempal = *tempal & 0x1F;
+			tempbx = 0;
+			if (pVBInfo->TVInfo & SetPALTV)
+				tempbx = tempbx + 2;
+			if (pVBInfo->TVInfo & SetCHTVOverScan)
+				tempbx++;
+			tempbx = tempbx << 1;
+		} */
+	} /* {End of VB} */
 
-	XGINew_SetReg1(pVBInfo->P3c4, 0x31, 0x00);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1);
+	if ((pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */
+		/* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
+		if ((pVBInfo->VBInfo & SetCRT2ToTV)) {
+			if (ModeNo <= 0x13) {
+				tempal
+						= pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+			} else {
+				tempal
+						= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+			}
 
-	XGINew_SetReg3(pVBInfo->P3c8, 0x00);
+			tempal = tempal & 0x0F;
+			tempbx = 0;
 
-	for (i = 0; i < 256; i++) {
-		XGINew_SetReg3((pVBInfo->P3c8 + 1),
-				(unsigned char) DAC_TEST_PARMS[0]);
-		XGINew_SetReg3((pVBInfo->P3c8 + 1),
-				(unsigned char) DAC_TEST_PARMS[1]);
-		XGINew_SetReg3((pVBInfo->P3c8 + 1),
-				(unsigned char) DAC_TEST_PARMS[2]);
-	}
+			if (pVBInfo->TVInfo & SetPALTV)
+				tempbx = tempbx + 2;
 
-	XGI_VBLongWait(pVBInfo);
-	XGI_VBLongWait(pVBInfo);
-	XGI_VBLongWait(pVBInfo);
+			if (pVBInfo->TVInfo & SetCHTVOverScan)
+				tempbx++;
 
-	mdelay(1);
+			/** tempbx = tempbx << 1; CH7007 ? **/
 
-	XGI_WaitDisply(pVBInfo);
-	temp = XGINew_GetReg2(pVBInfo->P3c2);
+			/* [Billy]07/05/29 CH7007 */
+			if (pVBInfo->IF_DEF_CH7007 == 1) {
+				switch (tempbx) {
+				case 0:
+					CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC;
+					break;
+				case 1:
+					CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC;
+					break;
+				case 2:
+					CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL;
+					break;
+				case 3:
+					CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL;
+					break;
+				default:
+					break;
 
-	if (temp & 0x10)
-		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
-	else
-		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
+				}
+			}
+			/* else {
+				switch(tempbx) {
+				case 0:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
+					break;
+				case 1:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
+					break;
+				case 2:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
+					break;
+				case 3:
+					CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
+					break;
+				default:
+					break;
+				}
+			}
+			*/
 
-	/* alan, avoid display something, set BLACK DAC if not restore DAC */
-	XGINew_SetReg3(pVBInfo->P3c8, 0x00);
+			tempal = CHTVVCLKPtr[tempal];
+			return tempal;
+		}
 
-	for (i = 0; i < 256; i++) {
-		XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
-		XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
-		XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
 	}
 
-	XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01);
-	XGINew_SetReg1(pVBInfo->P3d4, 0x63, CR63);
-	XGINew_SetReg1(pVBInfo->P3c4, 0x31, SR31);
+	tempal = (unsigned char) XGINew_GetReg2((pVBInfo->P3ca + 0x02));
+	tempal = tempal >> 2;
+	tempal &= 0x03;
 
-	/* [2004/05/11] Vicent */
-	XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
-			pVBInfo->P3d4, 0x53) & 0xFD));
-	XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
+	if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) /* for Dot8 Scaling LCD */
+		tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
+
+	if (ModeNo <= 0x13)
+		return tempal;
+
+	tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+	return tempal;
 }
 
-#if 0
-static void XGI_WaitDisplay(struct vb_device_info *pVBInfo)
+static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
+		unsigned char *di_1, struct vb_device_info *pVBInfo)
 {
-	while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01));
-	while (XGINew_GetReg2(pVBInfo->P3da) & 0x01);
+	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */
+		/* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
+		*di_0 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2B;
+		*di_1 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2C;
+	} else if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B
+			| VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+		if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag
+				& ProgrammingCRT2)) {
+			*di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B;
+			*di_1 = XGI_VBVCLKData[tempal].SR2C;
+		}
+	} else {
+		*di_0 = XGI_VCLKData[tempal].SR2B;
+		*di_1 = XGI_VCLKData[tempal].SR2C;
+	}
 }
-#endif
 
-unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
-		struct xgi_hw_device_info *HwDeviceExtension,
+static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex;
+	unsigned char di_0, di_1, tempal;
+	int i;
 
-	tempbx = pVBInfo->VBInfo;
-	pVBInfo->SetFlag |= ProgrammingCRT2;
-	XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
-	pVBInfo->SelectCRT2Rate = 4;
-	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
-			ModeIdIndex, pVBInfo);
-	XGI_SaveCRT2Info(ModeNo, pVBInfo);
-	XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
-	XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-	XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
-			RefreshRateTableIndex, pVBInfo);
-	XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
-			RefreshRateTableIndex, pVBInfo);
-	XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
-			RefreshRateTableIndex, pVBInfo);
-	XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-			HwDeviceExtension, pVBInfo);
-	XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
-			RefreshRateTableIndex, pVBInfo);
-	XGI_SetTap4Regs(pVBInfo);
-	XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
-	XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-			HwDeviceExtension, pVBInfo);
-	XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-	XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
-	XGI_AutoThreshold(pVBInfo);
-	return 1;
+	tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
+			pVBInfo);
+	XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
+	XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
+
+	for (i = 0; i < 4; i++) {
+		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30,
+				(unsigned short) (0x10 * i));
+		if (pVBInfo->IF_DEF_CH7007 == 1) {
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
+		} else if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+				&& (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2e, di_0);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2f, di_1);
+		} else {
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
+		}
+	}
 }
 
-static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
+static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
 {
-	if (!(pVBInfo->SetFlag & Win9xDOSMode))
-		XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40);
-}
+	unsigned short tempcl, tempch, temp, tempbl, tempax;
 
-static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo)
-{
-	unsigned short temp1, temp2;
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		tempcl = 0;
+		tempch = 0;
+		temp = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
 
-	XGINew_SetReg1(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
-	temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
-	temp2 = ~(SetInSlaveMode >> 8);
-	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1);
-}
+		if (!(temp & 0x20)) {
+			temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17);
+			if (temp & 0x80) {
+				if ((HwDeviceExtension->jChipType >= XG20)
+						|| (HwDeviceExtension->jChipType
+								>= XG40))
+					temp = XGINew_GetReg1(pVBInfo->P3d4,
+							0x53);
+				else
+					temp = XGINew_GetReg1(pVBInfo->P3d4,
+							0x63);
 
-static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short xres, yres, modeflag, resindex;
+				if (!(temp & 0x40))
+					tempcl |= ActiveCRT1;
+			}
+		}
 
-	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
-	if (ModeNo <= 0x13) {
-		xres = pVBInfo->StResInfo[resindex].HTotal;
-		yres = pVBInfo->StResInfo[resindex].VTotal;
-		/* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */
-	} else {
-		xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
-		yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+		temp = XGINew_GetReg1(pVBInfo->Part1Port, 0x2e);
+		temp &= 0x0f;
 
-		/*
-		if (pVBInfo->IF_DEF_FSTN) {
-			xres *= 2;
-			yres *= 2;
-		 } else {
-		*/
-		if (modeflag & HalfDCLK)
-			xres *= 2;
+		if (!(temp == 0x08)) {
+			tempax = XGINew_GetReg1(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
+			if (tempax & 0x04)
+				tempcl = tempcl | ActiveLCD;
 
-		if (modeflag & DoubleScanMode)
-			yres *= 2;
-		/* } */
-	}
+			temp &= 0x05;
 
-	if (pVBInfo->VBInfo & SetCRT2ToLCD) {
-		if (pVBInfo->IF_DEF_LVDS == 0) {
-			if (pVBInfo->LCDResInfo == Panel1600x1200) {
-				if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
-					if (yres == 1024)
-						yres = 1056;
+			if (!(tempcl & ActiveLCD))
+				if (temp == 0x01)
+					tempcl |= ActiveCRT2;
+
+			if (temp == 0x04)
+				tempcl |= ActiveLCD;
+
+			if (temp == 0x05) {
+				temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x00);
+
+				if (!(temp & 0x08))
+					tempch |= ActiveAVideo;
+
+				if (!(temp & 0x04))
+					tempch |= ActiveSVideo;
+
+				if (temp & 0x02)
+					tempch |= ActiveSCART;
+
+				if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+					if (temp & 0x01)
+						tempch |= ActiveHiTV;
 				}
-			}
 
-			if (pVBInfo->LCDResInfo == Panel1280x1024) {
-				if (yres == 400)
-					yres = 405;
-				else if (yres == 350)
-					yres = 360;
+				if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+					temp = XGINew_GetReg1(
+							pVBInfo->Part2Port,
+							0x4d);
 
-				if (pVBInfo->LCDInfo & LCDVESATiming) {
-					if (yres == 360)
-						yres = 375;
+					if (temp & 0x10)
+						tempch |= ActiveYPbPr;
 				}
+
+				if (tempch != 0)
+					tempcl |= ActiveTV;
 			}
+		}
 
-			if (pVBInfo->LCDResInfo == Panel1024x768) {
-				if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
-					if (!(pVBInfo->LCDInfo
-							& LCDNonExpanding)) {
-						if (yres == 350)
-							yres = 357;
-						else if (yres == 400)
-							yres = 420;
-						else if (yres == 480)
-							yres = 525;
-					}
-				}
+		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
+		if (tempcl & ActiveLCD) {
+			if ((pVBInfo->SetFlag & ReserveTVOption)) {
+				if (temp & ActiveTV)
+					tempcl |= ActiveTV;
 			}
 		}
+		temp = tempcl;
+		tempbl = ~ModeSwitchStatus;
+		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp);
 
-		if (xres == 720)
-			xres = 640;
+		if (!(pVBInfo->SetFlag & ReserveTVOption))
+			XGINew_SetReg1(pVBInfo->P3d4, 0x3e, tempch);
+	} else {
+		return;
 	}
+}
 
-	pVBInfo->VGAHDE = xres;
-	pVBInfo->HDE = xres;
-	pVBInfo->VGAVDE = yres;
-	pVBInfo->VDE = yres;
+void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
+{
+	/*
+	if ( HwDeviceExtension->jChipType >= XG20 ) {
+		pVBInfo->Set_VGAType = XG20;
+	} else if (HwDeviceExtension->jChipType >= XG40) {
+		pVBInfo->Set_VGAType = VGA_XGI340;
+	}
+	*/
+	pVBInfo->Set_VGAType = HwDeviceExtension->jChipType;
 }
 
-static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
+void XGI_GetVBType(struct vb_device_info *pVBInfo)
 {
+	unsigned short flag, tempbx, tempah;
 
-	if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
-			(pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
-		return 1;
+	if (pVBInfo->IF_DEF_CH7007 == 1) {
+		pVBInfo->VBType = VB_CH7007;
+		return;
+	}
+	if (pVBInfo->IF_DEF_LVDS == 0) {
+		tempbx = VB_XGI302B;
+		flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
+		if (flag != 0x02) {
+			tempbx = VB_XGI301;
+			flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01);
+			if (flag >= 0xB0) {
+				tempbx = VB_XGI301B;
+				if (flag >= 0xC0) {
+					tempbx = VB_XGI301C;
+					if (flag >= 0xD0) {
+						tempbx = VB_XGI301LV;
+						if (flag >= 0xE0) {
+							tempbx = VB_XGI302LV;
+							tempah
+									= XGINew_GetReg1(
+											pVBInfo->Part4Port,
+											0x39);
+							if (tempah != 0xFF)
+								tempbx
+										= VB_XGI301C;
+						}
+					}
+				}
+
+				if (tempbx & (VB_XGI301B | VB_XGI302B)) {
+					flag = XGINew_GetReg1(
+							pVBInfo->Part4Port,
+							0x23);
+
+					if (!(flag & 0x02))
+						tempbx = tempbx | VB_NoLCD;
+				}
+			}
+		}
+		pVBInfo->VBType = tempbx;
+	}
+	/*
+	else if (pVBInfo->IF_DEF_CH7017 == 1)
+		pVBInfo->VBType = VB_CH7017;
+	else //LVDS
+		pVBInfo->VBType = VB_LVDS_NS;
+	 */
 
-	return 0;
 }
 
-static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
+void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempax = 0, tempbx, modeflag, resinfo;
+	unsigned short tempax, push, tempbx, temp, modeflag;
 
-	struct XGI_LCDDataStruct *LCDPtr = NULL;
-	struct XGI_TVDataStruct *TVPtr = NULL;
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
+	pVBInfo->SetFlag = 0;
+	pVBInfo->ModeType = modeflag & ModeInfoFlag;
+	tempbx = 0;
+
+	if (pVBInfo->VBType & 0xFFFF) {
+		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x30); /* Check Display Device */
+		tempbx = tempbx | temp;
+		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
+		push = temp;
+		push = push << 8;
+		tempax = temp << 8;
+		tempbx = tempbx | tempax;
+		temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA
+				| SetInSlaveMode | DisableCRT2Display);
+		temp = 0xFFFF ^ temp;
+		tempbx &= temp;
+
+		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+
+		if (pVBInfo->IF_DEF_LCDA == 1) {
+
+			if ((pVBInfo->Set_VGAType >= XG20)
+					|| (pVBInfo->Set_VGAType >= XG40)) {
+				if (pVBInfo->IF_DEF_LVDS == 0) {
+					/* if ((pVBInfo->VBType & VB_XGI302B) || (pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C)) */
+					if (pVBInfo->VBType & (VB_XGI302B
+							| VB_XGI301LV
+							| VB_XGI302LV
+							| VB_XGI301C)) {
+						if (temp & EnableDualEdge) {
+							tempbx
+									|= SetCRT2ToDualEdge;
 
-	pVBInfo->NewFlickerMode = 0;
-	pVBInfo->RVBHRS = 50;
+							if (temp & SetToLCDA)
+								tempbx
+										|= SetCRT2ToLCDA;
+						}
+					}
+				} else if (pVBInfo->IF_DEF_CH7017 == 1) {
+					if (pVBInfo->VBType & VB_CH7017) {
+						if (temp & EnableDualEdge) {
+							tempbx
+									|= SetCRT2ToDualEdge;
 
-	if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
-		XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-				pVBInfo);
-		return;
-	}
+							if (temp & SetToLCDA)
+								tempbx
+										|= SetCRT2ToLCDA;
+						}
+					}
+				}
+			}
+		}
 
-	tempbx = 4;
+		if (pVBInfo->IF_DEF_YPbPr == 1) {
+			if (((pVBInfo->IF_DEF_LVDS == 0) && ((pVBInfo->VBType
+					& VB_XGI301LV) || (pVBInfo->VBType
+					& VB_XGI302LV) || (pVBInfo->VBType
+					& VB_XGI301C)))
+					|| ((pVBInfo->IF_DEF_CH7017 == 1)
+							&& (pVBInfo->VBType
+									& VB_CH7017))
+					|| ((pVBInfo->IF_DEF_CH7007 == 1)
+							&& (pVBInfo->VBType
+									& VB_CH7007))) { /* [Billy] 07/05/04 */
+				if (temp & SetYPbPr) { /* temp = CR38 */
+					if (pVBInfo->IF_DEF_HiVision == 1) {
+						temp = XGINew_GetReg1(
+								pVBInfo->P3d4,
+								0x35); /* shampoo add for new scratch */
+						temp &= YPbPrMode;
+						tempbx |= SetCRT2ToHiVisionTV;
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-		LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx,
-				ModeNo, ModeIdIndex, RefreshRateTableIndex,
-				pVBInfo);
+						if (temp != YPbPrMode1080i) {
+							tempbx
+									&= (~SetCRT2ToHiVisionTV);
+							tempbx
+									|= SetCRT2ToYPbPr;
+						}
+					}
 
-		pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
-		pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
-		pVBInfo->VGAHT = LCDPtr->VGAHT;
-		pVBInfo->VGAVT = LCDPtr->VGAVT;
-		pVBInfo->HT = LCDPtr->LCDHT;
-		pVBInfo->VT = LCDPtr->LCDVT;
+					/* tempbx |= SetCRT2ToYPbPr; */
+				}
+			}
+		}
 
-		if (pVBInfo->LCDResInfo == Panel1024x768) {
-			tempax = 1024;
-			tempbx = 768;
+		tempax = push; /* restore CR31 */
 
-			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
-				if (pVBInfo->VGAVDE == 357)
-					tempbx = 527;
-				else if (pVBInfo->VGAVDE == 420)
-					tempbx = 620;
-				else if (pVBInfo->VGAVDE == 525)
-					tempbx = 775;
-				else if (pVBInfo->VGAVDE == 600)
-					tempbx = 775;
-				/* else if (pVBInfo->VGAVDE==350) tempbx=560; */
-				/* else if (pVBInfo->VGAVDE==400) tempbx=640; */
+		if (pVBInfo->IF_DEF_LVDS == 0) {
+			if (pVBInfo->IF_DEF_YPbPr == 1) {
+				if (pVBInfo->IF_DEF_HiVision == 1)
+					temp = 0x09FC;
 				else
-					tempbx = 768;
+					temp = 0x097C;
+			} else {
+				if (pVBInfo->IF_DEF_HiVision == 1)
+					temp = 0x01FC;
+				else
+					temp = 0x017C;
+			}
+		} else { /* 3nd party chip */
+			if (pVBInfo->IF_DEF_CH7017 == 1)
+				temp = (SetCRT2ToTV | SetCRT2ToLCD
+						| SetCRT2ToLCDA);
+			else if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/03 */
+				temp = SetCRT2ToTV;
 			} else
-				tempbx = 768;
-		} else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
-			tempax = 1024;
-			tempbx = 768;
-		} else if (pVBInfo->LCDResInfo == Panel1280x1024) {
-			tempax = 1280;
-			if (pVBInfo->VGAVDE == 360)
-				tempbx = 768;
-			else if (pVBInfo->VGAVDE == 375)
-				tempbx = 800;
-			else if (pVBInfo->VGAVDE == 405)
-				tempbx = 864;
-			else
-				tempbx = 1024;
-		} else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
-			tempax = 1280;
-			tempbx = 1024;
-		} else if (pVBInfo->LCDResInfo == Panel1280x960) {
-			tempax = 1280;
-			if (pVBInfo->VGAVDE == 350)
-				tempbx = 700;
-			else if (pVBInfo->VGAVDE == 400)
-				tempbx = 800;
-			else if (pVBInfo->VGAVDE == 1024)
-				tempbx = 960;
-			else
-				tempbx = 960;
-		} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
-			tempax = 1400;
-			tempbx = 1050;
+				temp = SetCRT2ToLCD;
+		}
 
-			if (pVBInfo->VGAVDE == 1024) {
-				tempax = 1280;
-				tempbx = 1024;
-			}
-		} else if (pVBInfo->LCDResInfo == Panel1600x1200) {
-			tempax = 1600;
-			tempbx = 1200; /* alan 10/14/2003 */
-			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
-				if (pVBInfo->VGAVDE == 350)
-					tempbx = 875;
-				else if (pVBInfo->VGAVDE == 400)
-					tempbx = 1000;
-			}
+		if (!(tempbx & temp)) {
+			tempax |= DisableCRT2Display;
+			tempbx = 0;
 		}
 
-		if (pVBInfo->LCDInfo & LCDNonExpanding) {
-			tempax = pVBInfo->VGAHDE;
-			tempbx = pVBInfo->VGAVDE;
+		if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
+			if (!(pVBInfo->VBType & VB_NoLCD)) {
+				if (tempbx & SetCRT2ToLCDA) {
+					if (tempbx & SetSimuScanMode)
+						tempbx
+								&= (~(SetCRT2ToLCD
+										| SetCRT2ToRAMDAC
+										| SwitchToCRT2));
+					else
+						tempbx
+								&= (~(SetCRT2ToLCD
+										| SetCRT2ToRAMDAC
+										| SetCRT2ToTV
+										| SwitchToCRT2));
+				}
+			}
 		}
 
-		pVBInfo->HDE = tempax;
-		pVBInfo->VDE = tempbx;
-		return;
-	}
+		/* shampoo add */
+		if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
+			if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
+				if (tempbx & SetCRT2ToRAMDAC) {
+					tempbx &= (0xFF00 | SetCRT2ToRAMDAC
+							| SwitchToCRT2
+							| SetSimuScanMode);
+					tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+				}
+			} else {
+				tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD
+						| SetCRT2ToTV));
+			}
+		}
 
-	if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
-		tempbx = 4;
-		TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx,
-				ModeNo, ModeIdIndex, RefreshRateTableIndex,
-				pVBInfo);
+		if (!(pVBInfo->VBType & VB_NoLCD)) {
+			if (tempbx & SetCRT2ToLCD) {
+				tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchToCRT2
+						| SetSimuScanMode);
+				tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+			}
+		}
 
-		pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
-		pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
-		pVBInfo->VGAHT = TVPtr->VGAHT;
-		pVBInfo->VGAVT = TVPtr->VGAVT;
-		pVBInfo->HDE = TVPtr->TVHDE;
-		pVBInfo->VDE = TVPtr->TVVDE;
-		pVBInfo->RVBHRS = TVPtr->RVBHRS;
-		pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
+		if (tempbx & SetCRT2ToSCART) {
+			tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchToCRT2
+					| SetSimuScanMode);
+			tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+		}
 
-		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-			if (resinfo == 0x08)
-				pVBInfo->NewFlickerMode = 0x40;
-			else if (resinfo == 0x09)
-				pVBInfo->NewFlickerMode = 0x40;
-			else if (resinfo == 0x12)
-				pVBInfo->NewFlickerMode = 0x40;
+		if (pVBInfo->IF_DEF_YPbPr == 1) {
+			if (tempbx & SetCRT2ToYPbPr)
+				tempbx &= (0xFF00 | SwitchToCRT2
+						| SetSimuScanMode);
+		}
 
-			if (pVBInfo->VGAVDE == 350)
-				pVBInfo->TVInfo |= TVSimuMode;
+		if (pVBInfo->IF_DEF_HiVision == 1) {
+			if (tempbx & SetCRT2ToHiVisionTV)
+				tempbx &= (0xFF00 | SetCRT2ToHiVisionTV
+						| SwitchToCRT2
+						| SetSimuScanMode);
+		}
 
-			tempax = ExtHiTVHT;
-			tempbx = ExtHiTVVT;
+		if (tempax & DisableCRT2Display) { /* Set Display Device Info */
+			if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
+				tempbx = DisableCRT2Display;
+		}
 
-			if (pVBInfo->VBInfo & SetInSlaveMode) {
-				if (pVBInfo->TVInfo & TVSimuMode) {
-					tempax = StHiTVHT;
-					tempbx = StHiTVVT;
+		if (!(tempbx & DisableCRT2Display)) {
+			if ((!(tempbx & DriverMode))
+					|| (!(modeflag & CRT2Mode))) {
+				if (pVBInfo->IF_DEF_LCDA == 1) {
+					if (!(tempbx & SetCRT2ToLCDA))
+						tempbx
+								|= (SetInSlaveMode
+										| SetSimuScanMode);
+				}
 
-					if (!(modeflag & Charx8Dot)) {
-						tempax = StHiTextTVHT;
-						tempbx = StHiTextTVVT;
+				if (pVBInfo->IF_DEF_VideoCapture == 1) {
+					if (((HwDeviceExtension->jChipType
+							== XG40)
+							&& (pVBInfo->Set_VGAType
+									== XG40))
+							|| ((HwDeviceExtension->jChipType
+									== XG41)
+									&& (pVBInfo->Set_VGAType
+											== XG41))
+							|| ((HwDeviceExtension->jChipType
+									== XG42)
+									&& (pVBInfo->Set_VGAType
+											== XG42))
+							|| ((HwDeviceExtension->jChipType
+									== XG45)
+									&& (pVBInfo->Set_VGAType
+											== XG45))) {
+						if (ModeNo <= 13) {
+							if (!(tempbx
+									& SetCRT2ToRAMDAC)) { /*CRT2 not need to support*/
+								tempbx
+										&= (0x00FF
+												| (~SetInSlaveMode));
+								pVBInfo->SetFlag
+										|= EnableVCMode;
+							}
+						}
 					}
 				}
 			}
-		} else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-			if (pVBInfo->TVInfo & SetYPbPrMode750p) {
-				tempax = YPbPrTV750pHT; /* Ext750pTVHT */
-				tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
-			}
 
-			if (pVBInfo->TVInfo & SetYPbPrMode525p) {
-				tempax = YPbPrTV525pHT; /* Ext525pTVHT */
-				tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
-			} else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
-				tempax = YPbPrTV525iHT; /* Ext525iTVHT */
-				tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
-				if (pVBInfo->TVInfo & NTSC1024x768)
-					tempax = NTSC1024x768HT;
-			}
-		} else {
-			tempax = PALHT;
-			tempbx = PALVT;
-			if (!(pVBInfo->TVInfo & SetPALTV)) {
-				tempax = NTSCHT;
-				tempbx = NTSCVT;
-				if (pVBInfo->TVInfo & NTSC1024x768)
-					tempax = NTSC1024x768HT;
+			/* LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
+			if ((tempbx & SetInSlaveMode) && (tempbx
+					& SetCRT2ToLCDA)) {
+				tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA
+						| SetCRT2ToDualEdge);
+				pVBInfo->SetFlag |= ReserveTVOption;
 			}
 		}
-
-		pVBInfo->HT = tempax;
-		pVBInfo->VT = tempbx;
-		return;
 	}
+
+	pVBInfo->VBInfo = tempbx;
 }
 
-static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
+void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned char di_0, di_1, tempal;
-
-	tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
-			pVBInfo);
-	XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
-	XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
+	unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1;
 
-	if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */
-		/* 301 */
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, 0x10);
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
-	} else { /* 301b/302b/301lv/302lv */
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
-	}
+	tempbx = 0;
+	resinfo = 0;
 
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x00, 0x12);
+	if (pVBInfo->VBInfo & SetCRT2ToTV) {
+		if (ModeNo <= 0x13) {
+			modeflag
+					= pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+			resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+		} else {
+			modeflag
+					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+			resinfo
+					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+		}
 
-	if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
-		XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28);
-	else
-		XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x08);
-}
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			temp = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+			tempbx = temp;
+			if (tempbx & SetPALTV) {
+				tempbx &= (SetCHTVOverScan | SetPALMTV
+						| SetPALNTV | SetPALTV);
+				if (tempbx & SetPALMTV)
+					tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
+			} else
+				tempbx &= (SetCHTVOverScan | SetNTSCJ
+						| SetPALTV);
+			/*
+			if (pVBInfo->IF_DEF_LVDS == 0) {
+				index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info
+				temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N
+				tempbx |= temp2;
+				if (temp2 & 0x02)          //PAL-M
+					tempbx &= (~SetPALTV);
+			}
+			*/
+		}
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GETLCDVCLKPtr */
-/* Input : */
-/* Output : al -> VCLK Index */
-/* Description : */
-/* --------------------------------------------------------------------- */
-static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short index;
+		if (pVBInfo->IF_DEF_CH7017 == 1) {
+			tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-		if (pVBInfo->IF_DEF_ScaleLCD == 1) {
-			if (pVBInfo->LCDInfo & EnableScalingLCD)
-				return;
+			if (tempbx & TVOverScan)
+				tempbx |= SetCHTVOverScan;
 		}
 
-		/* index = XGI_GetLCDCapPtr(pVBInfo); */
-		index = XGI_GetLCDCapPtr1(pVBInfo);
+		if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/04 */
+			tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
 
-		if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
-			*di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
-			*di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
-		} else { /* LCDA */
-			*di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
-			*di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
+			if (tempbx & TVOverScan)
+				tempbx |= SetCHTVOverScan;
 		}
-	}
-	return;
-}
 
-static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
-		unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
-{
+		if (pVBInfo->IF_DEF_LVDS == 0) {
+			if (pVBInfo->VBInfo & SetCRT2ToSCART)
+				tempbx |= SetPALTV;
+		}
 
-	unsigned short index, modeflag;
-	unsigned short tempbx;
-	unsigned char tempal;
-	unsigned char *CHTVVCLKPtr = NULL;
+		if (pVBInfo->IF_DEF_YPbPr == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+				index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+				index1 &= YPbPrMode;
 
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+				if (index1 == YPbPrMode525i)
+					tempbx |= SetYPbPrMode525i;
 
-	if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo
-			& EnableScalingLCD))) { /* {LCDA/LCDB} */
-		index = XGI_GetLCDCapPtr(pVBInfo);
-		tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
+				if (index1 == YPbPrMode525p)
+					tempbx = tempbx | SetYPbPrMode525p;
+				if (index1 == YPbPrMode750p)
+					tempbx = tempbx | SetYPbPrMode750p;
+			}
+		}
 
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
-			return tempal;
+		if (pVBInfo->IF_DEF_HiVision == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+				tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
+		}
 
-		/* {TV} */
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
-			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-				tempal = HiTVVCLKDIV2;
-				if (!(pVBInfo->TVInfo & RPLLDIV2XO))
-					tempal = HiTVVCLK;
-				if (pVBInfo->TVInfo & TVSimuMode) {
-					tempal = HiTVSimuVCLK;
-					if (!(modeflag & Charx8Dot))
-						tempal = HiTVTextVCLK;
+		if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
+			if ((pVBInfo->VBInfo & SetInSlaveMode)
+					&& (!(pVBInfo->VBInfo & SetNotSimuMode)))
+				tempbx |= TVSimuMode;
+
+			if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo
+					== 8)) /* NTSC 1024x768, */
+				tempbx |= NTSC1024x768;
+
+			tempbx |= RPLLDIV2XO;
 
+			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+				if (pVBInfo->VBInfo & SetInSlaveMode)
+					tempbx &= (~RPLLDIV2XO);
+			} else {
+				if (tempbx & (SetYPbPrMode525p
+						| SetYPbPrMode750p))
+					tempbx &= (~RPLLDIV2XO);
+				else if (!(pVBInfo->VBType & (VB_XGI301B
+						| VB_XGI302B | VB_XGI301LV
+						| VB_XGI302LV | VB_XGI301C))) {
+					if (tempbx & TVSimuMode)
+						tempbx &= (~RPLLDIV2XO);
 				}
-				return tempal;
 			}
+		}
+	}
+	pVBInfo->TVInfo = tempbx;
+}
 
-			if (pVBInfo->TVInfo & SetYPbPrMode750p) {
-				tempal = YPbPr750pVCLK;
-				return tempal;
-			}
+unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
 
-			if (pVBInfo->TVInfo & SetYPbPrMode525p) {
-				tempal = YPbPr525pVCLK;
-				return tempal;
-			}
+	pVBInfo->LCDResInfo = 0;
+	pVBInfo->LCDTypeInfo = 0;
+	pVBInfo->LCDInfo = 0;
 
-			tempal = NTSC1024VCLK;
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */
+	}
 
-			if (!(pVBInfo->TVInfo & NTSC1024x768)) {
-				tempal = TVVCLKDIV2;
-				if (!(pVBInfo->TVInfo & RPLLDIV2XO))
-					tempal = TVVCLK;
-			}
+	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
+	tempbx = temp & 0x0F;
 
-			if (pVBInfo->VBInfo & SetCRT2ToTV)
-				return tempal;
-		}
-		/* else if ((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017)) {
-			if (ModeNo<=0x13)
-				*tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+	if (tempbx == 0)
+		tempbx = Panel1024x768; /* default */
+
+	/* LCD75 [2003/8/22] Vicent */
+	if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
+		if (pVBInfo->VBInfo & DriverMode) {
+			tempax = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
+			if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+				tempax &= 0x0F;
 			else
-				*tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-			*tempal = *tempal & 0x1F;
-			tempbx = 0;
-			if (pVBInfo->TVInfo & SetPALTV)
-				tempbx = tempbx + 2;
-			if (pVBInfo->TVInfo & SetCHTVOverScan)
-				tempbx++;
-			tempbx = tempbx << 1;
-		} */
-	} /* {End of VB} */
+				tempax = tempax >> 4;
 
-	if ((pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */
-		/* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
-		if ((pVBInfo->VBInfo & SetCRT2ToTV)) {
-			if (ModeNo <= 0x13) {
-				tempal
-						= pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-			} else {
-				tempal
-						= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+			if ((resinfo == 6) || (resinfo == 9)) {
+				if (tempax >= 3)
+					tempbx |= PanelRef75Hz;
+			} else if ((resinfo == 7) || (resinfo == 8)) {
+				if (tempax >= 4)
+					tempbx |= PanelRef75Hz;
 			}
+		}
+	}
 
-			tempal = tempal & 0x0F;
-			tempbx = 0;
-
-			if (pVBInfo->TVInfo & SetPALTV)
-				tempbx = tempbx + 2;
+	pVBInfo->LCDResInfo = tempbx;
 
-			if (pVBInfo->TVInfo & SetCHTVOverScan)
-				tempbx++;
+	/* End of LCD75 */
 
-			/** tempbx = tempbx << 1; CH7007 ? **/
+	if (pVBInfo->IF_DEF_OEMUtil == 1)
+		pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
 
-			/* [Billy]07/05/29 CH7007 */
-			if (pVBInfo->IF_DEF_CH7007 == 1) {
-				switch (tempbx) {
-				case 0:
-					CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC;
-					break;
-				case 1:
-					CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC;
-					break;
-				case 2:
-					CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL;
-					break;
-				case 3:
-					CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL;
-					break;
-				default:
-					break;
+	if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+		return 0;
 
-				}
-			}
-			/* else {
-				switch(tempbx) {
-				case 0:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
-					break;
-				case 1:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
-					break;
-				case 2:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
-					break;
-				case 3:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
-					break;
-				default:
-					break;
-				}
-			}
-			*/
+	tempbx = 0;
 
-			tempal = CHTVVCLKPtr[tempal];
-			return tempal;
-		}
+	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
 
-	}
+	temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
 
-	tempal = (unsigned char) XGINew_GetReg2((pVBInfo->P3ca + 0x02));
-	tempal = tempal >> 2;
-	tempal &= 0x03;
+	if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
+		temp &= ~EnableScalingLCD;
 
-	if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) /* for Dot8 Scaling LCD */
-		tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
+	tempbx |= temp;
 
-	if (ModeNo <= 0x13)
-		return tempal;
+	LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
 
-	tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-	return tempal;
-}
+	tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
 
-static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
-		unsigned char *di_1, struct vb_device_info *pVBInfo)
-{
-	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */
-		/* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
-		*di_0 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2B;
-		*di_1 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2C;
-	} else if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B
-			| VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
-		if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag
-				& ProgrammingCRT2)) {
-			*di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B;
-			*di_1 = XGI_VBVCLKData[tempal].SR2C;
+	if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
+		if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
+				& VB_XGI301C)) && (tempax & LCDDualLink)) {
+			tempbx |= SetLCDDualLink;
 		}
-	} else {
-		*di_0 = XGI_VCLKData[tempal].SR2B;
-		*di_1 = XGI_VCLKData[tempal].SR2C;
 	}
-}
-
-static void XGI_SetCRT2Offset(unsigned short ModeNo,
-		unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short offset;
-	unsigned char temp;
 
-	if (pVBInfo->VBInfo & SetInSlaveMode)
-		return;
+	if (pVBInfo->IF_DEF_CH7017 == 1) {
+		if (tempax & LCDDualLink)
+			tempbx |= SetLCDDualLink;
+	}
 
-	offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-			HwDeviceExtension, pVBInfo);
-	temp = (unsigned char) (offset & 0xFF);
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp);
-	temp = (unsigned char) ((offset & 0xFF00) >> 8);
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x09, temp);
-	temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
-}
+	if (pVBInfo->IF_DEF_LVDS == 0) {
+		if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo
+				& SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo
+				== 9) && (!(tempbx & EnableScalingLCD)))
+			tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
+	}
 
-static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short temp, colordepth, modeinfo, index, infoflag,
-			ColorDepth[] = { 0x01, 0x02, 0x04 };
+	/*
+	if (tempax & LCDBToA) {
+		tempbx |= SetLCDBToA;
+	}
+	*/
 
-	modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-	if (ModeNo <= 0x14)
-		infoflag = 0;
-	else
-		infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+	if (pVBInfo->IF_DEF_ExpLink == 1) {
+		if (modeflag & HalfDCLK) {
+			/* if (!(pVBInfo->LCDInfo&LCDNonExpanding)) */
+			if (!(tempbx & SetLCDtoNonExpanding)) {
+				tempbx |= EnableLVDSDDA;
+			} else {
+				if (ModeNo > 0x13) {
+					if (pVBInfo->LCDResInfo
+							== Panel1024x768) {
+						if (resinfo == 4) { /* 512x384  */
+							tempbx |= EnableLVDSDDA;
+						}
+					}
+				}
+			}
+		}
+	}
 
-	index = (modeinfo >> 8) & 0xFF;
+	if (pVBInfo->VBInfo & SetInSlaveMode) {
+		if (pVBInfo->VBInfo & SetNotSimuMode)
+			tempbx |= LCDVESATiming;
+	} else {
+		tempbx |= LCDVESATiming;
+	}
 
-	temp = pVBInfo->ScreenOffset[index];
+	pVBInfo->LCDInfo = tempbx;
 
-	if (infoflag & InterlaceMode)
-		temp = temp << 1;
+	if (pVBInfo->IF_DEF_PWD == 1) {
+		if (pVBInfo->LCDInfo & SetPWDEnable) {
+			if ((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
+					& VB_XGI301C)) {
+				if (!(tempax & PWDEnable))
+					pVBInfo->LCDInfo &= ~SetPWDEnable;
+			}
+		}
+	}
 
-	colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
+	if (pVBInfo->IF_DEF_LVDS == 0) {
+		if (tempax & (LockLCDBToA | StLCDBToA)) {
+			if (pVBInfo->VBInfo & SetInSlaveMode) {
+				if (!(tempax & LockLCDBToA)) {
+					if (ModeNo <= 0x13) {
+						pVBInfo->VBInfo
+								&= ~(SetSimuScanMode
+										| SetInSlaveMode
+										| SetCRT2ToLCD);
+						pVBInfo->VBInfo
+								|= SetCRT2ToLCDA
+										| SetCRT2ToDualEdge;
+					}
+				}
+			}
+		}
+	}
 
-	if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
-		temp = ModeNo - 0x7C;
-		colordepth = ColorDepth[temp];
-		temp = 0x6B;
-		if (infoflag & InterlaceMode)
-			temp = temp << 1;
-		return temp * colordepth;
-	} else {
-		return temp * colordepth;
+	/*
+	if (pVBInfo->IF_DEF_LVDS == 0) {
+		if (tempax & (LockLCDBToA | StLCDBToA)) {
+			if (pVBInfo->VBInfo & SetInSlaveMode) {
+				if (!((!(tempax & LockLCDBToA)) && (ModeNo > 0x13))) {
+					pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD);
+					pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge;
+				}
+			}
+		}
 	}
-}
+	*/
 
-static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
-{
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
-	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
+	return 1;
 }
 
-static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
+unsigned char XGI_SearchModeID(unsigned short ModeNo,
+		unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
 {
-	unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
+	if (ModeNo <= 5)
+		ModeNo |= 1;
+	if (ModeNo <= 0x13) {
+		/* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->SModeIDTable) / sizeof(struct XGI_StStruct); (*ModeIdIndex)++) */
+		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
+			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
+				break;
+			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
+				return 0;
+		}
 
-	if (ModeNo > 0x13) {
-		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index &= IndexMask;
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+		if (ModeNo == 0x07)
+			(*ModeIdIndex)++; /* 400 lines */
+		if (ModeNo <= 3)
+			(*ModeIdIndex) += 2; /* 400 lines */
+		/* else 350 lines */
+	} else {
+		/* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->EModeIDTable) / sizeof(struct XGI_ExtStruct); (*ModeIdIndex)++) */
+		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
+			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
+				break;
+			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+				return 0;
+		}
 	}
 
-	XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-			HwDeviceExtension, pVBInfo);
-	XGI_SetCRT2FIFO(pVBInfo);
-	/* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
-
-	for (tempcx = 4; tempcx < 7; tempcx++)
-		XGINew_SetReg1(pVBInfo->Part1Port, tempcx, 0x0);
-
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x50, 0x00);
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
+	return 1;
 }
 
-static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+/* win2000 MM adapter not support standard mode! */
+
+#if 0
+static unsigned char XGINew_CheckMemorySize(
 		struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short RefreshRateTableIndex,
+		unsigned short ModeNo,
+		unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
-			pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
+	unsigned short memorysize, modeflag, temp, temp1, tmp;
 
-	if (ModeNo > 0x13) {
-		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index &= IndexMask;
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	/*
+	if ((HwDeviceExtension->jChipType == XGI_650) ||
+	(HwDeviceExtension->jChipType == XGI_650M)) {
+		return 1;
 	}
+	*/
 
 	if (ModeNo <= 0x13)
 		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	else
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	/* bainy change table name */
-	if (modeflag & HalfDCLK) {
-		temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
-		XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
-		temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
-		temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
-		XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
-		tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
-		pushbx = pVBInfo->VGAHDE / 2 + 16;
-		tempcx = tempcx >> 1;
-		tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
-		tempcx += tempbx;
+	/* ModeType = modeflag&ModeInfoFlag; // Get mode type */
 
-		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
-			tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
-			tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
-							& 0xC0) << 2);
-			tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
-			tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
-			tempcx &= 0x1F;
-			temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
-			temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
-			tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
-		}
+	memorysize = modeflag & MemoryInfoFlag;
+	memorysize = memorysize > MemorySizeShift;
+	memorysize++; /* Get memory size */
 
-		tempbx += 4;
-		tempcx += 4;
+	temp = XGINew_GetReg1(pVBInfo->P3c4, 0x14); /* Get DRAM Size */
+	tmp = temp;
 
-		if (tempcx > (pVBInfo->VGAHT / 2))
-			tempcx = pVBInfo->VGAHT / 2;
+	if (HwDeviceExtension->jChipType == XG40) {
+		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+		if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+			temp <<= 2;
+		} else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
+			temp <<= 1;
+		}
+	} else if (HwDeviceExtension->jChipType == XG42) {
+		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+		if ((tmp & 0x04) == 0x04) { /* Dual channels */
+			temp <<= 1;
+		}
+	} else if (HwDeviceExtension->jChipType == XG45) {
+		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+		if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+			temp <<= 2;
+		} else if ((tmp & 0x0c) == 0x08) { /* triple channels */
+			temp1 = temp;
+			temp <<= 1;
+			temp += temp1;
+		} else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
+			temp <<= 1;
+		}
+	}
+	if (temp < memorysize)
+		return 0;
+	else
+		return 1;
+}
+#endif
 
-		temp = tempbx & 0x00FF;
+/*
+void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+	unsigned short data ;
+	unsigned short ModeFlag ;
 
-		XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
-	} else {
-		temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
-		XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
-		temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
-		temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
-		XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
-		tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
-		pushbx = pVBInfo->VGAHDE + 16;
-		tempcx = tempcx >> 1;
-		tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
-		tempcx += tempbx;
+	data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
+	data &= 0x7F;
+	XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
 
-		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
-			tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
-			tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]
-							& 0xC0) << 2);
-			tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
-			tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
-			tempcx &= 0x1F;
-			temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
-			temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
-			tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
-			tempbx += 16;
-			tempcx += 16;
+	if (ModeNo > 0x13) {
+		ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
+			data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
+			data |= 0x80;
+			XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
+			data = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
+			data &= 0xF7;
+			XGINew_SetReg1(pVBInfo->P3c4, 0x01, data);
 		}
+	}
+}
+*/
 
-		if (tempcx > pVBInfo->VGAHT)
-			tempcx = pVBInfo->VGAHT;
+static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
+{
+	unsigned char ujRet = 0;
+	unsigned char i = 0;
 
-		temp = tempbx & 0x00FF;
-		XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
+	for (i = 0; i < 8; i++) {
+		ujRet = ujRet << 1;
+		/* ujRet |= GETBITS(ujDate >> i, 0:0); */
+		ujRet |= (ujDate >> i) & 1;
 	}
 
-	tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
-	tempbx = pushbx;
-	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
-	tempax |= (tempbx & 0xFF00);
-	temp = (tempax & 0xFF00) >> 8;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp);
-	tempcx = (pVBInfo->VGAVT - 1);
-	temp = tempcx & 0x00FF;
+	return ujRet;
+}
 
-	if (pVBInfo->IF_DEF_CH7005 == 1) {
-		if (pVBInfo->VBInfo & 0x0C)
-			temp--;
-	}
+/*----------------------------------------------------------------------------*/
+/* output                                                                     */
+/*      bl[5] : LVDS signal                                                   */
+/*      bl[1] : LVDS backlight                                                */
+/*      bl[0] : LVDS VDD                                                      */
+/*----------------------------------------------------------------------------*/
+static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
+{
+	unsigned char CR4A, temp;
 
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
-	tempbx = pVBInfo->VGAVDE - 1;
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, temp);
-	temp = ((tempbx & 0xFF00) << 3) >> 8;
-	temp |= ((tempcx & 0xFF00) >> 8);
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x12, temp);
+	CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+	XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
 
-	tempax = pVBInfo->VGAVDE;
-	tempbx = pVBInfo->VGAVDE;
-	tempcx = pVBInfo->VGAVT;
-	tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
-	tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
 
-	if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
-		tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
-		temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+	temp = XG21GPIODataTransfer(temp);
+	temp &= 0x23;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
+	return temp;
+}
+
+/*----------------------------------------------------------------------------*/
+/* output                                                                     */
+/*      bl[5] : LVDS signal                                                   */
+/*      bl[1] : LVDS backlight                                                */
+/*      bl[0] : LVDS VDD                                                      */
+/*----------------------------------------------------------------------------*/
+static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
+{
+	unsigned char CR4A, CRB4, temp;
 
-		if (temp & 0x04)
-			tempbx |= 0x0100;
+	CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+	XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
 
-		if (temp & 0x080)
-			tempbx |= 0x0200;
+	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
 
-		temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
+	temp &= 0x0C;
+	temp >>= 2;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
+	CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4);
+	temp |= ((CRB4 & 0x04) << 3);
+	return temp;
+}
 
-		if (temp & 0x08)
-			tempbx |= 0x0400;
+void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE,
+		struct vb_device_info *pVBInfo)
+{
+
+	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
+	if (pXGIHWDE->jChipType == XG21) {
+		if (pVBInfo->IF_DEF_LVDS == 1) {
+			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
+				XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+				XGI_XG21SetPanelDelay(2, pVBInfo);
+			}
+			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
+				XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+			XGI_XG21SetPanelDelay(3, pVBInfo);
+			XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
+		} else {
+			XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
+		}
 
-		temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
-		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
 	}
 
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
-	temp = ((tempbx & 0xFF00) >> 8) << 4;
-	temp = ((tempcx & 0x000F) | (temp));
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x11, temp);
-	tempax = 0;
+	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
 
-	if (modeflag & DoubleScanMode)
-		tempax |= 0x80;
+	}
 
-	if (modeflag & HalfDCLK)
-		tempax |= 0x40;
+	if (pXGIHWDE->jChipType == XG27) {
+		if (pVBInfo->IF_DEF_LVDS == 1) {
+			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
+				XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+				XGI_XG21SetPanelDelay(2, pVBInfo);
+			}
+			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
+				XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+			XGI_XG21SetPanelDelay(3, pVBInfo);
+			XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
+		} else {
+			XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
+		}
 
-	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
+	}
 }
 
-static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short RefreshRateTableIndex,
+void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
-			modeflag, CRT1Index;
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index &= IndexMask;
+	if (pXGIHWDE->jChipType == XG21) {
+		if (pVBInfo->IF_DEF_LVDS == 1) {
+			XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
+			XGI_XG21SetPanelDelay(3, pVBInfo);
+		} else {
+			XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
+		}
 	}
 
-	if (!(pVBInfo->VBInfo & SetInSlaveMode))
-		return;
-
-	temp = 0xFF; /* set MAX HT */
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
-	/* if (modeflag & Charx8Dot) */
-	/*	tempcx = 0x08; */
-	/* else */
-	tempcx = 0x08;
-
-	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
-		modeflag |= Charx8Dot;
+	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
+		/* if (IsCH7007TVMode(pVBInfo) == 0) */
+		{
+		}
+	}
 
-	tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
+	if (pXGIHWDE->jChipType == XG27) {
+		if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
+			XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
+			XGI_XG21SetPanelDelay(3, pVBInfo);
+		}
 
-	if (modeflag & HalfDCLK)
-		tempax = tempax >> 1;
+		if (pVBInfo->IF_DEF_LVDS == 0)
+			XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
+	}
 
-	tempax = (tempax / tempcx) - 1;
-	tempbx |= ((tempax & 0x00FF) << 8);
-	temp = tempax & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x04, temp);
+	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
+}
 
-	temp = (tempbx & 0xFF00) >> 8;
+static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
+{
+	while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01))
+		break;
 
-	if (pVBInfo->VBInfo & SetCRT2ToTV) {
-		if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)))
-			temp += 2;
+	while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01))
+		break;
+}
 
-		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-			if (pVBInfo->VBType & VB_XGI301LV) {
-				if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
-					if (resinfo == 7)
-						temp -= 2;
-				}
-			} else if (resinfo == 7) {
-				temp -= 2;
-			}
-		}
-	}
+#if 0
+static void XGI_WaitDisplay(struct vb_device_info *pVBInfo)
+{
+	while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01));
+	while (XGINew_GetReg2(pVBInfo->P3da) & 0x01);
+}
+#endif
 
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
+static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
+{
+	if (!(pVBInfo->SetFlag & Win9xDOSMode))
+		XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40);
+}
 
-	if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
-		if (pVBInfo->VBInfo & SetCRT2ToTV)
-			tempax = pVBInfo->VGAHT;
-		else
-			tempax = XGI_GetVGAHT2(pVBInfo);
-	}
+static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo)
+{
+	unsigned short temp1, temp2;
 
-	if (tempax >= pVBInfo->VGAHT)
-		tempax = pVBInfo->VGAHT;
+	XGINew_SetReg1(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
+	temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
+	temp2 = ~(SetInSlaveMode >> 8);
+	XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1);
+}
 
-	if (modeflag & HalfDCLK)
-		tempax = tempax >> 1;
+static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short xres, yres, modeflag, resindex;
 
-	tempax = (tempax / tempcx) - 5;
-	tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		temp = (tempbx & 0x00FF) - 1;
-		if (!(modeflag & HalfDCLK)) {
-			temp -= 6;
-			if (pVBInfo->TVInfo & TVSimuMode) {
-				temp -= 4;
-				if (ModeNo > 0x13)
-					temp -= 10;
-			}
-		}
+	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+	if (ModeNo <= 0x13) {
+		xres = pVBInfo->StResInfo[resindex].HTotal;
+		yres = pVBInfo->StResInfo[resindex].VTotal;
+		/* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */
 	} else {
-		/* tempcx = tempbx & 0x00FF ; */
-		tempbx = (tempbx & 0xFF00) >> 8;
-		tempcx = (tempcx + tempbx) >> 1;
-		temp = (tempcx & 0x00FF) + 2;
-
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			temp -= 1;
-			if (!(modeflag & HalfDCLK)) {
-				if ((modeflag & Charx8Dot)) {
-					temp += 4;
-					if (pVBInfo->VGAHDE >= 800)
-						temp -= 6;
-				}
-			}
-		} else {
-			if (!(modeflag & HalfDCLK)) {
-				temp -= 4;
-				if (pVBInfo->LCDResInfo != Panel1280x960) {
-					if (pVBInfo->VGAHDE >= 800) {
-						temp -= 7;
-						if (pVBInfo->ModeType
-								== ModeEGA) {
-							if (pVBInfo->VGAVDE
-									== 1024) {
-								temp += 15;
-								if (pVBInfo->LCDResInfo
-										!= Panel1280x1024) {
-									temp
-											+= 7;
-								}
-							}
-						}
-
-						if (pVBInfo->VGAHDE >= 1280) {
-							if (pVBInfo->LCDResInfo
-									!= Panel1280x960) {
-								if (pVBInfo->LCDInfo
-										& LCDNonExpanding) {
-									temp
-											+= 28;
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
+		xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+		yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
 
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
+		/*
+		if (pVBInfo->IF_DEF_FSTN) {
+			xres *= 2;
+			yres *= 2;
+		 } else {
+		*/
+		if (modeflag & HalfDCLK)
+			xres *= 2;
 
-	if (pVBInfo->VBInfo & SetCRT2ToTV) {
-		if (pVBInfo->TVInfo & TVSimuMode) {
-			if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo
-					== 0x11) || (ModeNo == 0x13) || (ModeNo
-					== 0x0F)) {
-				XGINew_SetReg1(pVBInfo->Part1Port, 0x07, 0x5b);
-				XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0x03);
-			}
+		if (modeflag & DoubleScanMode)
+			yres *= 2;
+		/* } */
+	}
 
-			if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
-				if (pVBInfo->TVInfo & SetNTSCTV) {
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x07, 0x2A);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x08, 0x61);
-				} else {
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x07, 0x2A);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x08, 0x41);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x0C, 0xF0);
+	if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+		if (pVBInfo->IF_DEF_LVDS == 0) {
+			if (pVBInfo->LCDResInfo == Panel1600x1200) {
+				if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+					if (yres == 1024)
+						yres = 1056;
 				}
 			}
 
-			if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo
-					== 0x07)) {
-				if (pVBInfo->TVInfo & SetNTSCTV) {
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x07, 0x54);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x08, 0x00);
-				} else {
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x07, 0x55);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x08, 0x00);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x0C, 0xF0);
+			if (pVBInfo->LCDResInfo == Panel1280x1024) {
+				if (yres == 400)
+					yres = 405;
+				else if (yres == 350)
+					yres = 360;
+
+				if (pVBInfo->LCDInfo & LCDVESATiming) {
+					if (yres == 360)
+						yres = 375;
 				}
 			}
 
-			if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo
-					== 0x0D) || (ModeNo == 0x50)) {
-				if (pVBInfo->TVInfo & SetNTSCTV) {
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x07, 0x30);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x08, 0x03);
-				} else {
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x07, 0x2f);
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x08, 0x02);
+			if (pVBInfo->LCDResInfo == Panel1024x768) {
+				if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+					if (!(pVBInfo->LCDInfo
+							& LCDNonExpanding)) {
+						if (yres == 350)
+							yres = 357;
+						else if (yres == 400)
+							yres = 420;
+						else if (yres == 480)
+							yres = 525;
+					}
 				}
 			}
 		}
+
+		if (xres == 720)
+			xres = 640;
 	}
 
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
-	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
+	pVBInfo->VGAHDE = xres;
+	pVBInfo->HDE = xres;
+	pVBInfo->VGAVDE = yres;
+	pVBInfo->VDE = yres;
+}
 
-	tempbx = pVBInfo->VGAVT;
-	push1 = tempbx;
-	tempcx = 0x121;
-	tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
+static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
+{
 
-	if (tempbx == 357)
-		tempbx = 350;
-	if (tempbx == 360)
-		tempbx = 350;
-	if (tempbx == 375)
-		tempbx = 350;
-	if (tempbx == 405)
-		tempbx = 400;
-	if (tempbx == 525)
-		tempbx = 480;
+	if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
+			(pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
+		return 1;
 
-	push2 = tempbx;
+	return 0;
+}
+
+static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
+			StandTableIndex, CRT1Index;
+
+	pVBInfo->RVBHCMAX = 1;
+	pVBInfo->RVBHCFACT = 1;
+
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+		tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
+		tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
+		temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		CRT1Index
+				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index &= IndexMask;
+		temp1
+				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
+		temp2
+				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+		tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
+		tempbx
+				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
+		tempcx
+				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
+						<< 8;
+		tempcx &= 0x0100;
+		tempcx = tempcx << 2;
+		tempbx |= tempcx;
+		temp1
+				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+	}
+
+	if (temp1 & 0x01)
+		tempbx |= 0x0100;
+
+	if (temp1 & 0x20)
+		tempbx |= 0x0200;
+	tempax += 5;
+
+	if (modeflag & Charx8Dot)
+		tempax *= 8;
+	else
+		tempax *= 9;
+
+	pVBInfo->VGAHT = tempax;
+	pVBInfo->HT = tempax;
+	tempbx++;
+	pVBInfo->VGAVT = tempbx;
+	pVBInfo->VT = tempbx;
+}
+
+static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempax = 0, tempbx, modeflag, resinfo;
+
+	struct XGI_LCDDataStruct *LCDPtr = NULL;
+	struct XGI_TVDataStruct *TVPtr = NULL;
+
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	}
+
+	pVBInfo->NewFlickerMode = 0;
+	pVBInfo->RVBHRS = 50;
+
+	if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+		XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+				pVBInfo);
+		return;
+	}
+
+	tempbx = 4;
+
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+		LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx,
+				ModeNo, ModeIdIndex, RefreshRateTableIndex,
+				pVBInfo);
+
+		pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
+		pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
+		pVBInfo->VGAHT = LCDPtr->VGAHT;
+		pVBInfo->VGAVT = LCDPtr->VGAVT;
+		pVBInfo->HT = LCDPtr->LCDHT;
+		pVBInfo->VT = LCDPtr->LCDVT;
 
-	if (pVBInfo->VBInfo & SetCRT2ToLCD) {
 		if (pVBInfo->LCDResInfo == Panel1024x768) {
+			tempax = 1024;
+			tempbx = 768;
+
+			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+				if (pVBInfo->VGAVDE == 357)
+					tempbx = 527;
+				else if (pVBInfo->VGAVDE == 420)
+					tempbx = 620;
+				else if (pVBInfo->VGAVDE == 525)
+					tempbx = 775;
+				else if (pVBInfo->VGAVDE == 600)
+					tempbx = 775;
+				/* else if (pVBInfo->VGAVDE==350) tempbx=560; */
+				/* else if (pVBInfo->VGAVDE==400) tempbx=640; */
+				else
+					tempbx = 768;
+			} else
+				tempbx = 768;
+		} else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
+			tempax = 1024;
+			tempbx = 768;
+		} else if (pVBInfo->LCDResInfo == Panel1280x1024) {
+			tempax = 1280;
+			if (pVBInfo->VGAVDE == 360)
+				tempbx = 768;
+			else if (pVBInfo->VGAVDE == 375)
+				tempbx = 800;
+			else if (pVBInfo->VGAVDE == 405)
+				tempbx = 864;
+			else
+				tempbx = 1024;
+		} else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
+			tempax = 1280;
+			tempbx = 1024;
+		} else if (pVBInfo->LCDResInfo == Panel1280x960) {
+			tempax = 1280;
+			if (pVBInfo->VGAVDE == 350)
+				tempbx = 700;
+			else if (pVBInfo->VGAVDE == 400)
+				tempbx = 800;
+			else if (pVBInfo->VGAVDE == 1024)
+				tempbx = 960;
+			else
+				tempbx = 960;
+		} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+			tempax = 1400;
+			tempbx = 1050;
+
+			if (pVBInfo->VGAVDE == 1024) {
+				tempax = 1280;
+				tempbx = 1024;
+			}
+		} else if (pVBInfo->LCDResInfo == Panel1600x1200) {
+			tempax = 1600;
+			tempbx = 1200; /* alan 10/14/2003 */
 			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
-				if (tempbx == 350)
-					tempbx += 5;
-				if (tempbx == 480)
-					tempbx += 5;
+				if (pVBInfo->VGAVDE == 350)
+					tempbx = 875;
+				else if (pVBInfo->VGAVDE == 400)
+					tempbx = 1000;
 			}
 		}
-	}
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
-	tempbx = push2;
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
-
-	if (tempbx & 0x0100)
-		tempcx |= 0x0002;
-
-	tempax = 0x000B;
 
-	if (modeflag & DoubleScanMode)
-		tempax |= 0x08000;
+		if (pVBInfo->LCDInfo & LCDNonExpanding) {
+			tempax = pVBInfo->VGAHDE;
+			tempbx = pVBInfo->VGAVDE;
+		}
 
-	if (tempbx & 0x0200)
-		tempcx |= 0x0040;
+		pVBInfo->HDE = tempax;
+		pVBInfo->VDE = tempbx;
+		return;
+	}
 
-	temp = (tempax & 0xFF00) >> 8;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
+	if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
+		tempbx = 4;
+		TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx,
+				ModeNo, ModeIdIndex, RefreshRateTableIndex,
+				pVBInfo);
 
-	if (tempbx & 0x0400)
-		tempcx |= 0x0600;
+		pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
+		pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
+		pVBInfo->VGAHT = TVPtr->VGAHT;
+		pVBInfo->VGAVT = TVPtr->VGAVT;
+		pVBInfo->HDE = TVPtr->TVHDE;
+		pVBInfo->VDE = TVPtr->TVVDE;
+		pVBInfo->RVBHRS = TVPtr->RVBHRS;
+		pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
 
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
+		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+			if (resinfo == 0x08)
+				pVBInfo->NewFlickerMode = 0x40;
+			else if (resinfo == 0x09)
+				pVBInfo->NewFlickerMode = 0x40;
+			else if (resinfo == 0x12)
+				pVBInfo->NewFlickerMode = 0x40;
 
-	tempax = push1;
-	tempax -= tempbx; /* 0x0C Vertical Retrace Start */
-	tempax = tempax >> 2;
-	push1 = tempax; /* push ax */
+			if (pVBInfo->VGAVDE == 350)
+				pVBInfo->TVInfo |= TVSimuMode;
 
-	if (resinfo != 0x09) {
-		tempax = tempax << 1;
-		tempbx += tempax;
-	}
+			tempax = ExtHiTVHT;
+			tempbx = ExtHiTVVT;
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		if (pVBInfo->VBType & VB_XGI301LV) {
-			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
-				tempbx -= 10;
-			} else {
+			if (pVBInfo->VBInfo & SetInSlaveMode) {
 				if (pVBInfo->TVInfo & TVSimuMode) {
-					if (pVBInfo->TVInfo & SetPALTV) {
-						if (pVBInfo->VBType
-								& VB_XGI301LV) {
-							if (!(pVBInfo->TVInfo
-									& (SetYPbPrMode525p
-											| SetYPbPrMode750p
-											| SetYPbPrMode1080i)))
-								tempbx += 40;
-						} else {
-							tempbx += 40;
-						}
+					tempax = StHiTVHT;
+					tempbx = StHiTVVT;
+
+					if (!(modeflag & Charx8Dot)) {
+						tempax = StHiTextTVHT;
+						tempbx = StHiTextTVVT;
 					}
 				}
 			}
+		} else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+			if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+				tempax = YPbPrTV750pHT; /* Ext750pTVHT */
+				tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
+			}
+
+			if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+				tempax = YPbPrTV525pHT; /* Ext525pTVHT */
+				tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
+			} else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
+				tempax = YPbPrTV525iHT; /* Ext525iTVHT */
+				tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
+				if (pVBInfo->TVInfo & NTSC1024x768)
+					tempax = NTSC1024x768HT;
+			}
 		} else {
-			tempbx -= 10;
-		}
-	} else {
-		if (pVBInfo->TVInfo & TVSimuMode) {
-			if (pVBInfo->TVInfo & SetPALTV) {
-				if (pVBInfo->VBType & VB_XGI301LV) {
-					if (!(pVBInfo->TVInfo
-							& (SetYPbPrMode525p
-									| SetYPbPrMode750p
-									| SetYPbPrMode1080i)))
-						tempbx += 40;
-				} else {
-					tempbx += 40;
-				}
+			tempax = PALHT;
+			tempbx = PALVT;
+			if (!(pVBInfo->TVInfo & SetPALTV)) {
+				tempax = NTSCHT;
+				tempbx = NTSCVT;
+				if (pVBInfo->TVInfo & NTSC1024x768)
+					tempax = NTSC1024x768HT;
 			}
 		}
-	}
-	tempax = push1;
-	tempax = tempax >> 2;
-	tempax++;
-	tempax += tempbx;
-	push1 = tempax; /* push ax */
 
-	if ((pVBInfo->TVInfo & SetPALTV)) {
-		if (tempbx <= 513) {
-			if (tempax >= 513)
-				tempbx = 513;
-		}
+		pVBInfo->HT = tempax;
+		pVBInfo->VT = tempbx;
+		return;
 	}
-
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
-	tempbx--;
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
-
-	if (tempbx & 0x0100)
-		tempcx |= 0x0008;
-
-	if (tempbx & 0x0200)
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
-
-	tempbx++;
-
-	if (tempbx & 0x0100)
-		tempcx |= 0x0004;
-
-	if (tempbx & 0x0200)
-		tempcx |= 0x0080;
-
-	if (tempbx & 0x0400)
-		tempcx |= 0x0C00;
-
-	tempbx = push1; /* pop ax */
-	temp = tempbx & 0x00FF;
-	temp &= 0x0F;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
-
-	if (tempbx & 0x0010)
-		tempcx |= 0x2000;
-
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
-	temp = (tempcx & 0x0FF00) >> 8;
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
-	tempax = modeflag;
-	temp = (tempax & 0xFF00) >> 8;
-
-	temp = (temp >> 1) & 0x09;
-
-	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
-		temp |= 0x01;
-
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
-
-	if (pVBInfo->LCDInfo & LCDRGB18Bit)
-		temp = 0x80;
-	else
-		temp = 0x00;
-
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
-
-	return;
 }
 
-static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
 		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
-			modeflag, resinfo, crt2crtc;
-	unsigned char *TimingPoint;
+	unsigned char di_0, di_1, tempal;
 
-	unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
+	tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
+			pVBInfo);
+	XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
+	XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
-		crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		crt2crtc
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+	if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */
+		/* 301 */
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, 0x10);
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
+	} else { /* 301b/302b/301lv/302lv */
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
 	}
 
-	tempax = 0;
-
-	if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
-		tempax |= 0x0800;
-
-	if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
-		tempax |= 0x0400;
-
-	if (pVBInfo->VBInfo & SetCRT2ToSCART)
-		tempax |= 0x0200;
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x00, 0x12);
 
-	if (!(pVBInfo->TVInfo & SetPALTV))
-		tempax |= 0x1000;
+	if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
+		XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28);
+	else
+		XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x08);
+}
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
-		tempax |= 0x0100;
+static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
+		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+	unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
+	short index;
+	unsigned short modeflag;
 
-	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
-		tempax &= 0xfe00;
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	tempax = (tempax & 0xff00) >> 8;
+	index = (modeflag & ModeInfoFlag) - ModeEGA;
 
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x0, tempax);
-	TimingPoint = pVBInfo->NTSCTiming;
+	if (index < 0)
+		index = 0;
 
-	if (pVBInfo->TVInfo & SetPALTV)
-		TimingPoint = pVBInfo->PALTiming;
+	return ColorDepth[index];
+}
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		TimingPoint = pVBInfo->HiTVExtTiming;
+static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short temp, colordepth, modeinfo, index, infoflag,
+			ColorDepth[] = { 0x01, 0x02, 0x04 };
 
-		if (pVBInfo->VBInfo & SetInSlaveMode)
-			TimingPoint = pVBInfo->HiTVSt2Timing;
+	modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+	if (ModeNo <= 0x14)
+		infoflag = 0;
+	else
+		infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 
-		if (pVBInfo->SetFlag & TVSimuMode)
-			TimingPoint = pVBInfo->HiTVSt1Timing;
+	index = (modeinfo >> 8) & 0xFF;
 
-		if (!(modeflag & Charx8Dot))
-			TimingPoint = pVBInfo->HiTVTextTiming;
-	}
+	temp = pVBInfo->ScreenOffset[index];
 
-	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-		if (pVBInfo->TVInfo & SetYPbPrMode525i)
-			TimingPoint = pVBInfo->YPbPr525iTiming;
+	if (infoflag & InterlaceMode)
+		temp = temp << 1;
 
-		if (pVBInfo->TVInfo & SetYPbPrMode525p)
-			TimingPoint = pVBInfo->YPbPr525pTiming;
+	colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
 
-		if (pVBInfo->TVInfo & SetYPbPrMode750p)
-			TimingPoint = pVBInfo->YPbPr750pTiming;
+	if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
+		temp = ModeNo - 0x7C;
+		colordepth = ColorDepth[temp];
+		temp = 0x6B;
+		if (infoflag & InterlaceMode)
+			temp = temp << 1;
+		return temp * colordepth;
+	} else {
+		return temp * colordepth;
 	}
+}
 
-	for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
-		XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]);
+static void XGI_SetCRT2Offset(unsigned short ModeNo,
+		unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short offset;
+	unsigned char temp;
 
-	for (i = 0x39; i <= 0x45; i++, j++)
-		XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
+	if (pVBInfo->VBInfo & SetInSlaveMode)
+		return;
 
-	if (pVBInfo->VBInfo & SetCRT2ToTV)
-		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
+	offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+			HwDeviceExtension, pVBInfo);
+	temp = (unsigned char) (offset & 0xFF);
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp);
+	temp = (unsigned char) ((offset & 0xFF00) >> 8);
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x09, temp);
+	temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
+}
 
-	temp = pVBInfo->NewFlickerMode;
-	temp &= 0x80;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
+static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
+{
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
+	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
+}
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
-		tempax = 950;
+static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
 
-	if (pVBInfo->TVInfo & SetPALTV)
-		tempax = 520;
-	else
-		tempax = 440;
+	if (ModeNo > 0x13) {
+		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index &= IndexMask;
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	}
 
-	if (pVBInfo->VDE <= tempax) {
-		tempax -= pVBInfo->VDE;
-		tempax = tempax >> 2;
-		tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
-		push1 = tempax;
-		temp = (tempax & 0xFF00) >> 8;
-		temp += (unsigned short) TimingPoint[0];
+	XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+			HwDeviceExtension, pVBInfo);
+	XGI_SetCRT2FIFO(pVBInfo);
+	/* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
 
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
-			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
-					| SetCRT2ToSVIDEO | SetCRT2ToSCART
-					| SetCRT2ToYPbPr)) {
-				tempcx = pVBInfo->VGAHDE;
-				if (tempcx >= 1024) {
-					temp = 0x17; /* NTSC */
-					if (pVBInfo->TVInfo & SetPALTV)
-						temp = 0x19; /* PAL */
-				}
-			}
-		}
+	for (tempcx = 4; tempcx < 7; tempcx++)
+		XGINew_SetReg1(pVBInfo->Part1Port, tempcx, 0x0);
 
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
-		tempax = push1;
-		temp = (tempax & 0xFF00) >> 8;
-		temp += TimingPoint[1];
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x50, 0x00);
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
+}
 
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
-			if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
-					| SetCRT2ToSVIDEO | SetCRT2ToSCART
-					| SetCRT2ToYPbPr))) {
-				tempcx = pVBInfo->VGAHDE;
-				if (tempcx >= 1024) {
-					temp = 0x1D; /* NTSC */
-					if (pVBInfo->TVInfo & SetPALTV)
-						temp = 0x52; /* PAL */
-				}
-			}
-		}
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x02, temp);
+static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
+			pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
+
+	if (ModeNo > 0x13) {
+		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index &= IndexMask;
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	}
 
-	/* 301b */
-	tempcx = pVBInfo->HT;
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	if (XGI_IsLCDDualLink(pVBInfo))
+	/* bainy change table name */
+	if (modeflag & HalfDCLK) {
+		temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+		XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
+		temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
+		temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+		XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
+		tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
+		pushbx = pVBInfo->VGAHDE / 2 + 16;
 		tempcx = tempcx >> 1;
+		tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+		tempcx += tempbx;
 
-	tempcx -= 2;
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x1B, temp);
+		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+			tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+			tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
+							& 0xC0) << 2);
+			tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+			tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+			tempcx &= 0x1F;
+			temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
+			temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+			tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+		}
 
-	temp = (tempcx & 0xFF00) >> 8;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
+		tempbx += 4;
+		tempcx += 4;
 
-	tempcx = pVBInfo->HT >> 1;
-	push1 = tempcx; /* push cx */
-	tempcx += 7;
+		if (tempcx > (pVBInfo->VGAHT / 2))
+			tempcx = pVBInfo->VGAHT / 2;
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
-		tempcx -= 4;
+		temp = tempbx & 0x00FF;
 
-	temp = tempcx & 0x00FF;
-	temp = temp << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x22, 0x0F, temp);
+		XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
+	} else {
+		temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+		XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
+		temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
+		temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+		XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
+		tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
+		pushbx = pVBInfo->VGAHDE + 16;
+		tempcx = tempcx >> 1;
+		tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+		tempcx += tempbx;
 
-	tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
-	tempbx += tempcx;
-	push2 = tempbx;
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x24, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp);
+		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+			tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
+			tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]
+							& 0xC0) << 2);
+			tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+			tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+			tempcx &= 0x1F;
+			temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
+			temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+			tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+			tempbx += 16;
+			tempcx += 16;
+		}
 
-	tempbx = push2;
-	tempbx = tempbx + 8;
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		tempbx = tempbx - 4;
-		tempcx = tempbx;
-	}
+		if (tempcx > pVBInfo->VGAHT)
+			tempcx = pVBInfo->VGAHT;
 
-	temp = (tempbx & 0x00FF) << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x29, 0x0F, temp);
+		temp = tempbx & 0x00FF;
+		XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
+	}
 
-	j += 2;
-	tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
+	tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
+	tempbx = pushbx;
+	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+	tempax |= (tempbx & 0xFF00);
+	temp = (tempax & 0xFF00) >> 8;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
 	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x27, temp);
-	temp = ((tempcx & 0xFF00) >> 8) << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp);
-
-	tempcx += 8;
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
-		tempcx -= 4;
-
-	temp = tempcx & 0xFF;
-	temp = temp << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
-
-	tempcx = push1; /* pop cx */
-	j += 2;
-	temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
-	tempcx -= temp;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp);
+	tempcx = (pVBInfo->VGAVT - 1);
 	temp = tempcx & 0x00FF;
-	temp = temp << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
-
-	tempcx -= 11;
 
-	if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
-		tempax = XGI_GetVGAHT2(pVBInfo);
-		tempcx = tempax - 1;
+	if (pVBInfo->IF_DEF_CH7005 == 1) {
+		if (pVBInfo->VBInfo & 0x0C)
+			temp--;
 	}
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x2E, temp);
-
-	tempbx = pVBInfo->VDE;
 
-	if (pVBInfo->VGAVDE == 360)
-		tempbx = 746;
-	if (pVBInfo->VGAVDE == 375)
-		tempbx = 746;
-	if (pVBInfo->VGAVDE == 405)
-		tempbx = 853;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
+	tempbx = pVBInfo->VGAVDE - 1;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, temp);
+	temp = ((tempbx & 0xFF00) << 3) >> 8;
+	temp |= ((tempcx & 0xFF00) >> 8);
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x12, temp);
 
-	if (pVBInfo->VBInfo & SetCRT2ToTV) {
-		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
-			if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
-					| SetYPbPrMode750p)))
-				tempbx = tempbx >> 1;
-		} else
-			tempbx = tempbx >> 1;
-	}
+	tempax = pVBInfo->VGAVDE;
+	tempbx = pVBInfo->VGAVDE;
+	tempcx = pVBInfo->VGAVT;
+	tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+	tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
 
-	tempbx -= 2;
-	temp = tempbx & 0x00FF;
+	if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+		tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
+		temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		if (pVBInfo->VBType & VB_XGI301LV) {
-			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
-				if (pVBInfo->VBInfo & SetInSlaveMode) {
-					if (ModeNo == 0x2f)
-						temp += 1;
-				}
-			}
-		} else {
-			if (pVBInfo->VBInfo & SetInSlaveMode) {
-				if (ModeNo == 0x2f)
-					temp += 1;
-			}
-		}
-	}
+		if (temp & 0x04)
+			tempbx |= 0x0100;
 
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x2F, temp);
+		if (temp & 0x080)
+			tempbx |= 0x0200;
 
-	temp = (tempcx & 0xFF00) >> 8;
-	temp |= ((tempbx & 0xFF00) >> 8) << 6;
+		temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
 
-	if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
-		if (pVBInfo->VBType & VB_XGI301LV) {
-			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
-				temp |= 0x10;
+		if (temp & 0x08)
+			tempbx |= 0x0400;
 
-				if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
-					temp |= 0x20;
-			}
-		} else {
-			temp |= 0x10;
-			if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
-				temp |= 0x20;
-		}
+		temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
+		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
 	}
 
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x30, temp);
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
+	temp = ((tempbx & 0xFF00) >> 8) << 4;
+	temp = ((tempcx & 0x000F) | (temp));
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x11, temp);
+	tempax = 0;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
-		tempbx = pVBInfo->VDE;
-		tempcx = tempbx - 2;
+	if (modeflag & DoubleScanMode)
+		tempax |= 0x80;
 
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
-					| SetYPbPrMode750p)))
-				tempbx = tempbx >> 1;
-		}
+	if (modeflag & HalfDCLK)
+		tempax |= 0x40;
 
-		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
-			temp = 0;
-			if (tempcx & 0x0400)
-				temp |= 0x20;
+	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
+}
 
-			if (tempbx & 0x0400)
-				temp |= 0x40;
+static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
+{
+	unsigned long tempax, tempbx;
 
-			XGINew_SetReg1(pVBInfo->Part4Port, 0x10, temp);
-		}
+	tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
+			& 0xFFFF;
+	tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
+	tempax = (tempax * pVBInfo->HT) / tempbx;
 
-		temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x46, temp);
-		temp = (tempbx - 3) & 0x00FF;
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x47, temp);
-	}
+	return (unsigned short) tempax;
+}
 
-	tempbx = tempbx & 0x00FF;
+static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short RefreshRateTableIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
+			modeflag, CRT1Index;
 
-	if (!(modeflag & HalfDCLK)) {
-		tempcx = pVBInfo->VGAHDE;
-		if (tempcx >= pVBInfo->HDE) {
-			tempbx |= 0x2000;
-			tempax &= 0x00FF;
-		}
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index &= IndexMask;
 	}
 
-	tempcx = 0x0101;
+	if (!(pVBInfo->VBInfo & SetInSlaveMode))
+		return;
 
-	if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
-		if (pVBInfo->VGAHDE >= 1024) {
-			tempcx = 0x1920;
-			if (pVBInfo->VGAHDE >= 1280) {
-				tempcx = 0x1420;
-				tempbx = tempbx & 0xDFFF;
-			}
-		}
-	}
+	temp = 0xFF; /* set MAX HT */
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
+	/* if (modeflag & Charx8Dot) */
+	/*	tempcx = 0x08; */
+	/* else */
+	tempcx = 0x08;
 
-	if (!(tempbx & 0x2000)) {
-		if (modeflag & HalfDCLK)
-			tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
+	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+		modeflag |= Charx8Dot;
 
-		push1 = tempbx;
-		tempeax = pVBInfo->VGAHDE;
-		tempebx = (tempcx & 0xFF00) >> 8;
-		longtemp = tempeax * tempebx;
-		tempecx = tempcx & 0x00FF;
-		longtemp = longtemp / tempecx;
+	tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
 
-		/* 301b */
-		tempecx = 8 * 1024;
+	if (modeflag & HalfDCLK)
+		tempax = tempax >> 1;
 
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
-			tempecx = tempecx * 8;
-		}
+	tempax = (tempax / tempcx) - 1;
+	tempbx |= ((tempax & 0x00FF) << 8);
+	temp = tempax & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x04, temp);
 
-		longtemp = longtemp * tempecx;
-		tempecx = pVBInfo->HDE;
-		temp2 = longtemp % tempecx;
-		tempeax = longtemp / tempecx;
-		if (temp2 != 0)
-			tempeax += 1;
+	temp = (tempbx & 0xFF00) >> 8;
 
-		tempax = (unsigned short) tempeax;
+	if (pVBInfo->VBInfo & SetCRT2ToTV) {
+		if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+				| VB_XGI302LV | VB_XGI301C)))
+			temp += 2;
 
-		/* 301b */
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
-			tempcx = ((tempax & 0xFF00) >> 5) >> 8;
+		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+			if (pVBInfo->VBType & VB_XGI301LV) {
+				if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
+					if (resinfo == 7)
+						temp -= 2;
+				}
+			} else if (resinfo == 7) {
+				temp -= 2;
+			}
 		}
-		/* end 301b */
-
-		tempbx = push1;
-		tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
-				| (tempbx & 0x00FF));
-		tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
-				| (tempax & 0x00FF));
-		temp = (tempax & 0xFF00) >> 8;
-	} else {
-		temp = (tempax & 0x00FF) >> 8;
 	}
 
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x44, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
-	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
 
-	if (tempbx & 0x2000)
-		temp = 0;
+	if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
+		if (pVBInfo->VBInfo & SetCRT2ToTV)
+			tempax = pVBInfo->VGAHT;
+		else
+			tempax = XGI_GetVGAHT2(pVBInfo);
+	}
 
-	if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
-		temp |= 0x18;
+	if (tempax >= pVBInfo->VGAHT)
+		tempax = pVBInfo->VGAHT;
 
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
-	if (pVBInfo->TVInfo & SetPALTV) {
-		tempbx = 0x0382;
-		tempcx = 0x007e;
+	if (modeflag & HalfDCLK)
+		tempax = tempax >> 1;
+
+	tempax = (tempax / tempcx) - 5;
+	tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		temp = (tempbx & 0x00FF) - 1;
+		if (!(modeflag & HalfDCLK)) {
+			temp -= 6;
+			if (pVBInfo->TVInfo & TVSimuMode) {
+				temp -= 4;
+				if (ModeNo > 0x13)
+					temp -= 10;
+			}
+		}
 	} else {
-		tempbx = 0x0369;
-		tempcx = 0x0061;
-	}
+		/* tempcx = tempbx & 0x00FF ; */
+		tempbx = (tempbx & 0xFF00) >> 8;
+		tempcx = (tempcx + tempbx) >> 1;
+		temp = (tempcx & 0x00FF) + 2;
 
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x4b, temp);
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x4c, temp);
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			temp -= 1;
+			if (!(modeflag & HalfDCLK)) {
+				if ((modeflag & Charx8Dot)) {
+					temp += 4;
+					if (pVBInfo->VGAHDE >= 800)
+						temp -= 6;
+				}
+			}
+		} else {
+			if (!(modeflag & HalfDCLK)) {
+				temp -= 4;
+				if (pVBInfo->LCDResInfo != Panel1280x960) {
+					if (pVBInfo->VGAHDE >= 800) {
+						temp -= 7;
+						if (pVBInfo->ModeType
+								== ModeEGA) {
+							if (pVBInfo->VGAVDE
+									== 1024) {
+								temp += 15;
+								if (pVBInfo->LCDResInfo
+										!= Panel1280x1024) {
+									temp
+											+= 7;
+								}
+							}
+						}
 
-	temp = ((tempcx & 0xFF00) >> 8) & 0x03;
-	temp = temp << 2;
-	temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
+						if (pVBInfo->VGAHDE >= 1280) {
+							if (pVBInfo->LCDResInfo
+									!= Panel1280x960) {
+								if (pVBInfo->LCDInfo
+										& LCDNonExpanding) {
+									temp
+											+= 28;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
 
-	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-		temp |= 0x10;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
 
-		if (pVBInfo->TVInfo & SetYPbPrMode525p)
-			temp |= 0x20;
+	if (pVBInfo->VBInfo & SetCRT2ToTV) {
+		if (pVBInfo->TVInfo & TVSimuMode) {
+			if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo
+					== 0x11) || (ModeNo == 0x13) || (ModeNo
+					== 0x0F)) {
+				XGINew_SetReg1(pVBInfo->Part1Port, 0x07, 0x5b);
+				XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0x03);
+			}
 
-		if (pVBInfo->TVInfo & SetYPbPrMode750p)
-			temp |= 0x60;
-	}
+			if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
+				if (pVBInfo->TVInfo & SetNTSCTV) {
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x07, 0x2A);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x08, 0x61);
+				} else {
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x07, 0x2A);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x08, 0x41);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x0C, 0xF0);
+				}
+			}
 
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x4d, temp);
-	temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
+			if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo
+					== 0x07)) {
+				if (pVBInfo->TVInfo & SetNTSCTV) {
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x07, 0x54);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x08, 0x00);
+				} else {
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x07, 0x55);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x08, 0x00);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x0C, 0xF0);
+				}
+			}
 
-	if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
-		if (pVBInfo->TVInfo & NTSC1024x768) {
-			TimingPoint = XGI_NTSC1024AdjTime;
-			for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
-				XGINew_SetReg1(pVBInfo->Part2Port, i,
-						TimingPoint[j]);
+			if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo
+					== 0x0D) || (ModeNo == 0x50)) {
+				if (pVBInfo->TVInfo & SetNTSCTV) {
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x07, 0x30);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x08, 0x03);
+				} else {
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x07, 0x2f);
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x08, 0x02);
+				}
 			}
-			XGINew_SetReg1(pVBInfo->Part2Port, 0x43, 0x72);
 		}
 	}
 
-	/* [ycchen] 01/14/03 Modify for 301C PALM Support */
-	if (pVBInfo->VBType & VB_XGI301C) {
-		if (pVBInfo->TVInfo & SetPALMTV)
-			XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x08,
-					0x08); /* PALM Mode */
-	}
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
+	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
 
-	if (pVBInfo->TVInfo & SetPALMTV) {
-		tempax = (unsigned char) XGINew_GetReg1(pVBInfo->Part2Port,
-				0x01);
-		tempax--;
-		XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax);
+	tempbx = pVBInfo->VGAVT;
+	push1 = tempbx;
+	tempcx = 0x121;
+	tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
 
-		/* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
-		XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xEF);
-	}
+	if (tempbx == 357)
+		tempbx = 350;
+	if (tempbx == 360)
+		tempbx = 350;
+	if (tempbx == 375)
+		tempbx = 350;
+	if (tempbx == 405)
+		tempbx = 400;
+	if (tempbx == 525)
+		tempbx = 480;
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		if (!(pVBInfo->VBInfo & SetInSlaveMode))
-			XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, 0x00);
-	}
+	push2 = tempbx;
 
-	if (pVBInfo->VBInfo & SetCRT2ToTV)
-		return;
-}
+	if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+		if (pVBInfo->LCDResInfo == Panel1024x768) {
+			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+				if (tempbx == 350)
+					tempbx += 5;
+				if (tempbx == 480)
+					tempbx += 5;
+			}
+		}
+	}
+	tempbx--;
+	temp = tempbx & 0x00FF;
+	tempbx--;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
+	tempbx = push2;
+	tempbx--;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
 
-static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp,
-			tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
+	if (tempbx & 0x0100)
+		tempcx |= 0x0002;
 
-	struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
+	tempax = 0x000B;
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT1Index
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index &= IndexMask;
-	}
+	if (modeflag & DoubleScanMode)
+		tempax |= 0x08000;
 
-	if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
-		return;
+	if (tempbx & 0x0200)
+		tempcx |= 0x0040;
 
-	tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
+	temp = (tempax & 0xFF00) >> 8;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
 
-	if (XGI_IsLCDDualLink(pVBInfo))
-		tempbx = tempbx >> 1;
+	if (tempbx & 0x0400)
+		tempcx |= 0x0600;
 
-	tempbx -= 1;
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x2C, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
-	temp = 0x01;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
 
-	if (pVBInfo->LCDResInfo == Panel1280x1024) {
-		if (pVBInfo->ModeType == ModeEGA) {
-			if (pVBInfo->VGAHDE >= 1024) {
-				temp = 0x02;
-				if (pVBInfo->LCDInfo & LCDVESATiming)
-					temp = 0x01;
+	tempax = push1;
+	tempax -= tempbx; /* 0x0C Vertical Retrace Start */
+	tempax = tempax >> 2;
+	push1 = tempax; /* push ax */
+
+	if (resinfo != 0x09) {
+		tempax = tempax << 1;
+		tempbx += tempax;
+	}
+
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		if (pVBInfo->VBType & VB_XGI301LV) {
+			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+				tempbx -= 10;
+			} else {
+				if (pVBInfo->TVInfo & TVSimuMode) {
+					if (pVBInfo->TVInfo & SetPALTV) {
+						if (pVBInfo->VBType
+								& VB_XGI301LV) {
+							if (!(pVBInfo->TVInfo
+									& (SetYPbPrMode525p
+											| SetYPbPrMode750p
+											| SetYPbPrMode1080i)))
+								tempbx += 40;
+						} else {
+							tempbx += 40;
+						}
+					}
+				}
+			}
+		} else {
+			tempbx -= 10;
+		}
+	} else {
+		if (pVBInfo->TVInfo & TVSimuMode) {
+			if (pVBInfo->TVInfo & SetPALTV) {
+				if (pVBInfo->VBType & VB_XGI301LV) {
+					if (!(pVBInfo->TVInfo
+							& (SetYPbPrMode525p
+									| SetYPbPrMode750p
+									| SetYPbPrMode1080i)))
+						tempbx += 40;
+				} else {
+					tempbx += 40;
+				}
 			}
 		}
 	}
+	tempax = push1;
+	tempax = tempax >> 2;
+	tempax++;
+	tempax += tempbx;
+	push1 = tempax; /* push ax */
 
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, temp);
-	tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
-	push1 = tempbx;
+	if ((pVBInfo->TVInfo & SetPALTV)) {
+		if (tempbx <= 513) {
+			if (tempax >= 513)
+				tempbx = 513;
+		}
+	}
+
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
 	tempbx--;
 	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x03, temp);
-	temp = ((tempbx & 0xFF00) >> 8) & 0x07;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
 
-	tempcx = pVBInfo->VT - 1;
-	push2 = tempcx + 1;
-	temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x19, temp);
-	temp = (tempcx & 0xFF00) >> 8;
-	temp = temp << 5;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x1A, temp);
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
+	if (tempbx & 0x0100)
+		tempcx |= 0x0008;
 
-	/* Customized LCDB Des no add */
-	tempbx = 5;
-	LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
-			ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-	tempah = pVBInfo->LCDResInfo;
-	tempah &= PanelResInfo;
+	if (tempbx & 0x0200)
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
 
-	if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) {
-		tempbx = 1024;
-		tempcx = 768;
-	} else if ((tempah == Panel1280x1024) || (tempah == Panel1280x1024x75)) {
-		tempbx = 1280;
-		tempcx = 1024;
-	} else if (tempah == Panel1400x1050) {
-		tempbx = 1400;
-		tempcx = 1050;
-	} else {
-		tempbx = 1600;
-		tempcx = 1200;
-	}
+	tempbx++;
 
-	if (pVBInfo->LCDInfo & EnableScalingLCD) {
-		tempbx = pVBInfo->HDE;
-		tempcx = pVBInfo->VDE;
-	}
+	if (tempbx & 0x0100)
+		tempcx |= 0x0004;
 
-	pushbx = tempbx;
-	tempax = pVBInfo->VT;
-	pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
-	pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
-	pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
-	pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
-	tempbx = pVBInfo->LCDVDES;
-	tempcx += tempbx;
+	if (tempbx & 0x0200)
+		tempcx |= 0x0080;
 
-	if (tempcx >= tempax)
-		tempcx -= tempax; /* lcdvdes */
+	if (tempbx & 0x0400)
+		tempcx |= 0x0C00;
 
-	temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x05, temp);
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x06, temp);
-	tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
-	tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
-	tempah = tempch;
-	tempah = tempah << 3;
-	tempah |= tempbh;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x02, tempah);
+	tempbx = push1; /* pop ax */
+	temp = tempbx & 0x00FF;
+	temp &= 0x0F;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
 
-	/* getlcdsync() */
-	XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
-	tempcx = tempbx;
-	tempax = pVBInfo->VT;
-	tempbx = pVBInfo->LCDVRS;
+	if (tempbx & 0x0010)
+		tempcx |= 0x2000;
 
-	/* if (SetLCD_Info & EnableScalingLCD) */
-	tempcx += tempbx;
-	if (tempcx >= tempax)
-		tempcx -= tempax;
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
+	temp = (tempcx & 0x0FF00) >> 8;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
+	tempax = modeflag;
+	temp = (tempax & 0xFF00) >> 8;
 
-	temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x04, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	temp |= (tempcx & 0x000F);
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
-	tempcx = pushbx;
-	tempax = pVBInfo->HT;
-	tempbx = pVBInfo->LCDHDES;
-	tempbx &= 0x0FFF;
+	temp = (temp >> 1) & 0x09;
 
-	if (XGI_IsLCDDualLink(pVBInfo)) {
-		tempax = tempax >> 1;
-		tempbx = tempbx >> 1;
-		tempcx = tempcx >> 1;
-	}
+	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+		temp |= 0x01;
 
-	if (pVBInfo->VBType & VB_XGI302LV)
-		tempbx += 1;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
 
-	if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
-		tempbx += 1;
+	if (pVBInfo->LCDInfo & LCDRGB18Bit)
+		temp = 0x80;
+	else
+		temp = 0x00;
 
-	tempcx += tempbx;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
 
-	if (tempcx >= tempax)
-		tempcx -= tempax;
+	return;
+}
 
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
-	temp = ((tempbx & 0xFF00) >> 8) << 4;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x20, temp);
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
-	temp = (tempcx & 0xFF00) >> 8;
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x25, temp);
+static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
+		unsigned short RefreshRateTableIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
+			modeflag, resinfo, crt2crtc;
+	unsigned char *TimingPoint;
 
-	/* getlcdsync() */
-	XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
-	tempcx = tempax;
-	tempax = pVBInfo->HT;
-	tempbx = pVBInfo->LCDHRS;
-	/* if ( SetLCD_Info & EnableScalingLCD) */
-	if (XGI_IsLCDDualLink(pVBInfo)) {
-		tempax = tempax >> 1;
-		tempbx = tempbx >> 1;
-		tempcx = tempcx >> 1;
+	unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
+
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+		crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+		crt2crtc
+				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 	}
 
-	if (pVBInfo->VBType & VB_XGI302LV)
-		tempbx += 1;
+	tempax = 0;
+
+	if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
+		tempax |= 0x0800;
 
-	tempcx += tempbx;
+	if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+		tempax |= 0x0400;
 
-	if (tempcx >= tempax)
-		tempcx -= tempax;
+	if (pVBInfo->VBInfo & SetCRT2ToSCART)
+		tempax |= 0x0200;
 
-	temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x1C, temp);
+	if (!(pVBInfo->TVInfo & SetPALTV))
+		tempax |= 0x1000;
 
-	temp = (tempbx & 0xFF00) >> 8;
-	temp = temp << 4;
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
-	temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x21, temp);
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+		tempax |= 0x0100;
 
-	if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
-		if (pVBInfo->VGAVDE == 525) {
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-					| VB_XGI301LV | VB_XGI302LV
-					| VB_XGI301C)) {
-				temp = 0xC6;
-			} else
-				temp = 0xC4;
+	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+		tempax &= 0xfe00;
 
-			XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
-			XGINew_SetReg1(pVBInfo->Part2Port, 0x30, 0xB3);
-		}
+	tempax = (tempax & 0xff00) >> 8;
 
-		if (pVBInfo->VGAVDE == 420) {
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-					| VB_XGI301LV | VB_XGI302LV
-					| VB_XGI301C)) {
-				temp = 0x4F;
-			} else
-				temp = 0x4E;
-			XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
-		}
-	}
-}
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x0, tempax);
+	TimingPoint = pVBInfo->NTSCTiming;
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTap4Ptr */
-/* Input : */
-/* Output : di -> Tap4 Reg. Setting Pointer */
-/* Description : */
-/* --------------------------------------------------------------------- */
-static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short tempax, tempbx, i;
+	if (pVBInfo->TVInfo & SetPALTV)
+		TimingPoint = pVBInfo->PALTiming;
 
-	struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		TimingPoint = pVBInfo->HiTVExtTiming;
 
-	if (tempcx == 0) {
-		tempax = pVBInfo->VGAHDE;
-		tempbx = pVBInfo->HDE;
-	} else {
-		tempax = pVBInfo->VGAVDE;
-		tempbx = pVBInfo->VDE;
-	}
+		if (pVBInfo->VBInfo & SetInSlaveMode)
+			TimingPoint = pVBInfo->HiTVSt2Timing;
 
-	if (tempax < tempbx)
-		return &EnlargeTap4Timing[0];
-	else if (tempax == tempbx)
-		return &NoScaleTap4Timing[0]; /* 1:1 */
-	else
-		Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
+		if (pVBInfo->SetFlag & TVSimuMode)
+			TimingPoint = pVBInfo->HiTVSt1Timing;
 
-	if (pVBInfo->TVInfo & SetPALTV)
-		Tap4TimingPtr = PALTap4Timing;
+		if (!(modeflag & Charx8Dot))
+			TimingPoint = pVBInfo->HiTVTextTiming;
+	}
 
 	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
 		if (pVBInfo->TVInfo & SetYPbPrMode525i)
-			Tap4TimingPtr = YPbPr525iTap4Timing;
+			TimingPoint = pVBInfo->YPbPr525iTiming;
+
 		if (pVBInfo->TVInfo & SetYPbPrMode525p)
-			Tap4TimingPtr = YPbPr525pTap4Timing;
+			TimingPoint = pVBInfo->YPbPr525pTiming;
+
 		if (pVBInfo->TVInfo & SetYPbPrMode750p)
-			Tap4TimingPtr = YPbPr750pTap4Timing;
+			TimingPoint = pVBInfo->YPbPr750pTiming;
 	}
 
+	for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
+		XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]);
+
+	for (i = 0x39; i <= 0x45; i++, j++)
+		XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
+
+	if (pVBInfo->VBInfo & SetCRT2ToTV)
+		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
+
+	temp = pVBInfo->NewFlickerMode;
+	temp &= 0x80;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
+
 	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
-		Tap4TimingPtr = HiTVTap4Timing;
+		tempax = 950;
 
-	i = 0;
-	while (Tap4TimingPtr[i].DE != 0xFFFF) {
-		if (Tap4TimingPtr[i].DE == tempax)
-			break;
-		i++;
+	if (pVBInfo->TVInfo & SetPALTV)
+		tempax = 520;
+	else
+		tempax = 440;
+
+	if (pVBInfo->VDE <= tempax) {
+		tempax -= pVBInfo->VDE;
+		tempax = tempax >> 2;
+		tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+		push1 = tempax;
+		temp = (tempax & 0xFF00) >> 8;
+		temp += (unsigned short) TimingPoint[0];
+
+		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+				| VB_XGI302LV | VB_XGI301C)) {
+			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+					| SetCRT2ToSVIDEO | SetCRT2ToSCART
+					| SetCRT2ToYPbPr)) {
+				tempcx = pVBInfo->VGAHDE;
+				if (tempcx >= 1024) {
+					temp = 0x17; /* NTSC */
+					if (pVBInfo->TVInfo & SetPALTV)
+						temp = 0x19; /* PAL */
+				}
+			}
+		}
+
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
+		tempax = push1;
+		temp = (tempax & 0xFF00) >> 8;
+		temp += TimingPoint[1];
+
+		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+				| VB_XGI302LV | VB_XGI301C)) {
+			if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+					| SetCRT2ToSVIDEO | SetCRT2ToSCART
+					| SetCRT2ToYPbPr))) {
+				tempcx = pVBInfo->VGAHDE;
+				if (tempcx >= 1024) {
+					temp = 0x1D; /* NTSC */
+					if (pVBInfo->TVInfo & SetPALTV)
+						temp = 0x52; /* PAL */
+				}
+			}
+		}
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x02, temp);
 	}
-	return &Tap4TimingPtr[i];
-}
 
-static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
-{
-	unsigned short i, j;
+	/* 301b */
+	tempcx = pVBInfo->HT;
 
-	struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+	if (XGI_IsLCDDualLink(pVBInfo))
+		tempcx = tempcx >> 1;
 
-	if (!(pVBInfo->VBType & VB_XGI301C))
-		return;
+	tempcx -= 2;
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x1B, temp);
 
-#ifndef Tap4
-	XGINew_SetRegAND(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
-#else            /* Tap4 Setting */
+	temp = (tempcx & 0xFF00) >> 8;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
 
-	Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
-	for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
-		XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+	tempcx = pVBInfo->HT >> 1;
+	push1 = tempcx; /* push cx */
+	tempcx += 7;
 
-	if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
-		Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
-		for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
-			XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+		tempcx -= 4;
+
+	temp = tempcx & 0x00FF;
+	temp = temp << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x22, 0x0F, temp);
+
+	tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+	tempbx += tempcx;
+	push2 = tempbx;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x24, temp);
+	temp = (tempbx & 0xFF00) >> 8;
+	temp = temp << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp);
+
+	tempbx = push2;
+	tempbx = tempbx + 8;
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		tempbx = tempbx - 4;
+		tempcx = tempbx;
 	}
 
-	if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
-		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
-	else
-		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
-#endif
-}
+	temp = (tempbx & 0x00FF) << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x29, 0x0F, temp);
 
-static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short i;
-	unsigned char *tempdi;
-	unsigned short modeflag;
+	j += 2;
+	tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x27, temp);
+	temp = ((tempcx & 0xFF00) >> 8) << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp);
 
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+	tempcx += 8;
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+		tempcx -= 4;
 
-	XGINew_SetReg1(pVBInfo->Part3Port, 0x00, 0x00);
-	if (pVBInfo->TVInfo & SetPALTV) {
-		XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
-		XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
-	} else {
-		XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xF5);
-		XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xB7);
+	temp = tempcx & 0xFF;
+	temp = temp << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
+
+	tempcx = push1; /* pop cx */
+	j += 2;
+	temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+	tempcx -= temp;
+	temp = tempcx & 0x00FF;
+	temp = temp << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
+
+	tempcx -= 11;
+
+	if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+		tempax = XGI_GetVGAHT2(pVBInfo);
+		tempcx = tempax - 1;
 	}
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x2E, temp);
 
-	if (!(pVBInfo->VBInfo & SetCRT2ToTV))
-		return;
+	tempbx = pVBInfo->VDE;
 
-	if (pVBInfo->TVInfo & SetPALMTV) {
-		XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
-		XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
-		XGINew_SetReg1(pVBInfo->Part3Port, 0x3D, 0xA8);
+	if (pVBInfo->VGAVDE == 360)
+		tempbx = 746;
+	if (pVBInfo->VGAVDE == 375)
+		tempbx = 746;
+	if (pVBInfo->VGAVDE == 405)
+		tempbx = 853;
+
+	if (pVBInfo->VBInfo & SetCRT2ToTV) {
+		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+			if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
+					| SetYPbPrMode750p)))
+				tempbx = tempbx >> 1;
+		} else
+			tempbx = tempbx >> 1;
 	}
 
-	if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo
-			& SetCRT2ToYPbPr)) {
-		if (pVBInfo->TVInfo & SetYPbPrMode525i)
-			return;
+	tempbx -= 2;
+	temp = tempbx & 0x00FF;
 
-		tempdi = pVBInfo->HiTVGroup3Data;
-		if (pVBInfo->SetFlag & TVSimuMode) {
-			tempdi = pVBInfo->HiTVGroup3Simu;
-			if (!(modeflag & Charx8Dot))
-				tempdi = pVBInfo->HiTVGroup3Text;
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		if (pVBInfo->VBType & VB_XGI301LV) {
+			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+				if (pVBInfo->VBInfo & SetInSlaveMode) {
+					if (ModeNo == 0x2f)
+						temp += 1;
+				}
+			}
+		} else {
+			if (pVBInfo->VBInfo & SetInSlaveMode) {
+				if (ModeNo == 0x2f)
+					temp += 1;
+			}
 		}
+	}
 
-		if (pVBInfo->TVInfo & SetYPbPrMode525p)
-			tempdi = pVBInfo->Ren525pGroup3;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x2F, temp);
 
-		if (pVBInfo->TVInfo & SetYPbPrMode750p)
-			tempdi = pVBInfo->Ren750pGroup3;
+	temp = (tempcx & 0xFF00) >> 8;
+	temp |= ((tempbx & 0xFF00) >> 8) << 6;
 
-		for (i = 0; i <= 0x3E; i++)
-			XGINew_SetReg1(pVBInfo->Part3Port, i, tempdi[i]);
+	if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
+		if (pVBInfo->VBType & VB_XGI301LV) {
+			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+				temp |= 0x10;
 
-		if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
-			if (pVBInfo->TVInfo & SetYPbPrMode525p)
-				XGINew_SetReg1(pVBInfo->Part3Port, 0x28, 0x3f);
+				if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+					temp |= 0x20;
+			}
+		} else {
+			temp |= 0x10;
+			if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+				temp |= 0x20;
 		}
 	}
-	return;
-} /* {end of XGI_SetGroup3} */
 
-static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x30, temp);
 
-	unsigned long tempebx, tempeax, templong;
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
+		tempbx = pVBInfo->VDE;
+		tempcx = tempbx - 2;
 
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
+					| SetYPbPrMode750p)))
+				tempbx = tempbx >> 1;
+		}
 
-	temp = pVBInfo->RVBHCFACT;
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x13, temp);
+		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+			temp = 0;
+			if (tempcx & 0x0400)
+				temp |= 0x20;
 
-	tempbx = pVBInfo->RVBHCMAX;
-	temp = tempbx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x14, temp);
-	temp2 = ((tempbx & 0xFF00) >> 8) << 7;
-	tempcx = pVBInfo->VGAHT - 1;
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x16, temp);
+			if (tempbx & 0x0400)
+				temp |= 0x40;
 
-	temp = ((tempcx & 0xFF00) >> 8) << 3;
-	temp2 |= temp;
+			XGINew_SetReg1(pVBInfo->Part4Port, 0x10, temp);
+		}
 
-	tempcx = pVBInfo->VGAVT - 1;
-	if (!(pVBInfo->VBInfo & SetCRT2ToTV))
-		tempcx -= 5;
+		temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x46, temp);
+		temp = (tempbx - 3) & 0x00FF;
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x47, temp);
+	}
 
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x17, temp);
-	temp = temp2 | ((tempcx & 0xFF00) >> 8);
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x15, temp);
-	XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08);
-	tempcx = pVBInfo->VBInfo;
-	tempbx = pVBInfo->VGAHDE;
+	tempbx = tempbx & 0x00FF;
 
-	if (modeflag & HalfDCLK)
-		tempbx = tempbx >> 1;
+	if (!(modeflag & HalfDCLK)) {
+		tempcx = pVBInfo->VGAHDE;
+		if (tempcx >= pVBInfo->HDE) {
+			tempbx |= 0x2000;
+			tempax &= 0x00FF;
+		}
+	}
 
-	if (XGI_IsLCDDualLink(pVBInfo))
-		tempbx = tempbx >> 1;
+	tempcx = 0x0101;
 
-	if (tempcx & SetCRT2ToHiVisionTV) {
-		temp = 0;
-		if (tempbx <= 1024)
-			temp = 0xA0;
-		if (tempbx == 1280)
-			temp = 0xC0;
-	} else if (tempcx & SetCRT2ToTV) {
-		temp = 0xA0;
-		if (tempbx <= 800)
-			temp = 0x80;
-	} else {
-		temp = 0x80;
-		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
-			temp = 0;
-			if (tempbx > 800)
-				temp = 0x60;
+	if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
+		if (pVBInfo->VGAHDE >= 1024) {
+			tempcx = 0x1920;
+			if (pVBInfo->VGAHDE >= 1280) {
+				tempcx = 0x1420;
+				tempbx = tempbx & 0xDFFF;
+			}
 		}
 	}
 
-	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
-		temp = 0x00;
-		if (pVBInfo->VGAHDE == 1280)
-			temp = 0x40;
-		if (pVBInfo->VGAHDE == 1024)
-			temp = 0x20;
-	}
-	XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
+	if (!(tempbx & 0x2000)) {
+		if (modeflag & HalfDCLK)
+			tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
 
-	tempebx = pVBInfo->VDE;
+		push1 = tempbx;
+		tempeax = pVBInfo->VGAHDE;
+		tempebx = (tempcx & 0xFF00) >> 8;
+		longtemp = tempeax * tempebx;
+		tempecx = tempcx & 0x00FF;
+		longtemp = longtemp / tempecx;
 
-	if (tempcx & SetCRT2ToHiVisionTV) {
-		if (!(temp & 0xE000))
-			tempbx = tempbx >> 1;
-	}
+		/* 301b */
+		tempecx = 8 * 1024;
 
-	tempcx = pVBInfo->RVBHRS;
-	temp = tempcx & 0x00FF;
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x18, temp);
+		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+				| VB_XGI302LV | VB_XGI301C)) {
+			tempecx = tempecx * 8;
+		}
 
-	tempeax = pVBInfo->VGAVDE;
-	tempcx |= 0x04000;
+		longtemp = longtemp * tempecx;
+		tempecx = pVBInfo->HDE;
+		temp2 = longtemp % tempecx;
+		tempeax = longtemp / tempecx;
+		if (temp2 != 0)
+			tempeax += 1;
 
-	if (tempeax <= tempebx) {
-		tempcx = (tempcx & (~0x4000));
-		tempeax = pVBInfo->VGAVDE;
-	} else {
-		tempeax -= tempebx;
-	}
+		tempax = (unsigned short) tempeax;
 
-	templong = (tempeax * 256 * 1024) % tempebx;
-	tempeax = (tempeax * 256 * 1024) / tempebx;
-	tempebx = tempeax;
+		/* 301b */
+		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+				| VB_XGI302LV | VB_XGI301C)) {
+			tempcx = ((tempax & 0xFF00) >> 5) >> 8;
+		}
+		/* end 301b */
 
-	if (templong != 0)
-		tempebx++;
+		tempbx = push1;
+		tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
+				| (tempbx & 0x00FF));
+		tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
+				| (tempax & 0x00FF));
+		temp = (tempax & 0xFF00) >> 8;
+	} else {
+		temp = (tempax & 0x00FF) >> 8;
+	}
 
-	temp = (unsigned short) (tempebx & 0x000000FF);
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x1B, temp);
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x44, temp);
+	temp = (tempbx & 0xFF00) >> 8;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
+	temp = tempcx & 0x00FF;
 
-	temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x1A, temp);
-	tempbx = (unsigned short) (tempebx >> 16);
-	temp = tempbx & 0x00FF;
-	temp = temp << 4;
-	temp |= ((tempcx & 0xFF00) >> 8);
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x19, temp);
+	if (tempbx & 0x2000)
+		temp = 0;
 
-	/* 301b */
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		temp = 0x0028;
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x1C, temp);
-		tempax = pVBInfo->VGAHDE;
-		if (modeflag & HalfDCLK)
-			tempax = tempax >> 1;
+	if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+		temp |= 0x18;
 
-		if (XGI_IsLCDDualLink(pVBInfo))
-			tempax = tempax >> 1;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
+	if (pVBInfo->TVInfo & SetPALTV) {
+		tempbx = 0x0382;
+		tempcx = 0x007e;
+	} else {
+		tempbx = 0x0369;
+		tempcx = 0x0061;
+	}
 
-		/* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
-		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
-			if (tempax > 800)
-				tempax -= 800;
-		} else {
-			if (pVBInfo->VGAHDE > 800) {
-				if (pVBInfo->VGAHDE == 1024)
-					tempax = (tempax * 25 / 32) - 1;
-				else
-					tempax = (tempax * 20 / 32) - 1;
-			}
-		}
-		tempax -= 1;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x4b, temp);
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x4c, temp);
 
-		/*
-		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
-			if (pVBInfo->VBType & VB_XGI301LV) {
-				if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i))) {
-					if (pVBInfo->VGAHDE > 800) {
-						if (pVBInfo->VGAHDE == 1024)
-							tempax = (tempax * 25 / 32) - 1;
-						else
-							tempax = (tempax * 20 / 32) - 1;
-					}
-				}
-			} else {
-				if (pVBInfo->VGAHDE > 800) {
-					if (pVBInfo->VGAHDE == 1024)
-						tempax = (tempax * 25 / 32) - 1;
-					else
-						tempax = (tempax * 20 / 32) - 1;
-				}
-			}
-		}
-		*/
+	temp = ((tempcx & 0xFF00) >> 8) & 0x03;
+	temp = temp << 2;
+	temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
 
-		temp = (tempax & 0xFF00) >> 8;
-		temp = ((temp & 0x0003) << 4);
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x1E, temp);
-		temp = (tempax & 0x00FF);
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x1D, temp);
+	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+		temp |= 0x10;
 
-		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
-			if (pVBInfo->VGAHDE > 800)
-				XGINew_SetRegOR(pVBInfo->Part4Port, 0x1E, 0x08);
+		if (pVBInfo->TVInfo & SetYPbPrMode525p)
+			temp |= 0x20;
 
-		}
-		temp = 0x0036;
+		if (pVBInfo->TVInfo & SetYPbPrMode750p)
+			temp |= 0x60;
+	}
 
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			if (!(pVBInfo->TVInfo & (NTSC1024x768
-					| SetYPbPrMode525p | SetYPbPrMode750p
-					| SetYPbPrMode1080i))) {
-				temp |= 0x0001;
-				if ((pVBInfo->VBInfo & SetInSlaveMode)
-						&& (!(pVBInfo->TVInfo
-								& TVSimuMode)))
-					temp &= (~0x0001);
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x4d, temp);
+	temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
+
+	if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
+		if (pVBInfo->TVInfo & NTSC1024x768) {
+			TimingPoint = XGI_NTSC1024AdjTime;
+			for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
+				XGINew_SetReg1(pVBInfo->Part2Port, i,
+						TimingPoint[j]);
 			}
+			XGINew_SetReg1(pVBInfo->Part2Port, 0x43, 0x72);
 		}
+	}
 
-		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
-		tempbx = pVBInfo->HT;
-		if (XGI_IsLCDDualLink(pVBInfo))
-			tempbx = tempbx >> 1;
-		tempbx = (tempbx >> 1) - 2;
-		temp = ((tempbx & 0x0700) >> 8) << 3;
-		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
-		temp = tempbx & 0x00FF;
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x22, temp);
+	/* [ycchen] 01/14/03 Modify for 301C PALM Support */
+	if (pVBInfo->VBType & VB_XGI301C) {
+		if (pVBInfo->TVInfo & SetPALMTV)
+			XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x08,
+					0x08); /* PALM Mode */
 	}
-	/* end 301b */
 
-	if (pVBInfo->ISXPDOS == 0)
-		XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex,
-				pVBInfo);
-}
+	if (pVBInfo->TVInfo & SetPALMTV) {
+		tempax = (unsigned char) XGINew_GetReg1(pVBInfo->Part2Port,
+				0x01);
+		tempax--;
+		XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax);
 
-static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short Pindex, Pdata;
+		/* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
+		XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xEF);
+	}
 
-	Pindex = pVBInfo->Part5Port;
-	Pdata = pVBInfo->Part5Port + 1;
-	if (pVBInfo->ModeType == ModeVGA) {
-		if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
-				| CRT2DisplayFlag))) {
-			XGINew_EnableCRT2(pVBInfo);
-			/* LoadDAC2(pVBInfo->Part5Port, ModeNo, ModeIdIndex); */
-		}
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		if (!(pVBInfo->VBInfo & SetInSlaveMode))
+			XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, 0x00);
 	}
-	return;
+
+	if (pVBInfo->VBInfo & SetCRT2ToTV)
+		return;
 }
 
-static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
-		unsigned short ModeIdIndex,
+static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		unsigned short RefreshRateTableIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table;
-
-	struct XGI330_LCDDataTablStruct *tempdi = NULL;
+	unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp,
+			tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
 
-	tempbx = BX;
+	struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
 
 	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-		tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+		CRT1Index
+				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index &= IndexMask;
 	}
 
-	tempal = tempal & 0x0f;
+	if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+		return;
 
-	if (tempbx <= 1) { /* ExpLink */
-		if (ModeNo <= 0x13) {
-			tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
-		} else {
-			tempal
-					= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		}
+	tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
 
-		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-			if (ModeNo <= 0x13)
-				tempal
-						= pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
-			else
-				tempal
-						= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
-		}
+	if (XGI_IsLCDDualLink(pVBInfo))
+		tempbx = tempbx >> 1;
 
-		if (tempbx & 0x01)
-			tempal = (tempal >> 4);
+	tempbx -= 1;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x2C, temp);
+	temp = (tempbx & 0xFF00) >> 8;
+	temp = temp << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
+	temp = 0x01;
 
-		tempal = (tempal & 0x0f);
+	if (pVBInfo->LCDResInfo == Panel1280x1024) {
+		if (pVBInfo->ModeType == ModeEGA) {
+			if (pVBInfo->VGAHDE >= 1024) {
+				temp = 0x02;
+				if (pVBInfo->LCDInfo & LCDVESATiming)
+					temp = 0x01;
+			}
+		}
 	}
 
-	tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
-
-	if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
-		if ((tempbx == 5) || (tempbx) == 7)
-			tempcx = LCDDesDataLen2;
-		else if ((tempbx == 3) || (tempbx == 8))
-			tempcx = LVDSDesDataLen2;
-	}
-	/* mov di, word ptr cs:LCDDataList[bx] */
-	/* tempdi = pVideoMemory[LCDDataList + tempbx * 2] | (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, temp);
+	tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
+	push1 = tempbx;
+	tempbx--;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x03, temp);
+	temp = ((tempbx & 0xFF00) >> 8) & 0x07;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
 
-	switch (tempbx) {
-	case 0:
-		tempdi = XGI_EPLLCDCRT1Ptr_H;
-		break;
-	case 1:
-		tempdi = XGI_EPLLCDCRT1Ptr_V;
-		break;
-	case 2:
-		tempdi = XGI_EPLLCDDataPtr;
-		break;
-	case 3:
-		tempdi = XGI_EPLLCDDesDataPtr;
-		break;
-	case 4:
-		tempdi = XGI_LCDDataTable;
-		break;
-	case 5:
-		tempdi = XGI_LCDDesDataTable;
-		break;
-	case 6:
-		tempdi = XGI_EPLCHLCDRegPtr;
-		break;
-	case 7:
-	case 8:
-	case 9:
-		tempdi = NULL;
-		break;
-	default:
-		break;
-	}
+	tempcx = pVBInfo->VT - 1;
+	push2 = tempcx + 1;
+	temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x19, temp);
+	temp = (tempcx & 0xFF00) >> 8;
+	temp = temp << 5;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x1A, temp);
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
 
-	if (tempdi == NULL) /* OEMUtil */
-		return NULL;
+	/* Customized LCDB Des no add */
+	tempbx = 5;
+	LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+			ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+	tempah = pVBInfo->LCDResInfo;
+	tempah &= PanelResInfo;
 
-	table = tempbx;
-	i = 0;
+	if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) {
+		tempbx = 1024;
+		tempcx = 768;
+	} else if ((tempah == Panel1280x1024) || (tempah == Panel1280x1024x75)) {
+		tempbx = 1280;
+		tempcx = 1024;
+	} else if (tempah == Panel1400x1050) {
+		tempbx = 1400;
+		tempcx = 1050;
+	} else {
+		tempbx = 1600;
+		tempcx = 1200;
+	}
 
-	while (tempdi[i].PANELID != 0xff) {
-		tempdx = pVBInfo->LCDResInfo;
-		if (tempbx & 0x0080) { /* OEMUtil */
-			tempbx &= (~0x0080);
-			tempdx = pVBInfo->LCDTypeInfo;
-		}
+	if (pVBInfo->LCDInfo & EnableScalingLCD) {
+		tempbx = pVBInfo->HDE;
+		tempcx = pVBInfo->VDE;
+	}
 
-		if (pVBInfo->LCDInfo & EnableScalingLCD)
-			tempdx &= (~PanelResInfo);
+	pushbx = tempbx;
+	tempax = pVBInfo->VT;
+	pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
+	pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
+	pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
+	pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
+	tempbx = pVBInfo->LCDVDES;
+	tempcx += tempbx;
 
-		if (tempdi[i].PANELID == tempdx) {
-			tempbx = tempdi[i].MASK;
-			tempdx = pVBInfo->LCDInfo;
+	if (tempcx >= tempax)
+		tempcx -= tempax; /* lcdvdes */
 
-			if (ModeNo <= 0x13) /* alan 09/10/2003 */
-				tempdx |= SetLCDStdMode;
+	temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x05, temp);
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x06, temp);
+	tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
+	tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
+	tempah = tempch;
+	tempah = tempah << 3;
+	tempah |= tempbh;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x02, tempah);
 
-			if (modeflag & HalfDCLK)
-				tempdx |= SetLCDLowResolution;
+	/* getlcdsync() */
+	XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+	tempcx = tempbx;
+	tempax = pVBInfo->VT;
+	tempbx = pVBInfo->LCDVRS;
 
-			tempbx &= tempdx;
-			if (tempbx == tempdi[i].CAP)
-				break;
-		}
-		i++;
-	}
+	/* if (SetLCD_Info & EnableScalingLCD) */
+	tempcx += tempbx;
+	if (tempcx >= tempax)
+		tempcx -= tempax;
 
-	if (table == 0) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_LVDSCRT11024x768_1_H[tempal];
-			break;
-		case 1:
-			return &XGI_LVDSCRT11024x768_2_H[tempal];
-			break;
-		case 2:
-			return &XGI_LVDSCRT11280x1024_1_H[tempal];
-			break;
-		case 3:
-			return &XGI_LVDSCRT11280x1024_2_H[tempal];
-			break;
-		case 4:
-			return &XGI_LVDSCRT11400x1050_1_H[tempal];
-			break;
-		case 5:
-			return &XGI_LVDSCRT11400x1050_2_H[tempal];
-			break;
-		case 6:
-			return &XGI_LVDSCRT11600x1200_1_H[tempal];
-			break;
-		case 7:
-			return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
-			break;
-		case 8:
-			return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
-			break;
-		case 9:
-			return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
-			break;
-		case 10:
-			return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
-			break;
-		default:
-			break;
-		}
-	} else if (table == 1) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_LVDSCRT11024x768_1_V[tempal];
-			break;
-		case 1:
-			return &XGI_LVDSCRT11024x768_2_V[tempal];
-			break;
-		case 2:
-			return &XGI_LVDSCRT11280x1024_1_V[tempal];
-			break;
-		case 3:
-			return &XGI_LVDSCRT11280x1024_2_V[tempal];
-			break;
-		case 4:
-			return &XGI_LVDSCRT11400x1050_1_V[tempal];
-			break;
-		case 5:
-			return &XGI_LVDSCRT11400x1050_2_V[tempal];
-			break;
-		case 6:
-			return &XGI_LVDSCRT11600x1200_1_V[tempal];
-			break;
-		case 7:
-			return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
-			break;
-		case 8:
-			return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
-			break;
-		case 9:
-			return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
-			break;
-		case 10:
-			return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
-			break;
-		default:
-			break;
-		}
-	} else if (table == 2) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_LVDS1024x768Data_1[tempal];
-			break;
-		case 1:
-			return &XGI_LVDS1024x768Data_2[tempal];
-			break;
-		case 2:
-			return &XGI_LVDS1280x1024Data_1[tempal];
-			break;
-		case 3:
-			return &XGI_LVDS1280x1024Data_2[tempal];
-			break;
-		case 4:
-			return &XGI_LVDS1400x1050Data_1[tempal];
-			break;
-		case 5:
-			return &XGI_LVDS1400x1050Data_2[tempal];
-			break;
-		case 6:
-			return &XGI_LVDS1600x1200Data_1[tempal];
-			break;
-		case 7:
-			return &XGI_LVDSNoScalingData[tempal];
-			break;
-		case 8:
-			return &XGI_LVDS1024x768Data_1x75[tempal];
-			break;
-		case 9:
-			return &XGI_LVDS1024x768Data_2x75[tempal];
-			break;
-		case 10:
-			return &XGI_LVDS1280x1024Data_1x75[tempal];
-			break;
-		case 11:
-			return &XGI_LVDS1280x1024Data_2x75[tempal];
-			break;
-		case 12:
-			return &XGI_LVDSNoScalingDatax75[tempal];
-			break;
-		default:
-			break;
-		}
-	} else if (table == 3) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_LVDS1024x768Des_1[tempal];
-			break;
-		case 1:
-			return &XGI_LVDS1024x768Des_3[tempal];
-			break;
-		case 2:
-			return &XGI_LVDS1024x768Des_2[tempal];
-			break;
-		case 3:
-			return &XGI_LVDS1280x1024Des_1[tempal];
-			break;
-		case 4:
-			return &XGI_LVDS1280x1024Des_2[tempal];
-			break;
-		case 5:
-			return &XGI_LVDS1400x1050Des_1[tempal];
-			break;
-		case 6:
-			return &XGI_LVDS1400x1050Des_2[tempal];
-			break;
-		case 7:
-			return &XGI_LVDS1600x1200Des_1[tempal];
-			break;
-		case 8:
-			return &XGI_LVDSNoScalingDesData[tempal];
-			break;
-		case 9:
-			return &XGI_LVDS1024x768Des_1x75[tempal];
-			break;
-		case 10:
-			return &XGI_LVDS1024x768Des_3x75[tempal];
-			break;
-		case 11:
-			return &XGI_LVDS1024x768Des_2x75[tempal];
-			break;
-		case 12:
-			return &XGI_LVDS1280x1024Des_1x75[tempal];
-			break;
-		case 13:
-			return &XGI_LVDS1280x1024Des_2x75[tempal];
-			break;
-		case 14:
-			return &XGI_LVDSNoScalingDesDatax75[tempal];
-			break;
-		default:
-			break;
+	temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x04, temp);
+	temp = (tempbx & 0xFF00) >> 8;
+	temp = temp << 4;
+	temp |= (tempcx & 0x000F);
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
+	tempcx = pushbx;
+	tempax = pVBInfo->HT;
+	tempbx = pVBInfo->LCDHDES;
+	tempbx &= 0x0FFF;
+
+	if (XGI_IsLCDDualLink(pVBInfo)) {
+		tempax = tempax >> 1;
+		tempbx = tempbx >> 1;
+		tempcx = tempcx >> 1;
+	}
+
+	if (pVBInfo->VBType & VB_XGI302LV)
+		tempbx += 1;
+
+	if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
+		tempbx += 1;
+
+	tempcx += tempbx;
+
+	if (tempcx >= tempax)
+		tempcx -= tempax;
+
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
+	temp = ((tempbx & 0xFF00) >> 8) << 4;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x20, temp);
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
+	temp = (tempcx & 0xFF00) >> 8;
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x25, temp);
+
+	/* getlcdsync() */
+	XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+	tempcx = tempax;
+	tempax = pVBInfo->HT;
+	tempbx = pVBInfo->LCDHRS;
+	/* if ( SetLCD_Info & EnableScalingLCD) */
+	if (XGI_IsLCDDualLink(pVBInfo)) {
+		tempax = tempax >> 1;
+		tempbx = tempbx >> 1;
+		tempcx = tempcx >> 1;
+	}
+
+	if (pVBInfo->VBType & VB_XGI302LV)
+		tempbx += 1;
+
+	tempcx += tempbx;
+
+	if (tempcx >= tempax)
+		tempcx -= tempax;
+
+	temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x1C, temp);
+
+	temp = (tempbx & 0xFF00) >> 8;
+	temp = temp << 4;
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
+	temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x21, temp);
+
+	if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+		if (pVBInfo->VGAVDE == 525) {
+			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+					| VB_XGI301LV | VB_XGI302LV
+					| VB_XGI301C)) {
+				temp = 0xC6;
+			} else
+				temp = 0xC4;
+
+			XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
+			XGINew_SetReg1(pVBInfo->Part2Port, 0x30, 0xB3);
 		}
-	} else if (table == 4) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_ExtLCD1024x768Data[tempal];
-			break;
-		case 1:
-			return &XGI_StLCD1024x768Data[tempal];
-			break;
-		case 2:
-			return &XGI_CetLCD1024x768Data[tempal];
-			break;
-		case 3:
-			return &XGI_ExtLCD1280x1024Data[tempal];
-			break;
-		case 4:
-			return &XGI_StLCD1280x1024Data[tempal];
-			break;
-		case 5:
-			return &XGI_CetLCD1280x1024Data[tempal];
-			break;
-		case 6:
-			return &XGI_ExtLCD1400x1050Data[tempal];
-			break;
-		case 7:
-			return &XGI_StLCD1400x1050Data[tempal];
-			break;
-		case 8:
-			return &XGI_CetLCD1400x1050Data[tempal];
-			break;
-		case 9:
-			return &XGI_ExtLCD1600x1200Data[tempal];
-			break;
-		case 10:
-			return &XGI_StLCD1600x1200Data[tempal];
-			break;
-		case 11:
-			return &XGI_NoScalingData[tempal];
-			break;
-		case 12:
-			return &XGI_ExtLCD1024x768x75Data[tempal];
-			break;
-		case 13:
-			return &XGI_ExtLCD1024x768x75Data[tempal];
-			break;
-		case 14:
-			return &XGI_CetLCD1024x768x75Data[tempal];
-			break;
-		case 15:
-			return &XGI_ExtLCD1280x1024x75Data[tempal];
-			break;
-		case 16:
-			return &XGI_StLCD1280x1024x75Data[tempal];
-			break;
-		case 17:
-			return &XGI_CetLCD1280x1024x75Data[tempal];
-			break;
-		case 18:
-			return &XGI_NoScalingDatax75[tempal];
-			break;
-		default:
-			break;
+
+		if (pVBInfo->VGAVDE == 420) {
+			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+					| VB_XGI301LV | VB_XGI302LV
+					| VB_XGI301C)) {
+				temp = 0x4F;
+			} else
+				temp = 0x4E;
+			XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
 		}
-	} else if (table == 5) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_ExtLCDDes1024x768Data[tempal];
-			break;
-		case 1:
-			return &XGI_StLCDDes1024x768Data[tempal];
-			break;
-		case 2:
-			return &XGI_CetLCDDes1024x768Data[tempal];
-			break;
-		case 3:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_ExtLCDDLDes1280x1024Data[tempal];
-			else
-				return &XGI_ExtLCDDes1280x1024Data[tempal];
-			break;
-		case 4:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_StLCDDLDes1280x1024Data[tempal];
-			else
-				return &XGI_StLCDDes1280x1024Data[tempal];
-			break;
-		case 5:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_CetLCDDLDes1280x1024Data[tempal];
-			else
-				return &XGI_CetLCDDes1280x1024Data[tempal];
-			break;
-		case 6:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_ExtLCDDLDes1400x1050Data[tempal];
-			else
-				return &XGI_ExtLCDDes1400x1050Data[tempal];
-			break;
-		case 7:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_StLCDDLDes1400x1050Data[tempal];
-			else
-				return &XGI_StLCDDes1400x1050Data[tempal];
-			break;
-		case 8:
-			return &XGI_CetLCDDes1400x1050Data[tempal];
-			break;
-		case 9:
-			return &XGI_CetLCDDes1400x1050Data2[tempal];
-			break;
-		case 10:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_ExtLCDDLDes1600x1200Data[tempal];
-			else
-				return &XGI_ExtLCDDes1600x1200Data[tempal];
-			break;
-		case 11:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_StLCDDLDes1600x1200Data[tempal];
-			else
-				return &XGI_StLCDDes1600x1200Data[tempal];
-			break;
-		case 12:
-			return &XGI_NoScalingDesData[tempal];
-			break;
-		case 13:
-			return &XGI_ExtLCDDes1024x768x75Data[tempal];
-			break;
-		case 14:
-			return &XGI_StLCDDes1024x768x75Data[tempal];
-			break;
-		case 15:
-			return &XGI_CetLCDDes1024x768x75Data[tempal];
-			break;
-		case 16:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
-			else
-				return &XGI_ExtLCDDes1280x1024x75Data[tempal];
-			break;
-		case 17:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_StLCDDLDes1280x1024x75Data[tempal];
-			else
-				return &XGI_StLCDDes1280x1024x75Data[tempal];
-			break;
-		case 18:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
-				return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
-			else
-				return &XGI_CetLCDDes1280x1024x75Data[tempal];
-			break;
-		case 19:
-			return &XGI_NoScalingDesDatax75[tempal];
-			break;
-		default:
+	}
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTap4Ptr */
+/* Input : */
+/* Output : di -> Tap4 Reg. Setting Pointer */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempax, tempbx, i;
+
+	struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+
+	if (tempcx == 0) {
+		tempax = pVBInfo->VGAHDE;
+		tempbx = pVBInfo->HDE;
+	} else {
+		tempax = pVBInfo->VGAVDE;
+		tempbx = pVBInfo->VDE;
+	}
+
+	if (tempax < tempbx)
+		return &EnlargeTap4Timing[0];
+	else if (tempax == tempbx)
+		return &NoScaleTap4Timing[0]; /* 1:1 */
+	else
+		Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
+
+	if (pVBInfo->TVInfo & SetPALTV)
+		Tap4TimingPtr = PALTap4Timing;
+
+	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+		if (pVBInfo->TVInfo & SetYPbPrMode525i)
+			Tap4TimingPtr = YPbPr525iTap4Timing;
+		if (pVBInfo->TVInfo & SetYPbPrMode525p)
+			Tap4TimingPtr = YPbPr525pTap4Timing;
+		if (pVBInfo->TVInfo & SetYPbPrMode750p)
+			Tap4TimingPtr = YPbPr750pTap4Timing;
+	}
+
+	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+		Tap4TimingPtr = HiTVTap4Timing;
+
+	i = 0;
+	while (Tap4TimingPtr[i].DE != 0xFFFF) {
+		if (Tap4TimingPtr[i].DE == tempax)
 			break;
+		i++;
+	}
+	return &Tap4TimingPtr[i];
+}
+
+static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
+{
+	unsigned short i, j;
+
+	struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+
+	if (!(pVBInfo->VBType & VB_XGI301C))
+		return;
+
+#ifndef Tap4
+	XGINew_SetRegAND(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
+#else            /* Tap4 Setting */
+
+	Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
+	for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
+		XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+
+	if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
+		Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
+		for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
+			XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+	}
+
+	if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
+		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
+	else
+		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
+#endif
+}
+
+static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short i;
+	unsigned char *tempdi;
+	unsigned short modeflag;
+
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+
+	XGINew_SetReg1(pVBInfo->Part3Port, 0x00, 0x00);
+	if (pVBInfo->TVInfo & SetPALTV) {
+		XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
+		XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
+	} else {
+		XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xF5);
+		XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xB7);
+	}
+
+	if (!(pVBInfo->VBInfo & SetCRT2ToTV))
+		return;
+
+	if (pVBInfo->TVInfo & SetPALMTV) {
+		XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
+		XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
+		XGINew_SetReg1(pVBInfo->Part3Port, 0x3D, 0xA8);
+	}
+
+	if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo
+			& SetCRT2ToYPbPr)) {
+		if (pVBInfo->TVInfo & SetYPbPrMode525i)
+			return;
+
+		tempdi = pVBInfo->HiTVGroup3Data;
+		if (pVBInfo->SetFlag & TVSimuMode) {
+			tempdi = pVBInfo->HiTVGroup3Simu;
+			if (!(modeflag & Charx8Dot))
+				tempdi = pVBInfo->HiTVGroup3Text;
 		}
-	} else if (table == 6) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_CH7017LV1024x768[tempal];
-			break;
-		case 1:
-			return &XGI_CH7017LV1400x1050[tempal];
-			break;
-		default:
-			break;
+
+		if (pVBInfo->TVInfo & SetYPbPrMode525p)
+			tempdi = pVBInfo->Ren525pGroup3;
+
+		if (pVBInfo->TVInfo & SetYPbPrMode750p)
+			tempdi = pVBInfo->Ren750pGroup3;
+
+		for (i = 0; i <= 0x3E; i++)
+			XGINew_SetReg1(pVBInfo->Part3Port, i, tempdi[i]);
+
+		if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
+			if (pVBInfo->TVInfo & SetYPbPrMode525p)
+				XGINew_SetReg1(pVBInfo->Part3Port, 0x28, 0x3f);
 		}
 	}
-	return NULL;
-}
+	return;
+} /* {end of XGI_SetGroup3} */
 
-static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
-		unsigned short ModeIdIndex,
+static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
 		unsigned short RefreshRateTableIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short i, tempdx, tempbx, tempal, modeflag, table;
-	struct XGI330_TVDataTablStruct *tempdi = NULL;
+	unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
 
-	tempbx = BX;
+	unsigned long tempebx, tempeax, templong;
+
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+	else
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+
+	temp = pVBInfo->RVBHCFACT;
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x13, temp);
+
+	tempbx = pVBInfo->RVBHCMAX;
+	temp = tempbx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x14, temp);
+	temp2 = ((tempbx & 0xFF00) >> 8) << 7;
+	tempcx = pVBInfo->VGAHT - 1;
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x16, temp);
+
+	temp = ((tempcx & 0xFF00) >> 8) << 3;
+	temp2 |= temp;
+
+	tempcx = pVBInfo->VGAVT - 1;
+	if (!(pVBInfo->VBInfo & SetCRT2ToTV))
+		tempcx -= 5;
+
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x17, temp);
+	temp = temp2 | ((tempcx & 0xFF00) >> 8);
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x15, temp);
+	XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08);
+	tempcx = pVBInfo->VBInfo;
+	tempbx = pVBInfo->VGAHDE;
+
+	if (modeflag & HalfDCLK)
+		tempbx = tempbx >> 1;
+
+	if (XGI_IsLCDDualLink(pVBInfo))
+		tempbx = tempbx >> 1;
+
+	if (tempcx & SetCRT2ToHiVisionTV) {
+		temp = 0;
+		if (tempbx <= 1024)
+			temp = 0xA0;
+		if (tempbx == 1280)
+			temp = 0xC0;
+	} else if (tempcx & SetCRT2ToTV) {
+		temp = 0xA0;
+		if (tempbx <= 800)
+			temp = 0x80;
+	} else {
+		temp = 0x80;
+		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+			temp = 0;
+			if (tempbx > 800)
+				temp = 0x60;
+		}
+	}
+
+	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
+		temp = 0x00;
+		if (pVBInfo->VGAHDE == 1280)
+			temp = 0x40;
+		if (pVBInfo->VGAHDE == 1024)
+			temp = 0x20;
+	}
+	XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
+
+	tempebx = pVBInfo->VDE;
+
+	if (tempcx & SetCRT2ToHiVisionTV) {
+		if (!(temp & 0xE000))
+			tempbx = tempbx >> 1;
+	}
+
+	tempcx = pVBInfo->RVBHRS;
+	temp = tempcx & 0x00FF;
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x18, temp);
+
+	tempeax = pVBInfo->VGAVDE;
+	tempcx |= 0x04000;
+
+	if (tempeax <= tempebx) {
+		tempcx = (tempcx & (~0x4000));
+		tempeax = pVBInfo->VGAVDE;
+	} else {
+		tempeax -= tempebx;
+	}
+
+	templong = (tempeax * 256 * 1024) % tempebx;
+	tempeax = (tempeax * 256 * 1024) / tempebx;
+	tempebx = tempeax;
+
+	if (templong != 0)
+		tempebx++;
+
+	temp = (unsigned short) (tempebx & 0x000000FF);
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x1B, temp);
+
+	temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x1A, temp);
+	tempbx = (unsigned short) (tempebx >> 16);
+	temp = tempbx & 0x00FF;
+	temp = temp << 4;
+	temp |= ((tempcx & 0xFF00) >> 8);
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x19, temp);
+
+	/* 301b */
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		temp = 0x0028;
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x1C, temp);
+		tempax = pVBInfo->VGAHDE;
+		if (modeflag & HalfDCLK)
+			tempax = tempax >> 1;
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-		tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-	}
+		if (XGI_IsLCDDualLink(pVBInfo))
+			tempax = tempax >> 1;
 
-	tempal = tempal & 0x3f;
-	table = tempbx;
+		/* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
+		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+			if (tempax > 800)
+				tempax -= 800;
+		} else {
+			if (pVBInfo->VGAHDE > 800) {
+				if (pVBInfo->VGAHDE == 1024)
+					tempax = (tempax * 25 / 32) - 1;
+				else
+					tempax = (tempax * 20 / 32) - 1;
+			}
+		}
+		tempax -= 1;
 
-	switch (tempbx) {
-	case 0:
-		tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/
-		if (pVBInfo->IF_DEF_CH7007 == 1)
-			tempdi = XGI_EPLCHTVCRT1Ptr;
+		/*
+		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
+			if (pVBInfo->VBType & VB_XGI301LV) {
+				if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i))) {
+					if (pVBInfo->VGAHDE > 800) {
+						if (pVBInfo->VGAHDE == 1024)
+							tempax = (tempax * 25 / 32) - 1;
+						else
+							tempax = (tempax * 20 / 32) - 1;
+					}
+				}
+			} else {
+				if (pVBInfo->VGAHDE > 800) {
+					if (pVBInfo->VGAHDE == 1024)
+						tempax = (tempax * 25 / 32) - 1;
+					else
+						tempax = (tempax * 20 / 32) - 1;
+				}
+			}
+		}
+		*/
 
-		break;
-	case 1:
-		tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/
-		if (pVBInfo->IF_DEF_CH7007 == 1)
-			tempdi = XGI_EPLCHTVCRT1Ptr;
+		temp = (tempax & 0xFF00) >> 8;
+		temp = ((temp & 0x0003) << 4);
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x1E, temp);
+		temp = (tempax & 0x00FF);
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x1D, temp);
 
-		break;
-	case 2:
-		tempdi = XGI_EPLCHTVDataPtr;
-		break;
-	case 3:
-		tempdi = NULL;
-		break;
-	case 4:
-		tempdi = XGI_TVDataTable;
-		break;
-	case 5:
-		tempdi = NULL;
-		break;
-	case 6:
-		tempdi = XGI_EPLCHTVRegPtr;
-		break;
-	default:
-		break;
-	}
+		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
+			if (pVBInfo->VGAHDE > 800)
+				XGINew_SetRegOR(pVBInfo->Part4Port, 0x1E, 0x08);
 
-	if (tempdi == NULL) /* OEMUtil */
-		return NULL;
+		}
+		temp = 0x0036;
 
-	tempdx = pVBInfo->TVInfo;
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			if (!(pVBInfo->TVInfo & (NTSC1024x768
+					| SetYPbPrMode525p | SetYPbPrMode750p
+					| SetYPbPrMode1080i))) {
+				temp |= 0x0001;
+				if ((pVBInfo->VBInfo & SetInSlaveMode)
+						&& (!(pVBInfo->TVInfo
+								& TVSimuMode)))
+					temp &= (~0x0001);
+			}
+		}
 
-	if (pVBInfo->VBInfo & SetInSlaveMode)
-		tempdx = tempdx | SetTVLockMode;
+		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
+		tempbx = pVBInfo->HT;
+		if (XGI_IsLCDDualLink(pVBInfo))
+			tempbx = tempbx >> 1;
+		tempbx = (tempbx >> 1) - 2;
+		temp = ((tempbx & 0x0700) >> 8) << 3;
+		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
+		temp = tempbx & 0x00FF;
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x22, temp);
+	}
+	/* end 301b */
 
-	if (modeflag & HalfDCLK)
-		tempdx = tempdx | SetTVLowResolution;
+	if (pVBInfo->ISXPDOS == 0)
+		XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+				pVBInfo);
+}
 
-	i = 0;
+static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
+{
+	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
+}
 
-	while (tempdi[i].MASK != 0xffff) {
-		if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
-			break;
-		i++;
-	}
+static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short Pindex, Pdata;
 
-	if (table == 0x00) { /* 07/05/22 */
-	} else if (table == 0x01) {
-	} else if (table == 0x04) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_ExtPALData[tempal];
-			break;
-		case 1:
-			return &XGI_ExtNTSCData[tempal];
-			break;
-		case 2:
-			return &XGI_StPALData[tempal];
-			break;
-		case 3:
-			return &XGI_StNTSCData[tempal];
-			break;
-		case 4:
-			return &XGI_ExtHiTVData[tempal];
-			break;
-		case 5:
-			return &XGI_St2HiTVData[tempal];
-			break;
-		case 6:
-			return &XGI_ExtYPbPr525iData[tempal];
-			break;
-		case 7:
-			return &XGI_ExtYPbPr525pData[tempal];
-			break;
-		case 8:
-			return &XGI_ExtYPbPr750pData[tempal];
-			break;
-		case 9:
-			return &XGI_StYPbPr525iData[tempal];
-			break;
-		case 10:
-			return &XGI_StYPbPr525pData[tempal];
-			break;
-		case 11:
-			return &XGI_StYPbPr750pData[tempal];
-			break;
-		case 12: /* avoid system hang */
-			return &XGI_ExtNTSCData[tempal];
-			break;
-		case 13:
-			return &XGI_St1HiTVData[tempal];
-			break;
-		default:
-			break;
-		}
-	} else if (table == 0x02) {
-		switch (tempdi[i].DATAPTR) {
-		case 0:
-			return &XGI_CHTVUNTSCData[tempal];
-			break;
-		case 1:
-			return &XGI_CHTVONTSCData[tempal];
-			break;
-		case 2:
-			return &XGI_CHTVUPALData[tempal];
-			break;
-		case 3:
-			return &XGI_CHTVOPALData[tempal];
-			break;
-		default:
-			break;
+	Pindex = pVBInfo->Part5Port;
+	Pdata = pVBInfo->Part5Port + 1;
+	if (pVBInfo->ModeType == ModeVGA) {
+		if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
+				| CRT2DisplayFlag))) {
+			XGINew_EnableCRT2(pVBInfo);
+			/* LoadDAC2(pVBInfo->Part5Port, ModeNo, ModeIdIndex); */
 		}
-	} else if (table == 0x06) {
 	}
-	return NULL;
+	return;
 }
 
 /* --------------------------------------------------------------------- */
@@ -6680,69 +6376,12 @@ static void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBI
 static void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl,
 		struct vb_device_info *pVBInfo)
 {
-	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
-		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x26, tempbl, tempah);
-	else
-		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x11, tempbl, tempah);
-}
-
-static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
-{
-	unsigned char ujRet = 0;
-	unsigned char i = 0;
-
-	for (i = 0; i < 8; i++) {
-		ujRet = ujRet << 1;
-		/* ujRet |= GETBITS(ujDate >> i, 0:0); */
-		ujRet |= (ujDate >> i) & 1;
-	}
-
-	return ujRet;
-}
-
-/*----------------------------------------------------------------------------*/
-/* output                                                                     */
-/*      bl[5] : LVDS signal                                                   */
-/*      bl[1] : LVDS backlight                                                */
-/*      bl[0] : LVDS VDD                                                      */
-/*----------------------------------------------------------------------------*/
-static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
-{
-	unsigned char CR4A, temp;
-
-	CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
-	XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
-
-	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
-
-	temp = XG21GPIODataTransfer(temp);
-	temp &= 0x23;
-	XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
-	return temp;
-}
-
-/*----------------------------------------------------------------------------*/
-/* output                                                                     */
-/*      bl[5] : LVDS signal                                                   */
-/*      bl[1] : LVDS backlight                                                */
-/*      bl[0] : LVDS VDD                                                      */
-/*----------------------------------------------------------------------------*/
-static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
-{
-	unsigned char CR4A, CRB4, temp;
-
-	CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
-	XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
-
-	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
-
-	temp &= 0x0C;
-	temp >>= 2;
-	XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
-	CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4);
-	temp |= ((CRB4 & 0x04) << 3);
-	return temp;
+	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x26, tempbl, tempah);
+	else
+		XGINew_SetRegANDOR(pVBInfo->P3c4, 0x11, tempbl, tempah);
 }
+
 /*----------------------------------------------------------------------------*/
 /* input                                                                      */
 /*      bl[5] : 1;LVDS signal on                                              */
@@ -7386,453 +7025,575 @@ static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo)
 	if (tempah & 0x01) /* Chk LCDB Mode */
 		return 1;
 
-	return 0;
+	return 0;
+}
+
+void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempax, tempbx, tempah = 0, tempbl = 0;
+
+	if (pVBInfo->SetFlag == Win9xDOSMode)
+		return;
+
+	if (HwDeviceExtension->jChipType < XG40) {
+		if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+				|| (XGI_DisableChISLCD(pVBInfo))) {
+			if (!XGI_IsLCDON(pVBInfo)) {
+				if (pVBInfo->LCDInfo & SetPWDEnable)
+					XGI_EnablePWD(pVBInfo);
+				else {
+					pVBInfo->LCDInfo &= ~SetPWDEnable;
+					XGI_DisablePWD(pVBInfo);
+					if (pVBInfo->VBType & (VB_XGI301LV
+							| VB_XGI302LV
+							| VB_XGI301C)) {
+						tempbx = 0xFE; /* not 01h */
+						tempax = 0;
+					} else {
+						tempbx = 0xF7; /* not 08h */
+						tempax = 0x08;
+					}
+					XGI_SetPanelPower(tempax, tempbx,
+							pVBInfo);
+					XGI_SetPanelDelay(3, pVBInfo);
+				}
+			} /* end if (!XGI_IsLCDON(pVBInfo)) */
+		}
+	}
+
+	/*
+	if (CH7017) {
+		if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) {
+			if (!XGI_IsLCDON(pVBInfo)) {
+				if (DISCHARGE) {
+					tempbx = XGINew_GetCH7005(0x61);
+					if (tempbx < 0x01) // first time we power up
+						XGINew_SetCH7005(0x0066); // and disable power sequence
+					else
+						XGINew_SetCH7005(0x5f66); // leave VDD on - disable power
+				}
+			}
+		}
+	}
+	*/
+
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		tempah = 0x3F;
+		if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
+			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+					tempah = 0x7F; /* Disable Channel A */
+					if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+						tempah = 0xBF; /* Disable Channel B */
+
+					if (pVBInfo->SetFlag & DisableChB)
+						tempah &= 0xBF; /* force to disable Cahnnel */
+
+					if (pVBInfo->SetFlag & DisableChA)
+						tempah &= 0x7F; /* Force to disable Channel B */
+				}
+			}
+		}
+
+		XGINew_SetRegAND(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
+
+		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+			if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+					|| (XGI_DisableChISLCD(pVBInfo))
+					|| (XGI_IsLCDON(pVBInfo)))
+				XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
+		}
+
+		if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
+				& (DisableCRT2Display | SetCRT2ToLCDA
+						| SetSimuScanMode))) {
+			if (pVBInfo->SetFlag & GatingCRT)
+				XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
+			XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+		}
+
+		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+			if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
+					& SetCRT2ToLCDA))
+				XGINew_SetRegAND(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
+		}
+
+		XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
+
+		if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
+			XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xdf);
+
+		if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
+				& (DisableCRT2Display | SetSimuScanMode))
+				|| ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+						&& (pVBInfo->VBInfo
+								& (SetCRT2ToRAMDAC
+										| SetCRT2ToLCD
+										| SetCRT2ToTV))))
+			XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+
+		if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
+				& (DisableCRT2Display | SetSimuScanMode))
+				|| (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+				|| (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
+						| SetCRT2ToLCD | SetCRT2ToTV))) {
+			tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
+			XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
+			XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
+		}
+	} else { /* {301} */
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+			XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+			XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
+			XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
+		}
+
+		if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA
+				| SetSimuScanMode))
+			XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+	}
+
+	if (HwDeviceExtension->jChipType < XG40) {
+		if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+				|| (XGI_DisableChISLCD(pVBInfo))
+				|| (XGI_IsLCDON(pVBInfo))) {
+			if (pVBInfo->LCDInfo & SetPWDEnable) {
+				if (pVBInfo->LCDInfo & SetPWDEnable)
+					XGI_BacklightByDrv(pVBInfo);
+				else {
+					XGI_SetPanelDelay(4, pVBInfo);
+					if (pVBInfo->VBType & VB_XGI301LV) {
+						tempbl = 0xFD;
+						tempah = 0x00;
+					} else {
+						tempbl = 0xFB;
+						tempah = 0x04;
+					}
+				}
+			}
+			XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+		}
+	}
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVPtrIndex */
+/* Input : */
+/* Output : */
+/* Description : bx 0 : ExtNTSC */
+/* 1 : StNTSC */
+/* 2 : ExtPAL */
+/* 3 : StPAL */
+/* 4 : ExtHiTV */
+/* 5 : StHiTV */
+/* 6 : Ext525i */
+/* 7 : St525i */
+/* 8 : Ext525p */
+/* 9 : St525p */
+/* A : Ext750p */
+/* B : St750p */
+/* --------------------------------------------------------------------- */
+static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
+{
+	unsigned short tempbx = 0;
+
+	if (pVBInfo->TVInfo & SetPALTV)
+		tempbx = 2;
+	if (pVBInfo->TVInfo & SetYPbPrMode1080i)
+		tempbx = 4;
+	if (pVBInfo->TVInfo & SetYPbPrMode525i)
+		tempbx = 6;
+	if (pVBInfo->TVInfo & SetYPbPrMode525p)
+		tempbx = 8;
+	if (pVBInfo->TVInfo & SetYPbPrMode750p)
+		tempbx = 10;
+	if (pVBInfo->TVInfo & TVSimuMode)
+		tempbx++;
+
+	return tempbx;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVPtrIndex2 */
+/* Input : */
+/* Output : bx 0 : NTSC */
+/* 1 : PAL */
+/* 2 : PALM */
+/* 3 : PALN */
+/* 4 : NTSC1024x768 */
+/* 5 : PAL-M 1024x768 */
+/* 6-7: reserved */
+/* cl 0 : YFilter1 */
+/* 1 : YFilter2 */
+/* ch 0 : 301A */
+/* 1 : 301B/302B/301LV/302LV */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
+		unsigned char *tempch, struct vb_device_info *pVBInfo)
+{
+	*tempbx = 0;
+	*tempcl = 0;
+	*tempch = 0;
+
+	if (pVBInfo->TVInfo & SetPALTV)
+		*tempbx = 1;
+
+	if (pVBInfo->TVInfo & SetPALMTV)
+		*tempbx = 2;
+
+	if (pVBInfo->TVInfo & SetPALNTV)
+		*tempbx = 3;
+
+	if (pVBInfo->TVInfo & NTSC1024x768) {
+		*tempbx = 4;
+		if (pVBInfo->TVInfo & SetPALMTV)
+			*tempbx = 5;
+	}
+
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
+				& TVSimuMode)) {
+			*tempbx += 8;
+			*tempcl += 1;
+		}
+	}
+
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C))
+		(*tempch)++;
 }
 
-static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
+static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
 {
-	unsigned char tempal, tempah, tempbl, i;
-
-	tempah = XGINew_GetReg1(pVBInfo->P3d4, 0x36);
-	tempal = tempah & 0x0F;
-	tempah = tempah & 0xF0;
-	i = 0;
-	tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+	unsigned short index;
 
-	while (tempbl != 0xFF) {
-		if (tempbl & 0x80) { /* OEMUtil */
-			tempal = tempah;
-			tempbl = tempbl & ~(0x80);
-		}
+	unsigned char tempah, tempbl, tempbh;
 
-		if (tempal == tempbl)
-			break;
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA
+				| SetCRT2ToTV | SetCRT2ToRAMDAC)) {
+			tempbl = 0;
+			tempbh = 0;
 
-		i++;
+			index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
+			tempbl = pVBInfo->XGI_TVDelayList[index];
 
-		tempbl = pVBInfo->LCDCapList[i].LCD_ID;
-	}
+			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+					| VB_XGI301LV | VB_XGI302LV
+					| VB_XGI301C))
+				tempbl = pVBInfo->XGI_TVDelayList2[index];
 
-	return i;
-}
+			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+				tempbl = tempbl >> 4;
+			/*
+			if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
+				tempbl = CRT2Delay1;	// Get CRT2 Delay
+			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+				tempbl = CRT2Delay2;
+			*/
+			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+				index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
+				tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
 
-static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
-{
-	unsigned short tempah, tempal, tempbl, i;
+				if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+					tempbl = tempbh;
+			}
 
-	tempal = pVBInfo->LCDResInfo;
-	tempah = pVBInfo->LCDTypeInfo;
+			tempbl &= 0x0F;
+			tempbh &= 0xF0;
+			tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x2D);
 
-	i = 0;
-	tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+			if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
+					| SetCRT2ToTV)) { /* Channel B */
+				tempah &= 0xF0;
+				tempah |= tempbl;
+			}
 
-	while (tempbl != 0xFF) {
-		if ((tempbl & 0x80) && (tempbl != 0x80)) {
-			tempal = tempah;
-			tempbl &= ~0x80;
+			if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
+				tempah &= 0x0F;
+				tempah |= tempbh;
+			}
+			XGINew_SetReg1(pVBInfo->Part1Port, 0x2D, tempah);
+		}
+	} else if (pVBInfo->IF_DEF_LVDS == 1) {
+		tempbl = 0;
+		tempbh = 0;
+		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+			tempah
+					= pVBInfo->LCDCapList[XGI_GetLCDCapPtr(
+							pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */
+			tempah &= 0x0f;
+			tempah = tempah << 4;
+			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2D, 0x0f,
+					tempah);
 		}
+	}
+}
 
-		if (tempal == tempbl)
-			break;
+static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo)
+{
+	unsigned short temp;
 
-		i++;
-		tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
+
+	if (temp & LCDRGB18Bit) {
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
+				(unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
+	} else {
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
+				(unsigned short) (0x30 | (tempcx & 0x00C0)));
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
 	}
 
-	if (tempbl == 0xFF) {
-		pVBInfo->LCDResInfo = Panel1024x768;
-		pVBInfo->LCDTypeInfo = 0;
-		i = 0;
+	/*
+	if (tempcx & EnableLCD24bpp) {	// 24bits
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0)));
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
+	} else {
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
 	}
+	*/
+}
 
-	return i;
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLCDCap_B */
+/* Input : cx -> LCD Capability */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo)
+{
+	if (tempcx & EnableLCD24bpp) /* 24bits */
+		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
+				(unsigned short) (((tempcx & 0x00ff) >> 6)
+						| 0x0c));
+	else
+		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
+				(unsigned short) (((tempcx & 0x00ff) >> 6)
+						| 0x18)); /* Enable Dither */
 }
 
-static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth,
-		struct vb_device_info *pVBInfo)
+static void SetSpectrum(struct vb_device_info *pVBInfo)
 {
-	unsigned short Index;
+	unsigned short index;
 
-	Index = XGI_GetLCDCapPtr(pVBInfo);
-	*HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
-	*VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
+	index = XGI_GetLCDCapPtr(pVBInfo);
 
-	return;
+	XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
+	XGI_LongWait(pVBInfo);
+	XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
+	XGI_LongWait(pVBInfo);
+
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x31,
+			pVBInfo->LCDCapList[index].Spectrum_31);
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x32,
+			pVBInfo->LCDCapList[index].Spectrum_32);
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x33,
+			pVBInfo->LCDCapList[index].Spectrum_33);
+	XGINew_SetReg1(pVBInfo->Part4Port, 0x34,
+			pVBInfo->LCDCapList[index].Spectrum_34);
+	XGI_LongWait(pVBInfo);
+	XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
 }
 
-void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbl, tempah;
-
-	if (pVBInfo->SetFlag == Win9xDOSMode) {
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
-			XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-			return;
-		} else
-			/* LVDS or CH7017 */
-			return;
-	}
-
-	if (HwDeviceExtension->jChipType < XG40) {
-		if (!XGI_DisableChISLCD(pVBInfo)) {
-			if ((XGI_EnableChISLCD(pVBInfo)) || (pVBInfo->VBInfo
-					& (SetCRT2ToLCD | SetCRT2ToLCDA))) {
-				if (pVBInfo->LCDInfo & SetPWDEnable) {
-					XGI_EnablePWD(pVBInfo);
-				} else {
-					pVBInfo->LCDInfo &= (~SetPWDEnable);
-					if (pVBInfo->VBType & (VB_XGI301LV
-							| VB_XGI302LV
-							| VB_XGI301C)) {
-						tempbl = 0xFD;
-						tempah = 0x02;
-					} else {
-						tempbl = 0xFB;
-						tempah = 0x00;
-					}
+	unsigned short tempcx;
 
-					XGI_SetPanelPower(tempah, tempbl,
-							pVBInfo);
-					XGI_SetPanelDelay(1, pVBInfo);
-				}
-			}
-		}
-	} /* Not 340 */
+	tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
 
 	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
 			| VB_XGI302LV | VB_XGI301C)) {
-		if (!(pVBInfo->SetFlag & DisableChA)) {
-			if (pVBInfo->SetFlag & EnableChA) {
-				XGINew_SetReg1(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
-			} else {
-				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
-					XGINew_SetReg1(pVBInfo->Part1Port,
-							0x1E, 0x20); /* Power on */
-				}
-			}
-		}
-
-		if (!(pVBInfo->SetFlag & DisableChB)) {
-			if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
-					& (SetCRT2ToLCD | SetCRT2ToTV
-							| SetCRT2ToRAMDAC))) {
-				tempah = (unsigned char) XGINew_GetReg1(
-						pVBInfo->P3c4, 0x32);
-				tempah &= 0xDF;
-				if (pVBInfo->VBInfo & SetInSlaveMode) {
-					if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
-						tempah |= 0x20;
-				}
-				XGINew_SetReg1(pVBInfo->P3c4, 0x32, tempah);
-				XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20);
-
-				tempah = (unsigned char) XGINew_GetReg1(
-						pVBInfo->Part1Port, 0x2E);
-
-				if (!(tempah & 0x80))
-					XGINew_SetRegOR(pVBInfo->Part1Port,
-							0x2E, 0x80); /* BVBDOENABLE = 1 */
-
-				XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
-			}
-		}
-
-		if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
-				|| (!(pVBInfo->VBInfo & DisableCRT2Display))) {
-			XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x00, ~0xE0,
-					0x20); /* shampoo 0129 */
-			if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
-				if (!XGI_DisableChISLCD(pVBInfo)) {
-					if (XGI_EnableChISLCD(pVBInfo)
-							|| (pVBInfo->VBInfo
-									& (SetCRT2ToLCD
-											| SetCRT2ToLCDA)))
-						XGINew_SetRegAND(
-								pVBInfo->Part4Port,
-								0x2A, 0x7F); /* LVDS PLL power on */
-				}
-				XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
-			}
+		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
+			/* Set 301LV Capability */
+			XGINew_SetReg1(pVBInfo->Part4Port, 0x24,
+					(unsigned char) (tempcx & 0x1F));
 		}
+		/* VB Driving */
+		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D,
+				~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
+				(unsigned short) ((tempcx & (EnableVBCLKDRVLOW
+						| EnablePLLSPLOW)) >> 8));
+	}
 
-		tempah = 0x00;
-
-		if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
-			tempah = 0xc0;
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBInfo & SetCRT2ToLCD)
+			XGI_SetLCDCap_B(tempcx, pVBInfo);
+		else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+			XGI_SetLCDCap_A(tempcx, pVBInfo);
 
-			if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
-				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-					if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
-						tempah = tempah & 0x40;
-						if (pVBInfo->VBInfo
-								& SetCRT2ToLCDA)
-							tempah = tempah ^ 0xC0;
+		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+			if (tempcx & EnableSpectrum)
+				SetSpectrum(pVBInfo);
+		}
+	} else {
+		/* LVDS,CH7017 */
+		XGI_SetLCDCap_A(tempcx, pVBInfo);
+	}
+}
 
-						if (pVBInfo->SetFlag
-								& DisableChB)
-							tempah &= 0xBF;
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetAntiFlicker */
+/* Input : */
+/* Output : */
+/* Description : Set TV Customized Param. */
+/* --------------------------------------------------------------------- */
+static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempbx, index;
 
-						if (pVBInfo->SetFlag
-								& DisableChA)
-							tempah &= 0x7F;
+	unsigned char tempah;
 
-						if (pVBInfo->SetFlag
-								& EnableChB)
-							tempah |= 0x40;
+	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+		return;
 
-						if (pVBInfo->SetFlag
-								& EnableChA)
-							tempah |= 0x80;
-					}
-				}
-			}
-		}
+	tempbx = XGI_GetTVPtrIndex(pVBInfo);
+	tempbx &= 0xFE;
 
-		XGINew_SetRegOR(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
+	if (ModeNo <= 0x13)
+		index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+	else
+		index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
 
-		if (pVBInfo->SetFlag & Win9xDOSMode) {
-			XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-			return;
-		}
+	tempbx += index;
+	tempah = TVAntiFlickList[tempbx];
+	tempah = tempah << 4;
 
-		if (!(pVBInfo->SetFlag & DisableChA)) {
-			XGI_VBLongWait(pVBInfo);
-			if (!(pVBInfo->SetFlag & GatingCRT)) {
-				XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
-				XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-				XGI_VBLongWait(pVBInfo);
-			}
-		}
-	} /* 301 */
-	else { /* LVDS */
-		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
-				| SetCRT2ToLCDA))
-			XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
+}
 
-		tempah = (unsigned char) XGINew_GetReg1(pVBInfo->Part1Port,
-				0x2E);
-		if (!(tempah & 0x80))
-			XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
+static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempbx, index;
 
-		XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F);
-		XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-	} /* End of VB */
+	unsigned char tempah;
 
-	if (HwDeviceExtension->jChipType < XG40) {
-		if (!XGI_EnableChISLCD(pVBInfo)) {
-			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-				if (XGI_BacklightByDrv(pVBInfo))
-					return;
-			} else
-				return;
-		}
+	tempbx = XGI_GetTVPtrIndex(pVBInfo);
+	tempbx &= 0xFE;
 
-		if (pVBInfo->LCDInfo & SetPWDEnable) {
-			XGI_FirePWDEnable(pVBInfo);
-			return;
-		}
+	if (ModeNo <= 0x13)
+		index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
+	else
+		index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
 
-		XGI_SetPanelDelay(2, pVBInfo);
+	tempbx += index;
+	tempah = TVEdgeList[tempbx];
+	tempah = tempah << 5;
 
-		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
-			tempah = 0x01;
-			tempbl = 0xFE; /* turn on backlght */
-		} else {
-			tempbl = 0xF7;
-			tempah = 0x00;
-		}
-		XGI_SetPanelPower(tempah, tempbl, pVBInfo);
-	}
+	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
 }
 
-void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
 {
-	unsigned short tempax, tempbx, tempah = 0, tempbl = 0;
+	unsigned short tempbx;
 
-	if (pVBInfo->SetFlag == Win9xDOSMode)
-		return;
+	unsigned char tempcl, tempch;
 
-	if (HwDeviceExtension->jChipType < XG40) {
-		if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
-				|| (XGI_DisableChISLCD(pVBInfo))) {
-			if (!XGI_IsLCDON(pVBInfo)) {
-				if (pVBInfo->LCDInfo & SetPWDEnable)
-					XGI_EnablePWD(pVBInfo);
-				else {
-					pVBInfo->LCDInfo &= ~SetPWDEnable;
-					XGI_DisablePWD(pVBInfo);
-					if (pVBInfo->VBType & (VB_XGI301LV
-							| VB_XGI302LV
-							| VB_XGI301C)) {
-						tempbx = 0xFE; /* not 01h */
-						tempax = 0;
-					} else {
-						tempbx = 0xF7; /* not 08h */
-						tempax = 0x08;
-					}
-					XGI_SetPanelPower(tempax, tempbx,
-							pVBInfo);
-					XGI_SetPanelDelay(3, pVBInfo);
-				}
-			} /* end if (!XGI_IsLCDON(pVBInfo)) */
-		}
-	}
+	unsigned long tempData;
 
-	/*
-	if (CH7017) {
-		if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) {
-			if (!XGI_IsLCDON(pVBInfo)) {
-				if (DISCHARGE) {
-					tempbx = XGINew_GetCH7005(0x61);
-					if (tempbx < 0x01) // first time we power up
-						XGINew_SetCH7005(0x0066); // and disable power sequence
-					else
-						XGINew_SetCH7005(0x5f66); // leave VDD on - disable power
-				}
-			}
-		}
-	}
-	*/
+	XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+	tempData = TVPhaseList[tempbx];
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		tempah = 0x3F;
-		if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
-					tempah = 0x7F; /* Disable Channel A */
-					if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-						tempah = 0xBF; /* Disable Channel B */
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
+			& 0x000000FF));
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
+			& 0x0000FF00) >> 8));
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
+			& 0x00FF0000) >> 16));
+	XGINew_SetReg1(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
+			& 0xFF000000) >> 24));
+}
 
-					if (pVBInfo->SetFlag & DisableChB)
-						tempah &= 0xBF; /* force to disable Cahnnel */
+static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempbx, index;
 
-					if (pVBInfo->SetFlag & DisableChA)
-						tempah &= 0x7F; /* Force to disable Channel B */
-				}
-			}
-		}
+	unsigned char tempcl, tempch, tempal, *filterPtr;
 
-		XGINew_SetRegAND(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
+	XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
 
-		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
-			if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
-					|| (XGI_DisableChISLCD(pVBInfo))
-					|| (XGI_IsLCDON(pVBInfo)))
-				XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
-		}
+	switch (tempbx) {
+	case 0x00:
+	case 0x04:
+		filterPtr = NTSCYFilter1;
+		break;
 
-		if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
-				& (DisableCRT2Display | SetCRT2ToLCDA
-						| SetSimuScanMode))) {
-			if (pVBInfo->SetFlag & GatingCRT)
-				XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
-			XGI_DisplayOff(HwDeviceExtension, pVBInfo);
-		}
+	case 0x01:
+		filterPtr = PALYFilter1;
+		break;
 
-		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-			if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
-					& SetCRT2ToLCDA))
-				XGINew_SetRegAND(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
-		}
+	case 0x02:
+	case 0x05:
+	case 0x0D:
+		filterPtr = PALMYFilter1;
+		break;
+
+	case 0x03:
+		filterPtr = PALNYFilter1;
+		break;
 
-		XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
+	case 0x08:
+	case 0x0C:
+		filterPtr = NTSCYFilter2;
+		break;
 
-		if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
-			XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xdf);
+	case 0x0A:
+		filterPtr = PALMYFilter2;
+		break;
 
-		if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
-				& (DisableCRT2Display | SetSimuScanMode))
-				|| ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-						&& (pVBInfo->VBInfo
-								& (SetCRT2ToRAMDAC
-										| SetCRT2ToLCD
-										| SetCRT2ToTV))))
-			XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+	case 0x0B:
+		filterPtr = PALNYFilter2;
+		break;
 
-		if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
-				& (DisableCRT2Display | SetSimuScanMode))
-				|| (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-				|| (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
-						| SetCRT2ToLCD | SetCRT2ToTV))) {
-			tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
-			XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
-			XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
-		}
-	} else { /* {301} */
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-			XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
-			XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
-			XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
-		}
+	case 0x09:
+		filterPtr = PALYFilter2;
+		break;
 
-		if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA
-				| SetSimuScanMode))
-			XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+	default:
+		return;
 	}
 
-	if (HwDeviceExtension->jChipType < XG40) {
-		if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
-				|| (XGI_DisableChISLCD(pVBInfo))
-				|| (XGI_IsLCDON(pVBInfo))) {
-			if (pVBInfo->LCDInfo & SetPWDEnable) {
-				if (pVBInfo->LCDInfo & SetPWDEnable)
-					XGI_BacklightByDrv(pVBInfo);
-				else {
-					XGI_SetPanelDelay(4, pVBInfo);
-					if (pVBInfo->VBType & VB_XGI301LV) {
-						tempbl = 0xFD;
-						tempah = 0x00;
-					} else {
-						tempbl = 0xFB;
-						tempah = 0x04;
-					}
-				}
-			}
-			XGI_SetPanelPower(tempah, tempbl, pVBInfo);
-		}
-	}
-}
+	if (ModeNo <= 0x13)
+		tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+	else
+		tempal
+				= pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVPtrIndex */
-/* Input : */
-/* Output : */
-/* Description : bx 0 : ExtNTSC */
-/* 1 : StNTSC */
-/* 2 : ExtPAL */
-/* 3 : StPAL */
-/* 4 : ExtHiTV */
-/* 5 : StHiTV */
-/* 6 : Ext525i */
-/* 7 : St525i */
-/* 8 : Ext525p */
-/* 9 : St525p */
-/* A : Ext750p */
-/* B : St750p */
-/* --------------------------------------------------------------------- */
-static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
-{
-	unsigned short tempbx = 0;
+	if (tempcl == 0)
+		index = tempal * 4;
+	else
+		index = tempal * 7;
 
-	if (pVBInfo->TVInfo & SetPALTV)
-		tempbx = 2;
-	if (pVBInfo->TVInfo & SetYPbPrMode1080i)
-		tempbx = 4;
-	if (pVBInfo->TVInfo & SetYPbPrMode525i)
-		tempbx = 6;
-	if (pVBInfo->TVInfo & SetYPbPrMode525p)
-		tempbx = 8;
-	if (pVBInfo->TVInfo & SetYPbPrMode750p)
-		tempbx = 10;
-	if (pVBInfo->TVInfo & TVSimuMode)
-		tempbx++;
+	if ((tempcl == 0) && (tempch == 1)) {
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x35, 0);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x36, 0);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x37, 0);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
+	} else {
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
+	}
 
-	return tempbx;
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
+		XGINew_SetReg1(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
+	}
 }
 
 /* --------------------------------------------------------------------- */
@@ -7864,962 +7625,1088 @@ static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex,
 	}
 }
 
-static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2ModeRegs */
+/* Input : */
+/* Output : */
+/* Description : Origin code for crt2group */
+/* --------------------------------------------------------------------- */
+void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
 {
-	unsigned short index;
-
-	unsigned char tempah, tempbl, tempbh;
+	unsigned short tempbl;
+	short tempcl;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA
-				| SetCRT2ToTV | SetCRT2ToRAMDAC)) {
-			tempbl = 0;
-			tempbh = 0;
+	unsigned char tempah;
 
-			index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
-			tempbl = pVBInfo->XGI_TVDelayList[index];
+	/* XGINew_SetReg1(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */
+	tempah = 0;
+	if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+		tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00);
+		tempah &= ~0x10; /* BTRAMDAC */
+		tempah |= 0x40; /* BTRAM */
 
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-					| VB_XGI301LV | VB_XGI302LV
-					| VB_XGI301C))
-				tempbl = pVBInfo->XGI_TVDelayList2[index];
+		if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
+				| SetCRT2ToLCD)) {
+			tempah = 0x40; /* BTDRAM */
+			if (ModeNo > 0x13) {
+				tempcl = pVBInfo->ModeType;
+				tempcl -= ModeVGA;
+				if (tempcl >= 0) {
+					tempah = (0x008 >> tempcl); /* BT Color */
+					if (tempah == 0)
+						tempah = 1;
+					tempah |= 0x040;
+				}
+			}
+			if (pVBInfo->VBInfo & SetInSlaveMode)
+				tempah ^= 0x50; /* BTDAC */
+		}
+	}
 
-			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
-				tempbl = tempbl >> 4;
-			/*
-			if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
-				tempbl = CRT2Delay1;	// Get CRT2 Delay
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
-				tempbl = CRT2Delay2;
-			*/
-			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-				index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
-				tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
+	/* 0210 shampoo
+	if (pVBInfo->VBInfo & DisableCRT2Display) {
+		tempah = 0;
+	}
 
-				if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-					tempbl = tempbh;
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
+	if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
+		tempcl = pVBInfo->ModeType;
+		if (ModeNo > 0x13) {
+			tempcl -= ModeVGA;
+			if ((tempcl > 0) || (tempcl == 0)) {
+				tempah=(0x008>>tempcl) ;
+				if (tempah == 0)
+					tempah = 1;
+				tempah |= 0x040;
 			}
+		} else {
+			tempah = 0x040;
+		}
 
-			tempbl &= 0x0F;
-			tempbh &= 0xF0;
-			tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x2D);
+		if (pVBInfo->VBInfo & SetInSlaveMode) {
+			tempah = (tempah ^ 0x050);
+		}
+	}
+	*/
 
-			if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
-					| SetCRT2ToTV)) { /* Channel B */
-				tempah &= 0xF0;
-				tempah |= tempbl;
-			}
+	XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
+	tempah = 0x08;
+	tempbl = 0xf0;
+
+	if (pVBInfo->VBInfo & DisableCRT2Display) {
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
+	} else {
+		tempah = 0x00;
+		tempbl = 0xff;
+
+		if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
+				| SetCRT2ToLCD | SetCRT2ToLCDA)) {
+			if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
+					&& (!(pVBInfo->VBInfo & SetSimuScanMode))) {
+				tempbl &= 0xf7;
+				tempah |= 0x01;
+				XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e,
+						tempbl, tempah);
+			} else {
+				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+					tempbl &= 0xf7;
+					tempah |= 0x01;
+				}
+
+				if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
+						| SetCRT2ToTV | SetCRT2ToLCD)) {
+					tempbl &= 0xf8;
+					tempah = 0x01;
+
+					if (!(pVBInfo->VBInfo & SetInSlaveMode))
+						tempah |= 0x02;
+
+					if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+						tempah = tempah ^ 0x05;
+						if (!(pVBInfo->VBInfo
+								& SetCRT2ToLCD))
+							tempah = tempah ^ 0x01;
+					}
 
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
-				tempah &= 0x0F;
-				tempah |= tempbh;
+					if (!(pVBInfo->VBInfo
+							& SetCRT2ToDualEdge))
+						tempah |= 0x08;
+					XGINew_SetRegANDOR(pVBInfo->Part1Port,
+							0x2e, tempbl, tempah);
+				} else {
+					XGINew_SetRegANDOR(pVBInfo->Part1Port,
+							0x2e, tempbl, tempah);
+				}
 			}
-			XGINew_SetReg1(pVBInfo->Part1Port, 0x2D, tempah);
-		}
-	} else if (pVBInfo->IF_DEF_LVDS == 1) {
-		tempbl = 0;
-		tempbh = 0;
-		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
-			tempah
-					= pVBInfo->LCDCapList[XGI_GetLCDCapPtr(
-							pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */
-			tempah &= 0x0f;
-			tempah = tempah << 4;
-			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2D, 0x0f,
+		} else {
+			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl,
 					tempah);
 		}
 	}
-}
 
-static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
-{
-	unsigned short tempcx;
+	if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
+			| SetCRT2ToLCDA)) {
+		tempah &= (~0x08);
+		if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
+				& SetInSlaveMode))) {
+			tempah |= 0x010;
+		}
+		tempah |= 0x080;
 
-	tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			/* if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { */
+			tempah |= 0x020;
+			if (ModeNo > 0x13) {
+				if (pVBInfo->VBInfo & DriverMode)
+					tempah = tempah ^ 0x20;
+			}
+			/* } */
+		}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
-			/* Set 301LV Capability */
-			XGINew_SetReg1(pVBInfo->Part4Port, 0x24,
-					(unsigned char) (tempcx & 0x1F));
+		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
+		tempah = 0;
+
+		if (pVBInfo->LCDInfo & SetLCDDualLink)
+			tempah |= 0x40;
+
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			/* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) && (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))) { */
+			if (pVBInfo->TVInfo & RPLLDIV2XO)
+				tempah |= 0x40;
+			/* } */
 		}
-		/* VB Driving */
-		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D,
-				~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
-				(unsigned short) ((tempcx & (EnableVBCLKDRVLOW
-						| EnablePLLSPLOW)) >> 8));
+
+		if ((pVBInfo->LCDResInfo == Panel1280x1024)
+				|| (pVBInfo->LCDResInfo == Panel1280x1024x75))
+			tempah |= 0x80;
+
+		if (pVBInfo->LCDResInfo == Panel1280x960)
+			tempah |= 0x80;
+
+		XGINew_SetReg1(pVBInfo->Part4Port, 0x0C, tempah);
 	}
 
 	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
 			| VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBInfo & SetCRT2ToLCD)
-			XGI_SetLCDCap_B(tempcx, pVBInfo);
-		else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
-			XGI_SetLCDCap_A(tempcx, pVBInfo);
+		tempah = 0;
+		tempbl = 0xfb;
 
-		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
-			if (tempcx & EnableSpectrum)
-				SetSpectrum(pVBInfo);
+		if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+			tempbl = 0xff;
+			if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+				tempah |= 0x04; /* shampoo 0129 */
 		}
-	} else {
-		/* LVDS,CH7017 */
-		XGI_SetLCDCap_A(tempcx, pVBInfo);
-	}
-}
 
-static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo)
-{
-	unsigned short temp;
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x13, tempbl, tempah);
+		tempah = 0x00;
+		tempbl = 0xcf;
+		if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+				tempah |= 0x30;
+		}
 
-	temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
+		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
+		tempah = 0;
+		tempbl = 0x3f;
 
-	if (temp & LCDRGB18Bit) {
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
-				(unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
-	} else {
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
-				(unsigned short) (0x30 | (tempcx & 0x00C0)));
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
+		if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+				tempah |= 0xc0;
+		}
+		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, tempbl, tempah);
 	}
 
-	/*
-	if (tempcx & EnableLCD24bpp) {	// 24bits
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0)));
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
-	} else {
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
+	tempah = 0;
+	tempbl = 0x7f;
+	if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
+		tempbl = 0xff;
+		if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+			tempah |= 0x80;
 	}
-	*/
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDCap_B */
-/* Input : cx -> LCD Capability */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo)
-{
-	if (tempcx & EnableLCD24bpp) /* 24bits */
-		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
-				(unsigned short) (((tempcx & 0x00ff) >> 6)
-						| 0x0c));
-	else
-		XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
-				(unsigned short) (((tempcx & 0x00ff) >> 6)
-						| 0x18)); /* Enable Dither */
-}
-
-static void SetSpectrum(struct vb_device_info *pVBInfo)
-{
-	unsigned short index;
-
-	index = XGI_GetLCDCapPtr(pVBInfo);
 
-	XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
-	XGI_LongWait(pVBInfo);
-	XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
-	XGI_LongWait(pVBInfo);
+	XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x23, tempbl, tempah);
 
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x31,
-			pVBInfo->LCDCapList[index].Spectrum_31);
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x32,
-			pVBInfo->LCDCapList[index].Spectrum_32);
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x33,
-			pVBInfo->LCDCapList[index].Spectrum_33);
-	XGINew_SetReg1(pVBInfo->Part4Port, 0x34,
-			pVBInfo->LCDCapList[index].Spectrum_34);
-	XGI_LongWait(pVBInfo);
-	XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
+	if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->LCDInfo & SetLCDDualLink) {
+			XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x20);
+			XGINew_SetRegOR(pVBInfo->Part4Port, 0x34, 0x10);
+		}
+	}
 }
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetAntiFlicker */
-/* Input : */
-/* Output : */
-/* Description : Set TV Customized Param. */
-/* --------------------------------------------------------------------- */
-static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbx, index;
-
-	unsigned char tempah;
-
-	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
-		return;
-
-	tempbx = XGI_GetTVPtrIndex(pVBInfo);
-	tempbx &= 0xFE;
+	unsigned short tempbx;
 
-	if (ModeNo <= 0x13)
-		index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
-	else
-		index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
+	tempbx = 0;
 
-	tempbx += index;
-	tempah = TVAntiFlickList[tempbx];
-	tempah = tempah << 4;
+	if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+		tempbx = 0x08A0;
 
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
 }
 
-static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex,
+void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbx, index;
-
-	unsigned char tempah;
-
-	tempbx = XGI_GetTVPtrIndex(pVBInfo);
-	tempbx &= 0xFE;
-
-	if (ModeNo <= 0x13)
-		index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
-	else
-		index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
-
-	tempbx += index;
-	tempah = TVEdgeList[tempbx];
-	tempah = tempah << 5;
-
-	XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
+	unsigned short tempbx;
+	tempbx = 0;
 }
 
-static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
+void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbx;
 
-	unsigned char tempcl, tempch;
-
-	unsigned long tempData;
-
-	XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
-	tempData = TVPhaseList[tempbx];
-
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
-			& 0x000000FF));
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
-			& 0x0000FF00) >> 8));
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
-			& 0x00FF0000) >> 16));
-	XGINew_SetReg1(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
-			& 0xFF000000) >> 24));
+	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
+
 }
 
-static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
+void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbx, index;
 
-	unsigned char tempcl, tempch, tempal, *filterPtr;
+	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
 
-	XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+}
 
-	switch (tempbx) {
-	case 0x00:
-	case 0x04:
-		filterPtr = NTSCYFilter1;
-		break;
+unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
+{
+	unsigned short flag;
 
-	case 0x01:
-		filterPtr = PALYFilter1;
-		break;
+	if (pVBInfo->IF_DEF_LVDS == 1) {
+		return 1;
+	} else {
+		flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
+		if ((flag == 1) || (flag == 2))
+			return 1; /* 301b */
+		else
+			return 0;
+	}
+}
 
-	case 0x02:
-	case 0x05:
-	case 0x0D:
-		filterPtr = PALMYFilter1;
-		break;
+void XGI_LongWait(struct vb_device_info *pVBInfo)
+{
+	unsigned short i;
 
-	case 0x03:
-		filterPtr = PALNYFilter1;
-		break;
+	i = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
 
-	case 0x08:
-	case 0x0C:
-		filterPtr = NTSCYFilter2;
-		break;
+	if (!(i & 0xC0)) {
+		for (i = 0; i < 0xFFFF; i++) {
+			if (!(XGINew_GetReg2(pVBInfo->P3da) & 0x08))
+				break;
+		}
 
-	case 0x0A:
-		filterPtr = PALMYFilter2;
-		break;
+		for (i = 0; i < 0xFFFF; i++) {
+			if ((XGINew_GetReg2(pVBInfo->P3da) & 0x08))
+				break;
+		}
+	}
+}
 
-	case 0x0B:
-		filterPtr = PALNYFilter2;
-		break;
+static void XGI_VBLongWait(struct vb_device_info *pVBInfo)
+{
+	unsigned short tempal, temp, i, j;
+	return;
+	if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+		temp = 0;
+		for (i = 0; i < 3; i++) {
+			for (j = 0; j < 100; j++) {
+				tempal = XGINew_GetReg2(pVBInfo->P3da);
+				if (temp & 0x01) { /* VBWaitMode2 */
+					if ((tempal & 0x08))
+						continue;
 
-	case 0x09:
-		filterPtr = PALYFilter2;
-		break;
+					if (!(tempal & 0x08))
+						break;
 
-	default:
-		return;
+				} else { /* VBWaitMode1 */
+					if (!(tempal & 0x08))
+						continue;
+
+					if ((tempal & 0x08))
+						break;
+				}
+			}
+			temp = temp ^ 0x01;
+		}
+	} else {
+		XGI_LongWait(pVBInfo);
 	}
+	return;
+}
 
-	if (ModeNo <= 0x13)
-		tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
-	else
-		tempal
-				= pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
+		unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct vb_device_info *pVBInfo)
+{
+	short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 },
+			LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01,
+					0x01, 0x01 };
 
-	if (tempcl == 0)
-		index = tempal * 4;
+	unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
+
+	if (ModeNo <= 0x13)
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	else
-		index = tempal * 7;
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	if ((tempcl == 0) && (tempch == 1)) {
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x35, 0);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x36, 0);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x37, 0);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
-	} else {
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
+	if (pVBInfo->IF_DEF_CH7005 == 1) {
+		if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			if (modeflag & HalfDCLK)
+				return 0;
+		}
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
-		XGINew_SetReg1(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
-	}
-}
+	if (ModeNo < 0x14)
+		return 0xFFFF;
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVPtrIndex2 */
-/* Input : */
-/* Output : bx 0 : NTSC */
-/* 1 : PAL */
-/* 2 : PALM */
-/* 3 : PALN */
-/* 4 : NTSC1024x768 */
-/* 5 : PAL-M 1024x768 */
-/* 6-7: reserved */
-/* cl 0 : YFilter1 */
-/* 1 : YFilter2 */
-/* ch 0 : 301A */
-/* 1 : 301B/302B/301LV/302LV */
-/* Description : */
-/* --------------------------------------------------------------------- */
-static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
-		unsigned char *tempch, struct vb_device_info *pVBInfo)
-{
-	*tempbx = 0;
-	*tempcl = 0;
-	*tempch = 0;
+	index = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
+	index = index >> pVBInfo->SelectCRT2Rate;
+	index &= 0x0F;
 
-	if (pVBInfo->TVInfo & SetPALTV)
-		*tempbx = 1;
+	if (pVBInfo->LCDInfo & LCDNonExpanding)
+		index = 0;
 
-	if (pVBInfo->TVInfo & SetPALMTV)
-		*tempbx = 2;
+	if (index > 0)
+		index--;
 
-	if (pVBInfo->TVInfo & SetPALNTV)
-		*tempbx = 3;
+	if (pVBInfo->SetFlag & ProgrammingCRT2) {
+		if (pVBInfo->IF_DEF_CH7005 == 1) {
+			if (pVBInfo->VBInfo & SetCRT2ToTV)
+				index = 0;
+		}
 
-	if (pVBInfo->TVInfo & NTSC1024x768) {
-		*tempbx = 4;
-		if (pVBInfo->TVInfo & SetPALMTV)
-			*tempbx = 5;
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+			if (pVBInfo->IF_DEF_LVDS == 0) {
+				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+						| VB_XGI301LV | VB_XGI302LV
+						| VB_XGI301C))
+					temp
+							= LCDARefreshIndex[pVBInfo->LCDResInfo
+									& 0x0F]; /* 301b */
+				else
+					temp
+							= LCDRefreshIndex[pVBInfo->LCDResInfo
+									& 0x0F];
+
+				if (index > temp)
+					index = temp;
+			} else {
+				index = 0;
+			}
+		}
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
-				& TVSimuMode)) {
-			*tempbx += 8;
-			*tempcl += 1;
+	RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
+	ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
+	if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
+		/*
+		if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & XG2xNotSupport) {
+			index++;
+		}
+		*/
+		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800)
+				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
+						== 600)) {
+			index++;
+		}
+		/* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */
+		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024)
+				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
+						== 768)) {
+			index++;
+		}
+		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280)
+				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
+						== 1024)) {
+			index++;
+		}
+	}
+
+	i = 0;
+	do {
+		if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID
+				!= ModeNo)
+			break;
+		temp
+				= pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+		temp &= ModeInfoFlag;
+		if (temp < pVBInfo->ModeType)
+			break;
+		i++;
+		index--;
+
+	} while (index != 0xFFFF);
+	if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+		if (pVBInfo->VBInfo & SetInSlaveMode) {
+			temp
+					= pVBInfo->RefIndex[RefreshRateTableIndex
+							+ i - 1].Ext_InfoFlag;
+			if (temp & InterlaceMode)
+				i++;
 		}
 	}
+	i--;
+	if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
+		temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
+				RefreshRateTableIndex, &i, pVBInfo);
+	}
+	return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */
+}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C))
-		(*tempch)++;
+static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
+		struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short RefreshRateTableIndex;
+	/* unsigned short temp ; */
+
+	/* pVBInfo->SelectCRT2Rate = 0; */
+
+	pVBInfo->SetFlag |= ProgrammingCRT2;
+	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+			ModeIdIndex, pVBInfo);
+	XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
+	XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+	XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+			HwDeviceExtension, pVBInfo);
+	XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+	XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 }
 
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2ModeRegs */
-/* Input : */
-/* Output : */
-/* Description : Origin code for crt2group */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
+unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short tempbl;
-	short tempcl;
+	unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex;
 
-	unsigned char tempah;
+	tempbx = pVBInfo->VBInfo;
+	pVBInfo->SetFlag |= ProgrammingCRT2;
+	XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
+	pVBInfo->SelectCRT2Rate = 4;
+	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+			ModeIdIndex, pVBInfo);
+	XGI_SaveCRT2Info(ModeNo, pVBInfo);
+	XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
+	XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+	XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+			RefreshRateTableIndex, pVBInfo);
+	XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+			RefreshRateTableIndex, pVBInfo);
+	XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+			RefreshRateTableIndex, pVBInfo);
+	XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+			HwDeviceExtension, pVBInfo);
+	XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+			RefreshRateTableIndex, pVBInfo);
+	XGI_SetTap4Regs(pVBInfo);
+	XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
+	XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+			HwDeviceExtension, pVBInfo);
+	XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+	XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
+	XGI_AutoThreshold(pVBInfo);
+	return 1;
+}
 
-	/* XGINew_SetReg1(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */
-	tempah = 0;
-	if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
-		tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00);
-		tempah &= ~0x10; /* BTRAMDAC */
-		tempah |= 0x40; /* BTRAM */
+void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
+{
+	unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
+			0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
+			0x05, 0x00 };
 
-		if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
-				| SetCRT2ToLCD)) {
-			tempah = 0x40; /* BTDRAM */
-			if (ModeNo > 0x13) {
-				tempcl = pVBInfo->ModeType;
-				tempcl -= ModeVGA;
-				if (tempcl >= 0) {
-					tempah = (0x008 >> tempcl); /* BT Color */
-					if (tempah == 0)
-						tempah = 1;
-					tempah |= 0x040;
-				}
-			}
-			if (pVBInfo->VBInfo & SetInSlaveMode)
-				tempah ^= 0x50; /* BTDAC */
-		}
-	}
+	unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
 
-	/* 0210 shampoo
-	if (pVBInfo->VBInfo & DisableCRT2Display) {
-		tempah = 0;
-	}
+	unsigned char CR17, CR63, SR31;
+	unsigned short temp;
+	unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
 
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
-	if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
-		tempcl = pVBInfo->ModeType;
-		if (ModeNo > 0x13) {
-			tempcl -= ModeVGA;
-			if ((tempcl > 0) || (tempcl == 0)) {
-				tempah=(0x008>>tempcl) ;
-				if (tempah == 0)
-					tempah = 1;
-				tempah |= 0x040;
-			}
-		} else {
-			tempah = 0x040;
-		}
+	int i;
+	XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
 
-		if (pVBInfo->VBInfo & SetInSlaveMode) {
-			tempah = (tempah ^ 0x050);
-		}
-	}
-	*/
+	/* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
+	XGINew_SetReg1(pVBInfo->P3d4, 0x57, 0x4A);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
+			pVBInfo->P3d4, 0x53) | 0x02));
 
-	XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
-	tempah = 0x08;
-	tempbl = 0xf0;
+	SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31);
+	CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63);
+	SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01);
 
-	if (pVBInfo->VBInfo & DisableCRT2Display) {
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
-	} else {
-		tempah = 0x00;
-		tempbl = 0xff;
+	XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
+	XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
 
-		if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
-				| SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
-					&& (!(pVBInfo->VBInfo & SetSimuScanMode))) {
-				tempbl &= 0xf7;
-				tempah |= 0x01;
-				XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e,
-						tempbl, tempah);
-			} else {
-				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-					tempbl &= 0xf7;
-					tempah |= 0x01;
-				}
+	CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
 
-				if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
-						| SetCRT2ToTV | SetCRT2ToLCD)) {
-					tempbl &= 0xf8;
-					tempah = 0x01;
+	SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
 
-					if (!(pVBInfo->VBInfo & SetInSlaveMode))
-						tempah |= 0x02;
+	SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
+	SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
 
-					if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
-						tempah = tempah ^ 0x05;
-						if (!(pVBInfo->VBInfo
-								& SetCRT2ToLCD))
-							tempah = tempah ^ 0x01;
-					}
+	XGINew_SetReg1(pVBInfo->P3d4, 0x11, 0x00);
 
-					if (!(pVBInfo->VBInfo
-							& SetCRT2ToDualEdge))
-						tempah |= 0x08;
-					XGINew_SetRegANDOR(pVBInfo->Part1Port,
-							0x2e, tempbl, tempah);
-				} else {
-					XGINew_SetRegANDOR(pVBInfo->Part1Port,
-							0x2e, tempbl, tempah);
-				}
-			}
-		} else {
-			XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl,
-					tempah);
-		}
-	}
+	for (i = 0; i < 8; i++)
+		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
 
-	if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
-			| SetCRT2ToLCDA)) {
-		tempah &= (~0x08);
-		if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
-				& SetInSlaveMode))) {
-			tempah |= 0x010;
-		}
-		tempah |= 0x080;
+	for (i = 8; i < 11; i++)
+		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 8),
+				CRTCData[i]);
 
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			/* if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { */
-			tempah |= 0x020;
-			if (ModeNo > 0x13) {
-				if (pVBInfo->VBInfo & DriverMode)
-					tempah = tempah ^ 0x20;
-			}
-			/* } */
-		}
+	for (i = 11; i < 13; i++)
+		XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 4),
+				CRTCData[i]);
 
-		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
-		tempah = 0;
+	for (i = 13; i < 16; i++)
+		XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i - 3),
+				CRTCData[i]);
 
-		if (pVBInfo->LCDInfo & SetLCDDualLink)
-			tempah |= 0x40;
+	XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
+			& 0xE0));
 
-		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			/* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) && (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))) { */
-			if (pVBInfo->TVInfo & RPLLDIV2XO)
-				tempah |= 0x40;
-			/* } */
-		}
+	XGINew_SetReg1(pVBInfo->P3c4, 0x31, 0x00);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1);
 
-		if ((pVBInfo->LCDResInfo == Panel1280x1024)
-				|| (pVBInfo->LCDResInfo == Panel1280x1024x75))
-			tempah |= 0x80;
+	XGINew_SetReg3(pVBInfo->P3c8, 0x00);
+
+	for (i = 0; i < 256; i++) {
+		XGINew_SetReg3((pVBInfo->P3c8 + 1),
+				(unsigned char) DAC_TEST_PARMS[0]);
+		XGINew_SetReg3((pVBInfo->P3c8 + 1),
+				(unsigned char) DAC_TEST_PARMS[1]);
+		XGINew_SetReg3((pVBInfo->P3c8 + 1),
+				(unsigned char) DAC_TEST_PARMS[2]);
+	}
+
+	XGI_VBLongWait(pVBInfo);
+	XGI_VBLongWait(pVBInfo);
+	XGI_VBLongWait(pVBInfo);
+
+	mdelay(1);
+
+	XGI_WaitDisply(pVBInfo);
+	temp = XGINew_GetReg2(pVBInfo->P3c2);
+
+	if (temp & 0x10)
+		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
+	else
+		XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
 
-		if (pVBInfo->LCDResInfo == Panel1280x960)
-			tempah |= 0x80;
+	/* alan, avoid display something, set BLACK DAC if not restore DAC */
+	XGINew_SetReg3(pVBInfo->P3c8, 0x00);
 
-		XGINew_SetReg1(pVBInfo->Part4Port, 0x0C, tempah);
+	for (i = 0; i < 256; i++) {
+		XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
+		XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
+		XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		tempah = 0;
-		tempbl = 0xfb;
-
-		if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
-			tempbl = 0xff;
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA)
-				tempah |= 0x04; /* shampoo 0129 */
-		}
+	XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01);
+	XGINew_SetReg1(pVBInfo->P3d4, 0x63, CR63);
+	XGINew_SetReg1(pVBInfo->P3c4, 0x31, SR31);
 
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x13, tempbl, tempah);
-		tempah = 0x00;
-		tempbl = 0xcf;
-		if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
-			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
-				tempah |= 0x30;
-		}
+	/* [2004/05/11] Vicent */
+	XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
+			pVBInfo->P3d4, 0x53) & 0xFD));
+	XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
+}
 
-		XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
-		tempah = 0;
-		tempbl = 0x3f;
+void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned short tempbl, tempah;
 
-		if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
-			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
-				tempah |= 0xc0;
-		}
-		XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, tempbl, tempah);
+	if (pVBInfo->SetFlag == Win9xDOSMode) {
+		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+				| VB_XGI302LV | VB_XGI301C)) {
+			XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+			return;
+		} else
+			/* LVDS or CH7017 */
+			return;
 	}
 
-	tempah = 0;
-	tempbl = 0x7f;
-	if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
-		tempbl = 0xff;
-		if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
-			tempah |= 0x80;
-	}
+	if (HwDeviceExtension->jChipType < XG40) {
+		if (!XGI_DisableChISLCD(pVBInfo)) {
+			if ((XGI_EnableChISLCD(pVBInfo)) || (pVBInfo->VBInfo
+					& (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+				if (pVBInfo->LCDInfo & SetPWDEnable) {
+					XGI_EnablePWD(pVBInfo);
+				} else {
+					pVBInfo->LCDInfo &= (~SetPWDEnable);
+					if (pVBInfo->VBType & (VB_XGI301LV
+							| VB_XGI302LV
+							| VB_XGI301C)) {
+						tempbl = 0xFD;
+						tempah = 0x02;
+					} else {
+						tempbl = 0xFB;
+						tempah = 0x00;
+					}
 
-	XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x23, tempbl, tempah);
+					XGI_SetPanelPower(tempah, tempbl,
+							pVBInfo);
+					XGI_SetPanelDelay(1, pVBInfo);
+				}
+			}
+		}
+	} /* Not 340 */
 
-	if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->LCDInfo & SetLCDDualLink) {
-			XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x20);
-			XGINew_SetRegOR(pVBInfo->Part4Port, 0x34, 0x10);
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		if (!(pVBInfo->SetFlag & DisableChA)) {
+			if (pVBInfo->SetFlag & EnableChA) {
+				XGINew_SetReg1(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
+			} else {
+				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
+					XGINew_SetReg1(pVBInfo->Part1Port,
+							0x1E, 0x20); /* Power on */
+				}
+			}
 		}
-	}
-}
 
-static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short tempbx;
+		if (!(pVBInfo->SetFlag & DisableChB)) {
+			if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
+					& (SetCRT2ToLCD | SetCRT2ToTV
+							| SetCRT2ToRAMDAC))) {
+				tempah = (unsigned char) XGINew_GetReg1(
+						pVBInfo->P3c4, 0x32);
+				tempah &= 0xDF;
+				if (pVBInfo->VBInfo & SetInSlaveMode) {
+					if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
+						tempah |= 0x20;
+				}
+				XGINew_SetReg1(pVBInfo->P3c4, 0x32, tempah);
+				XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20);
 
-	tempbx = 0;
+				tempah = (unsigned char) XGINew_GetReg1(
+						pVBInfo->Part1Port, 0x2E);
 
-	if (pVBInfo->VBInfo & SetCRT2ToLCDA)
-		tempbx = 0x08A0;
+				if (!(tempah & 0x80))
+					XGINew_SetRegOR(pVBInfo->Part1Port,
+							0x2E, 0x80); /* BVBDOENABLE = 1 */
 
-}
+				XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
+			}
+		}
 
-void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short tempbx;
-	tempbx = 0;
-}
+		if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
+				|| (!(pVBInfo->VBInfo & DisableCRT2Display))) {
+			XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x00, ~0xE0,
+					0x20); /* shampoo 0129 */
+			if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+				if (!XGI_DisableChISLCD(pVBInfo)) {
+					if (XGI_EnableChISLCD(pVBInfo)
+							|| (pVBInfo->VBInfo
+									& (SetCRT2ToLCD
+											| SetCRT2ToLCDA)))
+						XGINew_SetRegAND(
+								pVBInfo->Part4Port,
+								0x2A, 0x7F); /* LVDS PLL power on */
+				}
+				XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
+			}
+		}
 
-static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
-			StandTableIndex, CRT1Index;
+		tempah = 0x00;
 
-	pVBInfo->RVBHCMAX = 1;
-	pVBInfo->RVBHCFACT = 1;
+		if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+			tempah = 0xc0;
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
-		tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
-		tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
-		temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		CRT1Index
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		CRT1Index &= IndexMask;
-		temp1
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
-		temp2
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
-		tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
-		tempbx
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
-		tempcx
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
-						<< 8;
-		tempcx &= 0x0100;
-		tempcx = tempcx << 2;
-		tempbx |= tempcx;
-		temp1
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
-	}
+			if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
+				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+					if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+						tempah = tempah & 0x40;
+						if (pVBInfo->VBInfo
+								& SetCRT2ToLCDA)
+							tempah = tempah ^ 0xC0;
 
-	if (temp1 & 0x01)
-		tempbx |= 0x0100;
+						if (pVBInfo->SetFlag
+								& DisableChB)
+							tempah &= 0xBF;
 
-	if (temp1 & 0x20)
-		tempbx |= 0x0200;
-	tempax += 5;
+						if (pVBInfo->SetFlag
+								& DisableChA)
+							tempah &= 0x7F;
 
-	if (modeflag & Charx8Dot)
-		tempax *= 8;
-	else
-		tempax *= 9;
+						if (pVBInfo->SetFlag
+								& EnableChB)
+							tempah |= 0x40;
 
-	pVBInfo->VGAHT = tempax;
-	pVBInfo->HT = tempax;
-	tempbx++;
-	pVBInfo->VGAVT = tempbx;
-	pVBInfo->VT = tempbx;
-}
+						if (pVBInfo->SetFlag
+								& EnableChA)
+							tempah |= 0x80;
+					}
+				}
+			}
+		}
 
-static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
-	short index;
-	unsigned short modeflag;
+		XGINew_SetRegOR(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
 
-	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+		if (pVBInfo->SetFlag & Win9xDOSMode) {
+			XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+			return;
+		}
+
+		if (!(pVBInfo->SetFlag & DisableChA)) {
+			XGI_VBLongWait(pVBInfo);
+			if (!(pVBInfo->SetFlag & GatingCRT)) {
+				XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
+				XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+				XGI_VBLongWait(pVBInfo);
+			}
+		}
+	} /* 301 */
+	else { /* LVDS */
+		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
+				| SetCRT2ToLCDA))
+			XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
 
-	index = (modeflag & ModeInfoFlag) - ModeEGA;
+		tempah = (unsigned char) XGINew_GetReg1(pVBInfo->Part1Port,
+				0x2E);
+		if (!(tempah & 0x80))
+			XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
 
-	if (index < 0)
-		index = 0;
+		XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F);
+		XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+	} /* End of VB */
 
-	return ColorDepth[index];
-}
+	if (HwDeviceExtension->jChipType < XG40) {
+		if (!XGI_EnableChISLCD(pVBInfo)) {
+			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+				if (XGI_BacklightByDrv(pVBInfo))
+					return;
+			} else
+				return;
+		}
 
-void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
+		if (pVBInfo->LCDInfo & SetPWDEnable) {
+			XGI_FirePWDEnable(pVBInfo);
+			return;
+		}
 
-	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
+		XGI_SetPanelDelay(2, pVBInfo);
 
+		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+			tempah = 0x01;
+			tempbl = 0xFE; /* turn on backlght */
+		} else {
+			tempbl = 0xF7;
+			tempah = 0x00;
+		}
+		XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+	}
 }
 
-void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
+static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension,
+		unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
+	unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp;
 
-	XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
-
-}
-
-static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
-{
-	XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
-}
+	unsigned short XGINew_P3cc = pVBInfo->P3cc;
 
-unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
-{
-	unsigned short flag;
+	/* XGINew_CRT1Mode = ModeNo; // SaveModeID */
+	StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+	/* XGI_SetBIOSData(ModeNo, ModeIdIndex); */
+	/* XGI_ClearBankRegs(ModeNo, ModeIdIndex); */
+	XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
+	XGI_SetMiscRegs(StandTableIndex, pVBInfo);
+	XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo);
+	XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
+	XGI_SetGRCRegs(StandTableIndex, pVBInfo);
+	XGI_ClearExt1Regs(pVBInfo);
 
-	if (pVBInfo->IF_DEF_LVDS == 1) {
-		return 1;
-	} else {
-		flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
-		if ((flag == 1) || (flag == 2))
-			return 1; /* 301b */
-		else
-			return 0;
+	/* if (pVBInfo->IF_DEF_ExpLink) */
+	if (HwDeviceExtension->jChipType == XG27) {
+		if (pVBInfo->IF_DEF_LVDS == 0)
+			XGI_SetDefaultVCLK(pVBInfo);
 	}
-}
-
-void XGI_LongWait(struct vb_device_info *pVBInfo)
-{
-	unsigned short i;
 
-	i = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
+	temp = ~ProgrammingCRT2;
+	pVBInfo->SetFlag &= temp;
+	pVBInfo->SelectCRT2Rate = 0;
 
-	if (!(i & 0xC0)) {
-		for (i = 0; i < 0xFFFF; i++) {
-			if (!(XGINew_GetReg2(pVBInfo->P3da) & 0x08))
-				break;
+	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+			| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA
+				| SetInSlaveMode)) {
+			pVBInfo->SetFlag |= ProgrammingCRT2;
 		}
+	}
 
-		for (i = 0; i < 0xFFFF; i++) {
-			if ((XGINew_GetReg2(pVBInfo->P3da) & 0x08))
-				break;
+	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+			ModeIdIndex, pVBInfo);
+	if (RefreshRateTableIndex != 0xFFFF) {
+		XGI_SetSync(RefreshRateTableIndex, pVBInfo);
+		XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+				pVBInfo, HwDeviceExtension);
+		XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
+				RefreshRateTableIndex, pVBInfo);
+		XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+				HwDeviceExtension, pVBInfo);
+		XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
+				RefreshRateTableIndex, pVBInfo);
+	}
+
+	if ((HwDeviceExtension->jChipType >= XG20)
+			&& (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */
+		if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9);
+			b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
+			XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
+		} else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo
+				== 0x0D)) {
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
+			XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3);
+			b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
+			XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
 		}
 	}
-}
 
-static void XGI_VBLongWait(struct vb_device_info *pVBInfo)
-{
-	unsigned short tempal, temp, i, j;
-	return;
-	if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
-		temp = 0;
-		for (i = 0; i < 3; i++) {
-			for (j = 0; j < 100; j++) {
-				tempal = XGINew_GetReg2(pVBInfo->P3da);
-				if (temp & 0x01) { /* VBWaitMode2 */
-					if ((tempal & 0x08))
-						continue;
+	if (HwDeviceExtension->jChipType >= XG21) {
+		temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+		if (temp & 0xA0) {
 
-					if (!(tempal & 0x08))
-						break;
+			/* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */
+			/* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */
+			/* XG21 CRT1 Timing */
+			if (HwDeviceExtension->jChipType == XG27)
+				XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
+						RefreshRateTableIndex, pVBInfo);
+			else
+				XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
+						RefreshRateTableIndex, pVBInfo);
 
-				} else { /* VBWaitMode1 */
-					if (!(tempal & 0x08))
-						continue;
+			XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
+					RefreshRateTableIndex);
 
-					if ((tempal & 0x08))
-						break;
-				}
+			if (HwDeviceExtension->jChipType == XG27)
+				XGI_SetXG27LCD(pVBInfo, RefreshRateTableIndex,
+						ModeNo);
+			else
+				XGI_SetXG21LCD(pVBInfo, RefreshRateTableIndex,
+						ModeNo);
+
+			if (pVBInfo->IF_DEF_LVDS == 1) {
+				if (HwDeviceExtension->jChipType == XG27)
+					XGI_SetXG27LVDSPara(ModeNo,
+							ModeIdIndex, pVBInfo);
+				else
+					XGI_SetXG21LVDSPara(ModeNo,
+							ModeIdIndex, pVBInfo);
 			}
-			temp = temp ^ 0x01;
+			/* XGINew_SetRegOR(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */
 		}
-	} else {
-		XGI_LongWait(pVBInfo);
 	}
-	return;
-}
 
-static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
-{
-	unsigned long tempax, tempbx;
+	pVBInfo->SetFlag &= (~ProgrammingCRT2);
+	XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
+	XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
+			RefreshRateTableIndex, pVBInfo);
 
-	tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
-			& 0xFFFF;
-	tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
-	tempax = (tempax * pVBInfo->HT) / tempbx;
+	/* XGI_LoadCharacter(); //dif ifdef TVFont */
 
-	return (unsigned short) tempax;
+	XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
+	/* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */
 }
 
-static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
-		unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
+unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
+			unsigned short ModeNo)
 {
-	unsigned short tempbx;
+	unsigned short ModeIdIndex;
+	/* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; */
+	struct vb_device_info VBINF;
+	struct vb_device_info *pVBInfo = &VBINF;
+	pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+	pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+	pVBInfo->IF_DEF_LVDS = 0;
+	pVBInfo->IF_DEF_CH7005 = 0;
+	pVBInfo->IF_DEF_LCDA = 1;
+	pVBInfo->IF_DEF_CH7017 = 0;
+	pVBInfo->IF_DEF_CH7007 = 0; /* [Billy] 2007/05/14 */
+	pVBInfo->IF_DEF_VideoCapture = 0;
+	pVBInfo->IF_DEF_ScaleLCD = 0;
+	pVBInfo->IF_DEF_OEMUtil = 0;
+	pVBInfo->IF_DEF_PWD = 0;
+
+	if (HwDeviceExtension->jChipType >= XG20) { /* kuku 2004/06/25 */
+		pVBInfo->IF_DEF_YPbPr = 0;
+		pVBInfo->IF_DEF_HiVision = 0;
+		pVBInfo->IF_DEF_CRT2Monitor = 0;
+		pVBInfo->VBType = 0; /*set VBType default 0*/
+	} else if (HwDeviceExtension->jChipType >= XG40) {
+		pVBInfo->IF_DEF_YPbPr = 1;
+		pVBInfo->IF_DEF_HiVision = 1;
+		pVBInfo->IF_DEF_CRT2Monitor = 1;
+	} else {
+		pVBInfo->IF_DEF_YPbPr = 1;
+		pVBInfo->IF_DEF_HiVision = 1;
+		pVBInfo->IF_DEF_CRT2Monitor = 0;
+	}
+
+	pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+	pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+	pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+	pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+	pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+	pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C;
+	pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+	pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+	pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+	pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+	pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+	pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+	pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+	pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+	pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+	pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+	pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+	pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
 
-	unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
-			VCLK65 + 2 };
-	unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, VCLK108_2 + 5,
-			VCLK108_2 + 5, VCLK108_2 + 5 };
-	unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
-	unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
-			VCLK65 + 2 };
-	unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
-			VCLK65 + 2 };
+	if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */
+		if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
+			pVBInfo->IF_DEF_LVDS = 1;
+	}
+	if (HwDeviceExtension->jChipType == XG27) {
+		if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
+			if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20)
+				pVBInfo->IF_DEF_LVDS = 1;
+		}
+	}
 
-	unsigned short CRT2Index, VCLKIndex;
-	unsigned short modeflag, resinfo;
-	unsigned char *CHTVVCLKPtr = NULL;
+	if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
+		XGI_GetVBType(pVBInfo);
 
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
-		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
-		CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT2Index
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+	InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+	if (ModeNo & 0x80) {
+		ModeNo = ModeNo & 0x7F;
+		/* XGINew_flag_clearbuffer = 0; */
+	}
+	/* else {
+		XGINew_flag_clearbuffer = 1;
 	}
+	*/
+	XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
 
-	if (pVBInfo->IF_DEF_LVDS == 0) {
-		CRT2Index = CRT2Index >> 6; /*  for LCD */
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/
-			if (pVBInfo->LCDResInfo != Panel1024x768)
-				VCLKIndex = LCDXlat2VCLK[CRT2Index];
-			else
-				VCLKIndex = LCDXlat1VCLK[CRT2Index];
-		} else { /* for TV */
-			if (pVBInfo->VBInfo & SetCRT2ToTV) {
-				if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-					if (pVBInfo->SetFlag & RPLLDIV2XO) {
-						VCLKIndex = HiTVVCLKDIV2;
+	if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */
+		XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
 
-						VCLKIndex += 25;
+	XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
 
-					} else {
-						VCLKIndex = HiTVVCLK;
+	XGI_GetVGAType(HwDeviceExtension, pVBInfo);
 
-						VCLKIndex += 25;
+	if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+		XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
+		XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
+		XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
+		XGI_DisableBridge(HwDeviceExtension, pVBInfo);
+		/* XGI_OpenCRTC(HwDeviceExtension, pVBInfo); */
 
-					}
+		if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+			XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
+					ModeIdIndex, pVBInfo);
 
-					if (pVBInfo->SetFlag & TVSimuMode) {
-						if (modeflag & Charx8Dot) {
-							VCLKIndex
-									= HiTVSimuVCLK;
+			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+				XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
+						HwDeviceExtension, pVBInfo);
+			}
+		} else {
+			if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
+				XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
+						ModeIdIndex, pVBInfo);
+				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+					XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
+							HwDeviceExtension,
+							pVBInfo);
+				}
+			}
+		}
 
-							VCLKIndex += 25;
+		if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+			switch (HwDeviceExtension->ujVBChipID) {
+			case VB_CHIP_301:
+				XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
+						pVBInfo); /*add for CRT2 */
+				break;
 
-						} else {
-							VCLKIndex
-									= HiTVTextVCLK;
+			case VB_CHIP_302:
+				XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
+						pVBInfo); /*add for CRT2 */
+				break;
 
-							VCLKIndex += 25;
+			default:
+				break;
+			}
+		}
 
-						}
-					}
+		XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
+		XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
+		XGI_CloseCRTC(HwDeviceExtension, pVBInfo);
+		XGI_EnableBridge(HwDeviceExtension, pVBInfo);
+	} /* !XG20 */
+	else {
+		if (pVBInfo->IF_DEF_LVDS == 1)
+			if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
+				return 0;
 
-					if (pVBInfo->VBType & VB_XGI301LV) { /* 301lv */
-						if (!(pVBInfo->VBExtInfo
-								== VB_YPbPr1080i)) {
-							VCLKIndex
-									= YPbPr750pVCLK;
-							if (!(pVBInfo->VBExtInfo
-									== VB_YPbPr750p)) {
-								VCLKIndex
-										= YPbPr525pVCLK;
-								if (!(pVBInfo->VBExtInfo
-										== VB_YPbPr525p)) {
-									VCLKIndex
-											= YPbPr525iVCLK_2;
-									if (!(pVBInfo->SetFlag
-											& RPLLDIV2XO))
-										VCLKIndex
-												= YPbPr525iVCLK;
-								}
-							}
-						}
-					}
-				} else {
-					if (pVBInfo->VBInfo & SetCRT2ToTV) {
-						if (pVBInfo->SetFlag
-								& RPLLDIV2XO) {
-							VCLKIndex = TVVCLKDIV2;
+		if (ModeNo <= 0x13) {
+			pVBInfo->ModeType
+					= pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+							& ModeInfoFlag;
+		} else {
+			pVBInfo->ModeType
+					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag
+							& ModeInfoFlag;
+		}
 
-							VCLKIndex += 25;
+		pVBInfo->SetFlag = 0;
+		if (pVBInfo->IF_DEF_CH7007 != 1)
+			pVBInfo->VBInfo = DisableCRT2Display;
 
-						} else {
-							VCLKIndex = TVVCLK;
+		XGI_DisplayOff(HwDeviceExtension, pVBInfo);
 
-							VCLKIndex += 25;
+		XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
+				pVBInfo);
 
-						}
-					}
-				}
-			} else { /* for CRT2 */
-				VCLKIndex = (unsigned char) XGINew_GetReg2(
-						(pVBInfo->P3ca + 0x02)); /* Port 3cch */
-				VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-				if (ModeNo > 0x13) {
-					VCLKIndex
-							= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; /* di+Ext_CRTVCLK */
-					VCLKIndex &= IndexMask;
-				}
-			}
-		}
-	} else { /* LVDS */
-		if (ModeNo <= 0x13)
-			VCLKIndex = CRT2Index;
-		else
-			VCLKIndex = CRT2Index;
+		XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+		/*
+		if (HwDeviceExtension->jChipType == XG21)
+			XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80);
+		*/
+	}
 
-		if (pVBInfo->IF_DEF_CH7005 == 1) {
-			if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
-				VCLKIndex &= 0x1f;
-				tempbx = 0;
+	/*
+	if (ModeNo <= 0x13) {
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+	} else {
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	}
+	pVBInfo->ModeType = modeflag&ModeInfoFlag;
+	pVBInfo->SetFlag = 0x00;
+	pVBInfo->VBInfo = DisableCRT2Display;
+	temp = XGINew_CheckMemorySize(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
 
-				if (pVBInfo->VBInfo & SetPALTV)
-					tempbx += 2;
+	if (temp == 0)
+		return (0);
 
-				if (pVBInfo->VBInfo & SetCHTVOverScan)
-					tempbx += 1;
+	XGI_DisplayOff(HwDeviceExtension, pVBInfo) ;
+	XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+	XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+	*/
 
-				switch (tempbx) {
-				case 0:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
-					break;
-				case 1:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
-					break;
-				case 2:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
-					break;
-				case 3:
-					CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
-					break;
-				default:
-					break;
-				}
+	XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
 
-				VCLKIndex = CHTVVCLKPtr[VCLKIndex];
-			}
-		} else {
-			VCLKIndex = VCLKIndex >> 6;
-			if ((pVBInfo->LCDResInfo == Panel800x600)
-					|| (pVBInfo->LCDResInfo == Panel320x480))
-				VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-			else if ((pVBInfo->LCDResInfo == Panel1024x768)
-					|| (pVBInfo->LCDResInfo
-							== Panel1024x768x75))
-				VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
-			else
-				VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
-		}
+	if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+		XGI_LockCRT2(HwDeviceExtension, pVBInfo);
 	}
-	/* VCLKIndex = VCLKIndex&IndexMask; */
 
-	return VCLKIndex;
+	return 1;
 }
-
-- 
1.7.4.1

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux