lib/lib_in_c.c

Code:
  1. /*  
  2.     By Marcus Xing  
  3.     lib/lib_kernel_in_c.c  
  4.     内核中用C写的功能函数  
  5. */  
  6.   
  7. #include "type.h"   
  8. #include "const.h"   
  9. #include "ipc.h"   
  10. #include "protect.h"   
  11. #include "proc.h"   
  12. #include "console.h"   
  13. #include "tty.h"   
  14. #include "global.h"   
  15. #include "proto.h"   
  16.   
  17. /* 内部声明 */  
  18. extern void I_to_A(const char *psz_Str,int num);    /* 此函数用汇编写的 */  
  19. static int V_Printf(char *buf,const char *fmt,const char *args);   
  20. static char* I_To_A_By_Radix(int num,int radix,char *buf);   
  21.   
  22. /*----------------------------------------------------------------------Disp_Int  
  23.     此函数以16进制打印一个32位的整数,  
  24.     不考虑无符号,前面的0不打印  
  25. */  
  26. void Disp_Int(int num)   
  27. {   
  28.     char buffer[16];        /* 栈中的局部临时数组 */  
  29.     I_To_A(buffer,num);     /* 将数字转换为字符数组送到临时数组中 */  
  30.     Disp_Str(buffer);       /* 交付打印 */  
  31. }   
  32.   
  33. /*------------------------------------------------------------------------Printf    
  34.     模拟Printf函数,可由用户进程调用,格式字符串长度不能超过128  
  35.     想使用就须调用Init_Console  
  36. */  
  37. int Printf(const char *fmt,...)   
  38. {   
  39.     char buf[128];  /* 解析好的串存放之地 */  
  40.     /* 指向格式字符串的后一个参数 */  
  41.     char *args_begin = (char*)((char*)(&fmt) + 4);   
  42.     /* 解析格式字符串 */  
  43.     int len = V_Printf(buf,fmt,args_begin);   
  44.        
  45.     /* 系统调用,交给内核在调用该函数的进程所绑定的控制台打印出来 */  
  46.     Write(buf);        
  47.        
  48.     return len;     /* 返回串的长度 */  
  49. }   
  50.   
  51. /*-----------------------------------------------------------------------Str_Cpy  
  52.     复制字符串,保证dest空间足够存放  
  53. */  
  54. void Str_Cpy(char *dest,const char *src)   
  55. {   
  56.     while((*src != '/0') && (*dest++ = *src++));   
  57.     *dest = '/0';   
  58. }   
  59.   
  60. /*-----------------------------------------------------------------------Str_Len  
  61.     求字符串长度  
  62. */  
  63. int Str_Len(const char *sz_str)   
  64. {   
  65.     int len = 0;   
  66.     while(*sz_str++ != '/0')   
  67.     {   
  68.         len++;     
  69.     }   
  70.     return len;   
  71. }   
  72.   
  73. /*-------------------------------------------------------------------------Delay  
  74.     粗糙的延迟函数   
  75. */  
  76. void Delay(u32 time)      
  77. {      
  78.     u32 i,j,k;      
  79.     for(i = 0 ; i < time ; i++)      
  80.     {      
  81.         for(j = 0 ; j < 100 ; j++)      
  82.         {      
  83.             for(k = 0 ; k < 10000 ; k++)      
  84.             {      
  85.                   
  86.             }      
  87.     }     
  88.   }    
  89. }    
  90.   
  91. /*--------------------------------------------------------------------Cursor_Loc  
  92.     光标跟随,使用了IO指令,注意使用IO指令的段是否有权限  
  93. */  
  94. void Cursor_Loc()   
  95. {   
  96.     /* 保证原子性 */  
  97.     Disable_Int();   
  98.     /* 根据d_Disp_Pos设置光标 */  
  99.     Out_Byte(CRTC_ADDR_REG,CURSOR_H);   
  100.     Out_Byte(CRTC_DATA_REG,((d_Disp_Pos / 2) >> 8) & 0xff);   
  101.     Out_Byte(CRTC_ADDR_REG,CURSOR_L);   
  102.     Out_Byte(CRTC_DATA_REG,(d_Disp_Pos / 2) & 0xff);   
  103.     Enable_Int();   
  104. }   
  105.   
  106. /*--------------------------------------------------------------------Make_Color  
  107.     产生一个颜色值  
  108. */  
  109. u8  Make_Color(u8 forward_color,u8 back_color)   
  110. {   
  111.     u8 color = (back_color << 4) & 0xf0;   
  112.     color |= forward_color;   
  113.     return color;   
  114. }   
  115.   
  116. /*----------------------------------------------------------------Assert_Failure    
  117.     断言功能函数  
  118. */  
  119. void Assert_Failure(char *file,char *base_file,int line)   
  120. {      
  121.     /* 否则在格式字符串的开头设为ASSERT标记,并把调用此函数的文件名等信息打印出来 */  
  122.     Printf("%c!ASEERT FILE:%s BASE FILE:%s LINE:%d",MAGIC_CHAR_ASSERT,file,base_file,line);   
  123.     /* 如果是用户进程则会跳转到这,死循环阻塞当前进程 */  
  124.     while(1);   
  125. }   
  126.   
  127. /*-------------------------------------------------------------------------Panic  
  128.   PANIC功能函数,不在用户进程中调用,发生严重问题使用才使用,会hlt掉整个系统  
  129. */  
  130. void Panic(char *fmt,...)   
  131. {   
  132.     /* 解析格式字符串到buf */  
  133.     char buf[256];   
  134.     char *args_first = (char*)((char*)&fmt + 4);   
  135.     V_Printf(buf,fmt,args_first);   
  136.        
  137.     /* 附加上PANIC标志后打印之,永远不会返回 */  
  138.     Printf("%c!%s",MAGIC_CHAR_PANIC,buf);   
  139. }   
  140.   
  141. /*---------------------------------------------------------------------Get_Ticks    
  142.     返回当前的ticks值  
  143. */  
  144. int Get_Ticks()   
  145. {   
  146.     Message m;   
  147.     m.msg_type = GET_TICKS;                 /* 设置消息类型 */  
  148.     Send_Receive_Shell(BOTH,4,&m);     
  149.     return m.r1;   
  150. }   
  151.   
  152. /*----------------------------------------------------------------------V_Printf  
  153.     解析格式字符串的功能函数  
  154. */  
  155. static int V_Printf(char *buf,const char *fmt,const char *args)   
  156. {   
  157.     char tmp[128];      /* 临时存放由数字转成串的空间 */  
  158.     char *p = buf;         
  159.        
  160.     /* 遍历格式字符串 */  
  161.     for(;*fmt != '/0';fmt++)   
  162.     {   
  163.         /* 如果不是控制字符,则直接放到buf中,开始下一次循环 */  
  164.         if(*fmt != '%')   
  165.         {   
  166.             *p++ = *fmt;   
  167.             continue;   
  168.         }   
  169.         /* 如果是控制字符,则指向'%'后的字符,解析之 */  
  170.         fmt++;   
  171.         switch(*fmt)   
  172.         {   
  173.             /* 如果是x,代表16进制数字 */  
  174.             case 'x':   
  175.                 /* 从可变参数表取出一个参数,解释成16进制整数并转换成串存放到tmp中 */  
  176.                 I_To_A_By_Radix((int)(*((int*)args)),16,tmp);   
  177.                 Str_Cpy(p,tmp);         /* 把转换好的串拷贝到buf中 */  
  178.                 p += Str_Len(tmp);      /* 移动p指向buf下一个可用的地址 */  
  179.                 args += 4;              /* 指向下一个可变参数 */  
  180.                 break;   
  181.                    
  182.             /* 如果是d代表10进制数字 */  
  183.             case 'd':   
  184.                 /* 从可变参数表取出一个参数,解释成10进制整数并转换成串存放到tmp中 */  
  185.                 I_To_A_By_Radix((int)(*((int*)args)),10,tmp);   
  186.                 Str_Cpy(p,tmp);         /* 把转换好的串拷贝到buf中 */  
  187.                 p += Str_Len(tmp);      /* 移动p指向buf下一个可用的地址 */  
  188.                 args += 4;              /* 指向下一个可变参数 */  
  189.                 break;   
  190.                    
  191.             /* 如果是c代表一个字符 */  
  192.             case 'c':   
  193.                 *p++ = (char)(*(char*)args);   
  194.                 args += 4;   
  195.                 break;   
  196.                    
  197.             /* 如果是s代表字符串 */  
  198.             case 's':   
  199.                 Str_Cpy(p,*(char**)args);   
  200.                 p += Str_Len(*(char**)args);   
  201.                 args += 4;                 
  202.                 break;   
  203.                    
  204.             default:   
  205.                 break;   
  206.         }   
  207.     }   
  208.        
  209.     *p = '/0';              /* 添加结束标志 */  
  210.     return p - buf;         /* 返回格式串的长度 */  
  211. }   
  212.   
  213. /*---------------------------------------------------------------I_To_A_By_Radix  
  214.     功能函数,把num转化为radix进制的串保存到buf中  
  215. */  
  216. static char* I_To_A_By_Radix(int num,int radix,char *buf)   
  217. {   
  218.     int quotient = num /radix;      /* 求得商 */  
  219.     int remainder = num % radix;    /* 求得余数 */  
  220.        
  221.     /* 如果商不为0,则递归调用 */  
  222.     if(quotient != 0)   
  223.     {   
  224.         buf = I_To_A_By_Radix(quotient,radix,buf);   
  225.     }   
  226.     /* 如果余数大于9,则转为字母,存入buf中 */  
  227.     *buf++ = (remainder > 9) ? (remainder - 10 + 'A'):(remainder + '0');   
  228.     return buf;   
  229. }   

 

你可能感兴趣的:(汇编,shell,IO,File,buffer,byte)