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

📄 vgacon.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	int beg;	unsigned short video_port_status = vga_video_port_reg + 6;	int font_select = 0x00;	if (vga_video_type != VIDEO_TYPE_EGAM) {		charmap = (char *)VGA_MAP_MEM(colourmap);		beg = 0x0e;#ifdef VGA_CAN_DO_64KB		if (vga_video_type == VIDEO_TYPE_VGAC)			beg = 0x06;#endif	} else {		charmap = (char *)VGA_MAP_MEM(blackwmap);		beg = 0x0a;	}	#ifdef BROKEN_GRAPHICS_PROGRAMS	/*	 * All fonts are loaded in slot 0 (0:1 for 512 ch)	 */	if (!arg)		return -EINVAL;		/* Return to default font not supported */	vga_font_is_default = 0;	font_select = ch512 ? 0x04 : 0x00;#else		/*	 * The default font is kept in slot 0 and is never touched.	 * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch)	 */	if (set) {		vga_font_is_default = !arg;		if (!arg)			ch512 = 0;		/* Default font is always 256 */		font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00;	}	if ( !vga_font_is_default )		charmap += 4*cmapsz;#endif	spin_lock_irq(&vga_lock);	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */	outb_p( 0x01, seq_port_val );   /* Synchronous reset */	outb_p( 0x02, seq_port_reg );	outb_p( 0x04, seq_port_val );   /* CPU writes only to map 2 */	outb_p( 0x04, seq_port_reg );	outb_p( 0x07, seq_port_val );   /* Sequential addressing */	outb_p( 0x00, seq_port_reg );	outb_p( 0x03, seq_port_val );   /* Clear synchronous reset */	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */	outb_p( 0x02, gr_port_val );    /* select map 2 */	outb_p( 0x05, gr_port_reg );	outb_p( 0x00, gr_port_val );    /* disable odd-even addressing */	outb_p( 0x06, gr_port_reg );	outb_p( 0x00, gr_port_val );    /* map start at A000:0000 */	spin_unlock_irq(&vga_lock);		if (arg) {		if (set)			for (i=0; i<cmapsz ; i++)				vga_writeb(arg[i], charmap + i);		else			for (i=0; i<cmapsz ; i++)				arg[i] = vga_readb(charmap + i);		/*		 * In 512-character mode, the character map is not contiguous if		 * we want to remain EGA compatible -- which we do		 */		if (ch512) {			charmap += 2*cmapsz;			arg += cmapsz;			if (set)				for (i=0; i<cmapsz ; i++)					vga_writeb(arg[i], charmap+i);			else				for (i=0; i<cmapsz ; i++)					arg[i] = vga_readb(charmap+i);		}	}		spin_lock_irq(&vga_lock);	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */	outb_p( 0x01, seq_port_val );   /* Synchronous reset */	outb_p( 0x02, seq_port_reg );	outb_p( 0x03, seq_port_val );   /* CPU writes to maps 0 and 1 */	outb_p( 0x04, seq_port_reg );	outb_p( 0x03, seq_port_val );   /* odd-even addressing */	if (set) {		outb_p( 0x03, seq_port_reg ); /* Character Map Select */		outb_p( font_select, seq_port_val );	}	outb_p( 0x00, seq_port_reg );	outb_p( 0x03, seq_port_val );   /* clear synchronous reset */	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */	outb_p( 0x00, gr_port_val );    /* select map 0 for CPU */	outb_p( 0x05, gr_port_reg );	outb_p( 0x10, gr_port_val );    /* enable even-odd addressing */	outb_p( 0x06, gr_port_reg );	outb_p( beg, gr_port_val );     /* map starts at b800:0 or b000:0 */	/* if 512 char mode is already enabled don't re-enable it. */	if ((set)&&(ch512!=vga_512_chars)) {	/* attribute controller */		int i;		for(i=0; i<MAX_NR_CONSOLES; i++) {			struct vc_data *c = vc_cons[i].d;			if (c && c->vc_sw == &vga_con)				c->vc_hi_font_mask = ch512 ? 0x0800 : 0;		}		vga_512_chars=ch512;		/* 256-char: enable intensity bit		   512-char: disable intensity bit */		inb_p( video_port_status );	/* clear address flip-flop */		outb_p ( 0x12, attrib_port ); /* color plane enable register */		outb_p ( ch512 ? 0x07 : 0x0f, attrib_port );		/* Wilton (1987) mentions the following; I don't know what		   it means, but it works, and it appears necessary */		inb_p( video_port_status );		outb_p ( 0x20, attrib_port );	}	spin_unlock_irq(&vga_lock);	return 0;}/* * Adjust the screen to fit a font of a certain height */static intvgacon_adjust_height(unsigned fontheight){	int rows, maxscan;	unsigned char ovr, vde, fsr;	if (fontheight == vga_video_font_height)		return 0;	vga_video_font_height = video_font_height = fontheight;	rows = video_scan_lines/fontheight;	/* Number of video rows we end up with */	maxscan = rows*fontheight - 1;		/* Scan lines to actually display-1 */	/* Reprogram the CRTC for the new font size	   Note: the attempt to read the overflow register will fail	   on an EGA, but using 0xff for the previous value appears to	   be OK for EGA text modes in the range 257-512 scan lines, so I	   guess we don't need to worry about it.	   The same applies for the spill bits in the font size and cursor	   registers; they are write-only on EGA, but it appears that they	   are all don't care bits on EGA, so I guess it doesn't matter. */	spin_lock_irq(&vga_lock);	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */	ovr = inb_p(vga_video_port_val);	outb_p( 0x09, vga_video_port_reg );		/* Font size register */	fsr = inb_p(vga_video_port_val);	spin_unlock_irq(&vga_lock);	vde = maxscan & 0xff;			/* Vertical display end reg */	ovr = (ovr & 0xbd) +			/* Overflow register */	      ((maxscan & 0x100) >> 7) +	      ((maxscan & 0x200) >> 3);	fsr = (fsr & 0xe0) + (fontheight-1);    /*  Font size register */	spin_lock_irq(&vga_lock);	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */	outb_p( ovr, vga_video_port_val );	outb_p( 0x09, vga_video_port_reg );		/* Font size */	outb_p( fsr, vga_video_port_val );	outb_p( 0x12, vga_video_port_reg );		/* Vertical display limit */	outb_p( vde, vga_video_port_val );	spin_unlock_irq(&vga_lock);		vc_resize_all(rows, 0);			/* Adjust console size */	return 0;}static int vgacon_font_op(struct vc_data *c, struct console_font_op *op){	int rc;	if (vga_video_type < VIDEO_TYPE_EGAM)		return -EINVAL;	if (op->op == KD_FONT_OP_SET) {		if (op->width != 8 || (op->charcount != 256 && op->charcount != 512))			return -EINVAL;		rc = vgacon_do_font_op(op->data, 1, op->charcount == 512);		if (!rc && !(op->flags & KD_FONT_FLAG_DONT_RECALC))			rc = vgacon_adjust_height(op->height);	} else if (op->op == KD_FONT_OP_GET) {		op->width = 8;		op->height = vga_video_font_height;		op->charcount = vga_512_chars ? 512 : 256;		if (!op->data) return 0;		rc = vgacon_do_font_op(op->data, 0, 0);	} else		rc = -ENOSYS;	return rc;}#elsestatic int vgacon_font_op(struct vc_data *c, struct console_font_op *op){	return -ENOSYS;}#endifstatic int vgacon_scrolldelta(struct vc_data *c, int lines){	if (!lines)			/* Turn scrollback off */		c->vc_visible_origin = c->vc_origin;	else {		int vram_size = vga_vram_end - vga_vram_base;		int margin = c->vc_size_row * 4;		int ul, we, p, st;		if (vga_rolled_over > (c->vc_scr_end - vga_vram_base) + margin) {			ul = c->vc_scr_end - vga_vram_base;			we = vga_rolled_over + c->vc_size_row;		} else {			ul = 0;			we = vram_size;		}		p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + lines * c->vc_size_row;		st = (c->vc_origin - vga_vram_base - ul + we) % we;		if (p < margin)			p = 0;		if (p > st - margin)			p = st;		c->vc_visible_origin = vga_vram_base + (p + ul) % we;	}	vga_set_mem_top(c);	return 1;}static int vgacon_set_origin(struct vc_data *c){	if (vga_is_gfx ||	/* We don't play origin tricks in graphic modes */	    (console_blanked && !vga_palette_blanked))	/* Nor we write to blanked screens */		return 0;	c->vc_origin = c->vc_visible_origin = vga_vram_base;	vga_set_mem_top(c);	vga_rolled_over = 0;	return 1;}static void vgacon_save_screen(struct vc_data *c){	static int vga_bootup_console = 0;	if (!vga_bootup_console) {		/* This is a gross hack, but here is the only place we can		 * set bootup console parameters without messing up generic		 * console initialization routines.		 */		vga_bootup_console = 1;		c->vc_x = ORIG_X;		c->vc_y = ORIG_Y;	}	if (!vga_is_gfx)		scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);}static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines){	unsigned long oldo;	unsigned int delta;		if (t || b != c->vc_rows || vga_is_gfx)		return 0;	if (c->vc_origin != c->vc_visible_origin)		vgacon_scrolldelta(c, 0);	if (!vga_hardscroll_enabled || lines >= c->vc_rows/2)		return 0;	oldo = c->vc_origin;	delta = lines * c->vc_size_row;	if (dir == SM_UP) {		if (c->vc_scr_end + delta >= vga_vram_end) {			scr_memcpyw((u16 *)vga_vram_base,				    (u16 *)(oldo + delta),				    c->vc_screenbuf_size - delta);			c->vc_origin = vga_vram_base;			vga_rolled_over = oldo - vga_vram_base;		} else			c->vc_origin += delta;		scr_memsetw((u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), c->vc_video_erase_char, delta);	} else {		if (oldo - delta < vga_vram_base) {			scr_memmovew((u16 *)(vga_vram_end - c->vc_screenbuf_size + delta),				     (u16 *)oldo,				     c->vc_screenbuf_size - delta);			c->vc_origin = vga_vram_end - c->vc_screenbuf_size;			vga_rolled_over = 0;		} else			c->vc_origin -= delta;		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;		scr_memsetw((u16 *)(c->vc_origin), c->vc_video_erase_char, delta);	}	c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;	c->vc_visible_origin = c->vc_origin;	vga_set_mem_top(c);	c->vc_pos = (c->vc_pos - oldo) + c->vc_origin;	return 1;}/* *  The console `switch' structure for the VGA based console */static int vgacon_dummy(struct vc_data *c){	return 0;}#define DUMMY (void *) vgacon_dummyconst struct consw vga_con = {	con_startup:		vgacon_startup,	con_init:		vgacon_init,	con_deinit:		vgacon_deinit,	con_clear:		DUMMY,	con_putc:		DUMMY,	con_putcs:		DUMMY,	con_cursor:		vgacon_cursor,	con_scroll:		vgacon_scroll,	con_bmove:		DUMMY,	con_switch:		vgacon_switch,	con_blank:		vgacon_blank,	con_font_op:		vgacon_font_op,	con_set_palette:	vgacon_set_palette,	con_scrolldelta:	vgacon_scrolldelta,	con_set_origin:		vgacon_set_origin,	con_save_screen:	vgacon_save_screen,	con_build_attr:		vgacon_build_attr,	con_invert_region:	vgacon_invert_region,};MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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