昨天已经让画面显示黑屏了,但是黑屏太没意思,今天来让画面画点东西吧。
今天的任务还是比较有趣的,主要包括内存写入、画面显示条纹图案、设定色号、绘制矩形,最后制作一个进度条。
每个大标题下的代码,都在文末的资源里,可自行下载实验。
内存写入(harib01a)
想要在画面上画东西,只要往VRAM里写点东西就可以了。
那什么是VRAM呢?
上一篇的最后已经用到了VRAM,不过没有做详细的讲解。
VRAM指的是显卡内存(video RAM),就是可以用来显示画面的内存。这一块内存可以像内存一样存储数据,它的各个地址都对应着画面上的像素。我们可以利用这个机制在画面上绘制各种各样的图案。
VRAM分布在内存分布图好几个不同的地方,不同画面模式的像素不一样,切换不同的画面模式,会使用不同VRAM,即不同画面模式可以使用的内存也不一样,我们预先把要使用的VRAM地址保存在BOOT_INFO里。
我们先来创建一个直接写入指定内存地址的语句,修改一下naskfunc.nas:
_write_mem8: ; void write_mem8(int addr, int data);
MOV ECX,[ESP+4] ; [ESP+4]中存放的是地址,将其读入ECX
MOV AL,[ESP+8] ; [ESP+8]中存放的是数据,将其读入AL
MOV [ECX],AL
RET
这个函数类似于C语言中的“write_mem8(0x1234,0x56)”,汇编语言中的“MOV BYTE[0x1234],0x56”。
在naskfunc.nas开头增加了一行INSTRSET指令的语句,它用来告诉nask这个是给486型号的CPU用的。
[INSTRSET "i486p"] ;
汇编部分已经准备好了,下面来修改一下C语言吧,这次导入了变量,bootpack.c内容修改如下:
void io_hlt(void);
void write_mem8(int addr, int data);
void HariMain(void)
{
int i; /* 变量声明:i是一个32位整数 */
for (i = 0xa0000; i <= 0xaffff; i++) {
write_mem8(i, 15); /* MOV BYTE [i],15 */
}
for (;;) {
io_hlt();
}
}
下一步用make run命令生成 haribote.img,使用该映像文件启动,画面显示了白屏。
这里画面显示为什么是白屏呢?
因为VRAM全部都写入了15,这意味着全部像素颜色都是第15种颜色,而第15种颜色碰巧是纯白,所以画面就显示了白屏。