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

📄 cirrus.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 4 页
字号:
    }/* Scanline offset */    if (modeinfo->bytesPerPixel == 4) {	/* At 32bpp the chip does an extra multiplication by two. */	if (cirrus_chiptype >= CLGD5436) {		/* Do these chipsets multiply by 4? */		moderegs[VGA_SCANLINEOFFSET] = modeinfo->lineWidth >> 5;		SETBITSFROMVALUE(moderegs[CIRRUS_CR1B], 0x10,				 modeinfo->lineWidth, 0x2000);	}	else {		moderegs[VGA_SCANLINEOFFSET] = modeinfo->lineWidth >> 4;		SETBITSFROMVALUE(moderegs[CIRRUS_CR1B], 0x10,				 modeinfo->lineWidth, 0x1000);	}    } else if (modeinfo->bitsPerPixel == 4)	/* 16 color mode (planar). */	moderegs[VGA_SCANLINEOFFSET] = modeinfo->lineWidth >> 1;    else {	moderegs[VGA_SCANLINEOFFSET] = modeinfo->lineWidth >> 3;	SETBITSFROMVALUE(moderegs[CIRRUS_CR1B], 0x10,			 modeinfo->lineWidth, 0x800);    }/* Clocking */    moderegs[VGA_MISCOUTPUT] |= 0x0C;	/* Use VCLK3. */    moderegs[CIRRUS_VCLK3NUMERATOR] =	fixed_clock_numerator[modetiming->selectedClockNo];    moderegs[CIRRUS_VCLK3DENOMINATOR] =	fixed_clock_denominator[modetiming->selectedClockNo];/* DAC register and Sequencer Mode */    {	unsigned char DAC, SR7;	DAC = 0x00;	SR7 = 0x00;	if (modeinfo->bytesPerPixel > 0)	    SR7 = 0x01;		/* Packed-pixel mode. */	if (modeinfo->bytesPerPixel == 2) {	    int rgbmode;	    rgbmode = 0;	/* 5-5-5 RGB. */	    if (modeinfo->colorBits == 16)		rgbmode = 1;	/* Add one for 5-6-5 RGB. */	    if (cirrus_chiptype >= CLGD5426) {		/* Pixel clock (double edge) mode. */		DAC = 0xD0 + rgbmode;		SR7 = 0x07;	    } else {		/* Single-edge (double VCLK). */		DAC = 0xF0 + rgbmode;		SR7 = 0x03;	    }	}	if (modeinfo->bytesPerPixel >= 3) {	    /* Set 8-8-8 RGB mode. */	    DAC = 0xE5;	    SR7 = 0x05;	    if (modeinfo->bytesPerPixel == 4)		SR7 = 0x09;	}#ifdef SUPPORT_5434_PALETTE_CLOCK_DOUBLING	if (modeinfo->bytesPerPixel == 1 && (modetiming->flags & HADJUSTED)) {	    /* Palette clock doubling mode on 5434 8bpp. */	    DAC = 0x4A;	    SR7 = 0x07;	}#endif	moderegs[CIRRUS_HIDDENDAC] = DAC;	moderegs[CIRRUS_SR7] = SR7;    }/* DRAM control and CRT FIFO */    if (cirrus_chiptype >= CLGD5422)	/* Enable large CRT FIFO. */	moderegs[CIRRUS_DRAMCONTROL] |= 0x20;    if (cirrus_memory == 2048 && cirrus_chiptype <= CLGD5429)	/* Enable DRAM Bank Select. */	moderegs[CIRRUS_DRAMCONTROL] |= 0x80;    if (cirrus_chiptype >= CLGD5424) {	/* CRT FIFO threshold setting. */	unsigned char threshold;	threshold = 8;/*	if (cirrus_chiptype >= CLGD5434)	    threshold = 1;*/	/* XXX Needs more elaborate setting. */	SETBITS(moderegs[CIRRUS_PERFTUNING], 0x0F, threshold);    }    if (CHIP_HAS_MCLK_REGISTER())	if (programmedMCLK != actualMCLK	    && modeinfo->bytesPerPixel > 0)	    /* Program higher MCLK for packed-pixel modes. */	    moderegs[CIRRUS_MCLKREGISTER] = programmedMCLK;}/* This is the clock mapping function that is put in the CardSpecs. */static int cirrus_map_clock(int bpp, int pixelclock){    if (bpp == 24 && cirrus_chiptype < CLGD5436)	/* Most chips need a tripled clock for 24bpp. */	return pixelclock * 3;    if (bpp == 16 && cirrus_chiptype <= CLGD5424)	/* The 5422/24 need to use a doubled clock. */	return pixelclock * 2;    return pixelclock;}/* This is the horizontal CRTC mapping function in the CardSpecs. */static int cirrus_map_horizontal_crtc(int bpp, int pixelclock, int htiming){#ifdef ALWAYS_USE_5434_PALETTE_CLOCK_DOUBLING    if (bpp == 8 && cirrus_chiptype >= CLGD5434)#else    if (bpp == 8 && cirrus_chiptype >= CLGD5434 && pixelclock > 86000)#endif	/* 5434 palette clock doubling mode; divide CRTC by 2. */	return htiming / 2;    /* Otherwise, don't change. */    return htiming;}static void init_acceleration_specs_for_mode(AccelSpecs * accelspecs, int bpp,					     int width_in_pixels);static int cirrus_setmode(int mode, int prv_mode){    unsigned char *moderegs;    ModeTiming *modetiming;    ModeInfo *modeinfo;    if ((mode < G640x480x256 && mode != G320x200x256)	|| mode == G720x348x2) {	__svgalib_clear_accelspecs(__svgalib_driverspecs->accelspecs);	/* Let the standard VGA driver set standard VGA modes */	/* But first reset an Cirrus extended register that */	/* an old XFree86 Trident probe corrupts. */	outw(CRT_IC, 0x4a0b);	return __svgalib_vga_driverspecs.setmode(mode, prv_mode);    }    if (!cirrus_modeavailable(mode))	return 1;    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);    modetiming = malloc(sizeof(ModeTiming));    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {	free(modetiming);	free(modeinfo);	return 1;    }    moderegs = malloc(CIRRUS_TOTAL_REGS);    cirrus_initializemode(moderegs, modetiming, modeinfo);    free(modetiming);    __svgalib_setregs(moderegs);	/* Set standard regs. */    cirrus_setregs(moderegs, mode);	/* Set extended regs. */    free(moderegs);    __svgalib_InitializeAcceleratorInterface(modeinfo);    init_acceleration_specs_for_mode(__svgalib_driverspecs->accelspecs,				     modeinfo->bitsPerPixel,			  modeinfo->lineWidth / modeinfo->bytesPerPixel);    __svgalib_cirrusaccel_init(__svgalib_driverspecs->accelspecs,		     modeinfo->bitsPerPixel,		     modeinfo->lineWidth / modeinfo->bytesPerPixel);    free(modeinfo);    return 0;}/* Unlock chipset-specific registers */static void cirrus_unlock(void){    int vgaIOBase, temp;    /* Are we Mono or Color? */    vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;    outb(SEQ_I, 0x06);    outb(SEQ_D, 0x12);		/* unlock cirrus special */    /* Put the Vert. Retrace End Reg in temp */    outb(vgaIOBase + 4, 0x11);    temp = inb(vgaIOBase + 5);    /* Put it back with PR bit set to 0 */    /* This unprotects the 0-7 CRTC regs so */    /* they can be modified, i.e. we can set */    /* the timing. */    outb(vgaIOBase + 5, temp & 0x7F);}/* Relock chipset-specific registers *//* (currently not used) */static void cirrus_lock(void){    outb(SEQ_I, 0x06);    outb(SEQ_D, 0x0F);		/* relock cirrus special */}/* Indentify chipset, initialize and return non-zero if detected */static int cirrus_test(void){    int oldlockreg;    int lockreg;    outb(SEQ_I, 0x06);    oldlockreg = inb(SEQ_D);    cirrus_unlock();    /* If it's a Cirrus at all, we should be */    /* able to read back the lock register */    outb(SEQ_I, 0x06);    lockreg = inb(SEQ_D);    /* Ok, if it's not 0x12, we're not a Cirrus542X. */    if (lockreg != 0x12) {	outb(SEQ_I, 0x06);	outb(SEQ_D, oldlockreg);	return 0;    }    /* The above check seems to be weak, so we also check the chip ID. */    outb(__svgalib_CRT_I, 0x27);    switch (inb(__svgalib_CRT_D) >> 2) {    case 0x22:    case 0x23:    case 0x24:    case 0x25:    case 0x26:    case 0x27:			/* 5429 */    case 0x28:			/* 5430 */    case 0x2A:			/* 5434 */    case 0x2B:			/* 5436 */    case 0x2E:			/* 5446 */    case 0x0E:			/* 7548 */	break;    default:	outb(SEQ_I, 0x06);	outb(SEQ_D, oldlockreg);	return 0;    }    if (cirrus_init(0, 0, 0))	return 0;		/* failure */    return 1;}/* Bank switching function -- set 64K page number */static void cirrus_setpage_2M(int page){    /* Cirrus banking register has been set to 16K granularity */    outw(GRA_I, (page << 10) + 0x09);}static void cirrus_setpage(int page){    /* default 4K granularity */    outw(GRA_I, (page << 12) + 0x09);}/* No r/w paging */static void cirrus_setrdpage(int page){}static void cirrus_setwrpage(int page){}/* Set display start address (not for 16 color modes) *//* Cirrus supports any address in video memory (up to 2Mb) */static void cirrus_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 */    /* Cirrus specific bits 0,1 and 18,19,20: */    outb(ATT_IW, (inb(ATT_R) & 0xf0) | (address & 3));    /* write sa0-1 to bits 0-1; other cards use bits 1-2 */    outb(CRT_IC, 0x1b);    outb(CRT_DC, (inb(CRT_DC) & 0xf2)	 | ((address & 0x40000) >> 18)	/* sa18: write to bit 0 */	 |((address & 0x80000) >> 17)	/* sa19: write to bit 2 */	 |((address & 0x100000) >> 17));	/* sa20: write to bit 3 */    outb(CRT_IC, 0x1d);    if (cirrus_memory > 2048)	outb(CRT_DC, (inb(CRT_DC) & 0x7f)	     | ((address & 0x200000) >> 14));	/* sa21: write to bit 7 */}/* Set logical scanline length (usually multiple of 8) *//* Cirrus supports multiples of 8, up to 4088 */static void cirrus_setlogicalwidth(int width){    outw(CRT_IC, 0x13 + (width >> 3) * 256);	/* lw3-lw11 */    outb(CRT_IC, 0x1b);    outb(CRT_DC, (inb(CRT_DC) & 0xef) | ((width & 0x800) >> 7));    /* write lw12 to bit 4 of Sequencer reg. 0x1b */}static void cirrus_setlinear(int addr){    int val;    outb(SEQ_I, 0x07);    val = inb(SEQ_D);    outb(SEQ_D, (val & 0x0f) | (addr << 4));}static int cirrus_linear(int op, int param){    if (op == LINEAR_ENABLE) {	cirrus_setlinear(0xE);	return 0;    }    if (op == LINEAR_DISABLE) {	cirrus_setlinear(0);	return 0;    }    if (cirrus_chiptype >= CLGD5424 && cirrus_chiptype <= CLGD5429) {	if (op == LINEAR_QUERY_BASE) {	    if (param == 0)		return 0xE00000;	/* 14MB */	    /*	     * Trying 64MB on a system with 16MB of memory is unsafe if the	     * card maps at 14MB. 14 MB was not attempted because of the	     * system memory check in vga_setlinearaddressing(). However,	     * linear addressing is enabled when looking at 64MB, causing a	     * clash between video card and system memory at 14MB.	     */	    if (__svgalib_physmem() <= 13 * 1024 * 1024) {		if (param == 1)		    return 0x4000000;	/* 64MB */		if (param == 2)		    return 0x4E00000;	/* 78MB */		if (param == 3)		    return 0x2000000;	/* 32MB */		if (param == 4)		    return 0x3E00000;	/* 62MB */	    }	    return -1;	}    }    if (cirrus_chiptype >= CLGD5430) {	if (op == LINEAR_QUERY_BASE) {            if(cirrus_pci_linear)return cirrus_pci_linear;	    if (param == 0)		return 0x04000000;	/* 64MB */	    if (param == 1)		return 0x80000000;	/* 2048MB */	    if (param == 2)		return 0x02000000;	/* 32MB */	    if (param == 3)		return 0x08000000;	/* 128MB */	    /* While we're busy, try some common PCI */	    /* motherboard-configured addresses as well. */	    /* We only read, so should be safe. */	    if (param == 4)		return 0xA0000000;	    if (param == 5)		return 0xA8000000;	    if (param == 6)		return 0xE0000000;	    if (param == 7)		return 0XFE000000;	    /*	     * Some PCI/VL motherboards only seem to let the	     * VL slave slot respond at addresses >= 2048MB.	     */	    if (param == 8)		return 0x84000000;	    if (param == 9)		return 0x88000000;	    return -1;	}    }    if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY)	return 0;		/* No granularity or range. */    else	return -1;		/* Unknown function. */}/* Function table (exported) */DriverSpecs __svgalib_cirrus_driverspecs ={    cirrus_saveregs,    cirrus_setregs,    cirrus_unlock,    cirrus_lock,    cirrus_test,    cirrus_init,    cirrus_setpage,    cirrus_setrdpage,    cirrus_setwrpage,    cirrus_setmode,    cirrus_modeavailable,    cirrus_setdisplaystart,    cirrus_setlogicalwidth,    cirrus_getmodeinfo,    0,				/* old blit funcs */    0,    0,    0,    0,    0,				/* ext_set */    0,				/* accel */    cirrus_linear,    NULL,                       /* Accelspecs */    NULL,                       /* Emulation */};/* Initialize chipset (called after detection) */static char *cirrus_chipname[] ={    "5420", "7548", "5420-75QC-B", "5422", "5422-80QC-C", "5424", "5426",     "5428", "5429", "5430", "5434", "5436"};static unsigned char fixedMCLK[4] ={0x1c, 0x19, 0x17, 0x15};static int cirrus_init(int force, int par1, int par2){    unsigned char v;    cirrus_unlock();    if (force) {	cirrus_memory = par1;	cirrus_chiptype = par2;    } else {	unsigned char partstatus;	outb(__svgalib_CRT_I, 0x27);	cirrus_chiptype = inb(__svgalib_CRT_D) >> 2;	cirrus_chiprev = 0;	partstatus = __svgalib_inCR(0x25);	switch (cirrus_chiptype) {	case 0x22:	    cirrus_chiptype = CLGD5420;#if 0	    /* Check for CL-GD5420-75QC-B. */	    /* It has a Hidden-DAC register. */	    outb(0x3C6, 0x00);	    outb(0x3C6, 0xFF);	    inb(0x3C6);

⌨️ 快捷键说明

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