自制操作系统日志——第十四天

自制操作系统日志——第十四天

今天主要的任务是给我们的分辨率升升级!然后,将继续开发出一个输入栏,以供我们随意的进行输入并删除数据。



前言

在前面几天呢,我们总是能看到我们再进行不断的优化代码,不断的加快一下中断的执行速度!这一些如此细微的改动,也许我们可能会觉得没什么必要。但是,要知道随着我们后面不断的开发,以及多任务下更多程序的介入,我们之前所作的一些优化的效果将会越来越重要。就比如,我们对于中断速度的优化,在后期当同时一很多中断发生时,这些优化后精进的速度,将会使得我们系统的反应能力大幅度的提高!!!

接着,我们已经大约度过了两周的时间了!!前两周我们对于开发操作系统所需的编程语言的学习呀,算法技巧的学习呀等等都已经大致的学完了。那么,此后就可以好好的利用其前面所学的继续我们的完善之路。然后,就是说前面13天的内容也是十分的重要且有意义的,希望我能够继续好好的多品味品味!!!


一、提高分辨率

在这之前我们使用的显卡模式主要是VGA模式,其分辨率主要是320x200x8的模式!!那么这一个分辨率明显是有所不足的!因此啊,下面我们将利用VBE模式下进行设置!

首先,VBE是多家显卡公司一起协商制定的统一显卡的设定标准。他们专门的制作了一个BIOS进行设定,以此来解决不同显卡设定、接口不同的问题。因此,以下我可能会使用VBE2.0以上的BIOS显卡设定,如果真机(vmware)不支持此类设定的话,那就只能继续使用VGA显卡了!

非VBE画面模式的设定:
AH=0; 调用0号子中断程序
AL = 画面模式号码

VBE画面模式的设定:
AX = 0x4f02
BX = 画面模式的设定
画面模式设定信息:
0x101 ⇒ 640x480x8
0x103 ⇒ 800x600x8
0x105 ⇒ 1024x768x8
0x107 ⇒ 1280x1024x8
在实际设定时一般还要加上0x4000后再赋值到bx中。
画面模式的存储信息内容:
word [es:di + 0x00] ⇒ 模式属性 …其中存储的bit7(第七位)上如果是1 则代表可以加上0x4000后进行传入!!!
word [es:di + 0x12] ⇒ x的分辨率
word [es:di + 0x14] ⇒ y的分辨率
byte [es:di + 0x19] ⇒ 颜色数…必须是8
byte [es:di + 0x1b] ⇒ 颜色指定方法,必须是4 (4 指调色板模式)
dword [es:di + 0x12] ⇒ VRAM地址
其中,es的段地址应该是:0x9000
那么以下,就让我们开始修改asmhead.nas:

我们主要做如下的工作:以下所采用中断后,读取的信息都会存入到90000:0000之中!

  1. 确认VBE是否存在,通过调用int 0x10 以及利用ax值是否改变进行确认;
  2. 确认版本,通过读取1中存取的信息来进行比较;
  3. 读取画面模式,并存入对应的内存之中;
  4. 进行画面模式的确认,确认颜色数是否为8,是否为调色版模式,是否模式属性的bit7位置上是1;
  5. 进行画面的切换;
  6. 如果以上有一个不行就跳转到此,恢复VGA 320x200x8模式
[INSTRSET "i486p"]

VBEMODE	EQU		0x105

  ORG 0xc200 ;程序最终被装载到内存的地址
    ;0x8000+0x4200=0xc2000;0x8000是内存存放软盘的地址,0x4200是软盘存放文件的地方

;确认VBE是否存在
    MOV AX,0x9000
	MOV ES,AX
	MOV DI,0
	MOV AX,0X4f00;有vbe的话值会自动编程0x004f
	INT 0x10  ;取得的数据也是放在es:di中
	CMP AX,0x004f
	JNE scrn320
;确认VBE版本,非2.0版本不能使用高分辨率
    MOV AX,[ES:DI+4]
	CMP AX,0x0200
	JB scrn320
;取得画面模式信息,这里的数据将会被放在es:di开始的256字节中
    MOV CX,VBEMODE
	MOV AX,0x4f01
	INT 0x10
	CMP AX,0x004f
	JNE scrn320
;画面模式信息确认
    CMP BYTE [ES:DI+0x19],8
	JNE scrn320
	CMP BYTE [ES:DI+0x1b],4
	JNE scrn320
	MOV AX,[ES:DI+0x00]
	AND AX,0x0080 
	JZ  scrn320
;画面模式切换
    MOV BX,VBEMODE+0x4000 
	mov AX,0x4f02 ;
    int 0x10
    mov byte [VMODE],8  ; 屏幕的模式(参考C语言的引用)
	MOV	AX,[ES:DI+0x12]
	MOV	[SCRNX],AX
	MOV	AX,[ES:DI+0x14]
	MOV	[SCRNY],AX
	MOV	EAX,[ES:DI+0x28]
	MOV	[VRAM],EAX
	JMP	keystatus

scrn320:
	MOV	AL,0x13			; VGA模式, 320x200
	MOV	AH,0x00
	INT	0x10
	MOV	BYTE [VMODE],8	; 记下画面模式,参考c
	MOV	WORD [SCRNX],320
	MOV	WORD [SCRNY],200
	MOV	DWORD [VRAM],0x000a0000
	
keystatus:
;用BIOS取得键盘上各种LED指示灯的状态
    mov ah,0x02 
    int 0x16 ;键盘BIOS
    mov [LEDS],al

然后,让我们make run一下看看!!
在这里插入图片描述
很棒,明显vmwar是支持的,那么至此我们就可以进入高分辨率的模式了!!!

二、增加键盘输入字符功能

1.输入单个字符

首先,我们打开该系统,可以发现再我们之前所作的设置里,当我们按下键盘的a时,按下是弹出1E,按起后弹出的就是9e。在书本里作者给我们罗列了很多按下键时的值。然后我们只需在此基础上+0x80就为按其后的值了!!

之所以会有两个值,也是因为方便告诉计算机:我按下了这个键,以及我松开了这个键。方便计算机知道什么时候开始,什么时候结束!!
在这里插入图片描述
然后,针对此我们进行更改一下主函数:

	if (fifo32_status(&fifo) == 0)
		{
			io_stihlt();
		}else 
		{ 
			i = fifo32_get(&fifo);
			io_sti();
			if (256 <= i && i <= 511) { /*键盘数据 */
				sprintf(s, "%02X", i - 256);
				putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);
				if( i == 0x1e + 256)
				{
					putfonts8_asc_sht(sht_win, 40, 28, COL8_000000, COL8_C6C6C6, "A", 1);
				}

在这里插入图片描述
哇哦,成功了!!

那么,继续再接再励,做一个输入框,然后可以任意输入数据并删除输入吧!!

2.输入框制作

根据上述的按下时的字符编码,我们在主函数中制作如下的数据:

   	static char keytable[0x54] = {
		0,   0,   '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0,   0,
		'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0,   0,   'A', 'S',
		'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0,   0,   ']', 'Z', 'X', 'C', 'V',
		'B', 'N', 'M', ',', '.', '/', 0,   '*', 0,   ' ', 0,   0,   0,   0,   0,   0,
		0,   0,   0,   0,   0,   0,   0,   '7', '8', '9', '-', '4', '5', '6', '+', '1',
		'2', '3', '0', '.'
	};

然后进一步的我们增加输入框以及实现输入删除的功能:(这其中涉及了光标的显示)

	int mx,my,i, cursor_x, cursor_c   ;make_textbox8(sht_win, 8, 28, 144, 16, COL8_FFFFFF);
	for(;;)   
	{
		io_cli(); //IF=0
		if (fifo32_status(&fifo) == 0)
		{
			io_stihlt();
		}else 
		{ 
			i = fifo32_get(&fifo);
			io_sti();
			if (256 <= i && i <= 511) { /*键盘数据 */
				sprintf(s, "%02X", i - 256);
				putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);
				if( i < 0x54 + 256)
				{
					if(keytable[i-256] != 0 && cursor_x < 144) //一般字符
					{//显示一个字符光标就向前移动一次
						s[0] = keytable[i-256];
						s[1] = 0;
						putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_C6C6C6, s, 1);
						cursor_x +=8;
					}
					if(i == 256 + 0x0e && cursor_x > 8) //退格键
					{//用空格把光标消去后移动一次
						putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1);
						cursor_x -=8;
					}
					//光标在显示
					boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
				    sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
				}

然后是输入框的代码:

//x0,y0是起始位置 ,sx是长度,sy是宽度
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c)
{
	int x1 = x0 + sx, y1 = y0 + sy;
	boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 2, y0 - 3, x1 + 1, y0 - 3);
	boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 3, y0 - 3, x0 - 3, y1 + 1);
	boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x0 - 3, y1 + 2, x1 + 1, y1 + 2);
	boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x1 + 2, y0 - 3, x1 + 2, y1 + 2);
	boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 1, y0 - 2, x1 + 0, y0 - 2);
	boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 2, y0 - 2, x0 - 2, y1 + 0);
	boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x0 - 2, y1 + 1, x1 + 0, y1 + 1);
	boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x1 + 1, y0 - 2, x1 + 1, y1 + 1);
	boxfill8(sht->buf, sht->bxsize, c,           x0 - 1, y0 - 1, x1 + 0, y1 + 0);
	return;
}

在这里插入图片描述

三、增加拖动窗口功能

这里我们先简单制作一个拖动窗口的功能,即按下鼠标左键就会显示窗口的位置!!

这里由于我们之前已经利用过图层来显示了,因此,这里的拖动,我们仅仅只需将图层位置和鼠标关联一下即可:

if (my > binfo->scrny - 1) {
						my = binfo->scrny - 1;
					}
					sprintf(s, "(%3d, %3d)", mx, my);
					putfonts8_asc_sht(sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 10);
					sheet_slide(sht_mouse, mx, my);
					if((mdec.btn & 0x01) != 0)//按下左键,移动窗口
					{
						sheet_slide(sht_win, mx - 80, my - 8);
					}

在这里插入图片描述


总结

以上就是我们今天进行内容,主要就是将分辨率进行了提高,然后还利用图层技术实现了简单的拖动功能!!!以及字符串的输入等等。

已经越来越像一个小型的操作系统了,继续努力加油!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值