`
923723914
  • 浏览: 632390 次
文章分类
社区版块
存档分类
最新评论

《30天自制操作系统》之——第05天

 
阅读更多
1.优化第4天代码:
在第四天的bootpack.c中绘制界面部分,都是将一些数字直接写入程序,这样的程序是没法维护的。所以第五天首先把这些数字用变量代替,后期更改需要更改的时候只需更改一处即可。再者,这些出现数字的地方主要是一些显存的设置,所以索性将它们放到结构体里面。
如下:
struct BOOTINFO{
	char cyls, leds, vmode, reserve;
	short scrnx, scrny;
	char *vram;
}

结构体中的变量和之前在asmhead.nas中设置的是对应的,如下:
CYLS	EQU	0x0ff0			; 设定启动区
LEDS	EQU 	0x0ff1
VMODE	EQU	0x0ff2			; 关于颜色数目的信息。颜色的位数
SCRNX	EQU	0x0ff4			; 分辨率的X(screen x)
SCRNY	EQU	0x0ff6			; 分辨率的Y(screen y)
VRAM	EQU 	0x0ff8			; 图像缓冲区的开始地址
接下来创建并初始化一个结构体指针,即可完成所有结构体内部变量的初始化,如下:
struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;

这条语句执行完以后:
binfo->cyls 的值为 0x0ff0
binfo->leds 的值为 0x0ff1
	...
2.显示字符、字符串、鼠标指针:

不管是显示字符还是字符串还是鼠标指针,原理都是一样的,就是往显存的特定地方写特定的值(颜色信息)

void putfont8(char *vram, int xsize, int x, int y, char c, char *font) //显示hankaku中的某一个字符
{
	int i; 
	char *p,d;
	
	for(i = 0; i < 16; i++)
	{
		p = vram + (y + i) * xsize + x;
		d = font[i];
		if((d & 0x80) != 0) { p[0] = c; }
		if((d & 0x40) != 0) { p[1] = c; }
		if((d & 0x20) != 0) { p[2] = c; }
		if((d & 0x10) != 0) { p[3] = c; }
		if((d & 0x08) != 0) { p[4] = c; }
		if((d & 0x04) != 0) { p[5] = c; }
		if((d & 0x02) != 0) { p[6] = c; }
		if((d & 0x01) != 0) { p[7] = c; }
	}
}

void putfont8_str(char *vram, int xsize, int x, int y, char c, unsigned char *s) //显示字符串s
{
	extern char hankaku[4096];
	
	for(; *s != 0x00; s++)
	{
		putfont8(vram, xsize, x, y, c, hankaku + *s * 16);
		x += 8;
	}
}

3.字库文件的连接

字库文件是一个txt文件,需要通过一些工具把他编译,连接到我们的程序中。makefile文件中的依赖关系,如下图


4.GDT与IDT的初始化

GDT: Global(segment) Descriptor Table 全局段号记录表.
IDT: Interrput Descriptor Table 中断记录表

1)为了解决内存范围重叠使用的问题,需要对内存进行分段(即对GDT进行初始化)。分段以后,即使两个程序
要同时访问内存地址0xa000,只要不在同一段,就不会产生冲突。


2)IDT记录了0~255的中断号码与调用函数的对应关系。

最终效果:


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics