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

📄 s3init.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/s3/s3init.c,v 3.110.2.6 1997/06/20 09:13:54 hohndel Exp $ *//* * Written by Jake Richter Copyright (c) 1989, 1990 Panacea Inc., * Londonderry, NH - All Rights Reserved *  * This code may be freely incorporated in any program without royalty, as long * as the copyright notice stays intact. *  * Additions by Kevin E. Martin (martin@cs.unc.edu) *  * KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEVIN E. MARTIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *  *//* * Modified by Amancio Hasty and Jon Tombs *  *//* $XConsortium: s3init.c /main/28 1996/10/28 04:55:18 kaleb $ */#define USE_VGAHWINIT#include "X.h"#include "Xmd.h"#ifndef OSKIT#include "input.h"#include "servermd.h"#endif /* !OSKIT */#include "scrnintstr.h"#ifndef OSKIT#include "site.h"#endif /* !OSKIT */#include "xf86Procs.h"#include "xf86_OSlib.h"#include "xf86_HWlib.h"#include "vga.h"#include "s3.h"#include "regs3.h"#include "s3Bt485.h"#include "Ti302X.h"#include "IBMRGB.h"#define XCONFIG_FLAGS_ONLY #include "xf86_Config.h"typedef struct {   vgaHWRec std;                /* good old IBM VGA */   unsigned char s3reg[10];     /* Video Atribute (CR30-34, CR38-3C) */   unsigned char s3sysreg[46];  /* Video Atribute (CR40-6D)*/   unsigned char ColorStack[8]; /* S3 hw cursor color stack CR4A/CR4B */}vgaS3Rec, *vgaS3Ptr;extern int   vgaIOBase;extern int   vgaCRIndex;extern int   vgaCRReg;int   s3InitCursorFlag = TRUE;int   s3HDisplay;extern xf86InfoRec xf86Info;static vgaS3Ptr oldS3 = NULL;static short savedVgaIOBase;pointer vgaNewVideoState = NULL;static LUTENTRY oldlut[256];static Bool LUTInited = FALSE;static short s3Initialised = 0;static int   old_clock;extern Bool (*s3ClockSelectFunc) (#if NeedNestedPrototypes	int	/* clock */#endif	);extern int s3DisplayWidth;extern Bool s3Localbus;extern Bool s3Mmio928;extern Bool s3NewMmio;extern Bool s3PixelMultiplexing;extern pointer vgaBase;extern pointer vgaBaseLow;extern pointer vgaBaseHigh;int currents3dac_border = 0xff;static void InitLUT(#if NeedFunctionPrototypes	void#endif	);#ifdef PC98extern void crtswitch(short);#endif#define new ((vgaHWPtr)vgaNewVideoState)unsigned short s3ChipId = 0;unsigned int  s3ChipRev = 0;#define	cebank() do {							\   	if (S3_801_928_SERIES(s3ChipId)) {				\		unsigned char tmp2;					\		outb(vgaCRIndex, 0x51);					\		tmp2 = inb(vgaCRReg);					\		outb(vgaCRReg, (tmp2 & 0xf3));				\	}								\} while (1 == 0)/* * Registers to save/restore in the 0x50 - 0x5f control range */static short reg50_mask = 0x673b; /* was 0x6733; */ /* was 0x4023 */extern unsigned char s3Port54;extern unsigned char s3Port51;extern unsigned char s3Port40;extern unsigned char s3Port59;extern unsigned char s3Port5A;extern unsigned char s3Port31;voids3CleanUp(void){   int   i;   unsigned char tmp;   UNLOCK_SYS_REGS;      vgaProtect(TRUE);   if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) &&       !OFLG_ISSET(OPTION_NOLINEAR_MODE, &s3InfoRec.options) &&       s3Mmio928) {     /*       Clear bit 7 of CRTC register 5C to map video memory normally.     */     int CR5C;     outb(vgaCRIndex, 0x5C);     CR5C = inb(vgaCRReg);     outb(vgaCRIndex, 0x5C);     outb(vgaCRReg, CR5C & ~0x80);     vgaBase = vgaBaseLow;   }   /* BL */   if (s3NewMmio)	{      outb (vgaCRIndex, 0x58);      outb (vgaCRReg, s3SAM256); /* disable linear mode */   } /* end BL */   WaitQueue(8);   outb(vgaCRIndex, 0x35);   tmp = inb(vgaCRReg);   outb(vgaCRReg, (tmp & 0xf0));   cebank();   outw(ADVFUNC_CNTL, 0);   if (s3Mmio928 || s3NewMmio) {      outb(vgaCRIndex, 0x53);      outb(vgaCRReg, 0x00);   } /* (s3ClockSelectFunc)(restore->std.NoClock); */   /* Restore Ramdac registers */  (s3Ramdacs[s3RamdacType].DacRestore)();   if (DAC_IS_TI3025) {      outb(vgaCRIndex, 0x5C);      outb(vgaCRReg, oldS3->s3sysreg[0x0C + 16]);   } /* restore s3 special bits */   if (S3_801_928_SERIES(s3ChipId)) {    /* restore 801 specific registers */      for (i = 32; i < (S3_x64_SERIES(s3ChipId) ? 46 :                       S3_805_I_SERIES(s3ChipId) ? 40 : 38) ; i++) {	 outb(vgaCRIndex, 0x40 + i);	 outb(vgaCRReg, oldS3->s3sysreg[i]);      }      for (i = 0; i < 16; i++) {	 if (!((1 << i) & reg50_mask))	   continue;	 outb(vgaCRIndex, 0x50 + i);	 outb(vgaCRReg, oldS3->s3sysreg[i + 16]);      }   }   for (i = 0; i < 5; i++) {      outb(vgaCRIndex, 0x30 + i);      outb(vgaCRReg, oldS3->s3reg[i]);      outb(vgaCRIndex, 0x38 + i);      outb(vgaCRReg, oldS3->s3reg[5 + i]);   }   for (i = 0; i < 16; i++) {      outb(vgaCRIndex, 0x40 + i);      outb(vgaCRReg, oldS3->s3sysreg[i]);   }   outb(vgaCRIndex, 0x45);   inb(vgaCRReg);         /* reset color stack pointer */   outb(vgaCRIndex, 0x4A);   for (i = 0; i < 4; i++)      outb(vgaCRReg, oldS3->ColorStack[i]);   outb(vgaCRIndex, 0x45);   inb(vgaCRReg);         /* reset color stack pointer */   outb(vgaCRIndex, 0x4B);   for (i = 4; i < 8; i++)      outb(vgaCRReg, oldS3->ColorStack[i]);   if (OFLG_ISSET(CLOCK_OPTION_ICS2595, &s3InfoRec.clockOptions)){      outb(vgaCRIndex, 0x42);      outb(vgaCRReg, (oldS3->s3sysreg[2] & 0xf0) | 0x01);      outb(vgaCRIndex, 0x5c);	/* switch back to 28MHz clock */      outb(vgaCRReg,   0x20);      outb(vgaCRReg,   0x00);   }   vgaHWRestore((vgaHWPtr)oldS3);   outb(0x3c2, old_clock);   i = inb(0x3CC);   if (savedVgaIOBase == 0x3B0)      i &= 0xFE;   else      i |= 0x01;   outb(0x3C2, i);   vgaIOBase = savedVgaIOBase;   vgaCRIndex = vgaIOBase + 4;   vgaCRReg = vgaIOBase + 5;         vgaProtect(FALSE);#ifdef PC98	crtswitch(0);#endif   xf86DisableIOPorts(s3InfoRec.scrnIndex);}Bools3Init(mode)     DisplayModePtr mode;{   short i, m, n;   int   interlacedived = mode->Flags & V_INTERLACE ? 2 : 1;   unsigned char tmp, CR5C;   unsigned int itmp;   extern Bool s3DAC8Bit;   int pixMuxShift = 0;   s3HDisplay = mode->HDisplay;   UNLOCK_SYS_REGS;   /* Force use of colour I/O address */   if (!s3Initialised) {      savedVgaIOBase = vgaIOBase;   }   i = inb(0x3CC);   outb(0x3C2, i | 0x01);   vgaIOBase = 0x3D0;   vgaCRIndex = 0x3D4;   vgaCRReg = 0x3D5;         if (!s3Initialised) {    /* blanket save of state */    /* unlock */      outb(vgaCRIndex, 0x38);      outb(vgaCRReg, 0x48);      old_clock = inb(0x3CC);      outb(vgaCRIndex, 0x35);	/* select segment 0 */      i = inb(vgaCRReg);      outb(vgaCRReg, i & 0xf0);      cebank();      oldS3 = vgaHWSave((vgaHWPtr)oldS3, sizeof(vgaS3Rec));      /*       * Set up the Serial Access Mode 256 Words Control       *   (bit 6 in CR58)       */      outb(vgaCRIndex, 0x58);      s3SAM256 = inb(vgaCRReg) & 0x80;      if (S3_968_SERIES(s3ChipId) || (S3_964_SERIES(s3ChipId) &&	  !OFLG_ISSET(OPTION_NUMBER_NINE, &s3InfoRec.options)))         s3SAM256 |= 0x40;      else if ((OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) &&               S3_928_ONLY(s3ChipId)) ||	       OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options))         s3SAM256 |= 0x80; /* set 6 MCLK cycles for R/W time on Mercury */      if (OFLG_ISSET(OPTION_EARLY_RAS_PRECHARGE, &s3InfoRec.options))	 s3SAM256 |= 0x80;      if (OFLG_ISSET(OPTION_LATE_RAS_PRECHARGE, &s3InfoRec.options))	 s3SAM256 &= 0x7f;      if (DAC_IS_TI3025) { 	  outb(vgaCRIndex, 0x5C);	  CR5C = inb(vgaCRReg);      }/* Save Ramdac registers */     (s3Ramdacs[s3RamdacType].DacSave)();       for (i = 0; i < 5; i++) {	 outb(vgaCRIndex, 0x30 + i);	 oldS3->s3reg[i] = inb(vgaCRReg);#ifdef REG_DEBUG	 ErrorF("CR%X = 0x%02x\n", 0x30 + i, oldS3->s3reg[i]);#endif	 outb(vgaCRIndex, 0x38 + i);	 oldS3->s3reg[5 + i] = inb(vgaCRReg);#ifdef REG_DEBUG	 ErrorF("CR%X = 0x%02x\n", 0x38 + i, oldS3->s3reg[i + 5]);#endif      }      outb(vgaCRIndex, 0x11);	/* allow writting to CR0-7 */      tmp = inb(vgaCRReg);      outb(vgaCRReg, tmp & 0x7f);      for (i = 0; i < 16; i++) {	 outb(vgaCRIndex, 0x40 + i);	 oldS3->s3sysreg[i] = inb(vgaCRReg);#ifdef REG_DEBUG	 ErrorF("CR%X = 0x%02x\n", 0x40 + i, oldS3->s3sysreg[i]);#endif      }      outb(vgaCRIndex, 0x45);      inb(vgaCRReg);         /* reset color stack pointer */      outb(vgaCRIndex, 0x4A);      for (i = 0; i < 4; i++) {	 oldS3->ColorStack[i] = inb(vgaCRReg);	 outb(vgaCRReg,oldS3->ColorStack[i]);  /* advance stack pointer */      }            outb(vgaCRIndex, 0x45);      inb(vgaCRReg);         /* reset color stack pointer */      outb(vgaCRIndex, 0x4B);      for (i = 4; i < 8; i++) {	 oldS3->ColorStack[i] = inb(vgaCRReg);	 outb(vgaCRReg,oldS3->ColorStack[i]);  /* advance stack pointer */      }      if (S3_801_928_SERIES(s3ChipId))          for (i = 0; i < 16; i++) {#ifdef REG_DEBUG	     outb(vgaCRIndex, 0x50 + i);	     ErrorF("CR%X = 0x%02x\n", 0x50 + i, inb(vgaCRReg));#endif	     if (!((1 << i) & reg50_mask))	       continue;	     outb(vgaCRIndex, 0x50 + i);	     oldS3->s3sysreg[i + 16] = inb(vgaCRReg);          }      if (DAC_IS_TI3025)  /* restore 5C from above */         oldS3->s3sysreg[0x0C + 16] = CR5C;      for (i = 32; i < (S3_x64_SERIES(s3ChipId) ? 46 :                       S3_805_I_SERIES(s3ChipId) ? 40 : 38); i++) {	 outb(vgaCRIndex, 0x40 + i);	 oldS3->s3sysreg[i] = inb(vgaCRReg);#ifdef REG_DEBUG	 ErrorF("CR%X = 0x%02x\n", 0x40 + i, oldS3->s3sysreg[i]);#endif      }      s3Initialised = 1;      vgaNewVideoState = vgaHWSave(vgaNewVideoState, sizeof(vgaS3Rec));      outb(DAC_MASK, 0);   } else if (DAC_IS_TI3025) {      /* switch the ramdac from bt485 to ti3020 mode clearing RS4 */      outb(vgaCRIndex, 0x5C);      CR5C = inb(vgaCRReg);      outb(vgaCRReg, CR5C & 0xDF);      /* clear TI_PLANAR_ACCESS bit */      s3OutTiIndReg(TI_CURS_CONTROL, 0x7F, 0x00);   }   if (s3UsingPixMux && (mode->Flags & V_PIXMUX))      s3PixelMultiplexing = TRUE;   else      s3PixelMultiplexing = FALSE;   if (OFLG_ISSET(OPTION_ELSA_W2000PRO, &s3InfoRec.options))      pixMuxShift = s3InfoRec.clock[mode->Clock] > 120000 ? 2 : 		      s3InfoRec.clock[mode->Clock] > 60000 ? 1 : 0 ;   else if (OFLG_ISSET(OPTION_MIRO_80SV,  &s3InfoRec.options))      pixMuxShift = ((mode->Flags & V_DBLCLK && s3Bpp == 1)		     || s3Bpp == 4) ? 1 : 0;   else if (DAC_IS_IBMRGB528)      pixMuxShift = (s3InfoRec.clock[mode->Clock] > 220000 && s3Bpp <= 2) ? 2 :	             s3InfoRec.clock[mode->Clock] > 110000 ? 1 : 0 ;   else if ((mode->Flags & V_DBLCLK)	    && (DAC_IS_TI3026) 	    && (OFLG_ISSET(CLOCK_OPTION_ICD2061A, &s3InfoRec.clockOptions)))      pixMuxShift =  (s3Bpp <= 2) ? 2 : 1;   else if ((mode->Flags & V_DBLCLK) && DAC_IS_TI3030)      pixMuxShift =  1;   else if (S3_964_SERIES(s3ChipId) && DAC_IS_IBMRGB)      pixMuxShift = mode->Flags & V_DBLCLK ? 1 : 0;   else if (S3_964_SERIES(s3ChipId) && DAC_IS_TI3025)      pixMuxShift =  mode->Flags & V_DBLCLK ? 1 : 0;   else if (S3_964_SERIES(s3ChipId) && DAC_IS_BT485_SERIES)      /* Stealth64 and Miro Crystal 20SV */      pixMuxShift =  mode->Flags & V_DBLCLK ? 1 : 0;   else if (S3_801_928_SERIES(s3ChipId) && DAC_IS_SC15025)      pixMuxShift = -(s3Bpp>>1);  /* for 16/32 bpp */   else if (S3_864_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId))	    /* && (DAC_IS_ATT498 || DAC_IS_STG1700) */      pixMuxShift = -(s3Bpp>>1);  /* for 16/32 bpp */   else if (S3_TRIOxx_SERIES(s3ChipId))      pixMuxShift = -(s3Bpp == 2);   else if (S3_x64_SERIES(s3ChipId)) /* XXXX Better to test the DAC type? */      pixMuxShift = 0;   else if ((S3_928_SERIES(s3ChipId) && 	     (DAC_IS_TI3020 || DAC_IS_BT485_SERIES)) &&            s3PixelMultiplexing) {      if (s3Bpp == 4)      pixMuxShift = 0;  /* 32 bit */      else if (s3Bpp == 2) pixMuxShift = 1;  /* 16 bit */      else                 pixMuxShift = 2;  /*  8 bit */   } else if (s3PixelMultiplexing)        pixMuxShift = 2; /* old default for   if (s3PixelMultiplexing) shifting */   else       pixMuxShift = 0;   if (!mode->CrtcHAdjusted) {      if (s3Bpp == 3 && 	  (   (S3_968_SERIES(s3ChipId) && DAC_IS_TI3026)	   || (S3_968_SERIES(s3ChipId) && DAC_IS_TI3030))) {	 	 mode->CrtcHTotal     = (mode->CrtcHTotal     * 3) / 4;	 mode->CrtcHDisplay   = (mode->CrtcHDisplay   * 3) / 4;	 mode->CrtcHSyncStart = (mode->CrtcHSyncStart * 3) / 4;	 mode->CrtcHSyncEnd   = (mode->CrtcHSyncEnd   * 3) / 4;	 mode->CrtcHSkew      = (mode->CrtcHSkew      * 3) / 4;      }      if (pixMuxShift > 0) {	 /* now divide the horizontal timing parameters as required */	 mode->CrtcHTotal     >>= pixMuxShift;	 mode->CrtcHDisplay   >>= pixMuxShift;	 mode->CrtcHSyncStart >>= pixMuxShift;	 mode->CrtcHSyncEnd   >>= pixMuxShift;	 mode->CrtcHSkew      >>= pixMuxShift;      }      else if (pixMuxShift < 0) {	 /* now multiply the horizontal timing parameters as required */	 mode->CrtcHTotal     <<= -pixMuxShift;	 mode->CrtcHDisplay   <<= -pixMuxShift;	 mode->CrtcHSyncStart <<= -pixMuxShift;	 mode->CrtcHSyncEnd   <<= -pixMuxShift;	 mode->CrtcHSkew      <<= -pixMuxShift;      }      mode->CrtcHAdjusted = TRUE;   }   /*     * do some sanity checks on the horizontal timing parameters     */   {       Bool changed=FALSE;      int oldCrtcHSyncStart, oldCrtcHSyncEnd, oldCrtcHTotal;      int p24_fact = 4;      oldCrtcHSyncStart = mode->CrtcHSyncStart;      oldCrtcHSyncEnd   = mode->CrtcHSyncEnd;      oldCrtcHTotal     = mode->CrtcHTotal;      if (mode->CrtcHTotal > 4096) {  /*  CrtcHTotal/8  is a 9 bit value */	 mode->CrtcHTotal = 4096;	 changed = TRUE;      }      if (mode->CrtcHSyncEnd >= mode->CrtcHTotal) {	 mode->CrtcHSyncEnd = mode->CrtcHTotal - 1;	          changed = TRUE;      }      if (mode->CrtcHSyncStart >= mode->CrtcHSyncEnd) {	 mode->CrtcHSyncStart = mode->CrtcHSyncEnd - 1;         changed = TRUE;      }      if ((DAC_IS_TI3030 || DAC_IS_IBMRGB528) && s3Bpp==1) {	 /* for 128bit bus we need multiple of 16 8bpp pixels... */	 if (mode->CrtcHTotal & 0x0f) {	    mode->CrtcHTotal = (mode->CrtcHTotal + 0x0f) & ~0x0f;

⌨️ 快捷键说明

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