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

📄 s3.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (s3_chiptype >= S3_864) {	    if (modeinfo->bitsPerPixel >= 8) {		/* Enable linear addressing. */		moderegs[S3_CR58] |= 0x10;		/* Set window size to 64K. */		moderegs[S3_CR58] &= ~0x03;		/* Assume CR59/5A are correctly set up for 0xA0000. */		/* Set CR6A linear bank to zero. */		moderegs[S3_CR6A] &= ~0x3F;		/* use alternate __svgalib_setpage() function */		__svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage864;	    } else {		/* doesn't work for 4bpp. */		__svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage;	    }	}#endif	moderegs[S3_CR59] = 0;	moderegs[S3_CR5A] = 0x0A;	/* Extended CRTC timing. */	moderegs[S3_CR5E] =	    (((modetiming->CrtcVTotal - 2) & 0x400) >> 10) |	    (((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);	    j = ((moderegs[VGA_CR0] + ((i & 0x01) << 8) +		  moderegs[VGA_CR4] + ((i & 0x10) << 4) + 1) / 2);	    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] &= ~0x57;	    moderegs[S3_CR5D] |= i;	}	{	    int i;#if 0				/* This seems wrong. Why doesn't XF86_S3 have problems? */	    if (s3_chiptype == S3_864 && s3_memory > 1024)		i = modetiming->HDisplay *		    modeinfo->bytesPerPixel / 8 + 1;	    /* else */#endif	    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;	}    }    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 && s3_chiptype <= S3_928) {	    /*	     * 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.	     */	    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;    {	unsigned long buf[16];		if (s3_pci = !(__svgalib_pci_find_vendor_vga(VENDOR_S3, buf)))	    s3_pci_linearbase = buf[4] & 0xFF800000;    }	    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(0x3d4, 0x35);    outb(0x3d5, (inb(0x3d5) & 0xF0) | (page & 0x0F));    if (s3_chiptype >= S3_801) {	outb(0x3d4, 0x51);	outb(0x3d5, (inb(0x3d5) & ~0x0C) | ((page & 0x30) >> 2));    }    inb(0x3d5);			/* 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(0x3d4, 0x6A);    outb(0x3d5, (inb(0x3d5) & ~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(0x3d4, 0x0d | ((address << 6) & 0xff00));	/* sa2-sa9 */    outw(0x3d4, 0x0c | ((address >> 2) & 0xff00));	/* sa10-sa17 */    inb(0x3da);			/* set ATC to addressing mode */    outb(0x3c0, 0x13 + 0x20);	/* select ATC reg 0x13 */    outb(0x3c0, (inb(0x3c1) & 0xf0) | ((address & 3) << 1));    /* write sa0-1 to bits 1-2 */    outb(0x3d4, 0x31);    outb(0x3d5, (inb(0x3d5) & ~0x30) | ((address & 0xc0000) >> 14));    if (s3_chiptype >= S3_801) {	outb(0x3d4, 0x51);	outb(0x3d5, (inb(0x3d5) & ~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_setlinear(unsigned int addr){    /* printf("s3_setlinear(0x%x) called\n", addr); */    s3_unlock();    outb(0x3d4, 0x58);    if (addr) {	int m;	switch (s3_memory) {	case 1024:	    m = 1;	    break;	case 2048:	    m = 2;	    break;	default:	    if (s3_memory > 2048)		m = 3;	    else {		printf("%s: mapping 1MB, but you've only got %dK!\n",		       __FUNCTION__);		m = 1;	    }	}	outb(0x3d5, inb(0x3d5) | 0x10 | m);	/* enable linear mode */	__svgalib_outCR(0x59, (addr >> 8));	__svgalib_outCR(0x5A, (addr) & 0xFF);    } else {	outb(0x3d5, inb(0x3d5) & ~0x13);	/* disable linear mode */	__svgalib_outCR(0x59, 0x00);	__svgalib_outCR(0x5A, 0x0A);    }    s3_lock();

⌨️ 快捷键说明

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