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

📄 vga16fb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;	par->crtc[VGA_CRTC_OVERFLOW] = r7;	par->vss = 0x00;	/* 3DA */	par->misc = 0xE3;	/* enable CPU, ports 0x3Dx, positive sync */	if (var->sync & FB_SYNC_HOR_HIGH_ACT)		par->misc &= ~0x40;	if (var->sync & FB_SYNC_VERT_HIGH_ACT)		par->misc &= ~0x80;		par->mode = mode;	if (mode & MODE_8BPP)		/* pixel clock == vga clock / 2 */		vga16fb_clock_chip(par, var->pixclock, info, 1, 2);	else		/* pixel clock == vga clock */		vga16fb_clock_chip(par, var->pixclock, info, 1, 1);		var->red.offset = var->green.offset = var->blue.offset = 	var->transp.offset = 0;	var->red.length = var->green.length = var->blue.length =		(par->isVGA) ? 6 : 2;	var->transp.length = 0;	var->activate = FB_ACTIVATE_NOW;	var->height = -1;	var->width = -1;	var->accel_flags = 0;	return 0;}#undef FAILstatic int vga16fb_set_par(struct fb_info *info){	struct vga16fb_par *par = info->par;	u8 gdc[VGA_GFX_C];	u8 seq[VGA_SEQ_C];	u8 atc[VGA_ATT_C];	int fh, i;	seq[VGA_SEQ_CLOCK_MODE] = 0x01 | par->clkdiv;	if (par->mode & MODE_TEXT)		seq[VGA_SEQ_PLANE_WRITE] = 0x03;	else		seq[VGA_SEQ_PLANE_WRITE] = 0x0F;	seq[VGA_SEQ_CHARACTER_MAP] = 0x00;	if (par->mode & MODE_TEXT)		seq[VGA_SEQ_MEMORY_MODE] = 0x03;	else if (par->mode & MODE_SKIP4)		seq[VGA_SEQ_MEMORY_MODE] = 0x0E;	else		seq[VGA_SEQ_MEMORY_MODE] = 0x06;	gdc[VGA_GFX_SR_VALUE] = 0x00;	gdc[VGA_GFX_SR_ENABLE] = 0x00;	gdc[VGA_GFX_COMPARE_VALUE] = 0x00;	gdc[VGA_GFX_DATA_ROTATE] = 0x00;	gdc[VGA_GFX_PLANE_READ] = 0;	if (par->mode & MODE_TEXT) {		gdc[VGA_GFX_MODE] = 0x10;		gdc[VGA_GFX_MISC] = 0x06;	} else {		if (par->mode & MODE_CFB)			gdc[VGA_GFX_MODE] = 0x40;		else			gdc[VGA_GFX_MODE] = 0x00;		gdc[VGA_GFX_MISC] = 0x05;	}	gdc[VGA_GFX_COMPARE_MASK] = 0x0F;	gdc[VGA_GFX_BIT_MASK] = 0xFF;	for (i = 0x00; i < 0x10; i++)		atc[i] = i;	if (par->mode & MODE_TEXT)		atc[VGA_ATC_MODE] = 0x04;	else if (par->mode & MODE_8BPP)		atc[VGA_ATC_MODE] = 0x41;	else		atc[VGA_ATC_MODE] = 0x81;	atc[VGA_ATC_OVERSCAN] = 0x00;	/* 0 for EGA, 0xFF for VGA */	atc[VGA_ATC_PLANE_ENABLE] = 0x0F;	if (par->mode & MODE_8BPP)		atc[VGA_ATC_PEL] = (info->var.xoffset & 3) << 1;	else		atc[VGA_ATC_PEL] = info->var.xoffset & 7;	atc[VGA_ATC_COLOR_PAGE] = 0x00;		if (par->mode & MODE_TEXT) {		fh = 16; // FIXME !!! Fudge font height. 		par->crtc[VGA_CRTC_MAX_SCAN] = (par->crtc[VGA_CRTC_MAX_SCAN] 					       & ~0x1F) | (fh - 1);	}	vga_io_w(VGA_MIS_W, vga_io_r(VGA_MIS_R) | 0x01);	/* Enable graphics register modification */	if (!par->isVGA) {		vga_io_w(EGA_GFX_E0, 0x00);		vga_io_w(EGA_GFX_E1, 0x01);	}		/* update misc output register */	vga_io_w(VGA_MIS_W, par->misc);		/* synchronous reset on */	vga_io_wseq(0x00, 0x01);	if (par->isVGA)		vga_io_w(VGA_PEL_MSK, par->pel_msk);	/* write sequencer registers */	vga_io_wseq(VGA_SEQ_CLOCK_MODE, seq[VGA_SEQ_CLOCK_MODE] | 0x20);	for (i = 2; i < VGA_SEQ_C; i++) {		vga_io_wseq(i, seq[i]);	}		/* synchronous reset off */	vga_io_wseq(0x00, 0x03);	/* deprotect CRT registers 0-7 */	vga_io_wcrt(VGA_CRTC_V_SYNC_END, par->crtc[VGA_CRTC_V_SYNC_END]);	/* write CRT registers */	for (i = 0; i < VGA_CRTC_REGS; i++) {		vga_io_wcrt(i, par->crtc[i]);	}		/* write graphics controller registers */	for (i = 0; i < VGA_GFX_C; i++) {		vga_io_wgfx(i, gdc[i]);	}		/* write attribute controller registers */	for (i = 0; i < VGA_ATT_C; i++) {		vga_io_r(VGA_IS1_RC);		/* reset flip-flop */		vga_io_wattr(i, atc[i]);	}	/* Wait for screen to stabilize. */	mdelay(50);	vga_io_wseq(VGA_SEQ_CLOCK_MODE, seq[VGA_SEQ_CLOCK_MODE]);	vga_io_r(VGA_IS1_RC);	vga_io_w(VGA_ATT_IW, 0x20);	vga16fb_update_fix(info);	return 0;}static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned blue){	static const unsigned char map[] = { 000, 001, 010, 011 };	int val;		if (regno >= 16)		return;	val = map[red>>14] | ((map[green>>14]) << 1) | ((map[blue>>14]) << 2);	vga_io_r(VGA_IS1_RC);   /* ! 0x3BA */	vga_io_wattr(regno, val);	vga_io_r(VGA_IS1_RC);   /* some clones need it */	vga_io_w(VGA_ATT_IW, 0x20); /* unblank screen */}static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue){	outb(regno,       VGA_PEL_IW);	outb(red   >> 10, VGA_PEL_D);	outb(green >> 10, VGA_PEL_D);	outb(blue  >> 10, VGA_PEL_D);}static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,			     unsigned blue, unsigned transp,			     struct fb_info *info){	struct vga16fb_par *par = info->par;	int gray;	/*	 *  Set a single color register. The values supplied are	 *  already rounded down to the hardware's capabilities	 *  (according to the entries in the `var' structure). Return	 *  != 0 for invalid regno.	 */		if (regno >= 256)		return 1;	gray = info->var.grayscale;		if (gray) {		/* gray = 0.30*R + 0.59*G + 0.11*B */		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;	}	if (par->isVGA) 		vga16_setpalette(regno,red,green,blue);	else		ega16_setpalette(regno,red,green,blue);	return 0;}static int vga16fb_pan_display(struct fb_var_screeninfo *var,			       struct fb_info *info) {	vga16fb_pan_var(info, var);	return 0;}/* The following VESA blanking code is taken from vgacon.c.  The VGA   blanking code was originally by Huang shi chao, and modified by   Christoph Rimek (chrimek@toppoint.de) and todd j. derr   (tjd@barefoot.org) for Linux. */static void vga_vesa_blank(struct vga16fb_par *par, int mode){	unsigned char SeqCtrlIndex = vga_io_r(VGA_SEQ_I);	unsigned char CrtCtrlIndex = vga_io_r(VGA_CRT_IC);		/* save original values of VGA controller registers */	if(!par->vesa_blanked) {		par->vga_state.CrtMiscIO = vga_io_r(VGA_MIS_R);		//sti();		par->vga_state.HorizontalTotal = vga_io_rcrt(0x00);	/* HorizontalTotal */		par->vga_state.HorizDisplayEnd = vga_io_rcrt(0x01);	/* HorizDisplayEnd */		par->vga_state.StartHorizRetrace = vga_io_rcrt(0x04);	/* StartHorizRetrace */		par->vga_state.EndHorizRetrace = vga_io_rcrt(0x05);	/* EndHorizRetrace */		par->vga_state.Overflow = vga_io_rcrt(0x07);		/* Overflow */		par->vga_state.StartVertRetrace = vga_io_rcrt(0x10);	/* StartVertRetrace */		par->vga_state.EndVertRetrace = vga_io_rcrt(0x11);	/* EndVertRetrace */		par->vga_state.ModeControl = vga_io_rcrt(0x17);	/* ModeControl */		par->vga_state.ClockingMode = vga_io_rseq(0x01);	/* ClockingMode */	}	/* assure that video is enabled */	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */	vga_io_wseq(0x01, par->vga_state.ClockingMode | 0x20);	/* test for vertical retrace in process.... */	if ((par->vga_state.CrtMiscIO & 0x80) == 0x80)		vga_io_w(VGA_MIS_W, par->vga_state.CrtMiscIO & 0xef);	/*	 * Set <End of vertical retrace> to minimum (0) and	 * <Start of vertical Retrace> to maximum (incl. overflow)	 * Result: turn off vertical sync (VSync) pulse.	 */	if (mode & FB_BLANK_VSYNC_SUSPEND) {		vga_io_wcrt(VGA_CRTC_V_SYNC_START, 0xff);		vga_io_wcrt(VGA_CRTC_V_SYNC_END, 0x40);		/* bits 9,10 of vert. retrace */		vga_io_wcrt(VGA_CRTC_OVERFLOW, par->vga_state.Overflow | 0x84);	}	if (mode & FB_BLANK_HSYNC_SUSPEND) {		/*		 * Set <End of horizontal retrace> to minimum (0) and		 *  <Start of horizontal Retrace> to maximum		 * Result: turn off horizontal sync (HSync) pulse.		 */		vga_io_wcrt(VGA_CRTC_H_SYNC_START, 0xff);		vga_io_wcrt(VGA_CRTC_H_SYNC_END, 0x00);	}	/* restore both index registers */	outb_p(SeqCtrlIndex, VGA_SEQ_I);	outb_p(CrtCtrlIndex, VGA_CRT_IC);}static void vga_vesa_unblank(struct vga16fb_par *par){	unsigned char SeqCtrlIndex = vga_io_r(VGA_SEQ_I);	unsigned char CrtCtrlIndex = vga_io_r(VGA_CRT_IC);		/* restore original values of VGA controller registers */	vga_io_w(VGA_MIS_W, par->vga_state.CrtMiscIO);	/* HorizontalTotal */	vga_io_wcrt(0x00, par->vga_state.HorizontalTotal);	/* HorizDisplayEnd */	vga_io_wcrt(0x01, par->vga_state.HorizDisplayEnd);	/* StartHorizRetrace */	vga_io_wcrt(0x04, par->vga_state.StartHorizRetrace);	/* EndHorizRetrace */	vga_io_wcrt(0x05, par->vga_state.EndHorizRetrace);	/* Overflow */	vga_io_wcrt(0x07, par->vga_state.Overflow);	/* StartVertRetrace */	vga_io_wcrt(0x10, par->vga_state.StartVertRetrace);	/* EndVertRetrace */	vga_io_wcrt(0x11, par->vga_state.EndVertRetrace);	/* ModeControl */	vga_io_wcrt(0x17, par->vga_state.ModeControl);	/* ClockingMode */	vga_io_wseq(0x01, par->vga_state.ClockingMode);	/* restore index/control registers */	vga_io_w(VGA_SEQ_I, SeqCtrlIndex);	vga_io_w(VGA_CRT_IC, CrtCtrlIndex);}static void vga_pal_blank(void){	int i;	for (i=0; i<16; i++) {		outb_p(i, VGA_PEL_IW);		outb_p(0, VGA_PEL_D);		outb_p(0, VGA_PEL_D);		outb_p(0, VGA_PEL_D);	}}/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */static int vga16fb_blank(int blank, struct fb_info *info){	struct vga16fb_par *par = info->par;	switch (blank) {	case FB_BLANK_UNBLANK:				/* Unblank */		if (par->vesa_blanked) {			vga_vesa_unblank(par);			par->vesa_blanked = 0;		}		if (par->palette_blanked) {			par->palette_blanked = 0;		}		break;	case FB_BLANK_NORMAL:				/* blank */		vga_pal_blank();		par->palette_blanked = 1;		break;	default:			/* VESA blanking */		vga_vesa_blank(par, blank);		par->vesa_blanked = 1;		break;	}	return 0;}static void vga_8planes_fillrect(struct fb_info *info, const struct fb_fillrect *rect){	u32 dx = rect->dx, width = rect->width;        char oldindex = getindex();        char oldmode = setmode(0x40);        char oldmask = selectmask();        int line_ofs, height;        char oldop, oldsr;        char __iomem *where;        dx /= 4;        where = info->screen_base + dx + rect->dy * info->fix.line_length;        if (rect->rop == ROP_COPY) {                oldop = setop(0);                oldsr = setsr(0);                width /= 4;                line_ofs = info->fix.line_length - width;                setmask(0xff);                height = rect->height;                while (height--) {                        int x;                        /* we can do memset... */                        for (x = width; x > 0; --x) {                                writeb(rect->color, where);                                where++;                        }                        where += line_ofs;                }        } else {                char oldcolor = setcolor(0xf);                int y;                oldop = setop(0x18);                oldsr = setsr(0xf);                setmask(0x0F);                for (y = 0; y < rect->height; y++) {                        rmw(where);                        rmw(where+1);                        where += info->fix.line_length;                }                setcolor(oldcolor);        }        setmask(oldmask);        setsr(oldsr);        setop(oldop);        setmode(oldmode);        setindex(oldindex);}static void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect){	int x, x2, y2, vxres, vyres, width, height, line_ofs;	char __iomem *dst;	vxres = info->var.xres_virtual;	vyres = info->var.yres_virtual;	if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)		return;	/* We could use hardware clipping but on many cards you get around	 * hardware clipping by writing to framebuffer directly. */	x2 = rect->dx + rect->width;	y2 = rect->dy + rect->height;	x2 = x2 < vxres ? x2 : vxres;	y2 = y2 < vyres ? y2 : vyres;	width = x2 - rect->dx;	switch (info->fix.type) {	case FB_TYPE_VGA_PLANES:		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {			height = y2 - rect->dy;			width = rect->width/8;			line_ofs = info->fix.line_length - width;			dst = info->screen_base + (rect->dx/8) + rect->dy * info->fix.line_length;			switch (rect->rop) {			case ROP_COPY:				setmode(0);				setop(0);				setsr(0xf);				setcolor(rect->color);				selectmask();				setmask(0xff);				while (height--) {					for (x = 0; x < width; x++) {						writeb(0, dst);						dst++;					}					dst += line_ofs;				}				break;			case ROP_XOR:				setmode(0);				setop(0x18);				setsr(0xf);				setcolor(0xf);				selectmask();				setmask(0xff);				while (height--) {					for (x = 0; x < width; x++) {						rmw(dst);						dst++;					}					dst += line_ofs;				}				break;			}		} else 			vga_8planes_fillrect(info, rect);		break;	case FB_TYPE_PACKED_PIXELS:	default:		cfb_fillrect(info, rect);		break;	}}static void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area){        char oldindex = getindex();        char oldmode = setmode(0x41);        char oldop = setop(0);        char oldsr = setsr(0xf);        int height, line_ofs, x;	u32 sx, dx, width;	char __iomem *dest;	char __iomem *src;        height = area->height;        sx = area->sx / 4;

⌨️ 快捷键说明

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