关闭

30天自制操作系统------图形处理相关

标签: 操作系统
80人阅读 评论(0) 收藏 举报
分类:

一、编写malloc

每个应用程序至少都需要一个窗口,窗口的内容需要保存在一块内存中,我们原来的做法是使用固定大小的数组如buf[320*200],然后往里面填写东西,但是这样子的后果就是应用程序的.hrb文件比较大,使用二进制文件打开.hrb文件发现里面有很多“00”。原因就是数组的声明就相当于汇编中的RESB指令,在内存中给为数组预留出了数组所需要的空间。

为了减小.hrb的大小,我们需要编写malloc函数,虽然说以前已经有一个memman_alloc函数,但是因为memman_alloc函数分配的内存空间并不位于应用程序的数据段范围内,所以我们需要编写一个为应用程序分配内存空间的API函数,然后将malloc的内存空间的首地址写到.hrb文件当中去,这样就可以有效减少.hrb文件的大小。

malloc函数若想要实现分配内存的功能,那么操作系统就需要提前给应用程序预留一定大小的空间用于malloc,因为应用程序所需要的内存空间无法预测,最好的做法是用于给malloc函数分配的内存空间可以调整大小,但是在我们自制的操作系统中没有实现这样的功能,只能给malloc函数预留一定大小的空间,这也算是一个需要优化的地方。

当然malloc函数还是需要对应的free函数。

 

编写API函数malloc的思路:

(1)使用memman_init函数初始化一个memman,参数中的地址要写应用程序段的地址;

(2)使用memman_free函数释放空间,为应用程序的malloc预留这段空间;

(3)使用memman_alloc函数为应用程序分配空间;

(4)应用程序结束时使用memman_free函数释放空间。

     虽然memman_initmemman_allocmemman_free这几个函数都只能在操作环境下使用,但是还是可以通过API的方式来进行调用。

 

二、画点/画线

每个任务都要有个窗口,也就是说每个任务都要有占用一个图层,想要在任务的界面上显示一些内容,只需要在对应的图层的buf中填写相应的内容,然后刷新图层即可。图层SHEET

的定义如下:

struct SHEET
{
	unsigned char *buf;  /*用来记录图层上所描画内容的地址*/
	int xsize,ysize,x,y,color,height,flags;
	struct SHTCTL *ctl;	
}; 

 (1)若要在窗口上显示一个点,那么就在对应图层的buf中修改一个单元的内容即可。

 2)若要在窗口上显示多个点,那么就在对应图层的buf中修改多个单元的内容即可。

 3)点动成线,可以画点就可以画线,两点确定一条直线,只要确定了线的起点坐标和终点坐标,就可以画出这条线。

画线的思路:

设起点(x0,y0 终点(x1,y1

         ①求横纵坐标的差值:dx=x1-x0 ,dy=y1-y0

         ②求横纵坐标差值的绝对值:dx=|dx|,dy=|dy|

         ③比较dxdy,确定点的个数len

        a.dx>=dylen=dx+1dx=1dy=dy/len,若x0<x1dx=-dx,若y0<y1dy=-dy

        b.dx<dylen=dy+1dy=1dx=dx/len,若x0<x1dx=-dx,若y0<y1dy=-dy

         ④ x=x0y=y0  

     按如下方式画len个点:画点(x,y),x+=dxy+=dy


三、关闭窗口

    应用程序结束之后其窗口应该关闭,一直留在桌面也不好看。

应用程序的窗口都对应一个图层,要想关闭应用程序的窗口,只需要将其所对应的图层的内存所释放即可,之前编写sheet.c时就有一个实现此功能的函数sheet_free(),我们只需要在API函数api_closewin中调用该函数即可。

想要实现按下某个键任务窗口关闭的功能,我们需要API实现如下功能get_key(),返回值为按键编码:

我们使用汇编语言编写该函数,在该函数中使用INT 0x40调用API,所以获取按键编码的工作实际上是hrb_api函数完成的。

hrb_api函数为该功能分配的功能号为1515号功能的工作原理如下

   1)改造TASK的结构,为其增加一个FIFO成员,如下:

    

struct TASK
{
	int sel,flags;  /*sel用来存放GDT的编号*/
	int level;
	int priority;	/*优先级*/
	struct FIFO fifo;
	struct TSS tss;
};

   2)让TASKFIFO来接收数据

   3)若FIFO为空,任务休眠

   4)若FIFO不为空,取出FIFO中的数据,对不同的数据做出不同的处理,若是键盘输入的数据,将按键编码返回,作为get_key()函数的返回值。

按照以上思路来编写应用程序时,程序结束之前会进入死循环,每次都判断get_key()的结果,判断它是否是我们指定的按键编码,若是则跳出循环,关闭窗口。

 

 

四、强制结束并关闭窗口

第三部分解决的是正常关闭窗口的思路,但是在强制结束任务时,窗口还是不会关闭。应用程序时在cmd_app函数中通过start_app来启动的,当应用程序执行完毕之后或者被强制结束后都会返回到cmd_app中执行start_app后的程序,利用这一点,我们可以在start_app调用结束后,释放任务对应的图层所使用的空间。

为了能将TASKSHEET对应,我们在SHEET中又添加了TASK成员,添加之后的SHEET结构如下:

 

struct SHEET
{
	unsigned char *buf;  /*用来记录图层上所描画内容的地址*/
	int xsize,ysize,x,y,color,height,flags;
	struct SHTCTL *ctl;
	struct TASK *task; /*该图层的任务*/ 
}; 

在生成新的窗口时将对应的图层和任务进行绑定,在结束任务时,将任务对应的图层的内存进行释放即可。



0
0

猜你在找
【直播】机器学习&深度学习系统实战(唐宇迪)
【直播】Kaggle 神器:XGBoost 从基础到实战(冒教授)
【直播回放】深度学习基础与TensorFlow实践(王琛)
【直播】计算机视觉原理及实战(屈教授)
【直播】机器学习之凸优化(马博士)
【直播】机器学习之矩阵(黄博士)
【直播】机器学习之概率与统计推断(冒教授)
【直播】机器学习之数学基础
【直播】TensorFlow实战进阶(智亮)
【直播】深度学习30天系统实训(唐宇迪)
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:296次
    • 积分:60
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档