CONSOLE这个结构中的成员按照下面初始化,original_addr和v_mem_limit用做定义控制台所占显存的总体情况,它们是静态的,一经初始化就不再改变;current_start_addr将随着屏幕卷动而变化,cursor变化更频繁,每输出一个字符就更新一次。
/*======================================================================*
init_screen
*======================================================================*/
PUBLIC void init_screen(TTY* p_tty)
{
int nr_tty = p_tty - tty_table;
p_tty->p_console = console_table + nr_tty;
int v_mem_size = V_MEM_SIZE >> 1; /* 显存总大小 (in WORD) */
int con_v_mem_size = v_mem_size / NR_CONSOLES;
p_tty->p_console->original_addr = nr_tty * con_v_mem_size;
p_tty->p_console->v_mem_limit = con_v_mem_size;
p_tty->p_console->current_start_addr = p_tty->p_console->original_addr;
/* 默认光标位置在最开始处 */
p_tty->p_console->cursor = p_tty->p_console->original_addr;
if (nr_tty == 0) {
/* 第一个控制台沿用原来的光标位置 */
p_tty->p_console->cursor = disp_pos / 2;
disp_pos = 0;
}
else {
out_char(p_tty->p_console, nr_tty + '0');
out_char(p_tty->p_console, '#');
}
set_cursor(p_tty->p_console->cursor);
}
第一个控制台沿用原来的光标位置,其他控制台光标都在屏幕左上角,并且将显示控制台号和一个字符 “#” (看起来好像一个特殊的Shell)。
/*======================================================================*
out_char
*======================================================================*/
PUBLIC void out_char(CONSOLE* p_con, char ch)
{
u8* p_vmem = (u8*)(V_MEM_BASE + p_con->cursor * 2);
*p_vmem++ = ch;
*p_vmem++ = DEFAULT_CHAR_COLOR;
p_con->cursor++;
set_cursor(p_con->cursor);
}
/*======================================================================*
scroll_screen
*----------------------------------------------------------------------*
滚屏.
*----------------------------------------------------------------------*
direction:
SCR_UP : 向上滚屏
SCR_DN : 向下滚屏
其它 : 不做处理
*======================================================================*/
PUBLIC void scroll_screen(CONSOLE* p_con, int direction)
{
if (direction == SCR_UP) {
if (p_con->current_start_addr > p_con->original_addr) {
p_con->current_start_addr -= SCREEN_WIDTH; //一行一行的移动
}
}
else if (direction == SCR_DN) {
if (p_con->current_start_addr + SCREEN_SIZE <
p_con->original_addr + p_con->v_mem_limit) {
p_con->current_start_addr += SCREEN_WIDTH;
}
}
else{
}
set_video_start_addr(p_con->current_start_addr);
set_cursor(p_con->cursor);
}