/* By Marcus Xing lib/lib_kernel_in_c.c 内核中用C写的功能函数 */ #include "type.h" #include "const.h" #include "protect.h" #include "proc.h" #include "console.h" #include "tty.h" #include "global.h" #include "proto.h" /* 内部声明 */ extern void I_to_A(const char *psz_Str,int num); /* 此函数用汇编写的 */ /*----------------------------------------------------------------------Disp_Int 此函数以16进制打印一个32位的整数, 不考虑无符号,前面的0不打印 */ void Disp_Int(int num) { char buffer[16]; /* 栈中的局部临时数组 */ I_to_A(buffer,num); /* 将数字转换为字符数组送到临时数组中 */ Disp_Str(buffer); /* 交付打印 */ } /*------------------------------------------------------------------------Printf 模拟Printf函数,可由用户进程调用,格式字符串长度不能超过128 想使用就须调用Init_Console */ int Printf(const char *fmt,...) { char buf[128]; /* 解析好的串存放之地 */ char tmp[16]; /* 临时存放由数字转成串的空间 */ char *p = buf; /* 指向格式字符串的后一个参数 */ char *arg = (char*)((char*)(&fmt) + 4); /* 遍历格式字符串 */ for(;*fmt != '/0';fmt++) { /* 如果不是控制字符,则直接放到buf中,开始下一次循环 */ if(*fmt != '%') { *p++ = *fmt; continue; } /* 如果是控制字符,则指向'%'后的字符,解析之 */ fmt++; switch(*fmt) { /* 如果是x,代表16进制数字 */ case 'x': /* 从可变参数表取出一个参数,解释成整数并转换成串存放到tmp中 */ I_to_A(tmp,(int)(*((int*)arg))); /* 把转换好的串拷贝到buf中 */ Str_Cpy(p,tmp); /* 移动p指向buf下一个可用的地址 */ p += Str_Len(tmp); /* 指向下一个可变参数 */ arg += 4; break; default: break; } } int len = p - buf; /* 取得解析好的字符串的长度 */ /* 系统调用,交给内核在调用该函数的进程所绑定的控制台打印出来 */ Write(buf,len); return len; /* 返回串的长度 */ } /*-----------------------------------------------------------------------Str_Cpy 复制字符串,保证dest空间足够存放 */ void Str_Cpy(char *dest,const char *src) { while((*src != '/0') && (*dest++ = *src++)); *dest = '/0'; } /*-----------------------------------------------------------------------Str_Len 求字符串长度 */ int Str_Len(const char *sz_str) { int len = 0; while(*sz_str++ != '/0') { len++; } return len; } /*-------------------------------------------------------------------------Delay 粗糙的延迟函数 */ void Delay(u32 time) { u32 i,j,k; for(i = 0 ; i < time ; i++) { for(j = 0 ; j < 100 ; j++) { for(k = 0 ; k < 10000 ; k++) { } } } } /*--------------------------------------------------------------------Cursor_Loc 光标跟随 */ void Cursor_Loc() { /* 保证原子性 */ Disable_Int(); /* 根据d_Disp_Pos设置光标 */ Out_Byte(CRTC_ADDR_REG,CURSOR_H); Out_Byte(CRTC_DATA_REG,((d_Disp_Pos / 2) >> 8) & 0xff); Out_Byte(CRTC_ADDR_REG,CURSOR_L); Out_Byte(CRTC_DATA_REG,(d_Disp_Pos / 2) & 0xff); Enable_Int(); } /*--------------------------------------------------------------------Make_Color 产生一个颜色值 */ u8 Make_Color(u8 forward_color,u8 back_color) { u8 color = (back_color << 4) & 0xf0; color |= forward_color; return color; }