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

📄 ibmrgb52x.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
字号:
/* * IBMRGB52x.c: *  * RAMDAC definitions for IBM's RGB52x PaletteDAC. * * Portion of this file is derived from XFree86's source code. * [insert XFree86's copyright here]. */#include <stdio.h>#include "libvga.h"#include "timing.h"#include "vgaregs.h"#include "driver.h"		/* for __svgalib_driver_report */#include "ramdac.h"#include "IBMRGB52x.h"#define IBMRGB52x_STATESIZE	0x101static int IBMRGB52x_dacspeed = 170000;		/* assuming 170MHz DAC */static int IBMRGB52x_fref = 16000;	/* assuming 16MHz refclock */static int IBMRGB52x_clk = 2;	/* use clock 2 */#ifdef INCLUDE_IBMRGB52x_DAC_TEST/*  * s3IBMRGB_Probe() from XFree86. *  * returns 0x01xx for 525, 0x02xx for 524/528, where xx = revision. */static int IBMRGB52x_probe(void){    unsigned char CR43, CR55, dac[3], lut[6];    unsigned char ilow, ihigh, id, rev, id2, rev2;    int i, j;    int ret = 0;    port_out(0x43, 0x3D4);    CR43 = port_in(0x3D5);    port_out(CR43 & ~0x02, 0x3D5);    port_out(0x55, 0x3D4);    CR55 = port_in(0x3D5);    port_out(CR55 & ~0x03, 0x3D5);    /* save DAC and first LUT entries */    for (i = 0; i < 3; i++)	dac[i] = port_in(IBMRGB_PIXEL_MASK + i);    for (i = j = 0; i < 2; i++) {	port_out(i, IBMRGB_READ_ADDR);	lut[j++] = port_in(IBMRGB_RAMDAC_DATA);	lut[j++] = port_in(IBMRGB_RAMDAC_DATA);	lut[j++] = port_in(IBMRGB_RAMDAC_DATA);    }    port_out(0x55, 0x3D4);    port_out((CR55 & ~0x03) | 0x01, 0x3D5);	/* set RS2 */    /* read ID and revision */    ilow = port_in(IBMRGB_INDEX_LOW);    ihigh = port_in(IBMRGB_INDEX_HIGH);    port_out(0, IBMRGB_INDEX_HIGH);	/* index high */    port_out(IBMRGB_rev, IBMRGB_INDEX_LOW);    rev = port_in(IBMRGB_INDEX_DATA);    port_out(IBMRGB_id, IBMRGB_INDEX_LOW);    id = port_in(IBMRGB_INDEX_DATA);    /* known IDs:         1 = RGB525       2 = RGB524, RGB528      */    if (id >= 1 && id <= 2) {	/* check if ID and revision are read only */	port_out(IBMRGB_rev, IBMRGB_INDEX_LOW);	port_out(~rev, IBMRGB_INDEX_DATA);	port_out(IBMRGB_id, IBMRGB_INDEX_LOW);	port_out(~id, IBMRGB_INDEX_DATA);	port_out(IBMRGB_rev, IBMRGB_INDEX_LOW);	rev2 = port_in(IBMRGB_INDEX_DATA);	port_out(IBMRGB_id, IBMRGB_INDEX_LOW);	id2 = port_in(IBMRGB_INDEX_DATA);	if (id == id2 && rev == rev2) {		/* IBM RGB52x found */	    ret = (id << 8) | rev;	} else {	    port_out(IBMRGB_rev, IBMRGB_INDEX_LOW);	    port_out(rev, IBMRGB_INDEX_DATA);	    port_out(IBMRGB_id, IBMRGB_INDEX_LOW);	    port_out(id, IBMRGB_INDEX_DATA);	}    }    port_out(ilow, IBMRGB_INDEX_LOW);    port_out(ihigh, IBMRGB_INDEX_HIGH);    port_out(0x55, 0x3D4);    port_out(CR55 & ~0x03, 0x3D5);	/* reset RS2 */    /* restore DAC and first LUT entries */    for (i = j = 0; i < 2; i++) {	port_out(i, IBMRGB_WRITE_ADDR);	port_out(lut[j++], IBMRGB_RAMDAC_DATA);	port_out(lut[j++], IBMRGB_RAMDAC_DATA);	port_out(lut[j++], IBMRGB_RAMDAC_DATA);    }    for (i = 0; i < 3; i++)	port_out(dac[i], IBMRGB_PIXEL_MASK + i);    port_out(0x43, 0x3D4);    port_out(CR43, 0x3D5);    port_out(0x55, 0x3D4);    port_out(CR55, 0x3D5);    return ret;}#else#define IBMRGB52x_probe 0#endif#ifdef INCLUDE_IBMRGB52x_DACstatic void IBMRGBSetClock(long freq, int clk, long dacspeed, long fref,		      int *best_m_out, int *best_n_out, int *best_df_out){    volatile double ffreq, fdacspeed, ffref;    volatile int df, n, m, max_n, min_df;    volatile int best_m = 69, best_n = 17, best_df = 0;    volatile double diff, mindiff;#define FREQ_MIN   16250	/* 1000 * (0+65) / 4 */#define FREQ_MAX  dacspeed    if (freq < FREQ_MIN)	ffreq = FREQ_MIN / 1000.0;    else if (freq > FREQ_MAX)	ffreq = FREQ_MAX / 1000.0;    else	ffreq = freq / 1000.0;    fdacspeed = dacspeed / 1e3;    ffref = fref / 1e3;    ffreq /= ffref;    ffreq *= 16;    mindiff = ffreq;    if (freq <= dacspeed / 4)	min_df = 0;    else if (freq <= dacspeed / 2)	min_df = 1;    else	min_df = 2;    for (df = 0; df < 4; df++) {	ffreq /= 2;	mindiff /= 2;	if (df < min_df)	    continue;	/* the remaining formula is  ffreq = (m+65) / n */	if (df < 3)	    max_n = fref / 1000 / 2;	else	    max_n = fref / 1000;	if (max_n > 31)	    max_n = 31;	for (n = 2; n <= max_n; n++) {	    m = (int) (ffreq * n + 0.5) - 65;	    if (m < 0)		m = 0;	    else if (m > 63)		m = 63;	    diff = (m + 65.0) / n - ffreq;	    if (diff < 0)		diff = -diff;	    if (diff < mindiff) {		mindiff = diff;		best_n = n;		best_m = m;		best_df = df;	    }	}    }#ifdef DEBUG    printf("clk %d, setting to %f, m 0x%02x %d, n 0x%02x %d, df %d\n", clk,	   ((best_m + 65.0) / best_n) / (8 >> best_df) * ffref,	   best_m, best_m, best_n, best_n, best_df);#endif    *best_m_out = best_m;    *best_n_out = best_n;    *best_df_out = best_df;}static void IBMRGB52x_init(void){    unsigned char tmp, CR55;#ifdef INCLUDE_IBMRGB52x_DAC_TEST    int idrev;    idrev = IBMRGB52x_probe();    if (__svgalib_driver_report)	printf("svgalib: Using IBM RGB 52%d PaletteDAC, revision %d.\n",	       (idrev >> 8) == 1 ? 5 : 4,	       idrev & 0xff);#else    if (__svgalib_driver_report)	printf("svgalib: Using IBM RGB 52x PaletteDAC.\n");#endif    /* set RS2 */    port_out(0x55, 0x3D4);    CR55 = port_in(0x3D5) & 0xFC;    port_out(CR55 | 0x01, 0x3D5);    tmp = port_in(IBMRGB_INDEX_CONTROL);    port_out(tmp & ~0x01, IBMRGB_INDEX_CONTROL);	/* turn off auto-increment */    port_out(0, IBMRGB_INDEX_HIGH);	/* reset index high */    __svgalib_outCR(0x55, CR55);}static int IBMRGB52x_match_programmable_clock(int desiredclock){    int m, n, df;    IBMRGBSetClock(desiredclock, IBMRGB52x_clk, IBMRGB52x_dacspeed,		   IBMRGB52x_fref, &m, &n, &df);    return ((m + 65.0) / n) / (8 >> df) * IBMRGB52x_fref;}static void IBMRGB52x_initialize_clock_state(unsigned char *regs, int freq){    int m, n, df;    IBMRGBSetClock(freq, IBMRGB52x_clk, IBMRGB52x_dacspeed,		   IBMRGB52x_fref, &m, &n, &df);    if (__svgalib_driver_report)	printf("clk %d, setting to %.3f, m 0x%02x %d, n 0x%02x %d, df %d\n",	       IBMRGB52x_clk, ((m + 65.0) / n) / (8 >> df) * IBMRGB52x_fref / 1000,	       m, m, n, n, df);    regs[IBMRGB_misc_clock] |= 0x01;    regs[IBMRGB_m0 + 2 * IBMRGB52x_clk] = (df << 6) | (m & 0x3f);    regs[IBMRGB_n0 + 2 * IBMRGB52x_clk] = n;    regs[IBMRGB_pll_ctrl2] &= 0xf0;    regs[IBMRGB_pll_ctrl2] |= IBMRGB52x_clk;    regs[IBMRGB_pll_ctrl1] &= 0xf8;    regs[IBMRGB_pll_ctrl1] |= 0x03;}static void IBMRGB52x_savestate(unsigned char *regs){    int i;    unsigned char tmp;    /* set RS2 */    port_out(0x55, 0x3D4);    tmp = port_in(0x3D5) & 0xFC;    port_out(tmp | 0x01, 0x3D5);    for (i = 0; i < 0x100; i++) {	port_out(i, IBMRGB_INDEX_LOW);	/* high index is set to 0 */	regs[i] = port_in(IBMRGB_INDEX_DATA);    }    regs[0x100] = __svgalib_inCR(0x22);    __svgalib_outCR(0x55, tmp);}/* SL: not complete, need more work for 525. */static void IBMRGB52x_restorestate(const unsigned char *regs){    int i;    unsigned char tmp;    /* set RS2 */    port_out(0x55, 0x3D4);    tmp = port_in(0x3D5) & 0xFC;    port_out(tmp | 0x01, 0x3D5);    for (i = 0; i < 0x100; i++) {	port_out(i, IBMRGB_INDEX_LOW);	/* high index is set to 0 */	port_out(regs[i], IBMRGB_INDEX_DATA);    }    __svgalib_outCR(0x22, regs[0x100]);    __svgalib_outCR(0x55, tmp);}static int IBMRGB52x_map_clock(int bpp, int pixelclock){    return pixelclock;}static int IBMRGB52x_map_horizontal_crtc(int bpp, int pixelclock, int htiming){#ifdef PIXEL_MULTIPLEXING    switch (bpp) {    case 4:	break;    case 8:	return htiming / 2;    case 16:	break;    case 24:	return htiming * 3 / 2;    case 32:	return htiming * 2;    }#endif    return htiming;}static void IBMRGB52x_initializestate(unsigned char *regs, int bpp, int colormode,				      int pixelclock){    unsigned char tmp;    regs[IBMRGB_misc_clock] = (regs[IBMRGB_misc_clock] & 0xf0) | 0x03;    regs[IBMRGB_sync] = 0;    regs[IBMRGB_hsync_pos] = 0;    regs[IBMRGB_pwr_mgmt] = 0;    regs[IBMRGB_dac_op] &= ~0x08;	/* no sync on green */    regs[IBMRGB_dac_op] |= 0x02;	/* fast slew */    regs[IBMRGB_pal_ctrl] = 0;    regs[IBMRGB_misc1] &= ~0x43;    regs[IBMRGB_misc1] |= 1;#ifdef PIXEL_MULTIPLEXING    if (bpp >= 8)	regs[IBMRGB_misc2] = 0x43;	/* use SID bus? 0x47 for DAC_8_BIT */#endif    tmp = __svgalib_inCR(0x22);    if (bpp <= 8)		/* and 968 */	__svgalib_outCR(0x22, tmp | 0x08);    else	__svgalib_outCR(0x22, tmp & ~0x08);    regs[IBMRGB_pix_fmt] &= ~0x07;    switch (bpp) {    case 4:    case 8:	regs[IBMRGB_pix_fmt] |= 0x03;	regs[IBMRGB_8bpp] = 0x00;	break;    case 15:	regs[IBMRGB_pix_fmt] |= 0x04;	regs[IBMRGB_16bpp] = 0x02;	break;    case 16:	regs[IBMRGB_pix_fmt] |= 0x04;	regs[IBMRGB_16bpp] = 0x00;	break;    case 24:	regs[IBMRGB_pix_fmt] |= 0x05;	/* SL: guess */	regs[IBMRGB_24bpp] = 0x00;	break;    case 32:	regs[IBMRGB_pix_fmt] |= 0x06;	regs[IBMRGB_32bpp] = 0x00;	break;    }    IBMRGB52x_initialize_clock_state(regs,				   IBMRGB52x_map_clock(bpp, pixelclock));}static void IBMRGB52x_qualify_cardspecs(CardSpecs * cardspecs, int dacspeed){    IBMRGB52x_dacspeed = __svgalib_setDacSpeed(dacspeed, 170000);	/* 220 MHz version exist also */    cardspecs->maxPixelClock4bpp = IBMRGB52x_dacspeed;    cardspecs->maxPixelClock8bpp = IBMRGB52x_dacspeed;#ifdef PIXEL_MULTIPLEXING    cardspecs->maxPixelClock16bpp = IBMRGB52x_dacspeed;    cardspecs->maxPixelClock24bpp = IBMRGB52x_dacspeed * 3 / 2;    cardspecs->maxPixelClock32bpp = IBMRGB52x_dacspeed / 2;#else    cardspecs->maxPixelClock16bpp = 0;    cardspecs->maxPixelClock24bpp = 0;    cardspecs->maxPixelClock32bpp = 0;#endif    cardspecs->mapClock = IBMRGB52x_map_clock;    cardspecs->matchProgrammableClock = IBMRGB52x_match_programmable_clock;    cardspecs->mapHorizontalCrtc = IBMRGB52x_map_horizontal_crtc;    cardspecs->flags |= CLOCK_PROGRAMMABLE;}DacMethods __svgalib_IBMRGB52x_methods ={    IBMRGB52x,    "IBM RGB 52x PaletteDAC",    DAC_HAS_PROGRAMMABLE_CLOCKS,    IBMRGB52x_probe,    IBMRGB52x_init,    IBMRGB52x_qualify_cardspecs,    IBMRGB52x_savestate,    IBMRGB52x_restorestate,    IBMRGB52x_initializestate,    IBMRGB52x_STATESIZE};#endif

⌨️ 快捷键说明

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