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

📄 s3.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 4 页
字号:
	    (((modetiming->CrtcVDisplay - 1) & 0x400) >> 9) |	    (((modetiming->CrtcVSyncStart) & 0x400) >> 8) |	    (((modetiming->CrtcVSyncStart) & 0x400) >> 6) | 0x40;	{	    int i, j;	    i = ((((modetiming->CrtcHTotal >> 3) - 5) & 0x100) >> 8) |		((((modetiming->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) |		((((modetiming->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) |		((modetiming->CrtcHSyncStart & 0x800) >> 7);	    if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 64)	    	i |= 0x08;	    if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 32)	    	i |= 0x20;	    j = ((moderegs[VGA_CR0] + ((i & 0x01) << 8) +		  moderegs[VGA_CR4] + ((i & 0x10) << 4) + 1) / 2);	    if (j - (moderegs[VGA_CR4] + ((i & 0x10) << 4)) < 4) {	    	if (moderegs[VGA_CR4] + ((i & 0x10) << 4) + 4 <= moderegs[VGA_CR0] + ((i & 0x01) << 8))	    	    j = moderegs[VGA_CR4] + ((i & 0x10) << 4) + 4;	    	else	    	    j = moderegs[VGA_CR0] + ((i & 0x01) << 8) + 1;	    }            	    moderegs[S3_CR3B] = j & 0xFF;	    i |= (j & 0x100) >> 2;	    /* Interlace mode frame offset. */	    moderegs[S3_CR3C] = (moderegs[VGA_CR0] + ((i & 0x01) << 8)) / 2;	    moderegs[S3_CR5D] = (moderegs[S3_CR5D] & 0x80) | i;	}	{	    int i;	    if (modeinfo->bitsPerPixel < 8)		i = modetiming->HDisplay / 4 + 1;	    else		i = modetiming->HDisplay *		    modeinfo->bytesPerPixel / 4 + 1;	    moderegs[S3_CR61] = (i >> 8) | 0x80;	    moderegs[S3_CR62] = i & 0xFF;	}    }				/* 801+ */    if (modetiming->flags & INTERLACED)	moderegs[S3_CR42] |= 0x20;    /*     * Clock select works as follows:     * Clocks 0 and 1 (VGA 25 and 28 MHz) can be selected via the     * two VGA MiscOutput clock select bits.     * If 0x3 is written to these bits, the selected clock index     * is taken from the S3 clock select register at CR42. Clock     * indices 0 and 1 should correspond to the VGA ones above,     * and 3 is often 0 MHz, followed by extended clocks for a     * total of mostly 16.     */    if (modetiming->flags & USEPROGRCLOCK)	moderegs[VGA_MISCOUTPUT] |= 0x0C;	/* External clock select. */    else if (modetiming->selectedClockNo < 2) {	/* Program clock select bits 0 and 1. */	moderegs[VGA_MISCOUTPUT] &= ~0x0C;	moderegs[VGA_MISCOUTPUT] |=	    (modetiming->selectedClockNo & 3) << 2;    } else if (modetiming->selectedClockNo >= 2) {	moderegs[VGA_MISCOUTPUT] |= 0x0C;	/* Program S3 clock select bits. */	moderegs[S3_CR42] &= ~0x1F;	moderegs[S3_CR42] |=	    modetiming->selectedClockNo;    }    if (s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) {	moderegs[S3_CR33] &= ~0x08;	if (modeinfo->bitsPerPixel == 16)	    moderegs[S3_CR33] |= 0x08;	/*	 * The rest of the DAC/clocking is setup by the	 * Trio64 code in the RAMDAC interface (ramdac.c).	 */    }    if (dac_used->id != NORMAL_DAC) {	int colormode;	colormode = __svgalib_colorbits_to_colormode(modeinfo->bitsPerPixel,					   modeinfo->colorBits);	dac_used->initializeState(&moderegs[S3_DAC_OFFSET],				  modeinfo->bitsPerPixel, colormode,				  modetiming->pixelClock);	if (dac_used->id == ATT20C490) {	    int pixmux, invert_vclk, blank_delay;	    pixmux = 0;	    invert_vclk = 0;	    blank_delay = 2;	    if (colormode == CLUT8_6		&& modetiming->pixelClock >= 67500) {		pixmux = 0x00;		invert_vclk = 1;	    } else if (colormode == CLUT8_8)		pixmux = 0x02;	    else if (colormode == RGB16_555)		pixmux = 0xa0;	    else if (colormode == RGB16_565)		pixmux = 0xc0;	    else if (colormode == RGB24_888_B)		pixmux = 0xe0;	    moderegs[S3_CR67] = pixmux | invert_vclk;	    moderegs[S3_CR6D] = blank_delay;	}	if (dac_used->id == S3_SDAC) {	    int pixmux, invert_vclk, blank_delay;	    pixmux = 0;	    invert_vclk = 0;	    blank_delay = 0;	    if (colormode == CLUT8_6		&& modetiming->pixelClock >= 67500) {#ifdef SDAC_8BPP_PIXMUX		/* x64 8bpp pixel multiplexing? */		pixmux = 0x10;		if (s3_chiptype != S3_866 && s3_chiptype != S3_868)		    invert_vclk = 1;		blank_delay = 2;#endif	    } else if (colormode == RGB16_555) {		pixmux = 0x30;		blank_delay = 2;	    } else if (colormode == RGB16_565) {		pixmux = 0x50;		blank_delay = 2;	    } else if (colormode == RGB24_888_B) {	/* XXXX 868/968 only */		pixmux = 0x90;		blank_delay = 2;	    } else if (colormode == RGB32_888_B) {		pixmux = 0x70;		blank_delay = 2;	    }	    moderegs[S3_CR67] = pixmux | invert_vclk;	    moderegs[S3_CR6D] = blank_delay;	    /* Clock select. */	    moderegs[S3_CR42] &= ~0x0F;	    moderegs[S3_CR42] |= 0x02;	}	if (dac_used->id == IBMRGB52x) {	    unsigned char pixmux, blank_delay, tmp;	    tmp = 0;	    pixmux = 0x11;	    blank_delay = 0;	    if (modeinfo->bitsPerPixel < 8 || colormode == RGB32_888_B)		pixmux = 0x00;	    moderegs[S3_CR58] |= 0x40;	    moderegs[S3_CR65] = 0;	    moderegs[S3_CR66] &= 0xf8;	    moderegs[S3_CR66] |= tmp;#ifdef PIXEL_MULTIPLEXING	    moderegs[S3_CR67] = pixmux;#endif	    moderegs[S3_CR6D] = blank_delay;	    /* Clock select. */	    moderegs[S3_CR42] &= ~0x0F;	    moderegs[S3_CR42] |= 0x02;	}    }#ifdef S3_LINEAR_SUPPORT    s3_cr58 = moderegs[S3_CR58];    s3_cr40 = moderegs[S3_CR40];    s3_cr54 = moderegs[S3_CR54];#endif    if (clk_used == &__svgalib_I2061A_clockchip_methods &&	(modetiming->flags & USEPROGRCLOCK)) {	/* Clock select. */	moderegs[S3_CR42] &= ~0x0F;	moderegs[S3_CR42] |= 0x02;    }    /* update the 8514 regs */    memcpy(moderegs + S3_8514_OFFSET, s3_8514regs, S3_8514_COUNT * 2);}/* Set a mode */static int s3_setmode(int mode, int prv_mode){    ModeInfo *modeinfo;    ModeTiming *modetiming;    unsigned char moderegs[S3_TOTAL_REGS];    int res;    if (mode < G640x480x256 || mode == G720x348x2) {	/* Let the standard VGA driver set standard VGA modes. */	res = __svgalib_vga_driverspecs.setmode(mode, prv_mode);	if (res == 0) {	    /*	     * ARI: Turn off virtual size of 1024 - this fixes all problems	     *      with standard modes, including 320x200x256.	     * 	     * SL:  Is this for 928 only?  Doesn't matter for 805.             *             * MZ:  Affects 765 as well, so I assume it is good for all chipsets.	     */	    s3_unlock();	    __svgalib_outCR(0x34, __svgalib_inCR(0x34) & ~0x10);	    s3_lock();	}	return res;    }    if (!s3_modeavailable(mode))	return 1;    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);    modetiming = malloc(sizeof(ModeTiming));    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {	free(modetiming);	free(modeinfo);	return 1;    }    /* Adjust the display width. */    modeinfo->lineWidth = s3_adjlinewidth(modeinfo->lineWidth);    CI.xbytes = modeinfo->lineWidth;    s3_initializemode(moderegs, modetiming, modeinfo);    free(modeinfo);    free(modetiming);    __svgalib_setregs(moderegs);	/* Set standard regs. */    s3_setregs(moderegs, mode);	/* Set extended regs. */    return 0;}/* Indentify chipset; return non-zero if detected *//* Some port I/O functions: */static unsigned char rdinx(int port, unsigned char index){    outb(port, index);    return inb(port + 1);}static void wrinx(int port, unsigned char index, unsigned char val){    outb(port, index);    outb(port + 1, val);}/* * Returns true iff the bits in 'mask' of register 'port', index 'index' * are read/write. */static int testinx2(int port, unsigned char index, unsigned char mask){    unsigned char old, new1, new2;    old = rdinx(port, index);    wrinx(port, index, (old & ~mask));    new1 = rdinx(port, index) & mask;    wrinx(port, index, (old | mask));    new2 = rdinx(port, index) & mask;    wrinx(port, index, old);    return (new1 == 0) && (new2 == mask);}static int s3_test(void){    int vgaIOBase, vgaCRIndex, vgaCRReg;    vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;    vgaCRIndex = vgaIOBase + 4;    vgaCRReg = vgaIOBase + 5;    outb(vgaCRIndex, 0x11);	/* for register CR11, (Vertical Retrace End) */    outb(vgaCRReg, 0x00);	/* set to 0 */    outb(vgaCRIndex, 0x38);	/* check if we have an S3 */    outb(vgaCRReg, 0x00);    /* Make sure we can't write when locked */    if (testinx2(vgaCRIndex, 0x35, 0x0f))	return 0;    outb(vgaCRIndex, 0x38);	/* for register CR38, (REG_LOCK1) */    outb(vgaCRReg, 0x48);	/* unlock S3 register set for read/write */    /* Make sure we can write when unlocked */    if (!testinx2(vgaCRIndex, 0x35, 0x0f))	return 0;    if (s3_init(0, 0, 0))	/* type not OK */	return 0;    return 1;}/* * Bank switching function - set 64K bank number *  * XXXX locking and unlocking might hurt performance but is safer. */static void s3_setpage(int page){#ifdef S3_16_COLORS    /*      * XXXX adjust the parameter for 4bpp (1bpp is ignored).  Shouldn't     * need this, but either me or the drawing functions are making bad     * assumptions about 4bpp.     */    if (infotable[CM].bytesperpixel == 0)	page *= 4;#endif#ifdef S3_KLUDGE_PAGE_MODE    /* adjust to use 256K pages */    if (CM == G320x200x256)	page *= 4;#endif    s3_unlock();    outb(CRT_IC, 0x35);    outb(CRT_DC, (inb(CRT_DC) & 0xF0) | (page & 0x0F));    if (s3_chiptype >= S3_801) {	outb(CRT_IC, 0x51);	outb(CRT_DC, (inb(CRT_DC) & ~0x0C) | ((page & 0x30) >> 2));    }    inb(CRT_DC);			/* ARI: Ferraro says: required for first generation 911 only */    s3_lock();}/* * Bank switching function - set 64K bank number for 864+ * (not for 4bpp) *  * XXXX locking and unlocking might hurt performance * (864 shouldn't need it). */#ifdef S3_LINEAR_MODE_BANKING_864static void s3_setpage864(int page){    s3_unlock();    /* "Linear" mode banking. */    outb(CRT_IC, 0x6A);    outb(CRT_DC, (inb(CRT_DC) & ~0x3F) | page);    s3_lock();}#endif/* * Set display start address (not for 16 color modes). * * This works up to 4Mb (should be able to go higher). *  * XXXX locking and unlocking might hurt performance but is safer. */static void s3_setdisplaystart(int address){#ifdef S3_KLUDGE_PAGE_MODE    /* adjust to use 256K pages */    if (CM == G320x200x256)	address *= 4;#endif    s3_unlock();    outw(CRT_IC, 0x0d | ((address << 6) & 0xff00));	/* sa2-sa9 */    outw(CRT_IC, 0x0c | ((address >> 2) & 0xff00));	/* sa10-sa17 */    inb(0x3da);			/* set ATC to addressing mode */    outb(ATT_IW, 0x13 + 0x20);	/* select ATC reg 0x13 */    outb(ATT_IW, (inb(ATT_R) & 0xf0) | ((address & 3) << 1));    /* write sa0-1 to bits 1-2 */    outb(CRT_IC, 0x31);    outb(CRT_DC, (inb(CRT_DC) & ~0x30) | ((address & 0xc0000) >> 14));    if (s3_chiptype >= S3_801) {	outb(CRT_IC, 0x51);	outb(CRT_DC, (inb(CRT_DC) & ~0x03) | ((address & 0x300000) >> 20));    }    s3_lock();}/* * Set logical scanline length (Multiples of 8 to 8184). * CR43.2 should be 0 for this. */static void s3_setlogicalwidth(int width){    __svgalib_outCR(0x13, (width >> 3));	/* lw3-lw11 */    __svgalib_outCR(0x51, (width & 0x300) >> 4);	/* lw12-lw13 */}#ifdef S3_LINEAR_SUPPORTstatic void s3_linear_enable(void){    s3_unlock();        if (s3_chiptype > S3_924) {    	int i;    	outb (CRT_IC, 0x40);    	i = (s3_cr40 & 0xf6) | 0x0a;    	outb (CRT_DC, (unsigned char) i);    	outb (CRT_IC, 0x58);    	outb (CRT_DC, s3_linear_opt | s3_cr58);    	if (s3_chiptype > S3_928) {    	    outb (CRT_IC, 0x54);    	    outb (CRT_DC, (s3_cr54 + 0x07));    	}    }        s3_lock();}static void s3_linear_disable(void){    s3_unlock();        if (s3_chiptype > S3_924) {    	if (s3_chiptype > S3_928) {    	    outb (CRT_IC, 0x54);    	    outb (CRT_DC, s3_cr54);    	}    	outb (CRT_IC, 0x58);    	outb (CRT_DC, s3_cr58);    	outb (CRT_IC, 0x40);    	outb (CRT_DC, s3_cr40);    }        s3_lock();}/* Set linear addressing mode */static int s3_linear(int op, int param){    if (op == LINEAR_QUERY_BASE)    	return s3_linear_base;    if (op == LINEAR_QUERY_GRANULARITY) {	switch (s3_memory) {	case 4096:	case 2048:	case 1024:	    return s3_memory * 1024;	default:	    return 1024 * 1024;	}    } else if (op == LINEAR_QUERY_RANGE)	return 256;    else if (op == LINEAR_ENABLE) {	s3_setpage(0);	s3_linear_enable();	s3_linear_addr = param;	return 0;    } else if (op == LINEAR_DISABLE) {	s3_setpage(0);	s3_linear_disable();	s3_linear_addr = 0;	return 0;    } else	return -1;}

⌨️ 快捷键说明

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