结构体、文字显示与GDT/IDT初始化
1. 接收启动信息
在上一章中,xsize和ysize的值都是直接赋值为320*200,但实际上我们需要从asmhead.nas先前保存下来的值中去。不然的话,当画面模式改变时系统就不能正确运行。所以试着用指针取得图像模式:
void HariMain(void)
{
char *vram;
int xsize, ysize;
short *binfo_scrnx, *binfo_scrny;
int *binfo_vram;
init_palette(); /*设定调色板*/
binfo_scrnx = (short *) 0x0ff4;
binfo_scrny = (short *) 0x0ff6;
binfo_vram = (int *) 0x0ff8;
xsize = *binfo_scrnx;
ysize = *binfo_scrny;
vram = (char *) *binfo_vram;
for(;;) {
io_hlt(); /*執行naskfunc里的_io_hlt*/
}
}
2/3. 结构体
可以看做结构体是将一堆变量集中声明,然后作为新的变量用于其他场合。
结构体的运用:
(1)先声明结构体:
struct BOOTINFO
{
char cyls, leds, vmode, reserve;
short scrnx, scrny;
char *varm;
};
(2)后定义结构体变量:
struct BOOTINFO abc;
或者定义结构体指针变量:
struct BOOTINFO *binfo;
这里binfo表示指针变量后应该首先给指针赋值,可写成:
Binfo = (struct BOOTINFP *)0x0ff0;
加上(struct BOOTINFP *)是对数字进行强制类型转换,告诉编译器这个数字是一个BOOTINFO类型的指针变量。
info指针指向地址0x0ff0是结构体的起始地址,结构体内的地址则依次按其类型增加。所以可以不用直接使用内存地址,而是使用*binfo来表示这个内存地址上12个字节的结构体。
在表示结构体内变量的时候,使用“.”表示:
xsize = (*binfo).scrnx;
因为binfo是指向结构体地址的指针变量,它表示其内部变量的形式很多,可以用箭头表示:
Xsieze = binfo->scrnx
,或者用binfo->scrnx
直接代替xsize
于是前面的代码可以简写为:
void HariMain(void)
{
struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;
init_palette(); /*设定调色板*/
init_screen(binfo->vram, binfo->scrnx, binfo->scrny);
for(;;) {
io_hlt(); /*執行naskfunc里的_io_hlt*/
}
}
注意:需要时=在主函数前面对init_screeen()函数进行声明:
void init_screen(char *vram, int x, int y);
然后在最后对该函数进行实现:
void init_screen(char *vram, int x, int y)
{
boxfill8(vram, x, COL8_008484, 0, 0, x - 1, y - 29);
boxfill8(vram, x, COL8_C6C6C6, 0, y - 28, x - 1, y - 28);
boxfill8(vram, x, COL8_FFFFFF, 0, y - 27, x - 1, y - 27);
boxfill8(vram, x, COL8_C6C6C6, 0, y - 26, x - 1, y - 1);
boxfill8(vram, x, COL8_FFFFFF, 3, y - 24, 59, y - 24);
boxfill8(vram, x, COL8_FFFFFF, 2, y - 24, 2, y - 4);
boxfill8(vram, x, COL8_848484, 3, y - 4, 59, y - 4);
boxfill8(vram, x, COL8_848484, 59, y - 23, 59, y - 5);
boxfill8(vram, x, COL8_000000, 2, y - 3, 59</