console.c

来自「一个用于学习的操作系统」· C语言 代码 · 共 788 行 · 第 1/2 页

C
788
字号
    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 init_con()
{
    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 + =
减小字号Ctrl + -
显示快捷键?