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

📄 sis.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
        write_xr(6,temp);        return 0;    };    if (op==LINEAR_DISABLE){        int temp;        sis_is_linear=0;         read_xr(6,temp);        temp &=0x7f;        write_xr(0x20,0) ;         write_xr(0x21,0) ;         write_xr(6,temp);        return 0;    };    if (op==LINEAR_QUERY_BASE) return sis_linear_base;    if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0;		/* No granularity or range. */        else return -1;		/* Unknown function. */}static int sis_match_programmable_clock(int clock){return clock ;}static int sis_map_clock(int bpp, int clock){return clock ;}static int sis_map_horizontal_crtc(int bpp, int pixelclock, int htiming){return htiming;}/* Function table (exported) */DriverSpecs __svgalib_sis_driverspecs ={    sis_saveregs,    sis_setregs,    sis_unlock,    sis_lock,    sis_test,    sis_init,    sis_setpage,    NULL,    NULL,    sis_setmode,    sis_modeavailable,    sis_setdisplaystart,    sis_setlogicalwidth,    sis_getmodeinfo,    0,				/* old blit funcs */    0,    0,    0,    0,    0,				/* ext_set */    0,				/* accel */    sis_linear,    0,				/* accelspecs, filled in during init. */    NULL,                       /* Emulation */};/* Initialize chipset (called after detection) */static int sis_init(int force, int par1, int par2){    unsigned long buf[64];    int found=0;    int _ioperm=0;    sis_unlock();    if (force) {	sis_memory = par1;        sis_chiptype = par2;    } else {    };    if (getenv("IOPERM") == NULL) {      _ioperm=1;      if (iopl(3) < 0) {        printf("svgalib: cannot get I/O permissions\n");        exit(1);      }    }    found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0);    if (_ioperm) iopl(0);    sis_linear_base=0;    sis_chiptype=0;    if (!found){       sis_linear_base=buf[4]&0xffffff00;       switch((buf[0]>>16)&0xffff) {            case PCI_CHIP_SG86C201: sis_chiptype=SIS_86C201; break;            case PCI_CHIP_SG86C202: sis_chiptype=SIS_86C202; break;            case PCI_CHIP_SG86C205: sis_chiptype=SIS_86C205; break;            case PCI_CHIP_SG86C215: sis_chiptype=SIS_86C215; break;            case PCI_CHIP_SG86C225: sis_chiptype=SIS_86C225; break;            case PCI_CHIP_SIS5597: sis_chiptype=SIS_5597; break;            case PCI_CHIP_SIS300:            case PCI_CHIP_SIS540:            case PCI_CHIP_SIS630:            case PCI_CHIP_SIS530: sis_chiptype=SIS_530; break;/*            case PCI_CHIP_SIS5598: sis_chiptype=SIS_5598; break;*/            case PCI_CHIP_SIS6326: sis_chiptype=SIS_6326; break;       };    };    if(sis_memory==0){        if ((sis_chiptype == SIS_6326)||(sis_chiptype==SIS_530)){            int temp;            read_xr(0x0C,temp);            temp >>= 1;            sis_memory=1024<<(temp&0x03);        };		        if ( sis_chiptype == SIS_5597) {            int temp,bsiz;		/* Because 5597 shares main memory, 		   I test for BIOS CONFIGURED memory.*/            read_xr(0x0C,temp);            bsiz = (temp >> 1) & 3;            read_xr(0x2F,temp);            temp &= 7;            temp++;            if (bsiz > 0) temp = temp << 1;            sis_memory = 256 * temp;        };        if(sis_chiptype<SIS_5597) {            int temp;            read_xr(0x0F,temp);            sis_memory=1024<<(temp&0x03);        };    };    if (__svgalib_driver_report) {	printf("Using SIS driver, %iKB. Chiptype=%i\n",sis_memory,sis_chiptype);    };    cardspecs = malloc(sizeof(CardSpecs));    cardspecs->videoMemory = sis_memory;    cardspecs->maxPixelClock4bpp = 75000;	    cardspecs->maxPixelClock8bpp = 135000;	    cardspecs->maxPixelClock16bpp = 135000;	    cardspecs->maxPixelClock24bpp = 135000;    cardspecs->maxPixelClock32bpp = 0;    cardspecs->flags = INTERLACE_DIVIDE_VERT | CLOCK_PROGRAMMABLE;    cardspecs->maxHorizontalCrtc = 2040;    cardspecs->maxPixelClock4bpp = 0;    cardspecs->nClocks =0;    cardspecs->mapClock = sis_map_clock;    cardspecs->mapHorizontalCrtc = sis_map_horizontal_crtc;    cardspecs->matchProgrammableClock=sis_match_programmable_clock;    __svgalib_driverspecs = &__svgalib_sis_driverspecs;    __svgalib_banked_mem_base=0xa0000;    __svgalib_banked_mem_size=0x10000;    __svgalib_linear_mem_base=sis_linear_base;    __svgalib_linear_mem_size=sis_memory*0x400;    return 0;}static voidsisCalcClock(int Clock, int max_VLD, unsigned int *vclk){    int M, N, P, PSN, VLD, PSNx;    int bestM=0, bestN=0, bestP=0, bestPSN=0, bestVLD=0;    double bestError, abest = 42.0, bestFout;    double target;    double Fvco, Fout;    double error, aerror;    /*     *	fd = fref*(Numerator/Denumerator)*(Divider/PostScaler)     *     *	M 	= Numerator [1:128]      *  N 	= DeNumerator [1:32]     *  VLD	= Divider (Vco Loop Divider) : divide by 1, 2     *  P	= Post Scaler : divide by 1, 2, 3, 4     *  PSN     = Pre Scaler (Reference Divisor Select)      *      * result in vclk[]     */#define Midx 	0#define Nidx 	1#define VLDidx 	2#define Pidx 	3#define PSNidx 	4#define Fref 14318180/* stability constraints for internal VCO -- MAX_VCO also determines  * the maximum Video pixel clock */#define MIN_VCO Fref#define MAX_VCO 135000000#define MAX_VCO_5597 353000000#define MAX_PSN 0 /* no pre scaler for this chip */#define TOLERANCE 0.01	/* search smallest M and N in this tolerance */    int M_min = 2;  int M_max = 128;  /*  abest=10000.0; */   target = Clock * 1000;      if ((sis_chiptype == SIS_5597) || (sis_chiptype == SIS_6326)){ 	int low_N = 2; 	int high_N = 5; 	int PSN = 1;  	P = 1; 	if (target < MAX_VCO_5597 / 2) 	    P = 2; 	if (target < MAX_VCO_5597 / 3) 	    P = 3; 	if (target < MAX_VCO_5597 / 4) 	    P = 4; 	if (target < MAX_VCO_5597 / 6) 	    P = 6; 	if (target < MAX_VCO_5597 / 8) 	    P = 8;  	Fvco = P * target;  	for (N = low_N; N <= high_N; N++){ 	    double M_desired = Fvco / Fref * N; 	    if (M_desired > M_max * max_VLD) 		continue;  	    if ( M_desired > M_max ) { 		M = M_desired / 2 + 0.5; 		VLD = 2; 	    } else { 		M = Fvco / Fref * N + 0.5; 		VLD = 1; 	    };  	    Fout = (double)Fref * (M * VLD)/(N * P);  	    error = (target - Fout) / target; 	    aerror = (error < 0) ? -error : error;/* 	    if (aerror < abest && abest > TOLERANCE) {*/ 	    if (aerror < abest) { 	        abest = aerror; 	        bestError = error; 	        bestM = M; 	        bestN = N; 	        bestP = P; 	        bestPSN = PSN; 	        bestVLD = VLD; 	        bestFout = Fout; 	    } 	}     }     else {         for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { 	    int low_N, high_N; 	    double FrefVLDPSN;  	    PSN = !PSNx ? 1 : 4;  	    low_N = 2; 	    high_N = 32;  	    for ( VLD = 1 ; VLD <= max_VLD ; VLD++ ) {  	        FrefVLDPSN = (double)Fref * VLD / PSN; 	        for (N = low_N; N <= high_N; N++) { 		    double tmp = FrefVLDPSN / N;  		    for (P = 1; P <= 4; P++) {	 		        double Fvco_desired = target * ( P ); 		        double M_desired = Fvco_desired / tmp;  		        /* Which way will M_desired be rounded?   		         *  Do all three just to be safe.   		         */ 		        int M_low = M_desired - 1; 		        int M_hi = M_desired + 1;  		        if (M_hi < M_min || M_low > M_max) 			    continue;  		        if (M_low < M_min) 			    M_low = M_min; 		        if (M_hi > M_max) 			    M_hi = M_max;  		        for (M = M_low; M <= M_hi; M++) { 			    Fvco = tmp * M; 			    if (Fvco <= MIN_VCO) 			        continue; 			    if (Fvco > MAX_VCO) 			        break;  			    Fout = Fvco / ( P );  			    error = (target - Fout) / target; 			    aerror = (error < 0) ? -error : error; 			    if (aerror < abest) { 			        abest = aerror; 			        bestError = error; 			        bestM = M; 			        bestN = N; 			        bestP = P; 			        bestPSN = PSN; 			        bestVLD = VLD; 			        bestFout = Fout; 			    } 		        } 		    } 	        } 	    }         }  }  vclk[Midx]    = bestM;  vclk[Nidx]    = bestN;  vclk[VLDidx]  = bestVLD;  vclk[Pidx]    = bestP;  vclk[PSNidx]  = bestPSN;};static void sisClockLoad(int Clock, unsigned char *regs) {    unsigned int 	vclk[5];    unsigned char 	temp, xr2a, xr2b;    sisCalcClock(Clock, 2, vclk);    xr2a = (vclk[Midx] - 1) & 0x7f ;    xr2a |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;    xr2b  = (vclk[Nidx] -1) & 0x1f ;	/* bits [4:0] contain denumerator -MC */    if (vclk[Pidx] <= 4){ 	    xr2b |= (vclk[Pidx] -1 ) << 5 ; /* postscale 1,2,3,4 */            temp=regs[XR(0x13)]; 	    temp &= 0xBF;            regs[XR(0x13)]=temp;    } else {	    xr2b |= ((vclk[Pidx] / 2) -1 ) << 5 ;  /* postscale 6,8 */             temp=regs[XR(0x13)]; 	    temp |= 0x40;            regs[XR(0x13)]=temp;    };    xr2b |= 0x80 ;   /* gain for high frequency */     regs[XR(0x2a)]=xr2a;    regs[XR(0x2b)]=xr2b;    if (sis_chiptype == SIS_5597 || sis_chiptype == SIS_6326) {        temp=regs[XR(0x23)]; 	if (sis_edo_vram) 	    temp |= 0x40;        regs[XR(0x23)]=temp;    }    if (sis_chiptype == SIS_5597 || sis_chiptype == SIS_6326 || sis_chiptype == SIS_530) { 	/*write_xr(0x3B, 0x08 );*/        if (sis_chiptype == SIS_5597) {            temp=regs[XR(0x34)]; 	    if (sis_host_bus) 	    	temp |= 0x18;  	    else temp &= ~0x18;            regs[XR(0x34)]=temp;            temp=regs[XR(0x3D)]; 	    if (sis_host_bus) 	     	  temp &= 0x0F;             regs[XR(0x3D)]=temp;	}	     	/* One-Cycle VRAM */        temp=regs[XR(0x34)]; 	if (sis_fast_vram)            regs[XR(0x34)]=temp;  	/* pci burst */        temp=regs[XR(0x35)]; 	if (sis_pci_burst_on)  	    temp |= 0x10; 	else if (sis_pci_burst_off) 	    temp &= ~0x10;        regs[XR(0x35)]=temp; 	/* pci burst,also */	if (sis_chiptype != SIS_530) {                temp=regs[XR(0x26)];		if (sis_pci_burst_on) 			temp |= 0x20;		else if (sis_pci_burst_off)			temp &= ~0x20;                regs[XR(0x26)]=temp;	}/* Merge FIFOs */	        	temp=regs[XR(0x07)];        temp |= 0x80;        regs[XR(0x07)]=temp;    };}static int sisMClk(void){ int mclk;  unsigned char xr28, xr29, xr13, xr10;    if (sis_chiptype == SIS_530) {	/* The MCLK in SiS530/620 is set by BIOS in SR10 */	read_xr(0x10, xr10);	switch(xr10 & 0x0f) {	case 1:		mclk = 75000; /* 75 Mhz */		break;	case 2:		mclk = 83000; /* 83 Mhz */		break;	case 3:		mclk = 100000;/* 100 Mhz */		break;	case 0:	default:		mclk = 66000; /* 66 Mhz */	}	return(mclk);    }    /* Numerator */    read_xr(0x28,xr28);    mclk=14318*((xr28 & 0x7f)+1);    /* Denumerator */    read_xr(0x29,xr29);    mclk=mclk/((xr29 & 0x1f)+1);  /* Divider. Does not seem to work for mclk for older cards */  if ( (sis_chiptype==SIS_6326) &&        ((xr28 & 0x80)!=0 ) ) {         mclk = mclk*2;    }    /* Post-scaler. Values depends on SR13 bit 7  */    read_xr(0x13,xr13);    if ( (xr13 & 0x80)==0 ) {      mclk = mclk / (((xr29 & 0x60) >> 5)+1);    }    else {      /* Values 00 and 01 are reserved */      if ((xr29 & 0x60) == 0x40) mclk=mclk/6;      if ((xr29 & 0x60) == 0x60) mclk=mclk/8;    }    return(mclk);}static voidsis_CPUthreshold(int dotClock,int bpp,int *thresholdLow,int *thresholdHigh){    unsigned char temp;    int mclk;    int safetymargin, gap;    float z, z1, z2; /* Yeou */    int factor;         mclk=sisMClk();    if (sis_chiptype == SIS_530) /* Yeou for 530 thresholod */    {        /* z = f *((dotClock * bpp)/(buswidth*mclk);           thresholdLow  = (z+1)/2 + 4;           thresholdHigh = 0x1F;                      where f = 0x60 when UMA (SR0D D[0] = 1)                     0x30      LFB (SR0D D[0] = 0)        */        read_xr (0x0d, temp); 	if (temp & 0x01) factor = 0x60;        else factor = 0x30;           z1 = (float)(dotClock * bpp);         z2 = (float)(64.0 * mclk); 	z = ((float) factor * (z1 / z2));        *thresholdLow = ((int)z + 1) / 2 + 4 ;           *thresholdHigh = 0x1F;     }    else {   /* For sis other product */        /* Adjust thresholds. Safetymargin is to be adjusted by fifo_XXX            options. Try to mantain a fifo margin of gap. At high Vclk*bpp           this isn't possible, so limit the thresholds.                   The values I guess are :           FIFO_CONSERVATIVE : safetymargin = 5 ;           FIFO_MODERATE     : safetymargin = 3 ;           Default           : safetymargin = 1 ;  (good enough in many cases)            FIFO_AGGRESSIVE   : safetymargin = 0 ;	            gap=4 seems to be the best value in either case...       */           safetymargin=3;        gap = 4;       *thresholdLow = ((bpp*dotClock) / mclk)+safetymargin;       *thresholdHigh = ((bpp*dotClock) / mclk)+gap+safetymargin;       /* 24 bpp seems to need lower FIFO limits.           At 16bpp is possible to put a thresholdHigh of 0 (0x10) with           good results on my system(good performance, and virtually no noise) */             if ( *thresholdLow > (bpp < 24 ? 0xe:0x0d) ) {     	     *thresholdLow = (bpp < 24 ? 0xe:0x0d);  	}        if ( *thresholdHigh > (bpp < 24 ? 0x10:0x0f) ) {  	     *thresholdHigh = (bpp < 24 ? 0x10:0x0f);	}    }; /* sis530 */}

⌨️ 快捷键说明

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