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(); }