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

📄 vgacon.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				 */				for (i = 0; i < 16; i++) {					inb_p(VGA_IS1_RC);					outb_p(i, VGA_ATT_W);					outb_p(i, VGA_ATT_W);				}				outb_p(0x20, VGA_ATT_W);				/*				 * Now set the DAC registers back to their				 * default values				 */				for (i = 0; i < 16; i++) {					outb_p(color_table[i], VGA_PEL_IW);					outb_p(default_red[i], VGA_PEL_D);					outb_p(default_grn[i], VGA_PEL_D);					outb_p(default_blu[i], VGA_PEL_D);				}			}		} else {			static struct resource cga_console_resource =			    { .name = "cga", .start = 0x3D4, .end = 0x3D5 };			vga_video_type = VIDEO_TYPE_CGA;			vga_vram_size = 0x2000;			display_desc = "*CGA";			request_resource(&ioport_resource,					 &cga_console_resource);			vga_video_font_height = 8;		}	}	vga_vram_base = VGA_MAP_MEM(vga_vram_base, vga_vram_size);	vga_vram_end = vga_vram_base + vga_vram_size;	/*	 *      Find out if there is a graphics card present.	 *      Are there smarter methods around?	 */	p = (volatile u16 *) vga_vram_base;	saved1 = scr_readw(p);	saved2 = scr_readw(p + 1);	scr_writew(0xAA55, p);	scr_writew(0x55AA, p + 1);	if (scr_readw(p) != 0xAA55 || scr_readw(p + 1) != 0x55AA) {		scr_writew(saved1, p);		scr_writew(saved2, p + 1);		goto no_vga;	}	scr_writew(0x55AA, p);	scr_writew(0xAA55, p + 1);	if (scr_readw(p) != 0x55AA || scr_readw(p + 1) != 0xAA55) {		scr_writew(saved1, p);		scr_writew(saved2, p + 1);		goto no_vga;	}	scr_writew(saved1, p);	scr_writew(saved2, p + 1);	if (vga_video_type == VIDEO_TYPE_EGAC	    || vga_video_type == VIDEO_TYPE_VGAC	    || vga_video_type == VIDEO_TYPE_EGAM) {		vga_hardscroll_enabled = vga_hardscroll_user_enable;		vga_default_font_height = screen_info.orig_video_points;		vga_video_font_height = screen_info.orig_video_points;		/* This may be suboptimal but is a safe bet - go with it */		vga_scan_lines =		    vga_video_font_height * vga_video_num_lines;	}	vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH;	vgacon_yres = vga_scan_lines;	if (!vga_init_done) {		vgacon_scrollback_startup();		vga_init_done = 1;	}	return display_desc;}static void vgacon_init(struct vc_data *c, int init){	unsigned long p;	/*	 * We cannot be loaded as a module, therefore init is always 1,	 * but vgacon_init can be called more than once, and init will	 * not be 1.	 */	c->vc_can_do_color = vga_can_do_color;	/* set dimensions manually if init != 0 since vc_resize() will fail */	if (init) {		c->vc_cols = vga_video_num_columns;		c->vc_rows = vga_video_num_lines;	} else		vc_resize(c, vga_video_num_columns, vga_video_num_lines);	c->vc_scan_lines = vga_scan_lines;	c->vc_font.height = vga_video_font_height;	c->vc_complement_mask = 0x7700;	if (vga_512_chars)		c->vc_hi_font_mask = 0x0800;	p = *c->vc_uni_pagedir_loc;	if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir ||	    !--c->vc_uni_pagedir_loc[1])		con_free_unimap(c);	c->vc_uni_pagedir_loc = vgacon_uni_pagedir;	vgacon_uni_pagedir[1]++;	if (!vgacon_uni_pagedir[0] && p)		con_set_default_unimap(c);}static void vgacon_deinit(struct vc_data *c){	/* When closing the last console, reset video origin */	if (!--vgacon_uni_pagedir[1]) {		c->vc_visible_origin = vga_vram_base;		vga_set_mem_top(c);		con_free_unimap(c);	}	c->vc_uni_pagedir_loc = &c->vc_uni_pagedir;	con_set_default_unimap(c);}static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,			    u8 blink, u8 underline, u8 reverse, u8 italic){	u8 attr = color;	if (vga_can_do_color) {		if (italic)			attr = (attr & 0xF0) | c->vc_itcolor;		else if (underline)			attr = (attr & 0xf0) | c->vc_ulcolor;		else if (intensity == 0)			attr = (attr & 0xf0) | c->vc_halfcolor;	}	if (reverse)		attr =		    ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) &				       0x77);	if (blink)		attr ^= 0x80;	if (intensity == 2)		attr ^= 0x08;	if (!vga_can_do_color) {		if (italic)			attr = (attr & 0xF8) | 0x02;		else if (underline)			attr = (attr & 0xf8) | 0x01;		else if (intensity == 0)			attr = (attr & 0xf0) | 0x08;	}	return attr;}static void vgacon_invert_region(struct vc_data *c, u16 * p, int count){	int col = vga_can_do_color;	while (count--) {		u16 a = scr_readw(p);		if (col)			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |			    (((a) & 0x0700) << 4);		else			a ^= ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;		scr_writew(a, p++);	}}static void vgacon_set_cursor_size(int xpos, int from, int to){	unsigned long flags;	int curs, cure;#ifdef TRIDENT_GLITCH	if (xpos < 16)		from--, to--;#endif	if ((from == cursor_size_lastfrom) && (to == cursor_size_lastto))		return;	cursor_size_lastfrom = from;	cursor_size_lastto = to;	spin_lock_irqsave(&vga_lock, flags);	if (vga_video_type >= VIDEO_TYPE_VGAC) {		outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);		curs = inb_p(vga_video_port_val);		outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);		cure = inb_p(vga_video_port_val);	} else {		curs = 0;		cure = 0;	}	curs = (curs & 0xc0) | from;	cure = (cure & 0xe0) | to;	outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);	outb_p(curs, vga_video_port_val);	outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);	outb_p(cure, vga_video_port_val);	spin_unlock_irqrestore(&vga_lock, flags);}static void vgacon_cursor(struct vc_data *c, int mode){	if (c->vc_mode != KD_TEXT)		return;	vgacon_restore_screen(c);	switch (mode) {	case CM_ERASE:		write_vga(14, (c->vc_pos - vga_vram_base) / 2);	        if (vga_video_type >= VIDEO_TYPE_VGAC)			vgacon_set_cursor_size(c->vc_x, 31, 30);		else			vgacon_set_cursor_size(c->vc_x, 31, 31);		break;	case CM_MOVE:	case CM_DRAW:		write_vga(14, (c->vc_pos - vga_vram_base) / 2);		switch (c->vc_cursor_type & 0x0f) {		case CUR_UNDERLINE:			vgacon_set_cursor_size(c->vc_x,					       c->vc_font.height -					       (c->vc_font.height <						10 ? 2 : 3),					       c->vc_font.height -					       (c->vc_font.height <						10 ? 1 : 2));			break;		case CUR_TWO_THIRDS:			vgacon_set_cursor_size(c->vc_x,					       c->vc_font.height / 3,					       c->vc_font.height -					       (c->vc_font.height <						10 ? 1 : 2));			break;		case CUR_LOWER_THIRD:			vgacon_set_cursor_size(c->vc_x,					       (c->vc_font.height * 2) / 3,					       c->vc_font.height -					       (c->vc_font.height <						10 ? 1 : 2));			break;		case CUR_LOWER_HALF:			vgacon_set_cursor_size(c->vc_x,					       c->vc_font.height / 2,					       c->vc_font.height -					       (c->vc_font.height <						10 ? 1 : 2));			break;		case CUR_NONE:			if (vga_video_type >= VIDEO_TYPE_VGAC)				vgacon_set_cursor_size(c->vc_x, 31, 30);			else				vgacon_set_cursor_size(c->vc_x, 31, 31);			break;		default:			vgacon_set_cursor_size(c->vc_x, 1,					       c->vc_font.height);			break;		}		break;	}}static int vgacon_doresize(struct vc_data *c,		unsigned int width, unsigned int height){	unsigned long flags;	unsigned int scanlines = height * c->vc_font.height;	u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan;	spin_lock_irqsave(&vga_lock, flags);	vgacon_xres = width * VGA_FONTWIDTH;	vgacon_yres = height * c->vc_font.height;	if (vga_video_type >= VIDEO_TYPE_VGAC) {		outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);		max_scan = inb_p(vga_video_port_val);		if (max_scan & 0x80)			scanlines <<= 1;		outb_p(VGA_CRTC_MODE, vga_video_port_reg);		mode = inb_p(vga_video_port_val);		if (mode & 0x04)			scanlines >>= 1;		scanlines -= 1;		scanlines_lo = scanlines & 0xff;		outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);		r7 = inb_p(vga_video_port_val) & ~0x42;		if (scanlines & 0x100)			r7 |= 0x02;		if (scanlines & 0x200)			r7 |= 0x40;		/* deprotect registers */		outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);		vsync_end = inb_p(vga_video_port_val);		outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);		outb_p(vsync_end & ~0x80, vga_video_port_val);	}	outb_p(VGA_CRTC_H_DISP, vga_video_port_reg);	outb_p(width - 1, vga_video_port_val);	outb_p(VGA_CRTC_OFFSET, vga_video_port_reg);	outb_p(width >> 1, vga_video_port_val);	if (vga_video_type >= VIDEO_TYPE_VGAC) {		outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);		outb_p(scanlines_lo, vga_video_port_val);		outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);		outb_p(r7,vga_video_port_val);		/* reprotect registers */		outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);		outb_p(vsync_end, vga_video_port_val);	}	spin_unlock_irqrestore(&vga_lock, flags);	return 0;}static int vgacon_switch(struct vc_data *c){	int x = c->vc_cols * VGA_FONTWIDTH;	int y = c->vc_rows * c->vc_font.height;	int rows = screen_info.orig_video_lines * vga_default_font_height/		c->vc_font.height;	/*	 * We need to save screen size here as it's the only way	 * we can spot the screen has been resized and we need to	 * set size of freshly allocated screens ourselves.	 */	vga_video_num_columns = c->vc_cols;	vga_video_num_lines = c->vc_rows;	/* We can only copy out the size of the video buffer here,	 * otherwise we get into VGA BIOS */	if (!vga_is_gfx) {		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,			    c->vc_screenbuf_size > vga_vram_size ?				vga_vram_size : c->vc_screenbuf_size);		if ((vgacon_xres != x || vgacon_yres != y) &&		    (!(vga_video_num_columns % 2) &&		     vga_video_num_columns <= screen_info.orig_video_cols &&		     vga_video_num_lines <= rows))			vgacon_doresize(c, c->vc_cols, c->vc_rows);	}	vgacon_scrollback_init(c->vc_size_row);	return 0;		/* Redrawing not needed */}static void vga_set_palette(struct vc_data *vc, unsigned char *table){	int i, j;	vga_w(state.vgabase, VGA_PEL_MSK, 0xff);	for (i = j = 0; i < 16; i++) {		vga_w(state.vgabase, VGA_PEL_IW, table[i]);		vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);		vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);		vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);	}}static int vgacon_set_palette(struct vc_data *vc, unsigned char *table){#ifdef CAN_LOAD_PALETTE	if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked	    || !CON_IS_VISIBLE(vc))		return -EINVAL;	vga_set_palette(vc, table);	return 0;#else	return -EINVAL;#endif}/* structure holding original VGA register settings */static struct {	unsigned char SeqCtrlIndex;	/* Sequencer Index reg.   */	unsigned char CrtCtrlIndex;	/* CRT-Contr. Index reg.  */	unsigned char CrtMiscIO;	/* Miscellaneous register */	unsigned char HorizontalTotal;	/* CRT-Controller:00h */	unsigned char HorizDisplayEnd;	/* CRT-Controller:01h */	unsigned char StartHorizRetrace;	/* CRT-Controller:04h */	unsigned char EndHorizRetrace;	/* CRT-Controller:05h */	unsigned char Overflow;	/* CRT-Controller:07h */	unsigned char StartVertRetrace;	/* CRT-Controller:10h */	unsigned char EndVertRetrace;	/* CRT-Controller:11h */	unsigned char ModeControl;	/* CRT-Controller:17h */	unsigned char ClockingMode;	/* Seq-Controller:01h */} vga_state;static void vga_vesa_blank(struct vgastate *state, int mode){	/* save original values of VGA controller registers */	if (!vga_vesa_blanked) {		spin_lock_irq(&vga_lock);		vga_state.SeqCtrlIndex = vga_r(state->vgabase, VGA_SEQ_I);		vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);		vga_state.CrtMiscIO = vga_r(state->vgabase, VGA_MIS_R);		spin_unlock_irq(&vga_lock);		outb_p(0x00, vga_video_port_reg);	/* HorizontalTotal */		vga_state.HorizontalTotal = inb_p(vga_video_port_val);		outb_p(0x01, vga_video_port_reg);	/* HorizDisplayEnd */		vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);		outb_p(0x04, vga_video_port_reg);	/* StartHorizRetrace */		vga_state.StartHorizRetrace = inb_p(vga_video_port_val);		outb_p(0x05, vga_video_port_reg);	/* EndHorizRetrace */		vga_state.EndHorizRetrace = inb_p(vga_video_port_val);		outb_p(0x07, vga_video_port_reg);	/* Overflow */		vga_state.Overflow = inb_p(vga_video_port_val);		outb_p(0x10, vga_video_port_reg);	/* StartVertRetrace */		vga_state.StartVertRetrace = inb_p(vga_video_port_val);		outb_p(0x11, vga_video_port_reg);	/* EndVertRetrace */		vga_state.EndVertRetrace = inb_p(vga_video_port_val);		outb_p(0x17, vga_video_port_reg);	/* ModeControl */		vga_state.ModeControl = inb_p(vga_video_port_val);		vga_state.ClockingMode = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);	}	/* assure that video is enabled */	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */	spin_lock_irq(&vga_lock);	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, vga_state.ClockingMode | 0x20);	/* test for vertical retrace in process.... */	if ((vga_state.CrtMiscIO & 0x80) == 0x80)		vga_w(state->vgabase, VGA_MIS_W, 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(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 */	vga_w(state->vgabase, VGA_SEQ_I, vga_state.SeqCtrlIndex);

⌨️ 快捷键说明

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