kernel/console.c

来源:互联网 发布:笔记本电池校正软件 编辑:程序博客网 时间:2024/06/03 21:19
Code:
  1. /*  
  2.     By Marcus Xing  
  3.     kernel/console.c  
  4.     与控制台有关的函数  
  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. static void Set_Cursor(u32 location);   
  19. static void Set_Video_Start_Addr(u32 start_addr);   
  20. static void Adjust_Cursor(Console *console);   
  21.   
  22. /*------------------------------------------------------------Is_Current_Console  
  23.     判断是否是参数传来的控制台是否是当前控制台  
  24. */  
  25. int Is_Current_Console(Console *console)   
  26. {   
  27.     return &Console_Table[Current_Console] == console;   
  28. }   
  29.   
  30. /*-------------------------------------------------------------------------Flush   
  31.     刷新当前控制台的显示位置和光标位置,本文件调用  
  32. */  
  33. void Flush(Console *con)   
  34. {   
  35.     Set_Video_Start_Addr(con->current_addr / 2);   
  36.     Set_Cursor(con->cursor / 2);   
  37. }   
  38.   
  39. /*------------------------------------------------------------------Init_Console  
  40.     初始化一个CONSOLE  
  41. */  
  42. void Init_Console(TTY *tty)   
  43. {   
  44.     int diff = tty - TTY_Table;  /* diff保存参数指示的TTY相对TTY_Table的索引 */  
  45.     tty->console = Console_Table + diff;    /* 指向对应的Console */  
  46.        
  47.     /*   
  48.         每个Console的所占的显存大小为8000字节。  
  49.         每个Console的起始地点为:每份的大小 * diff  
  50.         当前地址为起始地点,光标也是起始地点  
  51.     */  
  52.     int each_console_mem_size = 8000;      
  53.     tty->console->original_addr = each_console_mem_size * diff;   
  54.     tty->console->current_addr = tty->console->original_addr;   
  55.     tty->console->limit = each_console_mem_size;   
  56.     tty->console->cursor = tty->console->original_addr;   
  57.        
  58.     /* 如果是0号控制台,则光标位置就是d_Disp_Pos值 */  
  59.     if(diff == 0)   
  60.     {   
  61.         tty->console->cursor = d_Disp_Pos;   
  62.     }   
  63.     /* 否则,写入索引值+'$' */  
  64.     else  
  65.     {   
  66.         Out_Char(tty->console,'0' + diff);   
  67.         Out_Char(tty->console,'#');   
  68.     }   
  69. }   
  70.   
  71. /*----------------------------------------------------------------Select_Console  
  72.     选择控置台  
  73. */  
  74. void Select_Console(int console_no)   
  75. {   
  76.     /* 控制台号如果非法直接退出 */  
  77.     if(console_no < 0 || console_no >= TTY_NUM)   
  78.     {   
  79.         return;   
  80.     }   
  81.        
  82.     Current_Console = console_no;       /* Current_Console改为指定的值 */  
  83.        
  84.     Adjust_Cursor(&Console_Table[console_no]);      /* 调整光标 */  
  85.        
  86.     /* 刷新 */  
  87.     Flush(&Console_Table[console_no]);   
  88. }   
  89.   
  90. /*-----------------------------------------------------------------Scroll_Screen  
  91.     滚动当前的控制台  
  92. */  
  93. void Scroll_Screen(Console *con,int direction)   
  94. {   
  95.     /* 如果上滚 */  
  96.     if(direction == 1)   
  97.     {   
  98.         /* 如果显示位置大于原始地址,则显示地址上移1行 */  
  99.         if(con->current_addr > con->original_addr)   
  100.         {   
  101.             con->current_addr -= ROW_BYTE_NUM;   
  102.         }   
  103.     }   
  104.     /* 如果下滚 */  
  105.     else if(direction == 0)   
  106.     {   
  107.         /* 如果显示位置 + 160 小于当前控制台的下界,则显示地址下移1行 */  
  108.         if(con->current_addr + ROW_BYTE_NUM < con->original_addr + con->limit)   
  109.         {   
  110.             con->current_addr += ROW_BYTE_NUM;   
  111.         }   
  112.     }   
  113.        
  114.     Flush(con);     /* 刷新 */  
  115. }   
  116.   
  117. /*----------------------------------------------------------------------Out_Char  
  118.     把字符写进参数指定的控制台的显存中  
  119. */  
  120. void Out_Char(Console *console,char c)   
  121. {   
  122.     /* 指向显存起始位置0xb8000 + 当前控制台的光标位置 */  
  123.     u8 *p_video_mem = (u8*)(VIDEO_START_ADDR + console->cursor);   
  124.     u32 row;   
  125.        
  126.     switch(c)   
  127.     {   
  128.         /* 处理回车 */  
  129.         case '/n':   
  130.             /* row存放的是当前cursor指向的下一行的值 */  
  131.             row = console->cursor / ROW_BYTE_NUM;          
  132.             row++;   
  133.        
  134.             /* 如果row小于当前控制台的最大界限则使cursor指向下一行的开头 */  
  135.             if(row < ((console->original_addr + console->limit) / ROW_BYTE_NUM))   
  136.             {   
  137.                 console->cursor = row * ROW_BYTE_NUM;   
  138.             }   
  139.             break;   
  140.                
  141.         /* 处理退格 */  
  142.         case '/b':   
  143.             /* 如果当前控制台的cursor大于当前控制台的上界,则退格 */  
  144.             if(console->cursor > console->original_addr)   
  145.             {   
  146.                 /* 把字符写入相应的地址 */  
  147.                 *(--p_video_mem) = Make_Color(WHITE,BLACK);   
  148.                 *(--p_video_mem) = ' ';   
  149.                    
  150.                 /* 光标指向上一个字符 */  
  151.                 console->cursor -= 2;   
  152.             }   
  153.             break;   
  154.                
  155.         default:   
  156.             /* 如果当前控制台没超当前控制台的下界,则打印字符 */  
  157.             if(console->cursor < console->original_addr + console->limit)   
  158.             {   
  159.                 /* 把字符写入相应的地址 */  
  160.                 *p_video_mem++ = c;   
  161.                 *p_video_mem++ = Make_Color(WHITE,BLACK);   
  162.        
  163.                 /* 光标指向下一个字符 */  
  164.                 if(console->cursor + 2 < console->original_addr + console->limit)   
  165.                 {   
  166.                     console->cursor += 2;   
  167.                 }   
  168.             }   
  169.             break;   
  170.     }   
  171.        
  172.     Adjust_Cursor(console);     /* 调整光标 */  
  173. }   
  174.   
  175. /*--------------------------------------------------------------------Set_Cursor   
  176.     根据参数设置光标,本文件调用  
  177. */  
  178. static void Set_Cursor(u32 location)   
  179. {   
  180.     Disable_Int();   
  181.     Out_Byte(CRTC_ADDR_REG,CURSOR_H);   
  182.     Out_Byte(CRTC_DATA_REG,(location >> 8) & 0xff);   
  183.     Out_Byte(CRTC_ADDR_REG,CURSOR_L);   
  184.     Out_Byte(CRTC_DATA_REG,location & 0xff);   
  185.     Enable_Int();   
  186. }   
  187.   
  188. /*-----------------------------------------------------------------Adjust_Cursor  
  189.     如果当前控制台为参数传来的控制台则调整光标在视野内  
  190. */  
  191. static void Adjust_Cursor(Console *console)   
  192. {   
  193.     /* 如果参数等于当前控制台,则调整 */  
  194.     if(Is_Current_Console(console))   
  195.     {   
  196.         /* 如果光标超过当前视野的下界,则下滚 */  
  197.         while(console->cursor > console->current_addr + SCREEN_BYTE_NUM)   
  198.         {   
  199.             Scroll_Screen(console,0);   
  200.         }   
  201.        
  202.         /* 如果光标超过当前视野的上界,则上滚 */  
  203.         while(console->cursor < console->current_addr)   
  204.         {   
  205.             Scroll_Screen(console,1);   
  206.         }   
  207.            
  208.         /* 刷新 */  
  209.         Flush(console);   
  210.     }   
  211. }   
  212.   
  213. /*----------------------------------------------------------Set_Video_Start_Addr  
  214.     根据参数设置显示起始位置,本文件调用  
  215. */  
  216. static void Set_Video_Start_Addr(u32 start_addr)   
  217. {   
  218.     Disable_Int();   
  219.     Out_Byte(CRTC_ADDR_REG,START_ADDR_H);   
  220.     Out_Byte(CRTC_DATA_REG,(start_addr >> 8) & 0xff);   
  221.     Out_Byte(CRTC_ADDR_REG,START_ADDR_L);   
  222.     Out_Byte(CRTC_DATA_REG,start_addr & 0xff);   
  223.     Enable_Int();   
  224. }   
  225.   

 

原创粉丝点击