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

📄 屏幕显示.htm

📁 现在我们将试着在屏幕上显示点东西。为此
💻 HTM
📖 第 1 页 / 共 2 页
字号:
如果你需要的话,我已经编写了settextcolor函数来设置字符的颜色。 </FONT></P>
<TABLE id=table3 style="BORDER-COLLAPSE: collapse" width="100%" border=1>
  <TBODY>
  <TR>
    <TD><FONT face=Tahoma color=#800000 size=2>#include &lt; system.h 
      &gt;<BR><BR>/* 这些内容定义了我们的文字指针,背景和前景颜色(属性),和xy坐标。 */<BR>unsigned short 
      *textmemptr;<BR>int attrib = 0x0F;<BR>int csr_x = 0, csr_y = 0;<BR><BR>/* 
      滚动屏幕 */<BR>void scroll(void)<BR>{<BR>&nbsp;&nbsp;&nbsp; unsigned blank, 
      temp;<BR><BR>&nbsp;&nbsp;&nbsp; /* 把空格定义为空白字符...我们也要设置他的背景颜色 
      */<BR>&nbsp;&nbsp;&nbsp; blank = 0x20 | (attrib &lt;&lt; 
      8);<BR><BR>&nbsp;&nbsp;&nbsp; /*&nbsp; 25行是结尾,也就是说,我们要把它滚动上去 
      */<BR>&nbsp;&nbsp;&nbsp; if(csr_y &gt;= 25)<BR>&nbsp;&nbsp;&nbsp; 
      {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 把当前的字符块向上移动一行 
      */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = csr_y - 25 + 
      1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (textmemptr, 
      textmemptr + temp * 80, (25 - temp) * 80 * 
      2);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 
      最后,我们把最后一行设置为我们定义的空白字符。 */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      memsetw (textmemptr + (25 - temp) * 80, blank, 
      80);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csr_y = 25 - 
      1;<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR><BR>/* 更新硬件光标: 在输入的字符之后的那一行上显示一个闪烁。 
      */<BR>void move_csr(void)<BR>{<BR>&nbsp;&nbsp;&nbsp; unsigned 
      temp;<BR><BR>&nbsp;&nbsp;&nbsp; /* 
      在线性的内存块中找到索引的公式。表示为:<BR>&nbsp;&nbsp;&nbsp; *&nbsp; Index = [(y * width) + 
      x] */<BR>&nbsp;&nbsp;&nbsp; temp = csr_y * 80 + csr_x;<BR><BR>/* 
      向VGA控制器的CRT控制寄存器发送14和15标志。<BR>*&nbsp; 
      他们是索引字符的高位和低位,这个字符显示在硬件光标的闪烁处。<BR>*&nbsp; 
      想知道更多细节,你可以查看VGA规范的编程文档。一个相当好的文档在<BR>*&nbsp; 
      http://www.brackeen.com/home/vga */<BR>&nbsp;&nbsp;&nbsp; outportb(0x3D4, 
      14);<BR>&nbsp;&nbsp;&nbsp; outportb(0x3D5, temp &gt;&gt; 
      8);<BR>&nbsp;&nbsp;&nbsp; outportb(0x3D4, 15);<BR>&nbsp;&nbsp;&nbsp; 
      outportb(0x3D5, temp);<BR>}<BR><BR>/* 清空屏幕 */<BR>void 
      cls()<BR>{<BR>&nbsp;&nbsp;&nbsp; unsigned blank;<BR>&nbsp;&nbsp;&nbsp; int 
      i;<BR><BR>&nbsp;&nbsp;&nbsp; /* 同样的,我们需要一个用来做空白的'short'颜色 
      */<BR>&nbsp;&nbsp;&nbsp; blank = 0x20 | (attrib &lt;&lt; 
      8);<BR><BR>&nbsp;&nbsp;&nbsp; /* 用带有空白颜色的空白画满整个屏幕 */<BR>&nbsp;&nbsp;&nbsp; 
      for(i = 0; i &lt; 25; i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      memsetw (textmemptr + i * 80, blank, 80);<BR><BR>&nbsp;&nbsp;&nbsp; /* 
      更新我们的虚拟光标,然后移动物理光标 */<BR>&nbsp;&nbsp;&nbsp; csr_x = 
      0;<BR>&nbsp;&nbsp;&nbsp; csr_y = 0;<BR>&nbsp;&nbsp;&nbsp; 
      move_csr();<BR>}<BR><BR>/* 在屏幕上显示单个字符 */<BR>void putch(unsigned char 
      c)<BR>{<BR>&nbsp;&nbsp;&nbsp; unsigned short *where;<BR>&nbsp;&nbsp;&nbsp; 
      unsigned att = attrib &lt;&lt; 8;<BR><BR>&nbsp;&nbsp;&nbsp; /* 
      处理退格时,把光标向前一动一格 */<BR>&nbsp;&nbsp;&nbsp; if(c == 
      0x08)<BR>&nbsp;&nbsp;&nbsp; 
      {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(csr_x != 0) 
      csr_x--;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; /* 
      处理一个跳格时,增加光标的x值,但只移动到可以被8整除的位置上。 */<BR>&nbsp;&nbsp;&nbsp; else if(c == 
      0x09)<BR>&nbsp;&nbsp;&nbsp; 
      {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csr_x = (csr_x + 8) &amp; 
      ~(8 - 1);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; /* 处理一个回车, 
      直接把光标放回到最前面 */<BR>&nbsp;&nbsp;&nbsp; else if(c == 
      '\r')<BR>&nbsp;&nbsp;&nbsp; 
      {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csr_x = 
      0;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; /* 
      我们用DOS和BIOS的方法来处理新换行:我们把CR看作和换行一同出现。<BR>&nbsp;&nbsp;&nbsp; * 
      我们把x放到最前面,然后增加y值 */<BR>&nbsp;&nbsp;&nbsp; else if(c == 
      '\n')<BR>&nbsp;&nbsp;&nbsp; 
      {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csr_x = 
      0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      csr_y++;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; /* 
      任何比空格大的字符都是可以被打印出来的,包括空格本身。<BR>&nbsp;&nbsp;&nbsp; *&nbsp; 
      用来从线性的内存快中找出索引的公式表示为:<BR>&nbsp;&nbsp;&nbsp; *&nbsp; Index = [(y * width) + 
      x] */<BR>&nbsp;&nbsp;&nbsp; else if(c &gt;= ' ')<BR>&nbsp;&nbsp;&nbsp; 
      {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where = textmemptr + 
      (csr_y * 80 + csr_x);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *where 
      = c | att; /* 字符 AND 属性: 颜色 
      */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      csr_x++;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; /* 
      如果光标到达了屏幕宽度的边缘,我们就插入另一行 */<BR>&nbsp;&nbsp;&nbsp; if(csr_x &gt;= 
      80)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      csr_x = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      csr_y++;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; /* 
      如果需要的话,滚动屏幕,并移动光标 */<BR>&nbsp;&nbsp;&nbsp; scroll();<BR>&nbsp;&nbsp;&nbsp; 
      move_csr();<BR>}<BR><BR>/* 使用以上的方法,输出一个字符串 */<BR>void puts(unsigned char 
      *text)<BR>{<BR>&nbsp;&nbsp;&nbsp; int i;<BR><BR>&nbsp;&nbsp;&nbsp; for (i 
      = 0; i &lt; strlen(text); i++)<BR>&nbsp;&nbsp;&nbsp; 
      {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      putch(text[i]);<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR><BR>/* 设置我们要用的前景色和背景色 
      */<BR>void settextcolor(unsigned char forecolor, unsigned char 
      backcolor)<BR>{<BR>&nbsp;&nbsp;&nbsp; /* 上面的4位是背景色,下面的4位是前景色 
      */<BR>&nbsp;&nbsp;&nbsp; attrib = (backcolor &lt;&lt; 4) | (forecolor 
      &amp; 0x0F)<BR>}<BR><BR>/* 设置我们的字符模式VGA指针,然后清空屏幕,以备后用 */<BR>void 
      init_video(void)<BR>{<BR>&nbsp;&nbsp;&nbsp; textmemptr = (unsigned short 
      *)0xB8000;<BR>&nbsp;&nbsp;&nbsp; cls();<BR>}</FONT></TD></TR>
  <TR>
    <TD><B><FONT face=Tahoma size=2>屏幕显示: 
'scrn.c'</FONT></B></TD></TR></TBODY></TABLE>
<P><FONT face=Tahoma>接下去,我们可以把这个文件编译进我们的内核。因此,你需要编辑 'build.bat' 
,可以在里面增加一条新的gcc编译命令。复制'main.c'那一行的内容,并在它的下面粘贴一下。在这一行里,把'main'改成'scrn'就行了。 
同样,别忘记在LD命令时增加一个'scrn.o'文件。在main使用这些函数之前,需要在'system.h'文件里,增加putch, puts, cls, 
init_video, 和 settextcolor的函数声明。 因为这些是函数声明,别忘记加上'extern'关键字和分号。 </FONT></P>
<TABLE id=table4 style="BORDER-COLLAPSE: collapse" width="100%" border=1>
  <TBODY>
  <TR>
    <TD><FONT face=Tahoma color=#800000 size=2>extern void cls();<BR>extern 
      void putch(unsigned char c);<BR>extern void puts(unsigned char 
      *str);<BR>extern void settextcolor(unsigned char forecolor, unsigned char 
      backcolor);<BR>extern void init_video();</FONT></TD></TR>
  <TR>
    <TD><B><FONT face=Tahoma size=2>把这些都加入到 
      'system.h'中,这样我们就能在'main.c'里面调用这些函数了。</FONT></B></TD></TR></TBODY></TABLE>
<P><FONT 
face=Tahoma>现在,我们就可以安心地在main函数里使用我们新的屏幕显示函数了。打开'main.c'增加一行init_video(),然后,向puts函数中传递一个字符串:puts("Hello 
World!"); 最后,保存一下文件,双击 'build.bat'来编译你的内核,调试以下语法错误。 
把生成的'kernel.bin'复制到GRUB磁盘上,如果一切都正常的话,你的内核将会在黑色的屏幕上显示一句白色的 'Hello World!' ! 
</FONT></P>
<TABLE cols=200 width="100%">
  <TBODY>
  <TR>
    <TD align=left width=200><FONT face=Tahoma><A 
      href="http://rammaker.cosoft.org.cn/store/bkerndev_zh_CN_beta/Docs/creatingmain.htm">&lt;&lt; 
      C代码 和 main()</A> </FONT></TD>
    <TD align=middle width=*><FONT face=Tahoma><A 
      href="mailto:friesenb@gmail.com">联系 Brandon F.</A> </FONT></TD>
    <TD align=right width=200><FONT face=Tahoma><A 
      href="http://rammaker.cosoft.org.cn/store/bkerndev_zh_CN_beta/Docs/gdt.htm">全局描述表(GDT) 
      &gt;&gt;</A> </FONT></TD></TR></TBODY></TABLE></BODY></HTML>

⌨️ 快捷键说明

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