《30天自制操作系统》读书笔记Day18
2013-10-27 15:26
316 查看
GitHub地址:https://github.com/scusjs/
1.控制光标闪烁
运行前面的系统发现不管当前的焦点在哪个窗口,两个窗口光标都在闪烁。。这算是一个bug吧。
对于A任务,当其不是焦点时,将其cursor_c设置为-1,则其不显示光标;是焦点时,重新设置为COL_00000000,然后重新显示光标的时候进行判断:
最后在光标用计时器中,将所有的光标变化加上判断语句:
if(cursor_c >= 0){}即可。
对于命令窗口,由于不能直接获得HariMain中是否显示光标的值,所以使用FIFO来实现。
将光标开始闪烁定义为2,停止闪烁定义为3:
接着修改console_task:
由于系统启动时任务A处于焦点状态,所以这里的cursor_c默认为-1
其他地方每次cursor_c变化时都判断一下if (cursor_c >= 0 ),并加上如下对cursor_c的操作:
运行即可。
2.对回车的支持
目前位置程序还不能识别回车的。要相应回车,只要识别出来并换行,并识别输入字符,如果是输入命令则执行。但是现在先实现换行即可。
修改HariMain,当回车被按下时向命令行发送10+256(自己定义,可以是其他值):
然后在console_task中创建变量cursor_y变量,当回车按下则加1行(16)即可:
并在所有对光标相关操作那里将28改为cursor_y即可(注意:需要将其他涉及到的数值更改,比如44改为cursor_y + 16)。
最后,实现滚屏操作。
当到达最后一行时,继续回车则所有像素上移一行,并将最后一行涂黑即可。
首先定义int型的x,y,用来对所有的像素进行上移操作,将回车键处理过程修改成如下:
3.mem命令
搞定滚屏,尝试实现第一个命令行的命令——mem。
首先,注释掉前面在屏幕上显示的一些系统基本信息。
然后在console_task中实现命令。
最后在HariMain中修改使memtotal参数传入console_task:
运行即可实现mem命令的输入与错误命令的识别。
4.cls(clear)命令
cls、clear命令分别是Windows、Linux平台下对命令行、终端进行清屏工作的命令。
这个命令实质上是把整个窗口涂黑,然后把cursor_y重置为28:
5.dir(ls)命令
dir、ls命令分别为Windows、Linux平台下列出目录下文件命令。
在day3中已经实现从磁盘读取10个柱面的内容,这些内容中存放文件的数据放在了0x002600以后的位置。
这里先考虑把dogged.sys、ipl10.nas、make.bat这三个文件放入磁盘中,修改Makefile:
make后可以从img文件中看到,在0x002600开始,显示的是32字节为单位的文件名,这32字节的结构如下:
如果文件名第一字节为0xe5,表示已经被删除
如果文件名第一字节为0x00,表示这一段不包含文件名信息
属性信息中:
接下来就是实现命令了:
1.控制光标闪烁
运行前面的系统发现不管当前的焦点在哪个窗口,两个窗口光标都在闪烁。。这算是一个bug吧。
对于A任务,当其不是焦点时,将其cursor_c设置为-1,则其不显示光标;是焦点时,重新设置为COL_00000000,然后重新显示光标的时候进行判断:
if (cursor_c >= 0 ) { boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43); }
最后在光标用计时器中,将所有的光标变化加上判断语句:
if(cursor_c >= 0){}即可。
对于命令窗口,由于不能直接获得HariMain中是否显示光标的值,所以使用FIFO来实现。
将光标开始闪烁定义为2,停止闪烁定义为3:
fifo32_put(&task_cons->fifo, 2);//命令行窗口光标ON fifo32_put(&task_cons->fifo, 3);//命令行窗口光标OFF
接着修改console_task:
由于系统启动时任务A处于焦点状态,所以这里的cursor_c默认为-1
其他地方每次cursor_c变化时都判断一下if (cursor_c >= 0 ),并加上如下对cursor_c的操作:
i = fifo32_get(&task->fifo); 。。。。。 if (i == 2)//光标ON { cursor_c = COL8_FFFFFF; } if (i == 3)//光标OFF { boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x, 28, cursor_x + 7, 43); cursor_c = -1; }
运行即可。
2.对回车的支持
目前位置程序还不能识别回车的。要相应回车,只要识别出来并换行,并识别输入字符,如果是输入命令则执行。但是现在先实现换行即可。
修改HariMain,当回车被按下时向命令行发送10+256(自己定义,可以是其他值):
if (i == 256 + 0x1c)//回车键 { if (key_to != 0) { fifo32_put(&task_cons->fifo, 10 + 256); } }
然后在console_task中创建变量cursor_y变量,当回车按下则加1行(16)即可:
else if (i == 10 + 256) //回车键 { if (cursor_y < 28 +112)//用空格擦除光标 { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_y += 16; //显示提示符 putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, ">", 1); cursor_x = 16; } }
并在所有对光标相关操作那里将28改为cursor_y即可(注意:需要将其他涉及到的数值更改,比如44改为cursor_y + 16)。
最后,实现滚屏操作。
当到达最后一行时,继续回车则所有像素上移一行,并将最后一行涂黑即可。
首先定义int型的x,y,用来对所有的像素进行上移操作,将回车键处理过程修改成如下:
else if (i == 10 + 256) //回车键 { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1);//用空格擦除光标 if (cursor_y < 28 +112) { cursor_y += 16; } else//滚屏 { for (y = 28; y < 28 + 128; y++) { for (x = 8; x < 8 + 240; x++) { sheet->buf[x + y * sheet->bxsize] = sheet->buf[x + (y + 16) * sheet->bxsize];//所有像素上移 } } for (y = 28 + 112; y < 28 + 128; y++) { for (x = 8; x < 8 + 240; x++) { sheet->buf[x + y * sheet->bxsize] = COL8_000000;//最后一行进行涂黑 } } sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); } //显示提示符 putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, ">", 1); cursor_x = 16; }
3.mem命令
搞定滚屏,尝试实现第一个命令行的命令——mem。
首先,注释掉前面在屏幕上显示的一些系统基本信息。
然后在console_task中实现命令。
void console_task(struct SHEET *sheet, unsigned int memtotal) { struct TIMER *timer; struct TASK *task = task_now(); int i, fifobuf[128], cursor_x = 16, cursor_c = -1,cursor_y = 28; char s[30],cmdline[30]; struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; int x,y; fifo32_init(&task->fifo, 128, fifobuf, task); timer = timer_alloc(); timer_init(timer, &task->fifo, 1); timer_settime(timer, 50); //显示提示符 putfonts8_asc_sht(sheet, 8, 28, COL8_FFFFFF, COL8_000000, ">", 1); for (;;) { io_cli(); if (fifo32_status(&task->fifo) == 0) { task_sleep(task); io_sti(); } else { i = fifo32_get(&task->fifo); io_sti(); if (i <= 1) { //光标用定时器 if (i != 0) { timer_init(timer, &task->fifo, 0); if (cursor_c >= 0) { cursor_c = COL8_FFFFFF; } } else { timer_init(timer, &task->fifo, 1); if (cursor_c >= 0) { cursor_c = COL8_000000; } } timer_settime(timer, 50); } if (i == 2)//光标ON { cursor_c = COL8_FFFFFF; } if (i == 3)//光标OFF { boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); cursor_c = -1; } if (256 <= i && i <=511)//键盘数据 { if (i == 8 + 256) //退格键 { if (cursor_x > 16) { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x -= 8; } } else if (i == 10 + 256) //回车键 { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1);//用空格擦除光标 cmdline[cursor_x /8 - 2] = 0; cursor_y = cons_newline(cursor_y, sheet); //执行命令 if (strcmp(cmdline, "mem") == 0) { sprintf(s, "total %dMB", memtotal / (1024 * 1024)); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); sprintf(s, "free %dKB", memman_total(memman) / 1024); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); cursor_y = cons_newline(cursor_y, sheet); } else if (cmdline[0] != 0)//错误命令 { putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "Bad command.", 12); cursor_y = cons_newline(cursor_y, sheet); cursor_y = cons_newline(cursor_y, sheet); } //显示提示符 putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, ">", 1); cursor_x = 16; } else { if (cursor_x < 240) { s[0] = i - 256; s[1] = 0; cmdline[cursor_x / 8 - 2] = i - 256; putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; } } } if (cursor_c >= 0) { boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); } sheet_refresh(sheet, cursor_x, cursor_y, cursor_x + 8, cursor_y + 16); } } } int cons_newline(int cursor_y, struct SHEET *sheet) /* 换行处理 */ { int x, y; if (cursor_y < 28 + 112) { cursor_y += 16; } else { //滚屏 for (y = 28; y < 28 + 112; y++) { for (x = 8; x < 8 + 240; x++) { sheet->buf[x + y * sheet->bxsize] = sheet->buf[x + (y + 16) * sheet->bxsize]; } } for (y = 28 + 112; y < 28 + 128; y++) { for (x = 8; x < 8 + 240; x++) { sheet->buf[x + y * sheet->bxsize] = COL8_000000; } } sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); } return cursor_y; }
最后在HariMain中修改使memtotal参数传入console_task:
task_cons->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 12; *((int *) (task_cons->tss.esp + 8)) = memtotal;
运行即可实现mem命令的输入与错误命令的识别。
4.cls(clear)命令
cls、clear命令分别是Windows、Linux平台下对命令行、终端进行清屏工作的命令。
这个命令实质上是把整个窗口涂黑,然后把cursor_y重置为28:
else if ((strcmp(cmdline, "cls") == 0) || (strcmp(cmdline, "clear") == 0)) { for (y = 28; y < 28 + 128; y ++) { for (x = 8; x < 8 + 240; x ++) { sheet->buf[x + y * sheet->bxsize] = COL8_000000; } } sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); cursor_y = 28; }
5.dir(ls)命令
dir、ls命令分别为Windows、Linux平台下列出目录下文件命令。
在day3中已经实现从磁盘读取10个柱面的内容,这些内容中存放文件的数据放在了0x002600以后的位置。
这里先考虑把dogged.sys、ipl10.nas、make.bat这三个文件放入磁盘中,修改Makefile:
dogged.img : ipl10.bin dogged.sys Makefile $(EDIMG) imgin:../z_tools/fdimg0at.tek \ wbinimg src:ipl10.bin len:512 from:0 to:0 \ copy from:dogged.sys to:@: \ copy from:ipl10.nas to:@: \ copy from:make.bat to:@: \ imgout:dogged.img
make后可以从img文件中看到,在0x002600开始,显示的是32字节为单位的文件名,这32字节的结构如下:
struct FILEINFO { unsigned char name[8],ext[3],type; char reserve[10]; unsigned short time,date,clustno; unsigned int size; };
如果文件名第一字节为0xe5,表示已经被删除
如果文件名第一字节为0x00,表示这一段不包含文件名信息
属性信息中:
0x01 只读文件 0x01 隐藏文件 0x04 系统文件 0x08 非文件信息 0x10 目录
接下来就是实现命令了:
struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600); 。。。 else if ((strcmp(cmdline, "dir") == 0) || (strcmp(cmdline, "ls") == 0)) { for (x = 0; x < 224; x++)//最多允许224个文件 { if (finfo[x].name[0] == 0x00) { break; } if (finfo[x].name[0] != 0xe5) { if ((finfo[x].type & 0x18) == 0) { sprintf(s, "filename.ext %7d", finfo[x].size); for (y = 0; y < 8; y++) { s[y] = finfo[x].name[y]; } s[9] = finfo[x].ext[0]; s[10] = finfo[x].ext[1]; s[11] = finfo[x].ext[2]; putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); } } } }
相关文章推荐
- 读书笔记《30天自制操作系统》day11
- 多定时器处理3(30天自制操作系统 -- 读书笔记)
- 读书笔记《30天自制操作系统》day02
- 读书笔记《30天自制操作系统》day03
- 《30天自制操作系统》读书笔记(4) 绘图
- 读书笔记《30天自制操作系统》day03
- 读书笔记《30天自制操作系统》day04
- 《30天自制操作系统》读书笔记Day5
- 【1】--《30天自制操作系统》读书笔记--0~3天
- 读书笔记《30天自制操作系统》day06
- 读书笔记《30天自制操作系统》day01
- 《30天自制操作系统》读书笔记Day17
- 读书笔记《30天自制操作系统》day05
- 读书笔记《30天自制操作系统》day02
- 读书笔记《30天自制操作系统》day06
- 读书笔记《30天自制操作系统》day14
- 读书笔记《30天自制操作系统》day02
- 读书笔记《30天自制操作系统》day07
- 读书笔记《30天自制操作系统》day03
- 《30天自制操作系统》读书笔记Day4