vga16fb.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,441 行 · 第 1/3 页

C
1,441
字号
		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20; /* BLANK_START */	}	pos += lower;	par->crtc[VGA_CRTC_V_SYNC_START] = pos & 0xFF;	if (pos & 0x100)		r7 |= 0x04;	if (pos & 0x200)		r7 |= 0x80;	pos += vslen;	par->crtc[VGA_CRTC_V_SYNC_END] = (pos & 0x0F) & ~0x10; /* disabled IRQ */	pos += upper - 1; /* blank_end + 1 <= ytotal + 2 */	par->crtc[VGA_CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA,                     but some SVGA chips requires all 8 bits to set */	if (vxres >= 512)		FAIL("vxres too long");	par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;	if (mode & MODE_SKIP4)		par->crtc[VGA_CRTC_UNDERLINE] = 0x5F;	/* 256, cfb8 */	else		par->crtc[VGA_CRTC_UNDERLINE] = 0x1F;	/* 16, vgap */	par->crtc[VGA_CRTC_MODE] = rMode | ((mode & MODE_TEXT) ? 0xA3 : 0xE3);	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 = (struct vga16fb_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 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,       dac_reg);	outb(red   >> 10, dac_val);	outb(green >> 10, dac_val);	outb(blue  >> 10, dac_val);}static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,			     unsigned blue, unsigned transp,			     struct fb_info *info){	struct vga16fb_par *par = (struct vga16fb_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) {	if (var->xoffset + info->var.xres > info->var.xres_virtual ||	    var->yoffset + info->var.yres > info->var.yres_virtual)		return -EINVAL;	vga16fb_pan_var(info, var);	info->var.xoffset = var->xoffset;	info->var.yoffset = var->yoffset;	info->var.vmode &= ~FB_VMODE_YWRAP;	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. */#define attrib_port		VGA_ATC_IW#define seq_port_reg		VGA_SEQ_I#define seq_port_val		VGA_SEQ_D#define gr_port_reg		VGA_GFX_I#define gr_port_val		VGA_GFX_D#define video_misc_rd		VGA_MIS_R#define video_misc_wr		VGA_MIS_W#define vga_video_port_reg	VGA_CRT_IC#define vga_video_port_val	VGA_CRT_DCstatic void vga_vesa_blank(struct vga16fb_par *par, int mode){	unsigned char SeqCtrlIndex;	unsigned char CrtCtrlIndex;		//cli();	SeqCtrlIndex = vga_io_r(seq_port_reg);	CrtCtrlIndex = vga_io_r(vga_video_port_reg);	/* save original values of VGA controller registers */	if(!par->vesa_blanked) {		par->vga_state.CrtMiscIO = vga_io_r(video_misc_rd);		//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 */	//cli();	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(video_misc_wr, 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 & VESA_VSYNC_SUSPEND) {		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */		outb_p(0xff,vga_video_port_val); 	/* maximum value */		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */		outb_p(0x40,vga_video_port_val);	/* minimum (bits 0..3)  */		outb_p(0x07,vga_video_port_reg);	/* Overflow */		outb_p(par->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */	}	if (mode & VESA_HSYNC_SUSPEND) {		/*		 * Set <End of horizontal retrace> to minimum (0) and		 *  <Start of horizontal Retrace> to maximum		 * Result: turn off horizontal sync (HSync) pulse.		 */		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */		outb_p(0xff,vga_video_port_val);	/* maximum */		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */		outb_p(0x00,vga_video_port_val);	/* minimum (0) */	}	/* restore both index registers */	outb_p(SeqCtrlIndex,seq_port_reg);	outb_p(CrtCtrlIndex,vga_video_port_reg);	//sti();}static void vga_vesa_unblank(struct vga16fb_par *par){	unsigned char SeqCtrlIndex;	unsigned char CrtCtrlIndex;		//cli();	SeqCtrlIndex = vga_io_r(seq_port_reg);	CrtCtrlIndex = vga_io_r(vga_video_port_reg);	/* restore original values of VGA controller registers */	vga_io_w(video_misc_wr, 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(seq_port_reg, SeqCtrlIndex);	vga_io_w(vga_video_port_reg, CrtCtrlIndex);	//sti();}static void vga_pal_blank(void){	int i;	for (i=0; i<16; i++) {		outb_p (i, dac_reg) ;		outb_p (0, dac_val) ;		outb_p (0, dac_val) ;		outb_p (0, dac_val) ;	}}/* 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 = (struct vga16fb_par *) info->par;	switch (blank) {	case 0:				/* Unblank */		if (par->vesa_blanked) {			vga_vesa_unblank(par);			par->vesa_blanked = 0;		}		if (par->palette_blanked) {			//do_install_cmap(info->currcon, info);			par->palette_blanked = 0;		}		break;	case 1:				/* blank */		vga_pal_blank();		par->palette_blanked = 1;		break;	default:			/* VESA blanking */		vga_vesa_blank(par, blank-1);		par->vesa_blanked = 1;		break;	}	return 0;}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 *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);}void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect){	int x, x2, y2, vxres, vyres, width, height, line_ofs;	char *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) {

⌨️ 快捷键说明

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