现在来处理一下滚动的情况,一个TTY的容量不止4000字节啊,要是超过了咋办捏?只能重新设置一下显示的起始位置了,把这个功能写成一个函数,添在console.c中:
- void Scroll_Screen(CONSOLE *p_con,int direction)
- {
- if(direction == 0)
- {
- if(p_con->current_addr < p_con->start_addr + p_con->memory_size)
- {
- p_con->current_addr += 160;
- p_con->cursor += 160;
- }
- }
- else if(direction == 1)
- {
- if(p_con->current_addr > p_con->start_addr)
- {
- p_con->current_addr -= 160;
- p_con->cursor -= 160;
- }
- }
- Set_Start_Addr(p_con->current_addr / 2);
- Set_Cursor(p_con->cursor / 2);
- }
一次向上滚或向下滚一行,然后在In_Process函数中添加调用的语句:
- case DOWN:
- if((key_value & FLAG_SHIFT_L) || (key_value & FLAG_SHIFT_R))
- {
- Scroll_Screen(p_tty->console,0);
- }
- break;
- case UP:
- if((key_value & FLAG_SHIFT_L) || (key_value & FLAG_SHIFT_R))
- {
- Scroll_Screen(p_tty->console,1);
- }
- break;
make,运行,结果如图所示,分别为下滚和上滚的情形:
这篇也太短了吧,那么再写点。
我们还没实现Enter键和BackSpace键的功能,下面来模拟它们各自的功能。
由于按下这两个键的时候,得到的key值的第9位为1,就是不可打印的字符,所以在In_Process函数中要判断一下,如果按下的是这两个键,那么就往当前console的输出缓冲区中分别放入'/b','/n',这样在Out_Char函数中就可以做相应的处理。
先修改In_Process函数,把key值丢进输出缓冲区的代码写成了一个static函数:
- void In_Process(TTY *p_tty,u32 key_value)
- {
- if(!(key_value & FLAG_EXT))
- {
- Put_Key(p_tty,key_value);
- }
- else
- {
- int raw_key = key_value & 0x1ff;
- switch(raw_key)
- {
- case BACKSPACE:
- Put_Key(p_tty,'/b');
- break;
- case ENTER:
- Put_Key(p_tty,'/n');
- break;
- case DOWN:
- if((key_value & FLAG_SHIFT_L) || (key_value & FLAG_SHIFT_R))
- {
- Scroll_Screen(p_tty->console,0);
- }
- break;
- case UP:
- if((key_value & FLAG_SHIFT_L) || (key_value & FLAG_SHIFT_R))
- {
- Scroll_Screen(p_tty->console,1);
- }
- break;
- case F1:
- case F2:
- case F3:
- if((key_value & FLAG_SHIFT_L) || (key_value & FLAG_SHIFT_R))
- {
- Set_Console(raw_key - F1);
- }
- break;
- default:
- break;
- }
- }
- }
- static void Put_Key(TTY *p_tty,u32 key_value)
- {
- if(p_tty->count < 256)
- {
- Disable_Int();
- *p_tty->p_tty_tail = key_value;
- p_tty->p_tty_tail++;
- if(p_tty->p_tty_tail == p_tty->tty_buffer + 256)
- {
- p_tty->p_tty_tail = p_tty->tty_buffer;
- }
- p_tty->count++;
- Enable_Int();
- }
- }
接下来修改Out_Char函数:
- void Out_Char(CONSOLE *p_con,char c_disp)
- {
- u8 *p_disp_addr = (u8*)(0xb8000 + p_con->cursor);
- switch(c_disp)
- {
- case '/b':
- if(p_con->cursor != p_con->start_addr)
- {
- *(p_disp_addr - 1) = 0x7f;
- *(p_disp_addr - 2) = ' ';
- p_con->cursor -= 2;
- }
- break;
- case '/n':
- if((p_con->cursor / 160 + 1) != ((p_con->start_addr + p_con->memory_size) / 160))
- {
- p_con->cursor = ((p_con->cursor / 160) + 1) * 160;
- }
- break;
- default:
- if(p_con->cursor < p_con->start_addr + p_con->memory_size - 1)
- {
- *p_disp_addr++ = c_disp;
- *p_disp_addr++ = 0xa;
- p_con->cursor += 2;
- }
- break;
- }
- Set_Cursor(p_con->cursor / 2);
- Set_Start_Addr(p_con->current_addr / 2);
- }
逻辑很简单,但其中的if判断语句要特别注意,每个console都有自己的空间,这里的判断是为了防止越界。
make,运行,利用Enter和BackSpace键把内存信息删掉了一些: