⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 fairysky系统,是一个小型的内核,模拟linux原始版本的
💻 C
📖 第 1 页 / 共 2 页
字号:
	else if (!nr)
		nr = 1;
	while (nr--)
		insert_line();
}

static void csi_P(unsigned int nr)
{
	if (nr > VIDEO_NUM_COLUMNS)
		nr = VIDEO_NUM_COLUMNS;
	else if (!nr)
		nr = 1;
	while (nr--)
		delete_char();
}

static void csi_M(unsigned int nr)
{
	if (nr > video_num_lines)
		nr = video_num_lines;
	else if (!nr)
		nr=1;
	while (nr--)
		delete_line();
}



//新行
static void newline()
{
    if (y + 1 < bottom) {
        ++y;
        pos += video_size_row;
    } else {
        screen_up(top, bottom);
    }
}

//回车
static inline void enter()
{
    pos -= x << 1;
    x = 0;
}

//光标上已一行
static void reverse_line_feed(void)
{   
    if (y > top) {        
        y--;        
        pos -= video_size_row;      
        return; 
    } else {
      screen_down();
    }
}

//删除光标前一字符
static inline void del(int currcons)
{   
    if (x) {        
        pos -= 2;      
        x--;        
        *(unsigned short *)pos = video_erase_char;      
        need_wrap = 0;  
    }
}

static void respond(int currcons, struct tty_struct * tty)
{

	char * p = RESPONSE;

	cli();
	while (*p) {   
		PUTCH(*p, tty->read_q);
		p++;
	}
	sti();
	copy_to_cooked(tty);
	
}

enum {
    ESnormal,
    ESesc,
    ESsquare,
    ESgetpars,
    ESgotpars,
    ESfunckey,
    ESsetterm,
    ESsetgraph,
    ESgraph,
    ESgresc,
    ESignore
};

static int saved_x=0;
static int saved_y=0;

static void save_cur(void)
{
	saved_x = x;
	saved_y = y;
}

static void restore_cur(void)
{
	goto_xy(saved_x, saved_y);
}

void con_write(struct tty_struct * tty)
{
    int currcons = 0;
	int nr;
	char c;

	nr = CHARS(tty->write_q);
	while (nr--) {
		GETCH(tty->write_q, c);
        ////0:初始状态,或者原是状态4,或者原是状态1,但字符不是'['
        ////1:原是状态0,并且字符是转义字符ESC(0X1B)
        ////2:原是状态1,并且字符是'['
        ////3:原是状态2,或者原是状态3,并且字符是;或数字
        ////4:原是状态3,并且字符不是';'或数字
        
		switch(state) {
			case 0:
                //printk("|state==0|");
				if (c > 31 && c < 127) {//不是控制字符和扩展字符
					if (x >= VIDEO_NUM_COLUMNS) {
						x -= VIDEO_NUM_COLUMNS;
						pos -= video_size_row;
						newline();
					}

					__asm__("movb _attr, %%ah\n\t"
						"movw %%ax, %1\n\t"
						::"a" (c),"m" (*(short *)pos)
						);
                    
					pos += 2;
					x++;
				} else if (c == 27) {   //如果是转义符号
					state = 1;
                } else if (c == 10 || c == 11 || c == 12) { //如果是换行符,垂直制表符,换页符
					newline();
				} else if (c == 13) {   //如果是回车符
					enter();
				} else if (c == ERASE_CHAR(tty)) {  //如果是DEL,
					del(currcons);
				} else if (c == 8) {
					if (x) {
						x--;
						pos -= 2;
					}
				} else if (c == 9) {    //如果是TAB
					c = 8 - (x & 7);
					x += c;
					pos += c << 1;
					if (x > VIDEO_NUM_COLUMNS) {
						x -= VIDEO_NUM_COLUMNS;
						pos -= video_size_row;
						newline();
					}
					c=9;
				} else if (c == 7) {    //响铃符
					sysbeep();
                }
				break;
			case 1:
                //printk("|state==1|");
				state = 0;
				if (c == '[') {     //如果是'[',将状态转到2
					state = 2;
				} else if (c == 'E') {  
					goto_xy(currcons, y + 1);   //光标移到下一行开始处
				} else if (c == 'M') {
					reverse_line_feed();        //光标上移一行
				} else if (c == 'D') {
					newline();                  
				} else if (c == 'Z') {          //向终端发送应答字符序列
					respond(currcons, tty);
				} else if (c == '7') {
					save_cur();                 //保存光标位置
				} else if (c == '8') {
					restore_cur();              //恢复光标位置
                }
				break;
			case 2:
                //printk("|state==2|");
				for (npar = 0; npar < NPAR; npar++) {
					par[npar] = 0;
                }
				npar = 0;
				state = 3;
				if (ques = (c == '?')) {
					break;
                }
			case 3:
                //printk("|state==3|");
				if (c == ';' && npar < NPAR - 1) {
					npar++;
					break;
				} else if (c >= '0' && c <= '9') {
					par[npar] = 10 * par[npar] + c - '0';
					break;
				} else {
				    state=4;
                }
			case 4:
                //printk("|state==4|");
				state = 0;
				switch(c) {
					case 'G': 
                    case '`':
						if (par[0]) {
                            par[0]--;
                        }
						goto_xy(par[0], y);
						break;
					case 'A':
						if (!par[0]) {
                            par[0]++;
                        }
						goto_xy(x, y - par[0]);
						break;
					case 'B': 
                    case 'e':
						if (!par[0]) {
                            par[0]++;
                        }
						goto_xy(x, y + par[0]);
						break;
					case 'C': 
                    case 'a':
						if (!par[0]) {
                            par[0]++;
                        }
						goto_xy(x + par[0], y);
						break;
					case 'D':
						if (!par[0]) {
                            par[0]++;
                        }
			 			goto_xy(x - par[0],y);
						break;
					case 'E':
						if (!par[0]) {
                            par[0]++;
                        }
						goto_xy(0, y + par[0]);
						break;
					case 'F':
						if (!par[0]) {
                            par[0]++;
                        }
						goto_xy(0, y - par[0]);
						break;
					case 'd':
						if (par[0]) {
                            par[0]--;
                        }
						goto_xy(x, par[0]);
						break;
					case 'H': 
                    case 'f':
						if (par[0]) {
                            par[0]--;
                        }
						if (par[1]) {
                            par[1]--;
                        }
						goto_xy(par[1], par[0]);
						break;
					case 'J':
						csi_J(par[0]);
						break;
					case 'K':
						csi_K(par[0]);
						break;
					case 'L':
						csi_L(par[0]);
						break;
					case 'M':
						csi_M(par[0]);
						break;
					case 'P':
						csi_P(par[0]);
						break;
					case '@':
						csi_at(par[0]);
						break;
					case 'm':
						csi_m();
						break;
					case 'r':
						if (par[0]) {
                            par[0]--;
                        }
						if (!par[1]) {
                            par[1] = video_num_lines;
                        }
						if (par[0] < par[1] &&
						        par[1] <= video_num_lines) {
							top = par[0];
							bottom = par[1];
						}
						break;
					case 's':
						save_cur();
						break;
					case 'u':
						restore_cur();
						break;
				}
		}
	}
	set_cursor();
}

static void sysbeep(void)
{
    /*
        // enable counter 2 
        outb_p(inb_p(0x61)|3, 0x61);    
        // set command for counter 2, 2 byte write 
        outb_p(0xB6, 0x43); 
        // send 0x637 for 750 HZ 
        outb_p(0x37, 0x42); outb(0x06, 0x42);   
        // 1/8 second  
        timer_table[BEEP_TIMER].expires = jiffies + HZ/8;   
        timer_table[BEEP_TIMER].fn = sysbeepstop;   
        timer_active |= 1<<BEEP_TIMER;
        */
}

//直接在显示内存显示字符串
void console_print(const char *str)
{
    char c;

    while (c = *(str++)) {
        if (c == 10 || c == 13) {
            if (c == 10) {
                newline();
            }
            enter();
        } else {
            *(char *) pos = c;
            *(char *) (pos + 1) = ATTR;
            if (x == VIDEO_NUM_COLUMNS - 1) {
                newline();
                enter();
            } else {
                x++;
                pos += 2;
            }
        }
    }
    set_cursor();
}

//初始化控制台
void con_init()
{
    int currcons = 0;
    u16 *pmemchar;
    
    //暂时设置显示内存地址,现在比较笨,写死了,以后在根据显卡类型判断吧
    video_mem_base = 0xC00B8000;
    video_mem_term = 0xC00BDDC0;   

    video_mem_start = video_mem_base;
    video_mem_end = video_mem_term;

    origin = video_mem_base;
    pos = origin;
    video_size_row = VIDEO_NUM_COLUMNS * 2;
    bottom = video_num_lines;
    screen_end = video_mem_start + video_size_row * video_num_lines;

    video_erase_char = (7 << 8) | ' ';
    
	//for (currcons = 0; currcons < NR_CONSOLES; currcons++) {		   
    //    reset_terminal(currcons, currcons); 
    //}
    
    goto_xy(0, 0);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -