📄 屏幕显示.htm
字号:
如果你需要的话,我已经编写了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 < system.h
><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> unsigned blank,
temp;<BR><BR> /* 把空格定义为空白字符...我们也要设置他的背景颜色
*/<BR> blank = 0x20 | (attrib <<
8);<BR><BR> /* 25行是结尾,也就是说,我们要把它滚动上去
*/<BR> if(csr_y >= 25)<BR>
{<BR> /* 把当前的字符块向上移动一行
*/<BR> temp = csr_y - 25 +
1;<BR> memcpy (textmemptr,
textmemptr + temp * 80, (25 - temp) * 80 *
2);<BR><BR> /*
最后,我们把最后一行设置为我们定义的空白字符。 */<BR>
memsetw (textmemptr + (25 - temp) * 80, blank,
80);<BR> csr_y = 25 -
1;<BR> }<BR>}<BR><BR>/* 更新硬件光标: 在输入的字符之后的那一行上显示一个闪烁。
*/<BR>void move_csr(void)<BR>{<BR> unsigned
temp;<BR><BR> /*
在线性的内存块中找到索引的公式。表示为:<BR> * Index = [(y * width) +
x] */<BR> temp = csr_y * 80 + csr_x;<BR><BR>/*
向VGA控制器的CRT控制寄存器发送14和15标志。<BR>*
他们是索引字符的高位和低位,这个字符显示在硬件光标的闪烁处。<BR>*
想知道更多细节,你可以查看VGA规范的编程文档。一个相当好的文档在<BR>*
http://www.brackeen.com/home/vga */<BR> outportb(0x3D4,
14);<BR> outportb(0x3D5, temp >>
8);<BR> outportb(0x3D4, 15);<BR>
outportb(0x3D5, temp);<BR>}<BR><BR>/* 清空屏幕 */<BR>void
cls()<BR>{<BR> unsigned blank;<BR> int
i;<BR><BR> /* 同样的,我们需要一个用来做空白的'short'颜色
*/<BR> blank = 0x20 | (attrib <<
8);<BR><BR> /* 用带有空白颜色的空白画满整个屏幕 */<BR>
for(i = 0; i < 25; i++)<BR>
memsetw (textmemptr + i * 80, blank, 80);<BR><BR> /*
更新我们的虚拟光标,然后移动物理光标 */<BR> csr_x =
0;<BR> csr_y = 0;<BR>
move_csr();<BR>}<BR><BR>/* 在屏幕上显示单个字符 */<BR>void putch(unsigned char
c)<BR>{<BR> unsigned short *where;<BR>
unsigned att = attrib << 8;<BR><BR> /*
处理退格时,把光标向前一动一格 */<BR> if(c ==
0x08)<BR>
{<BR> if(csr_x != 0)
csr_x--;<BR> }<BR> /*
处理一个跳格时,增加光标的x值,但只移动到可以被8整除的位置上。 */<BR> else if(c ==
0x09)<BR>
{<BR> csr_x = (csr_x + 8) &
~(8 - 1);<BR> }<BR> /* 处理一个回车,
直接把光标放回到最前面 */<BR> else if(c ==
'\r')<BR>
{<BR> csr_x =
0;<BR> }<BR> /*
我们用DOS和BIOS的方法来处理新换行:我们把CR看作和换行一同出现。<BR> *
我们把x放到最前面,然后增加y值 */<BR> else if(c ==
'\n')<BR>
{<BR> csr_x =
0;<BR>
csr_y++;<BR> }<BR> /*
任何比空格大的字符都是可以被打印出来的,包括空格本身。<BR> *
用来从线性的内存快中找出索引的公式表示为:<BR> * Index = [(y * width) +
x] */<BR> else if(c >= ' ')<BR>
{<BR> where = textmemptr +
(csr_y * 80 + csr_x);<BR> *where
= c | att; /* 字符 AND 属性: 颜色
*/<BR>
csr_x++;<BR> }<BR><BR> /*
如果光标到达了屏幕宽度的边缘,我们就插入另一行 */<BR> if(csr_x >=
80)<BR> {<BR>
csr_x = 0;<BR>
csr_y++;<BR> }<BR><BR> /*
如果需要的话,滚动屏幕,并移动光标 */<BR> scroll();<BR>
move_csr();<BR>}<BR><BR>/* 使用以上的方法,输出一个字符串 */<BR>void puts(unsigned char
*text)<BR>{<BR> int i;<BR><BR> for (i
= 0; i < strlen(text); i++)<BR>
{<BR>
putch(text[i]);<BR> }<BR>}<BR><BR>/* 设置我们要用的前景色和背景色
*/<BR>void settextcolor(unsigned char forecolor, unsigned char
backcolor)<BR>{<BR> /* 上面的4位是背景色,下面的4位是前景色
*/<BR> attrib = (backcolor << 4) | (forecolor
& 0x0F)<BR>}<BR><BR>/* 设置我们的字符模式VGA指针,然后清空屏幕,以备后用 */<BR>void
init_video(void)<BR>{<BR> textmemptr = (unsigned short
*)0xB8000;<BR> 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"><<
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)
>></A> </FONT></TD></TR></TBODY></TABLE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -