- It complies somewhat with the corresponding VESA function
- in arguments and return values.
-
- Since this is probably called before the mode is changed,
- we use our pre-detected pSiS-values instead of SiS_Pr as
- regards chipset and video bridge type.
-
- Arguments:
- adaptnum: 0=CRT1, 1=LCD, 2=VGA2
- CRT2 DDC is only supported on SiS301, 301B, 302B.
- DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
- buffer: ptr to 256 data bytes which will be filled with read data.
-
- Returns 0xFFFF if error, otherwise
- if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum)
- if DDCdatatype = 0: Returns supported DDC modes
-
- */
-USHORT
-SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
-{
- unsigned char sr1f,cr17=1;
- USHORT result;
-
- if(adaptnum > 2) return 0xFFFF;
- if(DDCdatatype > 4) return 0xFFFF;
- if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
- if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
-
- sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
- if(VGAEngine == SIS_300_VGA) {
- cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
- if(!cr17) {
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
- }
- }
- if((sr1f) || (!cr17)) {
- SiS_WaitRetrace1(SiS_Pr);
- SiS_WaitRetrace1(SiS_Pr);
- SiS_WaitRetrace1(SiS_Pr);
- SiS_WaitRetrace1(SiS_Pr);
- }
-
- if(DDCdatatype == 0) {
- result = SiS_ProbeDDC(SiS_Pr);
- } else {
- result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
- if(VGAEngine == SIS_300_VGA) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
- }
- return result;
-}
-
-#ifdef LINUX_XF86
-
-static BOOLEAN
-checkedid1(unsigned char *buffer)
-{
- /* Check header */
- if((buffer[0] != 0x00) ||
- (buffer[1] != 0xff) ||
- (buffer[2] != 0xff) ||
- (buffer[3] != 0xff) ||
- (buffer[4] != 0xff) ||
- (buffer[5] != 0xff) ||
- (buffer[6] != 0xff) ||
- (buffer[7] != 0x00))
- return FALSE;
-
- /* Check EDID version and revision */
- if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
-
- /* Check week of manufacture for sanity */
- if(buffer[0x10] > 53) return FALSE;
-
- /* Check year of manufacture for sanity */
- if(buffer[0x11] > 40) return FALSE;
-
- return TRUE;
-}
-
-static BOOLEAN
-checkedid2(unsigned char *buffer)
-{
- USHORT year = buffer[6] | (buffer[7] << 8);
-
- /* Check EDID version */
- if((buffer[0] & 0xf0) != 0x20) return FALSE;
-
- /* Check week of manufacture for sanity */
- if(buffer[5] > 53) return FALSE;
-
- /* Check year of manufacture for sanity */
- if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
-
- return TRUE;
-}
-
-/* Sense the LCD parameters (CR36, CR37) via DDC */
-/* SiS30x(B) only */
-USHORT
-SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
-{
- USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
- USHORT index, myindex, lumsize, numcodes;
- unsigned char cr37=0, seekcode;
- BOOLEAN checkexpand = FALSE;
- int retry, i;
- unsigned char buffer[256];
-
- for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
- SiS_Pr->CP_HaveCustomData = FALSE;
- SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
-
- if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
- if(pSiS->VBFlags & VB_30xBDH) return 0;
-
- if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
-
- SiS_Pr->SiS_DDC_SecAddr = 0x00;
-
- /* Probe supported DA's */
- flag = SiS_ProbeDDC(SiS_Pr);
-#ifdef TWDEBUG
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
- "CRT2 DDC capabilities 0x%x\n", flag);
-#endif
- if(flag & 0x10) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
- DDCdatatype = 4;
- } else if(flag & 0x08) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
- DDCdatatype = 3;
- } else if(flag & 0x02) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
- DDCdatatype = 1;
- } else return 0; /* no DDC support (or no device attached) */
-
- /* Read the entire EDID */
- retry = 2;
- do {
- if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: DDC read failed (attempt %d), %s\n",
- (3-retry), (retry == 1) ? "giving up" : "retrying");
- retry--;
- if(retry == 0) return 0xFFFF;
- } else break;
- } while(1);
-
-#ifdef TWDEBUG
- for(i=0; i<256; i+=16) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
- buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
- buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
- buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
- }
-#endif
-
- /* Analyze EDID and retrieve LCD panel information */
- paneltype = 0;
- switch(DDCdatatype) {
- case 1: /* Analyze EDID V1 */
- /* Catch a few clear cases: */
- if(!(checkedid1(buffer))) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: EDID corrupt\n");
- return 0;
- }
-
- if(!(buffer[0x14] & 0x80)) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: Attached display expects analog input (0x%02x)\n",
- buffer[0x14]);
- return 0;
- }
-
- if((buffer[0x18] & 0x18) != 0x08) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
- ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
- ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
- "undefined"),
- buffer[0x18]);
- return 0;
- }
-
- /* Now analyze the first Detailed Timing Block and see
- * if the preferred timing mode is stored there. If so,
- * check if this is a standard panel for which we already
- * know the timing.
- */
-
- paneltype = Panel_Custom;
- checkexpand = FALSE;
-
- if(buffer[0x18] & 0x02) {
-
- xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
- yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
-
- SiS_Pr->CP_PreferredX = xres;
- SiS_Pr->CP_PreferredY = yres;
-
- switch(xres) {
- case 800:
- if(yres == 600) {
- paneltype = Panel_800x600;
- checkexpand = TRUE;
- }
- break;
- case 1024:
- if(yres == 768) {
- paneltype = Panel_1024x768;
- checkexpand = TRUE;
- }
- break;
- case 1280:
- if(yres == 1024) {
- paneltype = Panel_1280x1024;
- checkexpand = TRUE;
- } else if(yres == 960) {
- if(pSiS->VGAEngine == SIS_300_VGA) {
- paneltype = Panel300_1280x960;
- } else {
- paneltype = Panel310_1280x960;
- }
- } else if(yres == 768) {
- if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
- ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
- ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
- paneltype = Panel_1280x768;
- checkexpand = FALSE;
- cr37 |= 0x10;
- }
- }
- break;
- case 1400:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1050) {
- paneltype = Panel310_1400x1050;
- checkexpand = TRUE;
- }
- }
- break;
-#if 0 /* Treat this as custom, as we have no valid timing data yet */
- case 1600:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1200) {
- paneltype = Panel310_1600x1200;
- checkexpand = TRUE;
- }
- }
- break;
-#endif
- }
-
- if(paneltype != Panel_Custom) {
- if((buffer[0x47] & 0x18) == 0x18) {
- cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
- } else {
- /* What now? There is no digital separate output timing... */
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
- "CRT2: Unable to retrieve Sync polarity information\n");
- cr37 |= 0xc0; /* Default */
- }
- }
-
- }
-
- /* If we still don't know what panel this is, we take it
- * as a custom panel and derive the timing data from the
- * detailed timing blocks
- */
- if(paneltype == Panel_Custom) {
-
- BOOLEAN havesync = FALSE;
- int i, temp, base = 0x36;
- unsigned long estpack;
- unsigned short estx[] = {
- 720, 720, 640, 640, 640, 640, 800, 800,
- 800, 800, 832,1024,1024,1024,1024,1280,
- 1152
- };
- unsigned short esty[] = {
- 400, 400, 480, 480, 480, 480, 600, 600,
- 600, 600, 624, 768, 768, 768, 768,1024,
- 870
- };
-
- paneltype = 0;
- SiS_Pr->CP_Supports64048075 = TRUE;
-
- /* Find the maximum resolution */
-
- /* 1. From Established timings */
- estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
- for(i=16; i>=0; i--) {
- if(estpack & (1 << i)) {
- if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
- if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
- }
- }
-
- /* 2. From Standard Timings */
- for(i=0x26; i < 0x36; i+=2) {
- if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
- temp = (buffer[i] + 31) * 8;
- if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
- switch((buffer[i+1] & 0xc0) >> 6) {
- case 0x03: temp = temp * 9 / 16; break;
- case 0x02: temp = temp * 4 / 5; break;
- case 0x01: temp = temp * 3 / 4; break;
- }
- if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
- }
- }
-
- /* Now extract the Detailed Timings and convert them into modes */
-
- for(i = 0; i < 4; i++, base += 18) {
-
- /* Is this a detailed timing block or a monitor descriptor? */
- if(buffer[base] || buffer[base+1] || buffer[base+2]) {
-
- xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
- yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
-
- SiS_Pr->CP_HDisplay[i] = xres;
- SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
- SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
- SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
- SiS_Pr->CP_HBlankStart[i] = xres + 1;
- SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-
- SiS_Pr->CP_VDisplay[i] = yres;
- SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
- SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
- SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
- SiS_Pr->CP_VBlankStart[i] = yres + 1;
- SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-
- SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
-
- SiS_Pr->CP_DataValid[i] = TRUE;
-
- /* Sort out invalid timings, interlace and too high clocks */
- if((SiS_Pr->CP_HDisplay[i] & 7) ||
- (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
- (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
- ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) ||
- (buffer[base+17] & 0x80)) {
-
- SiS_Pr->CP_DataValid[i] = FALSE;
-
- } else {
-
- paneltype = Panel_Custom;
-
- SiS_Pr->CP_HaveCustomData = TRUE;
-
- if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
- if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
- if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
-
- SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
- SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
-
- /* By default we drive the LCD at 75Hz in 640x480 mode; if
- * the panel does not provide this mode, use 60hz
- */
- if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
-
- /* We must assume the panel can scale, since we have
- * no scaling data
- */
- checkexpand = FALSE;
- cr37 |= 0x10;
-
- /* Extract the sync polarisation information. This only works
- * if the Flags indicate a digital separate output.
- */
- if((buffer[base+17] & 0x18) == 0x18) {
- SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
- SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
- SiS_Pr->CP_SyncValid[i] = TRUE;
- if(!havesync) {
- cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
- havesync = TRUE;
- }
- } else {
- SiS_Pr->CP_SyncValid[i] = FALSE;
- }
- }
- }
- }
- if(!havesync) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
- "CRT2: Unable to retrieve Sync polarity information\n");
- }
- }
-
- if(paneltype && checkexpand) {
- /* If any of the Established low-res modes is supported, the
- * panel can scale automatically. For 800x600 panels, we only
- * check the even lower ones.
- */
- if(paneltype == Panel_800x600) {
- if(buffer[0x23] & 0xfc) cr37 |= 0x10;
- } else {
- if(buffer[0x23]) cr37 |= 0x10;
- }
- }
-
- break;
-
- case 3: /* Analyze EDID V2 */
- case 4:
- index = 0;
-
- if(!(checkedid2(buffer))) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: EDID corrupt\n");
- return 0;
- }
-
- if((buffer[0x41] & 0x0f) == 0x03) {
- index = 0x42 + 3;
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: Display supports TMDS input on primary interface\n");
- } else if((buffer[0x41] & 0xf0) == 0x30) {
- index = 0x46 + 3;
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: Display supports TMDS input on secondary interface\n");
- } else {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: Display does not support TMDS video interface (0x%02x)\n",
- buffer[0x41]);
- return 0;
- }
-
- paneltype = Panel_Custom;
- SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
- SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
- switch(xres) {
- case 800:
- if(yres == 600) {
- paneltype = Panel_800x600;
- checkexpand = TRUE;
- }
- break;
- case 1024:
- if(yres == 768) {
- paneltype = Panel_1024x768;
- checkexpand = TRUE;
- }
- break;
- case 1152:
- if(yres == 768) {
- if(pSiS->VGAEngine == SIS_300_VGA) {
- paneltype = Panel300_1152x768;
- } else {
- paneltype = Panel310_1152x768;
- }
- checkexpand = TRUE;
- }
- break;
- case 1280:
- if(yres == 960) {
- if(pSiS->VGAEngine == SIS_315_VGA) {
- paneltype = Panel310_1280x960;
- } else {
- paneltype = Panel300_1280x960;
- }
- } else if(yres == 1024) {
- paneltype = Panel_1280x1024;
- checkexpand = TRUE;
- }
- /* 1280x768 treated as custom here */
- break;
- case 1400:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1050) {
- paneltype = Panel310_1400x1050;
- checkexpand = TRUE;
- }
- }
- break;
-#if 0 /* Treat this one as custom since we have no timing data yet */
- case 1600:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1200) {
- paneltype = Panel310_1600x1200;
- checkexpand = TRUE;
- }
- }
- break;
-#endif
- }
-
- /* Determine if RGB18 or RGB24 */
- if(index) {
- if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
- cr37 |= 0x01;
- }
- }
-
- if(checkexpand) {
- /* TODO - for now, we let the panel scale */
- cr37 |= 0x10;
- }
-
- /* Now seek 4-Byte Timing codes and extract sync pol info */
- index = 0x80;
- if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
- lumsize = buffer[0x80] & 0x1f;
- if(buffer[0x80] & 0x80) lumsize *= 3;
- lumsize++; /* luminance header byte */
- index += lumsize;
- }
- index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
- index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
- numcodes = (buffer[0x7f] & 0xf8) >> 3;
- if(numcodes) {
- myindex = index;
- seekcode = (xres - 256) / 16;
- for(i=0; i<numcodes; i++) {
- if(buffer[myindex] == seekcode) break;
- myindex += 4;
- }
- if(buffer[myindex] == seekcode) {
- cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
- } else {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
- "CRT2: Unable to retrieve Sync polarity information\n");
- }
- } else {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
- "CRT2: Unable to retrieve Sync polarity information\n");
- }
-
- /* Now seek the detailed timing descriptions for custom panels */
- if(paneltype == Panel_Custom) {
-
- SiS_Pr->CP_Supports64048075 = TRUE;
-
- index += (numcodes * 4);
- numcodes = buffer[0x7f] & 0x07;
- for(i=0; i<numcodes; i++, index += 18) {
- xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
- yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
-
- SiS_Pr->CP_HDisplay[i] = xres;
- SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
- SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
- SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
- SiS_Pr->CP_HBlankStart[i] = xres + 1;
- SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-
- SiS_Pr->CP_VDisplay[i] = yres;
- SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
- SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
- SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
- SiS_Pr->CP_VBlankStart[i] = yres + 1;
- SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-
- SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
-
- SiS_Pr->CP_DataValid[i] = TRUE;
-
- if((SiS_Pr->CP_HDisplay[i] & 7) ||
- (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
- (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
- ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) ||
- (buffer[index + 17] & 0x80)) {
-
- SiS_Pr->CP_DataValid[i] = FALSE;
-
- } else {
-
- SiS_Pr->CP_HaveCustomData = TRUE;
-
- if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];