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

📄 chips.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 5 页
字号:
#define CT_540	 4#define CT_545	 5#define CT_546	 6#define CT_548	 7#define CT_550	 8#define CT_554	 9#define CT_555	10#define CT_8554	11#define CT_9000	12#define CT_4300	13static CardSpecs *cardspecs;/*----------------------------------------------------------------------*//*----------------------------------------------------------------------*/static void nothing(void){}/*----------------------------------------------------------------------*//* Fill in chipset specific mode information				*//*----------------------------------------------------------------------*/static void CHIPS_getmodeinfo(int mode, vga_modeinfo * modeinfo){#ifdef DEBUG    printf("CHIPS: CHIPS_getmodeinfo(%d, *)\n", mode);#endif	if (modeinfo->bytesperpixel > 0)	{	modeinfo->maxpixels = video_memory * 1024 /			modeinfo->bytesperpixel;	}	else	{	modeinfo->maxpixels = video_memory * 1024;	}	modeinfo->maxlogicalwidth = 2040;	modeinfo->linewidth_unit = 8;	modeinfo->startaddressrange = 0xfffff;	modeinfo->memory = video_memory;	if (mode == G320x200x256)	{		/* Special case: bank boundary may not fall within display. */		modeinfo->startaddressrange = 0xf0000;		/* Hack: disable page flipping capability for the moment. */		modeinfo->startaddressrange = 0xffff;		modeinfo->maxpixels = 65536;	}	modeinfo->haveblit = 0;	if (CHIPS_interlaced(mode))	{	modeinfo->flags |= IS_INTERLACED;	}	if (CHIPSchipset != CT_520)	{	    modeinfo->flags |= EXT_INFO_AVAILABLE | CAPABLE_LINEAR;		}#if defined(seperated_read_write_bank)	if (ctisHiQV) {	    /* HiQV doesn't have seperate Read/Write pages */	    modeinfo->flags &= ~HAVE_RWPAGE;	} else {	    modeinfo->flags |= HAVE_RWPAGE;	}#else	modeinfo->flags &= ~HAVE_RWPAGE;#endif}static void ctHWCalcClock(unsigned char *vclk, unsigned int Clock){#ifdef DEBUG    printf("CHIPS: ctHWCalcClock(*, %d)\n", Clock);#endif    vclk[MSR] =  (Clock << 2) & 0xC;    vclk[XR54] = vclk[MSR];    vclk[XR33] = 0;}#define Fref 14318180/*  * This is Ken Raeburn's <raeburn@raeburn.org> clock * calculation code just modified a little bit to fit in here. */static void ctCalcClock(unsigned char *vclk, unsigned int Clock){    int M, N, P, PSN, PSNx;    int bestM=0, bestN=0, bestP=0, bestPSN=0;    double bestError, abest = 42, bestFout=0;    double target;    double Fvco, Fout;    double error, aerror;    int M_min = 3;    /* Hack to deal with problem of Toshiba 720CDT clock */    int M_max = ctisHiQV ? 63 : 127;#ifdef DEBUG    printf("CHIPS: ctCalcClock(*, %d)\n", Clock);#endif    /* Other parameters available on the 65548 but not the 65545, and     * not documented in the Clock Synthesizer doc in rev 1.0 of the     * 65548 datasheet:     *      * + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545)     * 1, VCO divider loop uses divide by 16     *      * + XR30[5] = 1, reference clock is divided by 5     *      * Other parameters available on the 65550 and not on the 65545     *      * + XRCB[2] = 0, VCO divider loop uses divide by 4 (same as 65545)     * 1, VCO divider loop uses divide by 16     *      * + XRCB[1] = 1, reference clock is divided by 5     *      * + XRCB[7] = Vclk = Mclk     *      * + XRCA[0:1] = 2 MSB of a 10 bit M-Divisor     *      * + XRCA[4:5] = 2 MSB of a 10 bit N-Divisor     *      * I haven't put in any support for those here.  For simplicity,     * they should be set to 0 on the 65548, and left untouched on     * earlier chips.  */    target = Clock * 1000;    for (PSNx = 0; PSNx <= 1; PSNx++) {	int low_N, high_N;	double Fref4PSN;	PSN = PSNx ? 1 : 4;	low_N = 3;	high_N = 127;	while (Fref / (PSN * low_N) > 2.0e6)	    low_N++;	while (Fref / (PSN * high_N) < 150.0e3)	    high_N--;	Fref4PSN = Fref * 4 / PSN;	for (N = low_N; N <= high_N; N++) {	    double tmp = Fref4PSN / N;	    for (P = ctisHiQV ? 1 : 0; P <= 5; P++) {		      /* to force post divisor on Toshiba 720CDT */		double Fvco_desired = target * (1 << 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 <= 48.0e6)			continue;		    if (Fvco > 220.0e6)			break;		    Fout = Fvco / (1 << 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;			bestFout = Fout;		    }		}	    }	}    }    if (ctisHiQV) {        vclk[MSR] = 3 << 2;        /* Leave non-clock bits of FR03 alone */        vclk[HiQVFR03] = (vclk[HiQVFR03] & 0xF3) | vclk[MSR];	vclk[VCLK(0)] = bestM - 2;	vclk[VCLK(1)] = bestN - 2;	vclk[VCLK(2)] = 0;	vclk[VCLK(3)] = (bestP << 4) + (bestPSN == 1);#ifdef DEBUG	if (__svgalib_driver_report) {	    printf("Probed Freq: %.2f MHz", (float)(Clock / 1000.));            printf("VCLK(0) = %x, ",VCLK(0));            printf("VCLK(1) = %x, ",VCLK(1));            printf("VCLK(2) = %x, ",VCLK(2));            printf("VCLK(3) = %x\n",VCLK(3));	    printf(", vclk[0]=%X, vclk[1]=%X, vclk[2]=%X, vlck[3]=%X\n",		   vclk[VCLK(0)], vclk[VCLK(1)], vclk[VCLK(2)], vclk[VCLK(3)]);	    printf("Freq used: %.2f MHz\n", bestFout / 1.0e6);	}#endif	return;    } else {	        vclk[MSR] = 3 << 2;        /* Leave non-clock bits of XR54 alone */        vclk[XR54] = (vclk[XR54] & 0xF3) | vclk[MSR];	vclk[VCLK(0)] = (bestP << 1) + (bestPSN == 1);	vclk[VCLK(1)] = bestM - 2;	vclk[VCLK(2)] = bestN - 2;#ifdef DEBUG	if (__svgalib_driver_report) {	    printf("Probed Freq: %.2f MHz", (float)(Clock / 1000.));	    printf(", vclk[0]=%X, vclk[1]=%X, vclk[2]=%X\n",		   vclk[VCLK(0)], vclk[VCLK(1)], vclk[VCLK(2)]);	    printf("Freq used: %.2f MHz\n", bestFout / 1.0e6);	}#endif	return;    }    }static void ctClockSave(unsigned char regs[]){    unsigned char xr54, msr, temp;    int i;    unsigned int Clk;#ifdef DEBUG    printf("CHIPS: ctClockSave\n");#endif    msr = inb(0x3CC);  	/* save the standard VGA clock registers */    regs[MSR] = msr;        if (ctisHiQV) {	outb(0x3D0,0x03);	regs[HiQVFR03] = inb(0x3D1);/* save alternate clock select reg.  */	temp = (regs[HiQVFR03] & 0xC) >> 2;	if (temp == 3)	    temp = 2;	temp = temp << 2;	for (i = 0; i < 4; i++) {	    outb(0x3D6,0xC0 + i + temp);	    regs[VCLK(i)] = inb(0x3D7);	}    } else {	outb(0x3D6,0x33);    /* get status of MCLK/VCLK select reg.*/	regs[XR33] = inb(0x3D7);	outb(0x3D6,0x54);    /* save alternate clock select reg.   */	xr54 = inb(0x3D7);	regs[XR54] = xr54;	if ((CHIPSchipset == CT_535 || CHIPSchipset == CT_540 ||	     CHIPSchipset == CT_545 || CHIPSchipset == CT_546 ||	     CHIPSchipset == CT_548 || CHIPSchipset == CT_4300) && 	     (((xr54 & 0xC) == 0xC) || ((xr54 & 0xC) == 0x8))) {	    if (ctTextClock) {		Clk = ctTextClock;	    } else {#ifdef CHIPS_PROBE_TEXT_CLOCK		register int status = vgaIOBase + 0xA;		int maskval = 0x08;		unsigned long cnt, rcnt, sync;		int Clk1, Clk2;		sigset_t sig2block;		/* If we are using a programmable clock, then there		 * is no way to be sure that the register values		 * correspond to those currently uploaded to the VCO.		 * Hence we use the same ugly hack XFree uses to probe		 * the value of the clock */		/* Disable the interrupts */		sigfillset(&sig2block);		sigprocmask(SIG_BLOCK, &sig2block, (sigset_t *)NULL);		/* Select Clk1 */		outb(0x3C2, (msr & 0xF2) | 0x4 | ctVgaIOBaseFlag);		outb(0x3D6,0x54);		outb(0x3D7,((xr54 & 0xF3) | 0x4));	    		usleep(50000);     /* let VCO stabilise */	    		cnt  = 0;		sync = 200000;		while ((inb(status) & maskval) == 0x00) 	            if (sync-- == 0) goto finishClk1;		/* Something appears to be happening, so reset sync count */		sync = 200000;		while ((inb(status) & maskval) == maskval) 	            if (sync-- == 0) goto finishClk1;		/* Something appears to be happening, so reset sync count */		sync = 200000;		while ((inb(status) & maskval) == 0x00) 	            if (sync-- == 0) goto finishClk1;    		for (rcnt = 0; rcnt < 5; rcnt++) 		{		    while (!(inb(status) & maskval)) 		        cnt++;		    while ((inb(status) & maskval)) 		        cnt++;		}			      finishClk1:		Clk1 = cnt;		/* Select Clk2 or Clk3 */		outb(0x3C2, (msr & 0xFE) | ctVgaIOBaseFlag);		outb(0x3D6,0x54);		outb(0x3D7,xr54);	    		usleep(50000);     /* let VCO stabilise */		cnt  = 0;		sync = 200000;		while ((inb(status) & maskval) == 0x00) 	            if (sync-- == 0) goto finishClk2;		/* Something appears to be happening, so reset sync count */		sync = 200000;		while ((inb(status) & maskval) == maskval) 	            if (sync-- == 0) goto finishClk2;		/* Something appears to be happening, so reset sync count */		sync = 200000;		while ((inb(status) & maskval) == 0x00) 	            if (sync-- == 0) goto finishClk2;    		for (rcnt = 0; rcnt < 5; rcnt++) 		{		    while (!(inb(status) & maskval)) 		        cnt++;		    while ((inb(status) & maskval)) 		        cnt++;		}			      finishClk2:		Clk2 = cnt;		/* Re-enable the interrupts */		sigprocmask(SIG_UNBLOCK, &sig2block, (sigset_t *)NULL);		Clk = (int)(0.5 + (((float)28322) * Clk1) / Clk2);#else	/* CHIPS_PROBE_TEXT_CLOCK */		if (ctLCD) {		    Clk = LCD_TXT_CLOCK_FREQ;		} else {		    Clk = CRT_TXT_CLOCK_FREQ;		}#endif	    }	    /* Find a set of register settings that will give this	     * clock */	    ctCalcClock(regs, Clk);	}    }    return;}static void ctClockRestore(const unsigned char regs[])

⌨️ 快捷键说明

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