S3VMODETABLE* pmt;  ErrorF("%s %s: Found %d modes at this depth:\n", XCONFIG_PROBED, vga256InfoRec.name, s3vModeCount);
PS3VMODEENTRY pmt;  ErrorF( "%s %s: Found %d modes at this depth:\n", XCONFIG_PROBED, vga256InfoRec.name, s3vModeTable->NumModes);
S3SAVProbe(){S3PCIInformation *pciInfo = NULL;unsigned char config1, m, n, n1, n2, cr66, sr8;int mclk;DisplayModePtr pMode, pEnd;   if (vga256InfoRec.chipset) {      if (StrCaseCmp(vga256InfoRec.chipset,S3SAVIdent(0)))      return(FALSE);   }    /* Start with PCI probing, this should get us quite far already */   pciInfo = S3SAVGetPCIInfo();   if (!pciInfo)      return FALSE;   if (pciInfo && pciInfo->MemBase && !vga256InfoRec.MemBase) {      if (pciInfo->ChipType >= S3_SAVAGE4) {	 s3vPriv.MmioBase = pciInfo->MemBase + S3_NEWMMIO_REGBASE_S4;	 s3vPriv.FrameBufferBase = pciInfo->MemBase1;      }      else {	 s3vPriv.MmioBase = pciInfo->MemBase + S3_NEWMMIO_REGBASE_S3;	 s3vPriv.FrameBufferBase = pciInfo->MemBase;      }      vga256InfoRec.MemBase = s3vPriv.FrameBufferBase;   }   if (pciInfo)      if(pciInfo->ChipType != S3_SAVAGE3D && 	 pciInfo->ChipType != S3_SAVAGE3D_MV &&	 pciInfo->ChipType != S3_SAVAGE4 &&	 pciInfo->ChipType != S3_SAVAGE2000){          if (xf86Verbose > 1)             ErrorF("%s %s: Unsupported (non-Savage) S3 chipset detected!\n",                 XCONFIG_PROBED, vga256InfoRec.name);          return FALSE;          }      else {         s3vPriv.chip = pciInfo->ChipType;         ErrorF("%s %s: Detected S3 %s\n",XCONFIG_PROBED,            vga256InfoRec.name, xf86TokenToString(s3savChipTable, s3vPriv.chip));         ErrorF("%s %s: using driver for chipset \"%s\"\n",XCONFIG_PROBED,             vga256InfoRec.name, S3SAVIdent(0));	 }   vga256InfoRec.chipset = S3SAVIdent(0);#ifdef __alpha__   if (xf86bpp > 16)     FatalError("%s %s: %d bpp not yet supported for Alpha/AXP\n",		XCONFIG_GIVEN, vga256InfoRec.name, xf86bpp);#endif   /* Add/enable IO ports to list: call EnterLeave */   S3SAVEnterLeave(ENTER);   /* Unlock sys regs */   outb(vgaCRIndex, 0x38);   outb(vgaCRReg, 0x48);    /* Next go on to detect amount of installed ram */   outb(vgaCRIndex, 0x36);              /* for register CR36 (CONFG_REG1), */   config1 = inb(vgaCRReg);              /* get amount of vram installed */   outb(vgaCRIndex, 0x2e);   s3vPriv.ChipId = inb(vgaCRReg);         /* get chip id */   outb(vgaCRIndex, 0x2d);   s3vPriv.ChipId |= (inb(vgaCRReg) << 8);   /* And compute the amount of video memory and offscreen memory */   s3vPriv.MemOffScreen = 0;   if (!vga256InfoRec.videoRam) {      if( (s3vPriv.ChipId == PCI_SAVAGE4) ||      	  (s3vPriv.ChipId == PCI_SAVAGE2000)      ) {	 switch (config1 >> 5) {	 case 0:	    vga256InfoRec.videoRam = 2;	    break;	 case 1:	    vga256InfoRec.videoRam = 4;	    break;	 case 2:	    vga256InfoRec.videoRam = 8;	    break;	 case 3:	    vga256InfoRec.videoRam = 12;	    break;	 case 4:	    vga256InfoRec.videoRam = 16;	    break;	 case 5:	    vga256InfoRec.videoRam = 32;	    break;	 case 6:	    vga256InfoRec.videoRam = 64;	    break;	 default:	    vga256InfoRec.videoRam = 2;         }        }      else {	 switch((config1 & 0xC0) >> 6) {	 case 0:	    vga256InfoRec.videoRam = 8;	    break;	 case 1:	 case 2:	    vga256InfoRec.videoRam = 4;	    break;	 case 3:	 default:	    vga256InfoRec.videoRam = 2;	 }      }      vga256InfoRec.videoRam *= 1024;      if (xf86Verbose) {         if (s3vPriv.MemOffScreen)            ErrorF("%s %s: videoram:  %dk (plus %dk off-screen)\n",                   XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.videoRam,                   s3vPriv.MemOffScreen);         else            ErrorF("%s %s: videoram:  %dk\n",                   XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.videoRam);      }   } else {      if (xf86Verbose) {         ErrorF("%s %s: videoram:  %dk\n",              XCONFIG_GIVEN, vga256InfoRec.name, vga256InfoRec.videoRam);      }   }   /* reset S3 graphics engine to avoid memory corruption */   outb(vgaCRIndex, 0x66);   cr66 = inb(vgaCRReg);   outb(vgaCRReg, cr66 | 0x02);   usleep(10000);  /* wait a little bit... */   outb(vgaCRIndex, 0x66);   outb(vgaCRReg, cr66 & ~0x02);  /* clear reset flag */   usleep(10000);  /* wait a little bit... */   /* ViRGE built-in ramdac speeds */   if (vga256InfoRec.dacSpeeds[3] <= 0 && vga256InfoRec.dacSpeeds[2] > 0)      vga256InfoRec.dacSpeeds[3] = vga256InfoRec.dacSpeeds[2];   if (s3vPriv.chip == S3_SAVAGE3D ||       s3vPriv.chip == S3_SAVAGE3D_MV ||       s3vPriv.chip == S3_SAVAGE4 ||       s3vPriv.chip == S3_SAVAGE2000) {      if (vga256InfoRec.dacSpeeds[0] <= 0) vga256InfoRec.dacSpeeds[0] = 250000;      if (vga256InfoRec.dacSpeeds[1] <= 0) vga256InfoRec.dacSpeeds[1] = 250000;      if (vga256InfoRec.dacSpeeds[2] <= 0) vga256InfoRec.dacSpeeds[2] = 220000;      if (vga256InfoRec.dacSpeeds[3] <= 0) vga256InfoRec.dacSpeeds[3] = 220000;   }   else {      if (vga256InfoRec.dacSpeeds[0] <= 0) vga256InfoRec.dacSpeeds[0] = 250000;      if (vga256InfoRec.dacSpeeds[1] <= 0) vga256InfoRec.dacSpeeds[1] = 250000;      if (vga256InfoRec.dacSpeeds[2] <= 0) vga256InfoRec.dacSpeeds[2] = 220000;      if (vga256InfoRec.dacSpeeds[3] <= 0) vga256InfoRec.dacSpeeds[3] = 220000;   }   /* Set status word positions based on chip type. */   switch( s3vPriv.chip ) {      case S3_SAVAGE3D:      case S3_SAVAGE3D_MV:         s3vPriv.WaitQueue = WaitQueue3D;	 s3vPriv.WaitIdle = WaitIdle3D;	 s3vPriv.WaitIdleEmpty = WaitIdleEmpty3D;	 s3vPriv.WaitCommandEmpty = WaitCommandEmpty3D;	 break;      case S3_SAVAGE4:         s3vPriv.WaitQueue = WaitQueue4;	 s3vPriv.WaitIdle = WaitIdle4;	 s3vPriv.WaitIdleEmpty = WaitIdleEmpty4;	 s3vPriv.WaitCommandEmpty = WaitCommandEmpty4;         break;      case S3_SAVAGE2000:         s3vPriv.WaitQueue = WaitQueue2K;	 s3vPriv.WaitIdle = WaitIdle2K;	 s3vPriv.WaitIdleEmpty = WaitIdleEmpty2K;	 s3vPriv.WaitCommandEmpty = WaitCommandEmpty2K;         break;   }      if (vga256InfoRec.dacSpeedBpp <= 0)      if (xf86bpp > 24 && vga256InfoRec.dacSpeeds[3] > 0)	 vga256InfoRec.dacSpeedBpp = vga256InfoRec.dacSpeeds[3];      else if (xf86bpp >= 24 && vga256InfoRec.dacSpeeds[2] > 0)	 vga256InfoRec.dacSpeedBpp = vga256InfoRec.dacSpeeds[2];      else if (xf86bpp > 8 && xf86bpp < 24 && vga256InfoRec.dacSpeeds[1] > 0)	 vga256InfoRec.dacSpeedBpp = vga256InfoRec.dacSpeeds[1];      else if (xf86bpp <= 8 && vga256InfoRec.dacSpeeds[0] > 0)	 vga256InfoRec.dacSpeedBpp = vga256InfoRec.dacSpeeds[0];   if (xf86Verbose) {      ErrorF("%s %s: Ramdac speed: %d MHz",	     OFLG_ISSET(XCONFIG_DACSPEED, &vga256InfoRec.xconfigFlag) ?	     XCONFIG_GIVEN : XCONFIG_PROBED, vga256InfoRec.name,	     vga256InfoRec.dacSpeeds[0] / 1000);      if (vga256InfoRec.dacSpeedBpp != vga256InfoRec.dacSpeeds[0])	 ErrorF("  (%d MHz for %d bpp)",vga256InfoRec.dacSpeedBpp / 1000, xf86bpp);      ErrorF("\n");   }   /* Now set RAMDAC limits */   vga256InfoRec.maxClock = vga256InfoRec.dacSpeedBpp;   /* Detect current MCLK and print it for user */   outb(0x3c4, 0x08);   sr8 = inb(0x3c5);   outb(0x3c5, 0x06);    outb(0x3c4, 0x10);   n = inb(0x3c5);   outb(0x3c4, 0x11);   m = inb(0x3c5);   outb(0x3c4, 0x08);   outb(0x3c5, sr8);   m &= 0x7f;   n1 = n & 0x1f;   n2 = (n>>5) & 0x03;   mclk = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100;   ErrorF("%s %s: Detected current MCLK value of %1.3f MHz\n",XCONFIG_PROBED,       vga256InfoRec.name, mclk / 1000.0);   /* Now check if the user has specified "set_memclk" value in XConfig */   if (vga256InfoRec.MemClk > 0) {      if(vga256InfoRec.MemClk <= 100000) {         ErrorF("%s %s: Using Memory Clock value of %1.3f MHz\n",		OFLG_ISSET(XCONFIG_DACSPEED, &vga256InfoRec.xconfigFlag) ?		XCONFIG_GIVEN : XCONFIG_PROBED, vga256InfoRec.name, 		vga256InfoRec.MemClk/1000.0);         s3vPriv.MCLK = vga256InfoRec.MemClk;         }      else {         ErrorF("%s %s: Memory Clock value of %1.3f MHz is larger than limit of 100 MHz\n",              XCONFIG_GIVEN, vga256InfoRec.name, vga256InfoRec.MemClk/1000.0);         s3vPriv.MCLK = 0;         }      }   else s3vPriv.MCLK = 0;   /* Set scale factors for mode timings */   if (vgaBitsPerPixel == 8){      s3vPriv.HorizScaleFactor = 1;      }   else if (vgaBitsPerPixel == 16){      s3vPriv.HorizScaleFactor = 2;      }   else {           s3vPriv.HorizScaleFactor = 1;      }   /* And map MMIO memory, abort if we cannot */   s3savMmioMem = xf86MapVidMem(vga256InfoRec.scrnIndex, MMIO_REGION,	     (pointer) s3vPriv.MmioBase, S3_NEWMMIO_REGSIZE);   s3vPriv.MmioMem = s3savMmioMem;   s3vPriv.BciMem = (char*)s3vPriv.MmioMem + 0x10000;   if(s3savMmioMem == NULL)       FatalError("S3 Savage: Cannot map MMIO registers!\n");      /* Determine if we need to use the STREAMS processor */#if 0 /* Don't need to do this for Savage3D */   if (vgaBitsPerPixel >= 24) s3vPriv.NeedSTREAMS = TRUE;      else s3vPriv.NeedSTREAMS = FALSE;#endif   s3vPriv.STREAMSRunning = FALSE;#ifdef	USEBIOS   /* Go probe the BIOS for all the modes and refreshes at this depth. */   /*    * What I want here is an array of all mode numbers valid for this    * depth, and the list of valid refresh rates to go with them.      *    * x, y, mode, array[8] of refresh    */   if( s3vModeTable )   {      xfree( s3vModeTable );   }      s3vModeCount = S3SAVGetBIOSModeCount( vgaBitsPerPixel );   if( !s3vModeCount ) {     FatalError("%s %s: Failed to fetch any BIOS modes.\n",       XCONFIG_PROBED, vga256InfoRec.name     );   }   s3vModeTable = (S3VMODETABLE*)xcalloc(sizeof(S3VMODETABLE), s3vModeCount);   S3SAVGetBIOSModeTable( vgaBitsPerPixel, s3vModeTable );   if( xf86Verbose )   {      int i;      S3VMODETABLE* pmt;      ErrorF("%s %s: Found %d modes at this depth:\n",          XCONFIG_PROBED, vga256InfoRec.name, s3vModeCount);            for( i = 0, pmt = s3vModeTable; i < s3vModeCount; i++, pmt++ )      {         int j;         ErrorF( "[%03x] %d x %d", pmt->VesaMode, pmt->Width, pmt->Height );	 for( j = 0; j < pmt->RefreshCount; j++ )	 {	    ErrorF( ", %dHz", pmt->RefreshRate[j] );	 }	 ErrorF( "\n");      }   }#endif   pEnd = pMode = vga256InfoRec.modes;   do {      /* Setup the Mode.Private if required */      if (!pMode->PrivSize || !pMode->Private) {	 pMode->PrivSize = S3_MODEPRIV_SIZE;	 pMode->Private = (INT32 *)xcalloc(sizeof(INT32), S3_MODEPRIV_SIZE);	 pMode->Private[0] = 0;      }            /* Set default for invert_vclk */      if (!(pMode->Private[0] & (1 << S3_INVERT_VCLK))) {	 pMode->Private[S3_INVERT_VCLK] = 0;	 pMode->Private[0] |= 1 << S3_INVERT_VCLK;      }            /* Set default for blank_delay */      if (!(pMode->Private[0] & (1 << S3_BLANK_DELAY))) {	 pMode->Private[0] |= (1 << S3_BLANK_DELAY);	 if (vgaBitsPerPixel == 8)	       pMode->Private[S3_BLANK_DELAY] = 0x00;	    else if (vgaBitsPerPixel == 16)	       pMode->Private[S3_BLANK_DELAY] = 0x02;	    else	       pMode->Private[S3_BLANK_DELAY] = 0x04;      }            /* Set default for early_sc */      if (!(pMode->Private[0] & (1 << S3_EARLY_SC))) {	 pMode->Private[0] |= 1 << S3_EARLY_SC;	 pMode->Private[S3_EARLY_SC] = 0;      }      pMode = pMode->next;   } while (pMode != pEnd);   /* And finally set various possible option flags */   vga256InfoRec.bankedMono = FALSE;#ifdef XFreeXDGA   vga256InfoRec.directMode = XF86DGADirectPresent;#endif   OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &vga256InfoRec.clockOptions);   OFLG_SET(OPTION_SLOW_EDODRAM, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_FAST_DRAM, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_FPM_VRAM, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_PCI_BURST_ON, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_FIFO_CONSERV, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_FIFO_MODERATE, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_FIFO_AGGRESSIVE, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_PCI_RETRY, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_NOACCEL, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_SW_CURSOR, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_HW_CURSOR, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_EARLY_RAS_PRECHARGE, &S3V.ChipOptionFlags);   OFLG_SET(OPTION_LATE_RAS_PRECHARGE, &S3V.ChipOptionFlags);   s3vPriv.NoPCIRetry = 1;   S3V.ChipLinearBase = vga256InfoRec.MemBase;   S3V.ChipLinearSize = vga256InfoRec.videoRam * 1024;   return TRUE;   }