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

📄 et4000.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
    switch (info->colors) {    case 1 << 15:	/* All HiColor dacs handle 15 bit */	if ((et4000_dac & 1) == 0)	    return 0;	break;    case 1 << 16:	/* Unfortunately, we can't tell the difference between a Sierra Mark 2 */	/* and a Mark 3, and the mark 2 is only 15 bit. If this gives you trouble */	/* change it to (8|16) rather than (2|8|16) */	/* Currently allow Sierra Mark2/3, AT&T, STG-170x and AcuMos */	if ((et4000_dac & (2 | 8 | 16 | 32 | 64)) == 0)	    return 0;	break;    case 1 << 24:	/* Don't know how to set dac command register for Diamond SS2410 Dac */	/* Only allow AT&T, STG-170x and AcuMos */	if ((et4000_dac & (8 | 16 | 32 | 64)) == 0)	    return 0;	break;    }    return SVGADRV;}/* Check if mode is interlaced */static int et4000_interlaced(int mode){    const unsigned char *regs;    if (et4000_modeavailable(mode) != SVGADRV)	return 0;    regs = LOOKUPMODE(et4000_modes, mode);    if (regs == NULL || regs == DISABLE_MODE)	return 0;    return (regs[EXT + 5] & 0x80) != 0;		/* CRTC 35H */}/* Set a mode */static int et4000_setmode(int mode, int prv_mode){    const unsigned char *regs;    unsigned char i;    if (et4000_dac)	/* Standard dac behaviour */	__svgalib_hicolor(et4000_dac, STD_DAC);    switch (et4000_modeavailable(mode)) {    case STDVGADRV:	/* Reset extended register that is set to non-VGA */	/* compatible value for 132-column textmodes (at */	/* least on some cards). */	et4000_unlock();	outb(__svgalib_CRT_I, 0x34);	i = inb(__svgalib_CRT_D);	if ((i & 0x02) == 0x02)	    outb(__svgalib_CRT_D, (i & 0xfd)); /* DS */	return __svgalib_vga_driverspecs.setmode(mode, prv_mode);    case SVGADRV:	regs = LOOKUPMODE(et4000_modes, mode);	if (regs != NULL)	    break;    default:	return 1;		/* mode not available */    }    if (et4000_dac && !et4000_extdac)	switch (vga_getmodeinfo(mode)->colors) {	case 1 << 15:	    __svgalib_hicolor(et4000_dac, HI15_DAC);	    break;	case 1 << 16:	    __svgalib_hicolor(et4000_dac, HI16_DAC);	    break;	case 1 << 24:	    __svgalib_hicolor(et4000_dac, TC24_DAC);	    break;	}    __svgalib_setregs(regs);    et4000_setregs(regs, mode);    return 0;}/* Unlock chipset-specific registers */static void et4000_unlock(void){    /* get access to extended registers */    port_out(3, 0x3bf);    if (port_in(0x3cc) & 1)	port_out(0xa0, 0x3d8);    else	port_out(0xa0, 0x3b8);}/* Relock chipset-specific registers */static void et4000_lock(void){}/* Enable linear mode at a particular 4M page (0 to turn off) */static void et4000_setlinear(int addr){    et4000_unlock();    outb(CRT_IC, 0x36);    if (addr)	outb(CRT_DC, inb(CRT_DC) | 16);	/* enable linear mode */    else	outb(CRT_DC, inb(CRT_DC) & ~16);	/* disable linear mode */    outb(CRT_IC, 0x30);    outb(CRT_DC, addr);    et4000_lock();}/* Indentify chipset; return non-zero if detected */static int et4000_test(void){    unsigned char new, old, val;    int base;    et4000_unlock();    /* test for Tseng clues */    old = port_in(0x3cd);    port_out(0x55, 0x3cd);    new = port_in(0x3cd);    port_out(old, 0x3cd);    /* return false if not Tseng */    if (new != 0x55)	return 0;    /* test for ET4000 clues */    if (port_in(0x3cc) & 1)	base = CRT_IC;    else	base = 0x3b4;    port_out(0x33, base);    old = port_in(base + 1);    new = old ^ 0xf;    port_out(new, base + 1);    val = port_in(base + 1);    port_out(old, base + 1);    /* return true if ET4000 */    if (val == new) {	et4000_init(0, 0, 0);	return 1;    }    return 0;}static unsigned char last_page = 0;/* Bank switching function - set 64K bank number */static void et4000_setpage(int page){    /* Set both read and write bank. */    port_out(last_page = (page | ((page & 15) << 4)), SEG_SELECT);    if (et4000_chiptype >= CHIP_ET4000W32i) {	/* Write page4-5 to bits 0-1 of ext. bank register, */	/* and to bits 4-5. */	outb(0x3cb, (inb(0x3cb) & ~0x33) | (page >> 4) | (page & 0x30));    }}/* Bank switching function - set 64K read bank number */static void et4000_setrdpage(int page){    last_page &= 0x0F;    last_page |= (page << 4);    port_out(last_page, SEG_SELECT);    if (et4000_chiptype >= CHIP_ET4000W32i) {	/* Write page4-5 to bits 4-5 of ext. bank register. */	outb(0x3cb, (inb(0x3cb) & ~0x30) | (page & 0x30));    }}/* Bank switching function - set 64K write bank number */static void et4000_setwrpage(int page){    last_page &= 0xF0;    last_page |= page;    port_out(last_page, SEG_SELECT);    if (et4000_chiptype >= CHIP_ET4000W32i) {	/* Write page4-5 to bits 0-1 of ext. bank register. */	outb(0x3cb, (inb(0x3cb) & ~0x03) | (page >> 4));    }}/* Set display start address (not for 16 color modes) *//* ET4000 supports any address in video memory (up to 1Mb) *//* ET4000/W32i/p supports up to 4Mb */static void et4000_setdisplaystart(int address){    outw(CRT_IC, 0x0d + ((address >> 2) & 0x00ff) * 256);	/* 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, 0x33);    if (et4000_chiptype >= CHIP_ET4000W32i)	/* write sa18-21 to bit 0-3 */	outb(CRT_DC, (inb(CRT_DC) & 0xf0) | ((address & 0x3c0000) >> 18));    else	/* write sa18-19 to bit 0-3 */	outb(CRT_DC, (inb(CRT_DC) & 0xfc) | ((address & 0xc0000) >> 18));}/* Set logical scanline length (usually multiple of 8) *//* ET4000 supports multiples of 8 to 4088 */static void et4000_setlogicalwidth(int width){    outw(CRT_IC, 0x13 + (width >> 3) * 256);	/* lw3-lw11 */    outb(CRT_IC, 0x3f);    outb(CRT_DC, (inb(CRT_DC) & 0x7f)	 | ((width & 0x800) >> 5));	/* write lw12 to bit 7 */}static int et4000_ext_set(unsigned what, va_list params){    int param2, old_values;    switch (what) {    case VGA_EXT_AVAILABLE:	param2 = va_arg(params, int);	switch (param2) {	case VGA_AVAIL_SET:	    return VGA_EXT_AVAILABLE | VGA_EXT_SET | VGA_EXT_CLEAR | VGA_EXT_RESET;	case VGA_AVAIL_ACCEL:	    return 0;	case VGA_AVAIL_FLAGS:	    return pos_ext_settings;	}	return 0;    case VGA_EXT_SET:	old_values = ext_settings;	ext_settings |= (va_arg(params, int)) & pos_ext_settings;      params_changed:	if (((old_values ^ ext_settings) & pos_ext_settings)) {	    int cmd;	    CRITICAL = 1;	    vga_lockvc();	    _ramdac_dactocomm();	    cmd = inb(PEL_MSK);	    _ramdac_dactocomm();	    if (ext_settings & VGA_CLUT8)		cmd |= 2;	    else		cmd &= ~2;	    outb(PEL_MSK, cmd);	    vga_unlockvc();	    CRITICAL = 0;	}	return old_values;    case VGA_EXT_CLEAR:	old_values = ext_settings;	ext_settings &= ~((va_arg(params, int)) & pos_ext_settings);	goto params_changed;    case VGA_EXT_RESET:	old_values = ext_settings;	ext_settings = (va_arg(params, int)) & pos_ext_settings;	goto params_changed;    default:	return 0;    }}static int et4000_linear(int op, int param){    /* linear mode not supported on original chipset */    if (et4000_chiptype == CHIP_ET4000)	return -1;    else if (op == LINEAR_QUERY_GRANULARITY)	return 4 * 1024 * 1024;    else if (op == LINEAR_QUERY_RANGE)	return 256;    else if (op == LINEAR_ENABLE) {	et4000_setlinear(param / (4 * 1024 * 1024));	return 0;    } else if (op == LINEAR_DISABLE) {	et4000_setlinear(0);	return 0;    } else	return -1;}/* Function table (exported) */DriverSpecs __svgalib_et4000_driverspecs ={    et4000_saveregs,    et4000_setregs,    et4000_unlock,    et4000_lock,    et4000_test,    et4000_init,    et4000_setpage,    et4000_setrdpage,    et4000_setwrpage,    et4000_setmode,    et4000_modeavailable,    et4000_setdisplaystart,    et4000_setlogicalwidth,    et4000_getmodeinfo,    0,				/* bitblt */    0,				/* imageblt */    0,				/* fillblt */    0,				/* hlinelistblt */    0,				/* bltwait */    et4000_ext_set,    0,    et4000_linear,    NULL,                       /* Accelspecs */    NULL,                       /* Emulation */};/* Hicolor DAC detection derived from vgadoc (looks tricky) */#ifndef DAC_TYPEstatic int testdac(void){    int x, y, z, v, oldcommreg, oldpelreg, retval;    /* Use the following return values:     *      0: Ordinary DAC     *      1: Sierra SC11486 (32k)     *      3: Sierra 32k/64k     *      5: SS2410 15/24bit DAC     *      9: AT&T 20c491/2     *     10: STG-170x     */    retval = 0;			/* default to no fancy dac */    _ramdac_dactopel();    x = inb(PEL_MSK);    do {			/* wait for repeat of value */	y = x;	x = inb(PEL_MSK);    } while (x != y);    z = x;    inb(PEL_IW);    inb(PEL_MSK);    inb(PEL_MSK);    inb(PEL_MSK);    x = inb(PEL_MSK);    y = 8;    while ((x != 0x8e) && (y > 0)) {	x = inb(PEL_MSK);	y--;    }    if (x == 0x8e) {	/* We have an SS2410 */	retval = 1 | 4;	_ramdac_dactopel();    } else {	_ramdac_dactocomm();	oldcommreg = inb(PEL_MSK);	_ramdac_dactopel();	oldpelreg = inb(PEL_MSK);	x = oldcommreg ^ 0xFF;	outb(PEL_MSK, x);	_ramdac_dactocomm();	v = inb(PEL_MSK);	if (v != x) {	    v = _ramdac_setcomm(x = oldcommreg ^ 0x60);	    /* We have a Sierra SC11486 */	    retval = 1;	    if ((x & 0xe0) == (v & 0xe0)) {		/* We have a Sierra 32k/64k */		x = inb(PEL_MSK);		_ramdac_dactopel();		retval = 1 | 2;		if (x == inb(PEL_MSK)) {		    /* We have an ATT 20c491 or 20c492 */		    retval = 1 | 8;		    if (_ramdac_setcomm(0xFF) != 0xFF) {			/* We have a weird dac, AcuMos ADAC1 */			retval = 1 | 16;		    } else {	/* maybe an STG-170x */			/* try to enable ext. registers */			_ramdac_setcomm(oldcommreg | 0x10);			outb(PEL_MSK, 0);			outb(PEL_MSK, 0);			if (inb(PEL_MSK) == 0x44) {			    /* it's a 170x */			    /* Another read from PEL_MSK gets the chiptype, 0x02 == 1702. */			    retval = 1 | 64;			    et4000_extdac = 1;			}		    }		}	    }	    _ramdac_dactocomm();	    outb(PEL_MSK, oldcommreg);	}	_ramdac_dactopel();	outb(PEL_MSK, oldpelreg);    }    return retval;}#endif				/* !defined(DAC_TYPE) *//* Initialize chipset (called after detection) */static int et4000_init(int force, int par1, int par2){    int value;    int old, new, val;#ifdef USE_CLOCKS    int i;#endif#ifdef DYNAMIC    if (et4000_modes == NULL) {	FILE *regs;	regs = fopen(ET4000_REGS, "r");	if (regs != 0) {	    et4000_modes = NULL;	    __svgalib_readmodes(regs, &et4000_modes, &et4000_dac, &clocks[0]);	    fclose(regs);	} else	    et4000_modes = &No_Modes;    }#endif    /* Determine the ET4000 chip type. */    /* Test for ET4000/W32. */    old = inb(0x3cb);    outb(0x3cb, 0x33);    new = inb(0x3cb);    outb(0x3cb, old);    if (new != 0x33)	et4000_chiptype = CHIP_ET4000;    else {	/* ET4000/W32. */	if (getenv("IOPERM") == NULL && iopl(3) < 0)	    /* Can't get further I/O permissions -- */	    /* assume ET4000/W32. */	    et4000_chiptype = CHIP_ET4000W32;	else {	    outb(0x217a, 0xec);	    val = inb(0x217b) >> 4;	    switch (val) {	    case 0:		et4000_chiptype = CHIP_ET4000W32;		break;	    case 1:	    case 3:		et4000_chiptype = CHIP_ET4000W32i;		break;	    case 2:	    case 5:	    default:		et4000_chiptype = CHIP_ET4000W32p;	    }	    /* Do NOT set back iopl if set before, since */	    /* caller most likely still needs it! */	    if (getenv("IOPERM") == NULL)		iopl(0);	}    }    if (force)	et4000_memory = par1;    else {	outb(CRT_IC, 0x37);	value = inb(CRT_DC);	et4000_memory = (value & 0x08) ? 256 : 64;	switch (value & 3) {	case 2:	    et4000_memory *= 2;	    break;	case 3:	    et4000_memory *= 4;	    break;	}	if (value & 0x80)	    et4000_memory *= 2;	outb(CRT_IC, 0x32);	if (inb(CRT_DC) & 0x80) {	    /* Interleaved memory on ET4000/W32i/p: */	    /* Multiply by 2. */	    et4000_memory *= 2;	}    }#ifndef DAC_TYPE    if (et4000_dac < 0)	et4000_dac = testdac();#endif#ifdef USE_CLOCKS    /* Measure clock frequencies */    for (i = 0; i < CLOCKS; ++i)	get_clock(i);#endif    if (__svgalib_driver_report) {	char dacname[60];	switch (et4000_dac & ~1) {	case 0:	    strcpy(dacname, ", Hicolor Dac: Sierra SC11486");	    break;	case 2:	    strcpy(dacname, ", Hicolor Dac: Sierra 32k/64k");	    break;	case 4:	    strcpy(dacname, ", Hicolor Dac: SS2410");	    break;	case 8:	    strcpy(dacname, ", Hicolor Dac: ATT20c491/2");	    break;	case 16:	    strcpy(dacname, ", Hicolor Dac: ACUMOS ADAC1");	    break;	case 32:	    strcpy(dacname, ", Hicolor Dac: Sierra 15025/6 (24-bit)");	    break;	case 64:	    strcpy(dacname, ", Hicolor Dac: STG-170x (24-bit)");	    break;	default:	    strcpy(dacname, ", Hicolor Dac: Unknown");	    break;	}	printf("Using Tseng ET4000 driver (%s %d%s).",	       chipname[et4000_chiptype], et4000_memory,	       et4000_dac & 1 ? dacname : "");#ifdef USE_CLOCKS	printf(" Clocks:");	for (i = 0; i < 8; ++i)	    printf(" %d", (clocks[i] + 500) / 1000);#endif	printf("\n");    }    __svgalib_driverspecs = &__svgalib_et4000_driverspecs;    __svgalib_banked_mem_base=0xa0000;    __svgalib_banked_mem_size=0x10000;/*    __svgalib_linear_mem_base=LINEARBASE;    __svgalib_linear_mem_size=nv3_memory*0x400; */    pos_ext_settings = 0;    if (et4000_dac & (8 | 16 | 32 | 64))	pos_ext_settings = VGA_CLUT8;    return 0;}

⌨️ 快捷键说明

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