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

📄 console.c.bak

📁 一份精简的linux内核源代码
💻 BAK
📖 第 1 页 / 共 2 页
字号:
/* *  linux/kernel/console.c * *  (C) 1991  Linus Torvalds *//* *	console.c * * This module implements the console io functions *	'void con_init(void)' *	'void con_write(struct tty_queue * queue)' * Hopefully this will be a rather complete VT102 implementation. * * Beeping thanks to John T Kohl. *//* *  NOTE!!! We sometimes disable and enable interrupts for a short while * (to put a word in video IO), but this will work even for keyboard * interrupts. We know interrupts aren't enabled when getting a keyboard * interrupt, as we use trap-gates. Hopefully all is well. *//* * Code to check for different video-cards mostly by Galen Hunt, * <g-hunt@ee.utah.edu> */#include <linux/sched.h>#include <linux/tty.h>#include <asm/io.h>#include <asm/system.h>/* * These are set up by the setup-routine(setup.s) at boot-time: */#define ORIG_X			(*(unsigned char *)0x90000)           /* 初始关标列号*/#define ORIG_Y			(*(unsigned char *)0x90001)           /* 初始关标行号*/#define ORIG_VIDEO_PAGE		(*(unsigned short *)0x90004)      /*显示页面*/#define ORIG_VIDEO_MODE		((*(unsigned short *)0x90006) & 0xff)   /* 显示模式*/#define ORIG_VIDEO_COLS 	(((*(unsigned short *)0x90006) & 0xff00) >> 8) /* 字符列数*/#define ORIG_VIDEO_LINES	(25)                                /*显示行数*/#define ORIG_VIDEO_EGA_AX	(*(unsigned short *)0x90008)#define ORIG_VIDEO_EGA_BX	(*(unsigned short *)0x9000a)     /* 显存大小*/#define ORIG_VIDEO_EGA_CX	(*(unsigned short *)0x9000c)       /* 显卡特性参数*/#define VIDEO_TYPE_MDA		0x10	/* Monochrome(单色) Text Display	*/#define VIDEO_TYPE_CGA		0x11	/* CGA Display 			*/#define VIDEO_TYPE_EGAM		0x20	/* EGA/VGA in Monochrome Mode	*/#define VIDEO_TYPE_EGAC		0x21	/* EGA/VGA in Color Mode	*/#define NPAR 16 /* 转义字符序列中最大参数个数*/extern void keyboard_interrupt(void);  static unsigned char	video_type;		/* Type of display being used	*/static unsigned long	video_num_columns;	/* Number of text columns	*/static unsigned long	video_size_row;		/* Bytes per row		*/static unsigned long	video_num_lines;	/* Number of text lines		*/static unsigned char	video_page;		/* Initial video page		*/static unsigned long	video_mem_start;	/* Start of video RAM		*/static unsigned long	video_mem_end;		/* End of video RAM (sort of)	*/static unsigned short	video_port_reg;		/* Video register select port	*/static unsigned short	video_port_val;		/* Video register value port	*/static unsigned short	video_erase_char;	/* Char+Attrib to erase with	*//* 擦除字符属性及字符	*/static unsigned long	origin;		/* Used for EGA/VGA fast scroll	*//* 屏幕起始地址(orgin-video_mem_start即为)	*/static unsigned long	scr_end;	/* Used for EGA/VGA fast scroll	*//* 屏幕末端地址	*/static unsigned long	pos;   /* 当前光标对应显示内存位置*/static unsigned long	x,y;    /* 目前光标位置	*/static unsigned long	top,bottom; /* 屏幕中顶行行号,底行行号(top是相对于orgin的)	*/static unsigned long	state=0;  /* ANSI转义字符序列处理状态	*/static unsigned long	npar,par[NPAR]; /* ANSI转义字符序列参数和参数个数*/static unsigned long	ques=0;    /* 收到问号字符标志	*/static unsigned char	attr=0x07;   /* 字符属性(黑底白子)	*/static void sysbeep(void);   /* 系统蜂鸣函数*//* * this is what the terminal answers to a ESC-Z or csi0c * query (= vt100 response). */#define RESPONSE "\033[?1;2c"  /* 表示终端是高级视频终端(应答主机发问的应答序列)	*//* NOTE! gotoxy thinks x==video_num_columns is ok */static inline void gotoxy(unsigned int new_x,unsigned int new_y)/*更新光标当前所在位置和光标对应的显存位置pos。*/{	if (new_x > video_num_columns || new_y >= video_num_lines)		return;	x=new_x;	y=new_y;	pos=origin + y*video_size_row + (x<<1);}static inline void set_origin(void) /* 设置滚屏起始显存地址(在屏幕上显示数据的实质)	*/ /* 屏幕上一个字符用2个字节表示*/{	cli();	outb_p(12, video_port_reg);                     /* 选择显示控制数据寄存器r12*/	outb_p(0xff&((origin-video_mem_start)>>9), video_port_val); /* 向r12中写入卷屏起始地址高字节*/	outb_p(13, video_port_reg);                     /* 选择显示控制数据寄存器r13*/	outb_p(0xff&((origin-video_mem_start)>>1), video_port_val); /* 向r13中写入卷屏起始地址底字节*/	sti();}static void scrup(void)  /* 向上卷动一行*/{	if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM) /* 显卡类型*/	{		if (!top && bottom == video_num_lines) {/* 整屏窗口向下移动(显存中的数据不动,仅仅是屏幕在下移)*/			origin += video_size_row;			pos += video_size_row;			scr_end += video_size_row;			if (scr_end > video_mem_end) {/* 下移之后越界,则将屏幕中的数据移置显存开始位置*/				__asm__("cld\n\t"					"rep\n\t"					"movsl\n\t"   /*move data from edi(S) to esi(D)*/					"movl _video_num_columns,%1\n\t"					"rep\n\t"					"stosw"   /*在新行上填空格*/					::"a" (video_erase_char),					"c" ((video_num_lines-1)*video_num_columns>>1),					"D" (video_mem_start),					"S" (origin)					:"cx","di","si");				scr_end -= origin-video_mem_start;				pos -= origin-video_mem_start;				origin = video_mem_start;			} else { /*下移之后未越界,则将新进入屏幕的一行填成空格*/				__asm__("cld\n\t"					"rep\n\t"					"stosw"					::"a" (video_erase_char),					"c" (video_num_columns),					"D" (scr_end-video_size_row)					:"cx","di");			}			set_origin();/* 设置显示控制器中显示的内容*/		} else { /*非整屏移动(屏幕不动,仅移动显存中的数据)*/			__asm__("cld\n\t"				"rep\n\t"				"movsl\n\t"  /*将top--botton之间的数据上移一行*/				"movl _video_num_columns,%%ecx\n\t"				"rep\n\t"				"stosw"				::"a" (video_erase_char),				"c" ((bottom-top-1)*video_num_columns>>1),				"D" (origin+video_size_row*top),				"S" (origin+video_size_row*(top+1))				:"cx","di","si");		}	}	else		/* Not EGA/VGA */	{		__asm__("cld\n\t"			"rep\n\t"			"movsl\n\t"			"movl _video_num_columns,%%ecx\n\t"			"rep\n\t"			"stosw"			::"a" (video_erase_char),			"c" ((bottom-top-1)*video_num_columns>>1),			"D" (origin+video_size_row*top),			"S" (origin+video_size_row*(top+1))			:"cx","di","si");	}}static void scrdown(void)    /* 向下卷动一行*/{	if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM)	{		__asm__("std\n\t"			"rep\n\t"			"movsl\n\t"			"addl $2,%%edi\n\t"	/* %edi has been decremented by 4 */			"movl _video_num_columns,%%ecx\n\t"			"rep\n\t"			"stosw"			::"a" (video_erase_char),			"c" ((bottom-top-1)*video_num_columns>>1),			"D" (origin+video_size_row*bottom-4),			"S" (origin+video_size_row*(bottom-1)-4)			:"ax","cx","di","si");	}	else		/* Not EGA/VGA */	{		__asm__("std\n\t"			"rep\n\t"			"movsl\n\t"			"addl $2,%%edi\n\t"	/* %edi has been decremented by 4 */			"movl _video_num_columns,%%ecx\n\t"			"rep\n\t"			"stosw"			::"a" (video_erase_char),			"c" ((bottom-top-1)*video_num_columns>>1),			"D" (origin+video_size_row*bottom-4),			"S" (origin+video_size_row*(bottom-1)-4)			:"ax","cx","di","si");	}}static void lf(void)/*换行*/{	if (y+1<bottom) {		y++;		pos += video_size_row;		return;	}	scrup();}static void ri(void)/*反换行*/{	if (y>top) {		y--;		pos -= video_size_row;		return;	}	scrdown();}static void cr(void) /*回行首*/{	pos -= x<<1;	x=0;}static void del(void) /*删除一字符*/{	if (x) {		pos -= 2;		x--;		*(unsigned short *)pos = video_erase_char;	}}static void csi_J(int par)/*删除屏幕上的相关数据*/{	long count __asm__("cx");	long start __asm__("di");	switch (par) {		case 0:	/* erase from cursor to end of display */			count = (scr_end-pos)>>1;			start = pos;			break;		case 1:	/* erase from start to cursor */			count = (pos-origin)>>1;			start = origin;			break;		case 2: /* erase whole display */			count = video_num_columns * video_num_lines;			start = origin;			break;		default:			return;	}	__asm__("cld\n\t"		"rep\n\t"		"stosw\n\t"		::"c" (count),		"D" (start),"a" (video_erase_char)		:"cx","di");}static void csi_K(int par)/*类上*/{	long count __asm__("cx");	long start __asm__("di");	switch (par) {		case 0:	/* erase from cursor to end of line */			if (x>=video_num_columns)				return;			count = video_num_columns-x;			start = pos;			break;		case 1:	/* erase from start of line to cursor */			start = pos - (x<<1);			count = (x<video_num_columns)?x:video_num_columns;			break;		case 2: /* erase whole line */			start = pos - (x<<1);			count = video_num_columns;			break;		default:			return;	}	__asm__("cld\n\t"		"rep\n\t"		"stosw\n\t"		::"c" (count),		"D" (start),"a" (video_erase_char)		:"cx","di");}void csi_m(void) /*设置显示字符属性*/{	int i;	for (i=0;i<=npar;i++)		switch (par[i]) {			case 0:attr=0x07;break;			case 1:attr=0x0f;break;			case 4:attr=0x0f;break;			case 7:attr=0x70;break;			case 27:attr=0x07;break;		}}static inline void set_cursor(void)/*设置显示光标*/{	cli();	outb_p(14, video_port_reg);	outb_p(0xff&((pos-video_mem_start)>>9), video_port_val);	outb_p(15, video_port_reg);	outb_p(0xff&((pos-video_mem_start)>>1), video_port_val);	sti();}static void respond(struct tty_struct * tty)/*将RESPONSE放入读队列及辅助队列中*/{	char * p = RESPONSE;	cli();	while (*p) { /*逐字的放入read_q队列*/		PUTCH(*p,tty->read_q);		p++;	}	sti();	copy_to_cooked(tty);/*放入辅助队列*/}static void insert_char(void)/*插入空格*/{	int i=x;	unsigned short tmp, old = video_erase_char;	unsigned short * p = (unsigned short *) pos;	while (i++<video_num_columns) {		tmp=*p;		*p=old;		old=tmp;		p++;	}}static void insert_line(void)/*插入行*/{	int oldtop,oldbottom;	oldtop=top;	oldbottom=bottom;	top=y;

⌨️ 快捷键说明

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