我已经规范了系统代码风格,类似于按照linux分包,把各部分功能区分开了

Antz系统更新地址

Linux内核源码分析地址

Github项目地址

在之前的任务中,我们已经通过直接操作显卡驱动完成了简单的图形化。

需要了解之前的部分:

直接操作显卡请参考day03

简单图形化的实现请参考day09

键盘按键中断响应请参考day10

Makefile

项目目录

一 . 如何实现命令缓存

在之前已经完成了键盘的响应工作,但这种响应却是有很大的问题,比如说对于一次按键的两次中断处理。后来我把两种中断都加入了响应判断中,这样就不会有之前第10天所提到的bug了。

* 在替换函数中完成识别。修改如下

char* replace_char(char s[40]){
char *chr = "$" ;
if((strcmp(s,"1E")==0)||(strcmp(s,"9E")==0)){
chr = "a" ;
}else if((strcmp(s,"30")==0)||(strcmp(s,"B0")==0)){
chr = "b" ;
}
... // 省略
return chr ;

* 这里是一些功能按键的识别修改

    // Enter  -> 回车键 响应之前缓存的命令 换行
if((strcmp(s,"1C")==0)||(strcmp(s,"9C")==0)){
action_command(binfo); //响应命令
write_x = 58 ; //下面是换行
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");
}
// F1 -> 终端刷新 类似于clear命令
else if((strcmp(s,"3B")==0)||(strcmp(s,"BB")==0)){ //关于F1的响应中断
sprintf(command,"%s",""); // 命令缓存清空
flag = 0 ; // 按键模式回复默认,这个看第10天,本质目的是为了处理一次按键的两次终端
new_pe(binfo); // 通过操作显存直接刷新当前终端
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");
}
// Backspace -> 删格键
else if(strcmp(s,"0E")==0){
// 回退
write_x -= 8 ;
boxfill8(binfo->vram, binfo->scrnx , COL8_000000, write_x, write_y, write_x+19, write_y+19);
if(write_x<=58){
write_x = 146 ;
write_y -= 19 ;
}
}

这些就是按键识别上目前修改的内容了。

接下来我们要添加一个功能,在每次按键之后,不但在屏幕上显示这个键,而且将他缓存在缓冲区,在下次回车的时候进行识别,并清空。

先来看一个简单的demo

// command数组就是命令缓存区
char command[100] = ""; void add_command(char *s) {
sprintf(command,"%s%s",command,s);
} void action_command(){
// 响应
}

二 . 实现

command就是一个命令缓存数组,每次按键之后调用add_command()命令将这次的按键保存。

sprintf()这个函数是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。

我们使用sprintf函数直接在command后面添加了s字符。

那么在下次按下Enter的时候,我们只需要调用action_command,并且在里面识别是什么命令,然后做出合适的响应即可。

来看看完整的命令缓冲区实现。

// 指令缓存,但是因为中断响应的时间问题,终端输入速度要非常慢
char command[100] = "";
void add_command(char *s) { if(strcmp(s," ")==0){
sprintf(command,"%s%s",command,"");
}else if(strcmp(s,"$")){
//忽略这种错误输入
}else {
sprintf(command,"%s%s",command,s);
}
} void action_command(struct BOOTINFO *binfo){
// action command 响应命令
// ls命令
// data命令
if(strcmp(command,"data")==0){
// get new data;
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS in 2018");
}else if(strcmp(command,"cls")==0){
flag = 0 ;
new_pe(binfo);
}else if(strcmp(command,"version")==0){
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Antz.version.1.1");
}else if(strcmp(command,"help")==0){
// help内容过多,显示在图形化界面区域 }else if(sizeof(command)>=1){
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Not Found");
}
// 命令缓存清除
sprintf(command,"%s","");
}

现在使用Makefile来生成这个支持命令的img镜像。

    make img

使用虚拟机打开镜像,结果如下

终端主要代码如下:


int write_x = 55 ;
int write_y = 57 ; char* replace_char(char s[40]){
char *chr = "$" ;
if((strcmp(s,"1E")==0)||(strcmp(s,"9E")==0)){
chr = "a" ;
}else if((strcmp(s,"30")==0)||(strcmp(s,"B0")==0)){
chr = "b" ;
}else if((strcmp(s,"2E")==0)||(strcmp(s,"AE")==0)){
chr = "c" ;
}else if((strcmp(s,"20")==0)||(strcmp(s,"A0")==0)){
chr = "d" ;
}else if((strcmp(s,"12")==0)||(strcmp(s,"92")==0)){
chr = "e" ;
}else if((strcmp(s,"21")==0)||(strcmp(s,"A1")==0)){
chr = "f" ;
}else if((strcmp(s,"22")==0)||(strcmp(s,"A2")==0)){
chr = "g" ;
}else if((strcmp(s,"23")==0)||(strcmp(s,"A3")==0)){
chr = "h" ;
}else if((strcmp(s,"17")==0)||(strcmp(s,"97")==0)){
chr = "i" ;
}else if((strcmp(s,"24")==0)||(strcmp(s,"A4")==0)){
chr = "j" ;
}else if((strcmp(s,"25")==0)||(strcmp(s,"A5")==0)){
chr = "k" ;
}else if((strcmp(s,"26")==0)||(strcmp(s,"A6")==0)){
chr = "l" ;
}else if((strcmp(s,"32")==0)||(strcmp(s,"B2")==0)){
chr = "m" ;
}else if((strcmp(s,"31")==0)||(strcmp(s,"B1")==0)){
chr = "n" ;
}else if((strcmp(s,"18")==0)||(strcmp(s,"98")==0)){
chr = "o" ;
}else if((strcmp(s,"19")==0)||(strcmp(s,"99")==0)){
chr = "p" ;
}else if((strcmp(s,"10")==0)||(strcmp(s,"90")==0)){
chr = "q" ;
}else if((strcmp(s,"13")==0)||(strcmp(s,"93")==0)){
chr = "r" ;
}else if((strcmp(s,"1F")==0)||(strcmp(s,"9F")==0)){
chr = "s" ;
}else if((strcmp(s,"14")==0)||(strcmp(s,"94")==0)){
chr = "t" ;
}else if((strcmp(s,"16")==0)||(strcmp(s,"96")==0)){
chr = "u" ;
}else if((strcmp(s,"2F")==0)||(strcmp(s,"AF")==0)){
chr = "v" ;
}else if((strcmp(s,"11")==0)||(strcmp(s,"91")==0)){
chr = "w" ;
}else if((strcmp(s,"2D")==0)||(strcmp(s,"AD")==0)){
chr = "x" ;
}else if((strcmp(s,"15")==0)||(strcmp(s,"95")==0)){
chr = "y" ;
}else if((strcmp(s,"2C")==0)||(strcmp(s,"AC")==0)){
chr = "z" ;
}else if((strcmp(s,"39")==0)||(strcmp(s,"B9")==0)){
chr = " " ;
}
return chr ;
} int flag = 1 ; // 指令缓存,但是因为中断响应的时间问题,终端输入速度要非常慢
char command[100] = "";
void add_command(char *s) {
/*
if(strcmp(s," ")==0){
sprintf(command,"%s%s",command,"");
}else if(strcmp(s,"$")){
//忽略这种错误输入
}else {
}
*/
sprintf(command,"%s%s",command,s); } void action_command(struct BOOTINFO *binfo){
// action command
// ls
// data
if(strcmp(command,"data")==0){
// get new data;
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS in 2018");
}else if(strcmp(command,"cls")==0){
flag = 0 ;
new_pe(binfo);
}else if(strcmp(command,"version")==0){
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Antz.version.1.1");
}else if(strcmp(command,"help")==0){
// help内容过多,显示在图形化界面区域
}else if(sizeof(command)>=1){
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Not Found");
}
// 命令缓存清除
sprintf(command,"%s","");
} void key(struct BOOTINFO *binfo,char s[40]){
if((strcmp(s,"1C")==0)||(strcmp(s,"9C")==0)){
action_command(binfo);
write_x = 58 ;
write_y += 19 ;
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");
}else if((strcmp(s,"3B")==0)||(strcmp(s,"BB")==0)){ //关于F1的响应中断
sprintf(command,"%s","");
flag = 0 ;
new_pe(binfo);
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");
}else if(strcmp(s,"0E")==0){
// 回退
write_x -= 8 ;
boxfill8(binfo->vram, binfo->scrnx , COL8_000000, write_x, write_y, write_x+19, write_y+19);
if(write_x<=58){
write_x = 146 ;
write_y -= 19 ;
}
}else {
//putfonts8_asc(binfo->vram, binfo->scrnx, write_x, write_y, COL8_FFFFFF, s);
putfonts8_asc(binfo->vram, binfo->scrnx, write_x, write_y, COL8_FFFFFF, replace_char(s));
add_command(replace_char(s));
write_x += 8 ;
// 添加响应区
//清除
//boxfill8(binfo->vram, binfo->scrnx, COL8_008400 , 300 ,240 ,310 ,250);
//打印字符 Only use debug
//putfonts8_asc(binfo->vram, binfo->scrnx, 300, 240 ,COL8_000000, s) ;
}
if(write_x>148){
write_x = 58 ;
write_y += 19 ;
//putfonts8_asc(binfo->vram, binfo->scrnx, 4, 57, COL8_FFFFFF, "AntzOS>");
}
if(write_y>180){
new_pe(binfo);
putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");
} } void main(void)
{
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
char s[40], mcursor[256], keybuf[32], mousebuf[128];
int mx, my, i; init_gdtidt();
init_pic();
io_sti(); /* PIC的初始化已经完成*/ fifo8_init(&keyfifo, 32, keybuf);
fifo8_init(&mousefifo, 128, mousebuf);
io_out8(PIC0_IMR, 0xf9); /* 开放PIC1和键盘中断(11111001) */
io_out8(PIC1_IMR, 0xef); /* 开放鼠标中断(11101111) */ init_keyboard(); init_palette();
init_screen8(binfo->vram, binfo->scrnx, binfo->scrny); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "Terminal-Antz");
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_000000, "Terminal-Antz");
putfonts8_asc(binfo->vram, binfo->scrnx, 107, 0, COL8_000000, "|-|o|x|");
putfonts8_asc(binfo->vram, binfo->scrnx, 4, 19, COL8_FFFFFF, "AntzOS> SayHello()");
putfonts8_asc(binfo->vram, binfo->scrnx, 4, 38, COL8_FFFFFF, "Hello My AntzOs.");
putfonts8_asc(binfo->vram, binfo->scrnx, 4, 57, COL8_FFFFFF, "AntzOS>_"); for (;;) {
io_cli();
if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {
io_stihlt();
} else {
if (fifo8_status(&keyfifo) != 0) { i = fifo8_get(&keyfifo);
io_sti();
sprintf(s, "%02X", i);
if (flag){
key(binfo,s);
}
if(flag==1){
flag = 0 ;
}else {
flag = 1 ;
}
}
}
}
} void new_pe(struct BOOTINFO *binfo){
write_x = 58 ;
write_y = 19 ;
// 右边并没有保存
init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "Terminal-Antz");
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_000000, "Terminal-Antz");
putfonts8_asc(binfo->vram, binfo->scrnx, 107, 0, COL8_000000, "|-|o|x|");
// 此处保留此输出,交给调用者自己
// putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");
}

自制操作系统Antz(11)——实现shell(下)命令响应的更多相关文章

  1. 自制操作系统Antz(10)——实现shell(上)

    我已经规范了系统代码风格,类似于按照linux分包,把各部分功能区分开了 Antz系统更新地址 Linux内核源码分析地址 Github项目地址 在之前的任务中,我们已经通过直接操作显卡驱动完成了简单 ...

  2. 自制操作系统Antz(9)——实现内核 (下) 实现图形化界面

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  3. 自制操作系统Antz -- 系列文章

    自制操作系统Antz day10——实现shell(上) AntzUhl 2018-10-10 16:25 阅读:192 评论:0   Linux内核源码分析 day01——内存寻址 AntzUhl ...

  4. 自制操作系统Antz(13) 显示图片

    显示图片只是在多媒体课上看着bmp格式图片的突发奇想,然后就实现在了我自己的操作系统 Antz系统更新地址 Linux内核源码分析地址 Github项目地址 效果图: 显示图片的原理 在之前显卡操作时 ...

  5. 自制操作系统Antz(4)——进入保护模式 (下) 实现内核并从硬盘载入

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  6. 自制操作系统Antz(12)——承上启下

    我已经规范了系统代码风格,类似于按照linux分包,把各部分功能区分开了 Antz系统更新地址 Linux内核源码分析地址 Github项目地址 在之前的工作中,AntzOS已经从单调的界面,变得逐渐 ...

  7. 自制操作系统Antz(8)——实现内核 (中) 扩展内核

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html 在前几天的任务中,我们已经简单实现了MBR,直接操作显示器和硬盘操作 ...

  8. 自制操作系统Antz(5)——深入理解保护模式与进入方法

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  9. 自制操作系统Antz(1)——Boot Sector

    0.引子 最近在看操作系统底层方面的东西,最开始的为什么是07c00h这个问题就让我对操作系统有了很大的兴趣.所以准备在看书之余顺便写一个操作系统(Anz).至于为什么这个系统会被叫做Antz,可以参 ...

随机推荐

  1. jexus System.BadImageFormatException Details: Non-web exception. Exception origin (name of application or object): App_global.asax_ai3fjolq.

    Application ExceptionSystem.BadImageFormatExceptionInvalid method header format 0Description: HTTP 5 ...

  2. disconf安装问题

    安装参考文档:https://blog.csdn.net/fengyao1995/article/details/66491226 主要说说遇到的几个问题 1.在步骤6构建的时候,用jdk1.8,进行 ...

  3. 去除桌面SVN问号

    由于误操作,桌面文件全部带着问号. 找到一种比较方便的方法解决. 1.显示受保护文件.文件夹win7系统 - 随便打开一个文件夹 -  在菜单栏里点 工具 - 文件夹选项 - 查看 以下如图中选择 2 ...

  4. jpython basic

    https://blog.csdn.net/zhongweijian/article/details/4742549https://www.jython.org/downloads.htmlhttps ...

  5. 本地浏览器Websql数据库操作

    前几天看到一个小姐姐问我一个添加修改的我看了一下案例弄了一个出来.... 参考案例:HTML5本地数据库(WebSQL)[转] - 狂流 - 博客园  https://www.cnblogs.com/ ...

  6. FEX(Fabric Extender)

    一.FEX Cisco Nexus 2000 FEX作为N5K.N6K.N7K.FI的一个远程线卡,单独的2K是没有网管功能的,必须配合父系交换机使用. 主要解决TOR和EOR的问题,TOR,接线简单 ...

  7. 支持Linux系统的加密狗

    深思数盾 https://www.sense.com.cn/ 产品:精锐5 版本:标准版.精灵版.IE版.时钟锁 快速实现高安全度的软件保护,轻松定义多种授权模式1.防止软件盗版,防止逆向工程 通过增 ...

  8. [LeetCode] 139. Word Break_ Medium tag: Dynamic Programming

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  9. 2019CCF-GAIR全球人工智能与机器人峰会于7月在深圳召开

    全球人工智能与机器人峰会(CCF-GAIR)是由中国计算机学会(CCF)主办,雷锋网.香港中文大学(深圳)承办,得到了深圳市政府的大力指导,是国内人工智能和机器人学术界.工业界及投资界三大领域的顶级交 ...

  10. Vue父子组件及非父子组件如何通信

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: 子组件通过props来接收数据: 方式1: 方式2 : 方式3: 这样呢,就实现了父组件向子组件传递数 ...