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

📄 console.c

📁 带中文注释的 linux 0.11 源代码0.11,很好的
💻 C
📖 第 1 页 / 共 3 页
字号:
	    }	  else if (c == 9)	    {	      c = 8 - (x & 7);	      x += c;	      pos += c << 1;	      if (x > video_num_columns)		{		  x -= video_num_columns;		  pos -= video_size_row;		  lf ();		}	      c = 9;// 如果字符c 是响铃符BEL(7),则调用蜂鸣函数,是扬声器发声。	    }	  else if (c == 7)	    sysbeep ();	  break;// 如果原状态是0,并且字符是转义字符ESC(0x1b = 033 = 27),则转到状态1 处理。	case 1:	  state = 0;// 如果字符c 是'[',则将状态state 转到2。	  if (c == '[')	    state = 2;// 如果字符c 是'E',则光标移到下一行开始处(0 列)。	  else if (c == 'E')	    gotoxy (0, y + 1);// 如果字符c 是'M',则光标上移一行。	  else if (c == 'M')	    ri ();// 如果字符c 是'D',则光标下移一行。	  else if (c == 'D')	    lf ();// 如果字符c 是'Z',则发送终端应答字符序列。	  else if (c == 'Z')	    respond (tty);// 如果字符c 是'7',则保存当前光标位置。注意这里代码写错!应该是(c=='7')。	  else if (x == '7')	    save_cur ();// 如果字符c 是'8',则恢复到原保存的光标位置。注意这里代码写错!应该是(c=='8')。	  else if (x == '8')	    restore_cur ();	  break;// 如果原状态是1,并且上一字符是'[',则转到状态2 来处理。	case 2:// 首先对ESC 转义字符序列参数使用的处理数组par[]清零,索引变量npar 指向首项,并且设置状态// 为3。若此时字符不是'?',则直接转到状态3 去处理,否则去读一字符,再到状态3 处理代码处。	  for (npar = 0; npar < NPAR; npar++)	    par[npar] = 0;	  npar = 0;	  state = 3;	  if (ques = (c == '?'))	    break;// 如果原来是状态2;或者原来就是状态3,但原字符是';'或数字,则在下面处理。	case 3:// 如果字符c 是分号';',并且数组par 未满,则索引值加1。	  if (c == ';' && npar < NPAR - 1)	    {	      npar++;	      break;// 如果字符c 是数字字符'0'-'9',则将该字符转换成数值并与npar 所索引的项组成10 进制数。	    }	  else if (c >= '' && c <= '9')	    {	      par[npar] = 10 * par[npar] + c - '';	      break;// 否则转到状态4。	    }	  else	    state = 4;// 如果原状态是状态3,并且字符不是';'或数字,则转到状态4 处理。首先复位状态state=0。	case 4:	  state = 0;	  switch (c)	    {// 如果字符c 是'G'或'`',则par[]中第一个参数代表列号。若列号不为零,则将光标右移一格。	    case 'G':	    case '`':	      if (par[0])		par[0]--;	      gotoxy (par[0], y);	      break;// 如果字符c 是'A',则第一个参数代表光标上移的行数。若参数为0 则上移一行。	    case 'A':	      if (!par[0])		par[0]++;	      gotoxy (x, y - par[0]);	      break;// 如果字符c 是'B'或'e',则第一个参数代表光标下移的行数。若参数为0 则下移一行。	    case 'B':	    case 'e':	      if (!par[0])		par[0]++;	      gotoxy (x, y + par[0]);	      break;// 如果字符c 是'C'或'a',则第一个参数代表光标右移的格数。若参数为0 则右移一格。	    case 'C':	    case 'a':	      if (!par[0])		par[0]++;	      gotoxy (x + par[0], y);	      break;// 如果字符c 是'D',则第一个参数代表光标左移的格数。若参数为0 则左移一格。	    case 'D':	      if (!par[0])		par[0]++;	      gotoxy (x - par[0], y);	      break;// 如果字符c 是'E',则第一个参数代表光标向下移动的行数,并回到0 列。若参数为0 则下移一行。	    case 'E':	      if (!par[0])		par[0]++;	      gotoxy (0, y + par[0]);	      break;// 如果字符c 是'F',则第一个参数代表光标向上移动的行数,并回到0 列。若参数为0 则上移一行。	    case 'F':	      if (!par[0])		par[0]++;	      gotoxy (0, y - par[0]);	      break;// 如果字符c 是'd',则第一个参数代表光标所需在的行号(从0 计数)。	    case 'd':	      if (par[0])		par[0]--;	      gotoxy (x, par[0]);	      break;// 如果字符c 是'H'或'f',则第一个参数代表光标移到的行号,第二个参数代表光标移到的列号。	    case 'H':	    case 'f':	      if (par[0])		par[0]--;	      if (par[1])		par[1]--;	      gotoxy (par[1], par[0]);	      break;// 如果字符c 是'J',则第一个参数代表以光标所处位置清屏的方式:// ANSI 转义序列:'ESC [sJ'(s = 0 删除光标到屏幕底端;1 删除屏幕开始到光标处;2 整屏删除)。	    case 'J':	      csi_J (par[0]);	      break;// 如果字符c 是'K',则第一个参数代表以光标所在位置对行中字符进行删除处理的方式。// ANSI 转义字符序列:'ESC [sK'(s = 0 删除到行尾;1 从开始删除;2 整行都删除)。	    case 'K':	      csi_K (par[0]);	      break;// 如果字符c 是'L',表示在光标位置处插入n 行(ANSI 转义字符序列'ESC [nL')。	    case 'L':	      csi_L (par[0]);	      break;// 如果字符c 是'M',表示在光标位置处删除n 行(ANSI 转义字符序列'ESC [nM')。	    case 'M':	      csi_M (par[0]);	      break;// 如果字符c 是'P',表示在光标位置处删除n 个字符(ANSI 转义字符序列'ESC [nP')。	    case 'P':	      csi_P (par[0]);	      break;// 如果字符c 是'@',表示在光标位置处插入n 个字符(ANSI 转义字符序列'ESC [n@')。	    case '@':	      csi_at (par[0]);	      break;// 如果字符c 是'm',表示改变光标处字符的显示属性,比如加粗、加下划线、闪烁、反显等。// ANSI 转义字符序列:'ESC [nm'。n = 0 正常显示;1 加粗;4 加下划线;7 反显;27 正常显示。	    case 'm':	      csi_m ();	      break;// 如果字符c 是'r',则表示用两个参数设置滚屏的起始行号和终止行号。	    case 'r':	      if (par[0])		par[0]--;	      if (!par[1])		par[1] = video_num_lines;	      if (par[0] < par[1] && par[1] <= video_num_lines)		{		  top = par[0];		  bottom = par[1];		}	      break;// 如果字符c 是's',则表示保存当前光标所在位置。	    case 's':	      save_cur ();	      break;// 如果字符c 是'u',则表示恢复光标到原保存的位置处。	    case 'u':	      restore_cur ();	      break;	    }	}    }// 最后根据上面设置的光标位置,向显示控制器发送光标显示位置。  set_cursor ();}/** void con_init(void);** This routine initalizes console interrupts, and does nothing* else. If you want the screen to clear, call tty_write with* the appropriate escape-sequece.** Reads the information preserved by setup.s to determine the current display* type and sets everything accordingly.*//** void con_init(void);* 这个子程序初始化控制台中断,其它什么都不做。如果你想让屏幕干净的话,就使用* 适当的转义字符序列调用tty_write()函数。** 读取setup.s 程序保存的信息,用以确定当前显示器类型,并且设置所有相关参数。*/voidcon_init (void){  register unsigned char a;  char *display_desc = "????";  char *display_ptr;  video_num_columns = ORIG_VIDEO_COLS;	// 显示器显示字符列数。  video_size_row = video_num_columns * 2;	// 每行需使用字节数。  video_num_lines = ORIG_VIDEO_LINES;	// 显示器显示字符行数。  video_page = ORIG_VIDEO_PAGE;	// 当前显示页面。  video_erase_char = 0x0720;	// 擦除字符(0x20 显示字符, 0x07 是属性)。// 如果原始显示模式等于7,则表示是单色显示器。  if (ORIG_VIDEO_MODE == 7)	/* Is this a monochrome display? */    {      video_mem_start = 0xb0000;	// 设置单显映象内存起始地址。      video_port_reg = 0x3b4;	// 设置单显索引寄存器端口。      video_port_val = 0x3b5;	// 设置单显数据寄存器端口。// 根据BIOS 中断int 0x10 功能0x12 获得的显示模式信息,判断显示卡单色显示卡还是彩色显示卡。// 如果使用上述中断功能所得到的BX 寄存器返回值不等于0x10,则说明是EGA 卡。因此初始// 显示类型为EGA 单色;所使用映象内存末端地址为0xb8000;并置显示器描述字符串为'EGAm'。// 在系统初始化期间显示器描述字符串将显示在屏幕的右上角。      if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)	{	  video_type = VIDEO_TYPE_EGAM;	// 设置显示类型(EGA 单色)。	  video_mem_end = 0xb8000;	// 设置显示内存末端地址。	  display_desc = "EGAm";	// 设置显示描述字符串。	}// 如果BX 寄存器的值等于0x10,则说明是单色显示卡MDA。则设置相应参数。      else	{	  video_type = VIDEO_TYPE_MDA;	// 设置显示类型(MDA 单色)。	  video_mem_end = 0xb2000;	// 设置显示内存末端地址。	  display_desc = "*MDA";	// 设置显示描述字符串。	}    }// 如果显示模式不为7,则为彩色模式。此时所用的显示内存起始地址为0xb800;显示控制索引寄存// 器端口地址为0x3d4;数据寄存器端口地址为0x3d5。  else				/* If not, it is color. */    {      video_mem_start = 0xb8000;	// 显示内存起始地址。      video_port_reg = 0x3d4;	// 设置彩色显示索引寄存器端口。      video_port_val = 0x3d5;	// 设置彩色显示数据寄存器端口。// 再判断显示卡类别。如果BX 不等于0x10,则说明是EGA 显示卡。      if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)	{	  video_type = VIDEO_TYPE_EGAC;	// 设置显示类型(EGA 彩色)。	  video_mem_end = 0xbc000;	// 设置显示内存末端地址。	  display_desc = "EGAc";	// 设置显示描述字符串。	}// 如果BX 寄存器的值等于0x10,则说明是CGA 显示卡。则设置相应参数。      else	{	  video_type = VIDEO_TYPE_CGA;	// 设置显示类型(CGA)。	  video_mem_end = 0xba000;	// 设置显示内存末端地址。	  display_desc = "*CGA";	// 设置显示描述字符串。	}    }/* Let the user known what kind of display driver we are using *//* 让用户知道我们正在使用哪一类显示驱动程序 */// 在屏幕的右上角显示显示描述字符串。采用的方法是直接将字符串写到显示内存的相应位置处。// 首先将显示指针display_ptr 指到屏幕第一行右端差4 个字符处(每个字符需2 个字节,因此减8)。  display_ptr = ((char *) video_mem_start) + video_size_row - 8;// 然后循环复制字符串中的字符,并且每复制一个字符都空开一个属性字节。  while (*display_desc)    {      *display_ptr++ = *display_desc++;	// 复制字符。      display_ptr++;		// 空开属性字节位置。    }/* Initialize the variables used for scrolling (mostly EGA/VGA) *//* 初始化用于滚屏的变量(主要用于EGA/VGA) */  origin = video_mem_start;	// 滚屏起始显示内存地址。  scr_end = video_mem_start + video_num_lines * video_size_row;	// 滚屏结束内存地址。  top = 0;			// 最顶行号。  bottom = video_num_lines;	// 最底行号。  gotoxy (ORIG_X, ORIG_Y);	// 初始化光标位置x,y 和对应的内存位置pos。  set_trap_gate (0x21, &keyboard_interrupt);	// 设置键盘中断陷阱门。  outb_p (inb_p (0x21) & 0xfd, 0x21);	// 取消8259A 中对键盘中断的屏蔽,允许IRQ1。  a = inb_p (0x61);		// 延迟读取键盘端口0x61(8255A 端口PB)。  outb_p (a | 0x80, 0x61);	// 设置禁止键盘工作(位7 置位),  outb (a, 0x61);		// 再允许键盘工作,用以复位键盘操作。}/* from bsd-net-2: *///// 停止蜂鸣。// 复位8255A PB 端口的位1 和位0。voidsysbeepstop (void){/* disable counter 2 *//* 禁止定时器2 */  outb (inb_p (0x61) & 0xFC, 0x61);}int beepcount = 0;// 开通蜂鸣。// 8255A 芯片PB 端口的位1 用作扬声器的开门信号;位0 用作8253 定时器2 的门信号,该定时器的// 输出脉冲送往扬声器,作为扬声器发声的频率。因此要使扬声器蜂鸣,需要两步:首先开启PB 端口// 位1 和位0(置位),然后设置定时器发送一定的定时频率即可。static voidsysbeep (void){/* enable counter 2 *//* 开启定时器2 */  outb_p (inb_p (0x61) | 3, 0x61);/* set command for counter 2, 2 byte write *//* 送设置定时器2 命令 */  outb_p (0xB6, 0x43);/* send 0x637 for 750 HZ *//* 设置频率为750HZ,因此送定时值0x637 */  outb_p (0x37, 0x42);  outb (0x06, 0x42);/* 1/8 second *//* 蜂鸣时间为1/8 秒 */  beepcount = HZ / 8;}

⌨️ 快捷键说明

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