30天自制操作系统
上QQ阅读APP看书,第一时间看更新

5 增加字体(harib02e)

虽然字符“A”显示出来了,但这段程序只能显示“A”而不能显示别的字符。所以我们需要很多别的字体来显示其他字符。英文字母就有26个,分别有大写和小写,还有10个数字,再加上各种符号肯定超过30个了。啊,还有很多,太麻烦了,所以我们决定沿用OSASK的字体数据。当然,我们暂时还不考虑显示汉字什么的。这些复杂的东西,留待以后再做。现在我们集中精力解决字母显示的问题。

另外,这里沿用的OSASK的字体,其作者不是笔者,而是平木敬太郎先生和圣人(Kiyoto)先生。事先已经从他们那里得到了使用许可权,所以可以自由使用这种字体。

我们这次就将hankaku.txt这个文本文件加入到我们的源程序大家庭中来。这个文件的内容如下:

hankaku.txt的内容

char 0x41
........
...**...
...**...
...**...
...**...
..*..*..
..*..*..
..*..*..
..*..*..
.******.
.*....*.
.*....*.
.*....*.
***..***
........
........

这比十六进制数和只有0和1的二进制数都容易看一些。

■■■■■

当然,这既不是C语言,也不是汇编语言,所以需要专用的编译器。新做一个编译器很麻烦,所以我们还是使用在制作OSASK时曾经用过的工具(makefont.exe)。说是编译器,其实有点言过其实了,只不过是将上面这样的文本文件(256个字符的字体文件)读进来,然后输出成16×256=4096字节的文件而已。

编译后生成hankaku.bin文件,但仅有这个文件还不能与bootpack.obj连接,因为它不是目标(obj)文件。所以,还要加上连接所必需的接口信息,将它变成目标文件。这项工作由bin2obj.exe来完成。它的功能是将所给的文件自动转换成目标程序,就像将源程序转换成汇编那样。也就是说,好像将下面这两行程序编译成了汇编:

_hankanku:
    DB各种数据(共4096字节)

当然,如果大家不喜欢现在这种字体的话,可以随便修改hankaku.txt。本书的中心任务是自制操作系统,所以字体就由大家自己制作了。

各种工具的使用方法,请参阅Makefile的内容。因为不是很难,这里就不再说明了。

如果在C语言中使用这种字体数据,只需要写上以下语句就可以了。

extern char hankaku[4096];

像这种在源程序以外准备的数据,都需要加上extern属性。这样,C编译器就能够知道它是外部数据,并在编译时做出相应调整。

■■■■■

OSASK的字体数据,依照一般的ASCII字符编码,含有256个字符。A的字符编码是0x41,所以A的字体数据,放在自“hankaku+0x41 * 16”开始的16字节里。C语言中A的字符编码可以用’A’来表示,正好可以用它来代替0x41,所以也可以写成“hankaku +‘A' * 16”。

我们使用以上字体数据,向bootpack.c里添加了很多内容,请大家浏览一下。如果顺利的话,会显示出“ABC 123”。下面就来“make run”一下吧。很好,运行正常。

本次的HariMain的内容

void HariMain(void)
{
    struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;
    extern char hankaku[4096];

    init_palette();
    init_screen(binfo->vram, binfo->scrnx, binfo->scrny);
    putfont8(binfo->vram, binfo->scrnx, 8, 8, COL8_FFFFFF, hankaku + 'A' * 16);
    putfont8(binfo->vram, binfo->scrnx, 16, 8, COL8_FFFFFF, hankaku + 'B' * 16);
    putfont8(binfo->vram, binfo->scrnx, 24, 8, COL8_FFFFFF, hankaku + 'C' * 16);
    putfont8(binfo->vram, binfo->scrnx, 40, 8, COL8_FFFFFF, hankaku + '1' * 16);
    putfont8(binfo->vram, binfo->scrnx, 48, 8, COL8_FFFFFF, hankaku + '2' * 16);
    putfont8(binfo->vram, binfo->scrnx, 56, 8, COL8_FFFFFF, hankaku + '3' * 16);

    for (; ; ) {
    }
        io_hlt();
}