《30天自制操作系统》笔记----Day18

控制光标闪烁

任务A和console_task光标闪烁原理相差不大,所以分析一个就可以类推另一个。
首先通过tab键来切换窗口,所以在for循环中加入以下代码:

if (256 <= i && i <= 511) { /*键盘数据*/
		(中略)
			if (i == 256 + 0x0f) { /* Tab键*/
					if (key_to == 0) {
							key_to = 1;
							make_wtitle8(buf_win, sht_win->bxsize, "task_a", 0);
							make_wtitle8(buf_cons, sht_cons->bxsize, "console", 1);
							/*从此开始*/ cursor_c = -1; /* 不显示光标 */
							/*到此结束*/ boxfill8(sht_win->buf, sht_win->bxsize, COL8_FFFFFF,cursor_x, 28, cursor_x + 7, 43);
					} else {
							key_to = 0;
							make_wtitle8(buf_win, sht_win->bxsize, "task_a", 1);
							make_wtitle8(buf_cons, sht_cons->bxsize, "console", 0);
		 /*这里!*/ cursor_c = COL8_000000; /*显示光标*/
		 			}
		 			sheet_refresh(sht_win, 0, 0, sht_win->bxsize, 21);
					sheet_refresh(sht_cons, 0, 0, sht_cons->bxsize, 21);
			}
(中略)
/*重新显示光标*/
/*从此开始*/ if (cursor_c >= 0) {
							boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x,28, cursor_x + 7, 43);
						}

也就是通过key_to作为flag来回切换,然后光标闪烁通过定时器来控制,即cursor_c

对回车键支持

首先简单通过按下回车键实现换行操作,修改HariMain,使其按下回车键,向命令行窗口发送(10+256)其中10可以自行修改成7,89都行。

if (i == 256 + 0x1c) { /*回车键*/
			if (key_to != 0) { /*发送至命令行窗口*/
						fifo32_put(&task_cons->fifo, 10 + 256);
			}
}

同时修改console_task,创建一个cursor_y变量,当按下回车键时,将cursor_y加1。

if (256 <= i && i <= 511) { /*键盘数据(通过任务A)*/
			if (i == 8 + 256) {
			/*退格键*/
		(中略)
/*从此开始*/ } 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;
	/*到此结束*/ }
}

窗口滚动支持

上文操作到最后一行回车键就不管用了,需要增加窗口下滚动功能。
只需要把所有的像素往上移动一行就行,并将最下面的一行涂黑。

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);
}

命令行

mem命令

mem->memory,显示内存使用情况

char s[30],cmdline[30];
struct MEMMAN *memman =(struct MEMMAN *)MEMMAN_ADDR;
/*passing*/
if(i==10+256){/*按下回车*/
	if(cmdline[0] == 'm'&& cmdline[1] == 'e' &&cmdline[2]=='m'&&cmdline[3]==0){
		sprintf(s,"total %dMB",,memtotoal/(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, "Badcommand.", 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;
	}
}

cls命令

cls->clear screen

/*我们简化cmdline*/
cmdline[30]->c[30]
/*或者调用strcmp函数*/
if (strcmp(cmdline, "mem") == 0)

所以我们可以简化成如下:

 if (strcmp(cmdline, "cls") == 0) {
	/* cls命令*/
	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;
	}

dir命令

作为os,我们的目标是制作可执行文件让它运行,所以先制作一个显示磁盘内文件名称的命令。

首先定义结构体以及读取的地址:

#define ADR_DISKIMG 0x00100000
struct FILEINFO {
	unsigned char name[8], ext[3], type;
	char reserve[10];
	unsigned short time, date, clustno;
	unsigned int size;
};

开始的8个字节是文件名。文件名不足8个字节时,后面用空格补足。接下来3个字节是扩展名,和文件名一样,不足3个字节时用空格补足,如果文件没有扩展名,则这3个字节都用空格补足。扩展名和文件名一样,也全部使用了大写字母。
后面1个字节存放文件的属性信息:
0x01……只读文件(不可写入)
0x02……隐藏文件
0x04……系统文件
0x08……非文件信息(比如磁盘名称等)
0x10……目录
0xe5…已经删除
0x00…不包含任何文件名信息

struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600); 
if (strcmp(cmdline, "dir") == 0) {
/* dir命令 */
		for (x = 0; x < 224; x++) {
			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);
			}
		}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃人的坤坤坤坤坤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值