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

📄 s3init.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	    changed = TRUE;	 }      }      if (s3Bpp == 3) {	 /* for packed 24bpp CrtcHTotal must be multiple of 3*8... */	 if ((mode->CrtcHTotal >> 3) % 3 != 0) {	    mode->CrtcHTotal >>= 3;	    mode->CrtcHTotal += 3 - mode->CrtcHTotal % 3;	    mode->CrtcHTotal <<= 3;	    changed = TRUE;	    p24_fact = 3;	 }      }      if (changed) {	 ErrorF("%s %s: mode line has to be modified ...\n",		XCONFIG_PROBED, s3InfoRec.name);	 ErrorF("\t\tfrom   %4d %4d %4d %4d   %4d %4d %4d %4d\n"		,mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal		,mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal		);	 ErrorF("\t\tto     %4d %4d %4d %4d   %4d %4d %4d %4d\n"		,((mode->CrtcHDisplay   << 8) >> (8-pixMuxShift)) * 4 / p24_fact		,((mode->CrtcHSyncStart << 8) >> (8-pixMuxShift)) * 4 / p24_fact		,((mode->CrtcHSyncEnd   << 8) >> (8-pixMuxShift)) * 4 / p24_fact		,((mode->CrtcHTotal     << 8) >> (8-pixMuxShift)) * 4 / p24_fact		,mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal		);      }   }   if (!vgaHWInit(mode, sizeof(vgaS3Rec)))      return(FALSE);   new->MiscOutReg |= 0x0C;		/* enable CR42 clock selection */   new->Sequencer[0] = 0x03;		/* XXXX shouldn't need this */   new->CRTC[19] = s3BppDisplayWidth >> 3;   new->CRTC[23] = 0xE3;		/* XXXX shouldn't need this */   new->Attribute[0x11] = currents3dac_border; /* The overscan colour AR11 gets */					/* disabled anyway */   if ((S3_TRIO64V_SERIES(s3ChipId) && (s3ChipRev <= 0x53) && (s3Bpp==1)) ^       !!OFLG_ISSET(OPTION_TRIO64VP_BUG2, &s3InfoRec.options)) {      /* set correct blanking for broken Trio64V+ to avoid bright left border:	 blank signal needs to go off ~400 usec before video signal starts 	 w/o border:  blank_shift = 0 */      int blank_shift = 400 * s3InfoRec.clock[mode->Clock] / 1000000 / 8;      new->CRTC[2]  = mode->CrtcHDisplay >> 3;      new->CRTC[3] &= ~0x1f;      new->CRTC[3] |=  ((mode->CrtcHTotal >> 3) - 2 - blank_shift) & 0x1f;      new->CRTC[5] &= ~0x80;      new->CRTC[5] |= (((mode->CrtcHTotal >> 3) - 2 - blank_shift) & 0x20) << 2;            new->CRTC[21] =  (mode->CrtcVDisplay - 1) & 0xff;       new->CRTC[7] &= ~0x08;      new->CRTC[7] |= ((mode->CrtcVDisplay - 1) & 0x100) >> 5;      new->CRTC[9] &= ~0x20;      new->CRTC[9] |= ((mode->CrtcVDisplay - 1) & 0x200) >> 4;      new->CRTC[22] = (mode->CrtcVTotal - 2) & 0xFF;   }   vgaProtect(TRUE);   if (vgaIOBase == 0x3B0)      new->MiscOutReg &= 0xFE;   else      new->MiscOutReg |= 0x01;   if (OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) &&        S3_928_ONLY(s3ChipId)) {      /*       * Make sure that parallel option is already set correctly before       * changing the clock doubler state.       * XXXX maybe the !s3PixelMultiplexing bit is not required?       */      if (s3PixelMultiplexing) {	 outb(vgaCRIndex, 0x5C);	 outb(vgaCRReg, 0x20);	 outb(0x3C7, 0x21);	 /* set s3 reg53 to parallel addressing by or'ing 0x20		*/	 outb(vgaCRIndex, 0x53);	 tmp = inb(vgaCRReg);	 outb(vgaCRReg, tmp | 0x20);  	 outb(vgaCRIndex, 0x5C);	 outb(vgaCRReg, 0x00);      } else {	 outb(vgaCRIndex, 0x5C);	 outb(vgaCRReg, 0x20);	 outb(0x3C7, 0x00); 	 /* set s3 reg53 to non-parallel addressing by and'ing 0xDF	*/	 outb(vgaCRIndex, 0x53);	 tmp = inb(vgaCRReg);	 outb(vgaCRReg, tmp & 0xDF);	 outb(vgaCRIndex, 0x5C);	 outb(vgaCRReg, 0x00);      }      if (s3Bpp == 4)          s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 1);  /* 0x06 -> 0x07 */      else         s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 0);  /* 0x06 */   }   if(    (DAC_IS_TI3026 || DAC_IS_TI3030)        && (OFLG_ISSET(CLOCK_OPTION_ICD2061A, &s3InfoRec.clockOptions))){      /*       * for the boards with Ti3026 and external ICD2061A clock chip we       * need to enable clock doubling, if necessary       */      if( mode->Flags & V_DBLCLK ) {#ifdef EXTENDED_DEBUG	 ErrorF("Putting Ti3026 into external double clock mode\n");#endif         s3OutTi3026IndReg(TI_INPUT_CLOCK_SELECT,0x00,0x08);      }      else {#ifdef EXTENDED_DEBUG	 ErrorF("Putting Ti3026 into external clock mode\n");#endif         s3OutTi3026IndReg(TI_INPUT_CLOCK_SELECT,0x00,0x00);      }      if (s3Bpp == 4)          s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 1);  /* 0x06 -> 0x07 */      else         s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 0);  /* 0x06 */   }   if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) &&       !OFLG_ISSET(OPTION_NOLINEAR_MODE, &s3InfoRec.options) &&       s3Mmio928) {     /*       Set bit 7 of CRTC register 5C to map video memory with       LAW31-26 = 011111 rather than 000000.  Note that this remaps       all addresses seen by the 928, including the VGA Base Address.     */     int CR5C;     outb(vgaCRIndex, 0x5C);     CR5C = inb(vgaCRReg);     outb(vgaCRIndex, 0x5C);     outb(vgaCRReg, CR5C | 0x80);     vgaBase = vgaBaseHigh;   }   if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options) &&       !OFLG_ISSET(OPTION_NOLINEAR_MODE, &s3InfoRec.options) &&       s3Mmio928) {     int CR5C;     outb(vgaCRIndex, 0x5C);     CR5C = inb(vgaCRReg);     outb(vgaCRIndex, 0x5C);       switch(s3InfoRec.depth) {       case 24:       case 32:	 outb(vgaCRReg, CR5C | 0xf0);	 break;       case 16:       case 15:	 outb(vgaCRReg, CR5C | 0x70);	 break;       default:	 outb(vgaCRReg, CR5C | 0xa0);       }       vgaBase = vgaBaseHigh;}   /* Don't change the clock bits when using an external clock program */   if (new->NoClock < 0) {      tmp = inb(0x3CC);      new->MiscOutReg = (new->MiscOutReg & 0xF3) | (tmp & 0x0C);   } else {      /* XXXX Should we really do something about the return value? */      if (OFLG_ISSET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions))	 (void) (s3ClockSelectFunc)(mode->SynthClock);      else         (void) (s3ClockSelectFunc)(mode->Clock);           if ((mode->Flags & V_DBLCLK)	 && (DAC_IS_TI3026 || DAC_IS_TI3030) 	 && (OFLG_ISSET(CLOCK_OPTION_ICD2061A, &s3InfoRec.clockOptions))){	 if (s3Bpp <= 2)	    Ti3026SetClock(mode->SynthClock / 2, 2, s3Bpp, TI_LOOP_CLOCK);	 else 	    Ti3026SetClock(mode->SynthClock, 2, s3Bpp, TI_LOOP_CLOCK);	    	 s3OutTi3026IndReg(TI_MCLK_LCLK_CONTROL, ~0x20, 0x20);      }      if ((DAC_IS_TI3026 || DAC_IS_TI3030) && s3Bpp == 3) {	 s3OutTi3026IndReg(TI_MCLK_LCLK_CONTROL, ~0x20, 0x20);      }   }/* Initialize Ramdac */     if(!(s3Ramdacs[s3RamdacType].DacInit)(mode)) {	/* blah */     }   s3InitCursorFlag = TRUE;  /* turn on the cursor during the next load */   outb(0x3C2, new->MiscOutReg);   for (i = 1; i < 5; i++)      outw(0x3C4, (new->Sequencer[i] << 8) | i);   for (i = 0; i < 25; i++)      outw(vgaCRIndex, (new->CRTC[i] << 8) | i);   for (i = 0; i < 9; i++)      outw(0x3CE, (new->Graphics[i] << 8) | i);   i = inb(vgaIOBase + 0x0A);	/* reset flip-flop */   for (i = 0; i < 16; i++) {      outb(0x3C0, i);      outb(0x3C0, new->Attribute[i]);   }   for (i = 16; i < 21; i++) {      outb(0x3C0, i | 0x20);      outb(0x3C0, new->Attribute[i]);   }   if (s3DisplayWidth == 2048)      s3Port31 = 0x8f;   else      s3Port31 = 0x8d;   outb(vgaCRIndex, 0x31);   outb(vgaCRReg, s3Port31);   outb(vgaCRIndex, 0x32);   outb(vgaCRReg, 0x00);   outb(vgaCRIndex, 0x33);   if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options))     /* Blank border comes earlier than display enable. */     outb(vgaCRReg, 0x00);   else if (!S3_TRIOxx_SERIES(s3ChipId))      outb(vgaCRReg, 0x20);   outb(vgaCRIndex, 0x34);   outb(vgaCRReg, 0x10);		/* 1024 */   outb(vgaCRIndex, 0x35);   outb(vgaCRReg, 0x00);   cebank();#if 0  /* x64: set to 1 if PCI read bursts should be enabled        * NOTE: there are known problems with PCI burst mode in SATURN        * chipset rev. 2 so this is commented out, maybe a new XF86Config        * option should be used        */   if (S3_x64_SERIES(s3ChipId)) {      outb(vgaCRIndex, 0x3a);      outb(vgaCRReg, 0xb5 & 0x7f);   } else#endif      {	 int pci_disc;	 if (OFLG_ISSET(OPTION_NO_PCI_DISC, &s3InfoRec.options))	    pci_disc = 0x00;	 else	    pci_disc = 0x80;	 outb(vgaCRIndex, 0x66);  /* set CR66_7 before CR3A_7 */	 tmp = inb(vgaCRReg) & 0x7f;	 outb(vgaCRReg, tmp | pci_disc);	 	 outb(vgaCRIndex, 0x3a);	 if (OFLG_ISSET(OPTION_SLOW_DRAM_REFRESH, &s3InfoRec.options))	    outb(vgaCRReg, 0x37 | pci_disc);	 else	    outb(vgaCRReg, 0x35 | pci_disc);      }   outb(vgaCRIndex, 0x3b);   outb(vgaCRReg, (new->CRTC[0] + new->CRTC[4] + 1) / 2);   outb(vgaCRIndex, 0x3c);   outb(vgaCRReg, new->CRTC[0]/2);	/* Interlace mode frame offset */   /* x64: CR40 changed a lot for 864/964; wait and see if this still works */   outb(vgaCRIndex, 0x40);   if (S3_911_SERIES (s3ChipId)) {      i = (inb(vgaCRReg) & 0xf2);      s3Port40 = (i | 0x09);      outb(vgaCRReg, s3Port40);   } else {      if (s3Localbus) {	 i = (inb(vgaCRReg) & 0xf2);	 if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) ||	     OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options))	   /* Set no wait states on STB Pegasus. */	   s3Port40 = (i | 0x01);	 else s3Port40 = (i | 0x05);	 outb(vgaCRReg, s3Port40);      } else {	 i = (inb(vgaCRReg) & 0xf6);	 s3Port40 = (i | 0x01);	 outb(vgaCRReg, s3Port40);      }   }   outb(vgaCRIndex, 0x43);   switch (s3InfoRec.depth) {   case 24:   case 32:      if (S3_864_SERIES(s3ChipId))	 outb(vgaCRReg, 0x08);  /* 0x88 can't be used for 864/964 */      else if (S3_801_928_SERIES(s3ChipId) && DAC_IS_SC15025)	 outb(vgaCRReg, 0x01);  /* ELSA Winner 1000 */      else if (DAC_IS_BT485_SERIES && S3_928_SERIES(s3ChipId))	 outb(vgaCRReg, 0x00);      break;   case 15:   case 16:      if (DAC_IS_ATT490 || DAC_IS_GENDAC || DAC_IS_SC1148x_SERIES /* JON */		|| DAC_IS_SS2410 ) /*??? I'm not sure - but the 490 does it */  	 outb(vgaCRReg, 0x80);      else if (DAC_IS_TI3025)	 outb(vgaCRReg, 0x10);      else if (DAC_IS_TI3026 || DAC_IS_TI3030)	 outb(vgaCRReg, 0x10);      else if (DAC_IS_IBMRGB)	 outb(vgaCRReg, 0x10);      else if (S3_864_SERIES(s3ChipId))	 outb(vgaCRReg, 0x08);  /* 0x88 can't be used for 864/964 */      else if (S3_928_SERIES(s3ChipId)) {	 if (DAC_IS_SC15025)	    outb(vgaCRReg, 0x01);  /* ELSA Winner 1000 */	 else if (DAC_IS_BT485_SERIES || DAC_IS_TI3020)	    outb(vgaCRReg, 0x00);	 else	    outb(vgaCRReg, 0x09);  /* who uses this ? */      }      else if (DAC_IS_ATT498 && S3_805_I_SERIES(s3ChipId))	 outb(vgaCRReg, 0x00);      else	 outb(vgaCRReg, 0x09);      break;   case 8:   default:      outb(vgaCRReg, 0x00); /* DON'T enable XOR addresses */      break;   }   outb(vgaCRIndex, 0x44);   outb(vgaCRReg, 0x00);   outb(vgaCRIndex, 0x45);   i = inb(vgaCRReg) & 0xf2;   /* hi/true cursor color enable */   switch (s3InfoRec.bitsPerPixel) {   case 16:      if (!S3_x64_SERIES(s3ChipId) && !S3_805_I_SERIES(s3ChipId) &&          !DAC_IS_TI3020)	 i = i | 0x04;      break;   case 32:      if (S3_x64_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId) ||	  DAC_IS_TI3020)	 i = i | 0x04; /* for 16bit RAMDAC, 0x0c for 8bit RAMDAC */      else	 i = i | 0x08;      break;   }   outb(vgaCRReg, i);   if (S3_801_928_SERIES(s3ChipId) || S3_964_SERIES(s3ChipId)) {      outb(vgaCRIndex, 0x50);      i = inb(vgaCRReg);      i &= ~0xf1;      switch (s3InfoRec.bitsPerPixel) {	case 8:           break;	case 16:	   i |= 0x10;	   break;	case 24:	   i |= 0x20;	   break;	case 32:	   i |= 0x30;	   break;      }      switch (s3DisplayWidth) { 	case 640:	   i |= 0x40;	   break;	case 800:	   i |= 0x80;	   break;	case 1152:	   i |= 0x01;	   break;	case 1280:	   i |= 0xc0;	   break;	case 1600:	   i |= 0x81;	   break;	default: /* 1024 and 2048 */	   ;      }      outb(vgaCRReg, i);      outb(vgaCRIndex, 0x51);      s3Port51 = (inb(vgaCRReg) & 0xC0) | ((s3BppDisplayWidth >> 7) & 0x30);      if (OFLG_ISSET(OPTION_NO_SPLIT_XFER, &s3InfoRec.options))	 s3Port51 |= 0x40;      if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) ||	  OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) {	if (s3PixelMultiplexing)	  /* In Pixel Multiplexing mode, disable split transfers. */	  s3Port51 |= 0x40;	else	  /* In VGA mode, enable split transfers. */	  s3Port51 &= ~0x40;      }      outb(vgaCRReg, s3Port51);      outb(vgaCRIndex, 0x58);      outb(vgaCRReg, s3SAM256);#ifdef DEBUG      ErrorF("Writing CR59 0x%02x, CR5A 0x%02x\n", s3Port59, s3Port5A);#endif      outb(vgaCRIndex, 0x59);      outb(vgaCRReg, s3Port59);      outb(vgaCRIndex, 0x5A);      outb(vgaCRReg, s3Port5A);            outb(vgaCRIndex, 0x53);      tmp = inb(vgaCRReg) & ~0x18;      if (s3Mmio928)	 tmp |= 0x10;      if (s3NewMmio) {	 if (s3InfoRec.MemBase != 0) {	    s3Port59 = (s3InfoRec.MemBase >> 24) & 0xfc;	    s3Port5A = 0;	    outb(vgaCRIndex, 0x59);	    outb(vgaCRReg, s3Port59);	    outb(vgaCRIndex, 0x5a);	    outb(vgaCRReg, s3Port5A);	    outb(vgaCRIndex, 0x53);	 }	 tmp |= 0x18;      }      /*       * Now the DRAM interleaving bit for the 801/805 chips       * Note, we don't touch this bit for 928 chips because they use it       * for pixel multiplexing control.       */      if (S3_801_SERIES(s3ChipId)) {	 if (S3_805_I_SERIES(s3ChipId) && s3InfoRec.videoRam == 2048)	    tmp |= 0x20;	 else	    tmp &= ~0x20;      }      outb(vgaCRReg, tmp);      if (s3NewMmio) {      	 outb (vgaCRIndex, 0x58);	 outb (vgaCRReg, (s3LinApOpt & ~0x04) | s3SAM256);  /* window size for linear mode */      }      n = 255;      outb(vgaCRIndex, 0x54);      if (S3_x64_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId)) {	 int clock2,mclk;	 clock2 = s3InfoRec.clock[mode->Clock] * s3Bpp;	 if (s3InfoRec.s3MClk > 0) 	    mclk = s3InfoRec.s3MClk;	 else if (S3_805_I_SERIES(s3ChipId))	    mclk = 50000;  /* 50 MHz, guess for 805i limit */	 else	    mclk = 60000;  /* 60 MHz, limit for 864 */	 if (s3InfoRec.videoRam < 2048 || S3_TRIO32_SERIES(s3ChipId))	    clock2 *= 2;	 m = (int)((mclk/1000.0*.72+16.867)*89.736/(clock2/1000.0+39)-21.1543);	 if (s3InfoRec.videoRam < 2048 || S3_TRIO32_SERIES(s3ChipId))	    m /= 2;	 m -= s3InfoRec.s3Madjust;	 if (m > 31) m = 31;	 else if (m < 0) {	    m = 0;	    n = 16;	 }      }      else if (s3InfoRec.videoRam == 512 || mode->HDisplay > 1200) /* XXXX */	 m = 0;      else if (s3InfoRec.videoRam == 1024)         m = 2;      else	 m = 20;      if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options)) 	s3Port54 = 0x7F;      else if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options))	s3Port54 = 0;      else s3Port54 = m << 3;      outb(vgaCRReg, s3Port54);            n -= s3InfoRec.s3Nadjust;      if (n < 0) n = 0;      else if (n > 255) n = 255;      outb(vgaCRIndex, 0x60);      outb(vgaCRReg, n);

⌨️ 快捷键说明

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