《30天自制操作系统》 04 C语言和画面显示的练习
04 C语言和画面显示的练习
原文中作者花了很大的力气讲解C语言的有关知识,这里就不多赘述了。。
1. 显示模式和显存
前一天的内容作者就将我们的操作系统的显示设置为VGA 320*200 8 位调色板
模式,8位意味着我们可以使用256种颜色,但本质上VGA还是RGB成色模式,需要3个字节表示一个完整的颜色,我们只能设置色号,就是一个8位数到24位颜色的映射,设置的方法后面介绍。
并且将显示的分辨率设置为320*200
,每一个像素都需要一个字节(8位)来表示颜色
此模式下显存的地址范围为0xa0000 -0xaffff
,但是一个像素存储一个字节只需要320*200
字节,但是显存范围是64K比存储像素的大一些,也不知是什么原因。。
2. 汇编实现内存写入
1 | _write_mem8: ; void write_mem8(int addr, int data); |
这里是32位模式所以我们使用的寄存器都是拓展寄存器,这里C语言编译器函数参数是从右到左压入栈,所以这里只是简单的把一个32位的数据写到指定的32位地址的内存中去
3. 色号设定
前面提到过我们的显示模式是VGA 8位调色板模式,需要自己对不同的256个颜色编号指定不同的颜色。作者使用了16种颜色来绘制他的操作系统,如下:
1 | static unsigned char table_rgb[16 * 3] = { |
同时作者提供了许多帮助写如端口的函数:
1 | void io_hlt(void); // 之前出现过的悬停CPU |
其汇编实现如下:
1 | ; naskfunc |
代码中右IN OUT
指令,这两个指令是CPU和其他输入输出设备交互的必备指令,IN
从指定端口读入数据,OUT
则是写数据,注意汇编中(C语言编译后)函数的返回值都是通过EAX寄存器
接下来要开始真正设置色号,VGA 调色板模式设置流程如下:
- 首先在一连串的访问中屏蔽中断(比如CLI) 。
- 将想要设定的调色板号码写入0x03c8, 紧接着, 按R, G, B的顺序写入 0x03c9。 如果还想继续设定下一个调色板, 则省略调色板号码, 再按照RGB的 顺序写入0x03c9就行了。
- 如果想要读出当前调色板的状态, 首先要将调色板的号码写入0x03c7, 再从 0x03c9读取3次。 读出的顺序就是R, G, B。 如果要继续读出下一个调色板, 同 样也是省略调色板号码的设定, 按RGB的顺序读出。
- 如果最初执行了CLI, 那么最后要执行STI
对应的C语言代码如下:
1 | void io_hlt(void); |
效果图如下:
3. 绘制矩形
画面坐标系都是左上坐标系(左上角为顶点),所以对于坐标(x,y)
我们只需要通过0xa0000 + x + y * 320
定为该坐标的对应地址,这么一来绘制矩形就简单多了
绘制矩形代码如下:
1 | /* |
效果图如下:
作者最后还绘制了一个简陋的界面都是通过绘制矩形实现这里就不多说了