From 220b36f4e39e5bc43bd14ab0db65ad93bea00367 Mon Sep 17 00:00:00 2001 From: xiaoxiao <1010386862@qq.com> Date: Fri, 30 Dec 2022 00:44:31 +0800 Subject: [PATCH] fix bug(Erase,Scorll) --- kernel/vga.c | 206 +++++++++++++++++++++++++++++++-------------------- user/test.c | 53 +++++++++++-- 2 files changed, 171 insertions(+), 88 deletions(-) diff --git a/kernel/vga.c b/kernel/vga.c index be3e4d6..fa9a272 100644 --- a/kernel/vga.c +++ b/kernel/vga.c @@ -150,35 +150,47 @@ void vga_tty_init(NTTY *tty) // called by csi static void csi_scroll(vga_buf *vgabuf, i16 scroll_num) { - u16 *buf = vgabuf->buf; - while (scroll_num > 0) + while (scroll_num > 0) // down { - // down scroll_num--; - if (vgabuf->scr_top_line == vgabuf->scr_cur_line) + for (int i = SCR_HEIGHT - 1; i > 0; i--) { - vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line); - if (vgabuf->scr_top_line == vgabuf->head_line) + int line_dst = ADDLINE(vgabuf->scr_top_line, i); + int line_src = ADDLINE(vgabuf->scr_top_line, i - 1); + u32 *ptr_buf_dst = (u32 *)(vgabuf->buf + sizeof(u16) * line_dst * SCR_WIDTH); + u32 *ptr_buf_src = (u32 *)(vgabuf->buf + sizeof(u16) * line_src * SCR_WIDTH); + for (int p = 0; p < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++p) { - vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line); - return; + *ptr_buf_dst++ = *ptr_buf_src++; } - vgabuf->scr_bot_line = NEXTLINE(vgabuf->scr_bot_line); - vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line); } - vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line); + u32 *ptr_buf_start = (u32 *)(vgabuf->buf + sizeof(u16) * (vgabuf->scr_top_line) * SCR_WIDTH); + for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) + { + *ptr_buf_start++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space + } } - while (scroll_num < 0) + while (scroll_num < 0) // up { - // up scroll_num++; - if (vgabuf->scr_top_line == vgabuf->head_line) - return; - vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line); - if (CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE) == SCR_HEIGHT) - vgabuf->scr_cur_line = LASTLINE(vgabuf->scr_cur_line); - // if (CYCLE_SUB(vgabuf->scr_bot_line, vgabuf->scr_bot_line, SCR_MAXLINE) == SCR_HEIGHT) - // vgabuf->scr_bot_line = LASTLINE(vgabuf->scr_bot_line); + + for (int i = 0; i < SCR_HEIGHT - 1; i++) + { + int line_dst = ADDLINE(vgabuf->scr_top_line, i); + int line_src = ADDLINE(vgabuf->scr_top_line, i + 1); + u32 *ptr_buf_dst = (u32 *)(vgabuf->buf + sizeof(u16) * line_dst * SCR_WIDTH); + u32 *ptr_buf_src = (u32 *)(vgabuf->buf + sizeof(u16) * line_src * SCR_WIDTH); + for (int p = 0; p < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++p) + { + *ptr_buf_dst++ = *ptr_buf_src++; + } + } + int line_end = ADDLINE(vgabuf->scr_top_line, SCR_HEIGHT - 1); + u32 *ptr_buf_end = (u32 *)(vgabuf->buf + sizeof(u16) * line_end * SCR_WIDTH); + for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) + { + *ptr_buf_end++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space + } } } @@ -221,14 +233,12 @@ static void nextcol(vga_buf *vgabuf) static void cursor_locate(i16 row, i16 col, vga_buf *vgabuf) { - if (row == 0) - { - vgabuf->scr_cur_line = vgabuf->scr_top_line; - } - while (row > 0 && row < SCR_HEIGHT - 1) + + vgabuf->scr_cur_line = vgabuf->scr_top_line; + while (row > 0 && row < SCR_HEIGHT) { row--; - vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_top_line); + vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line); if (vgabuf->scr_cur_line == vgabuf->scr_bot_line) break; } @@ -347,51 +357,96 @@ static void set_color(vga_buf *vgabuf) { warn("unsupport CSI: color"); } - - if (vgabuf->param2 == 0 && vgabuf->param1 == 0) + if (vgabuf->CSI == CSI_PARAM2) { - vgabuf->color = DEFAULT_CHAR_COLOR; - } - else if (vgabuf->param2 == 1) - { - vgabuf->color |= 0x8800; - } - else if (vgabuf->param2 == 2) - { - vgabuf->color &= 0x7700; - } - else if (30 <= vgabuf->param2 && vgabuf->param2 <= 37) - { - vgabuf->param2 -= 30; - param12vga_color(&(vgabuf->param2)); - vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param2); - } - else if (40 <= vgabuf->param2 && vgabuf->param2 <= 47) - { - vgabuf->param2 -= 40; - param12vga_color(&(vgabuf->param2)); - vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param2); - } - else if (90 <= vgabuf->param2 && vgabuf->param2 <= 97) - { - vgabuf->param2 -= 90; - param12vga_color(&(vgabuf->param2)); - vgabuf->param2 |= 0x8; - vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param2); - } - else if (100 <= vgabuf->param2 && vgabuf->param2 <= 107) - { - vgabuf->param2 -= 100; - param12vga_color(&(vgabuf->param2)); - vgabuf->param2 |= 0x8; - vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param2); - } - else - { - warn("unsupport CSI: color"); + if (vgabuf->param2 == 0 && vgabuf->param1 == 0) + { + vgabuf->color = DEFAULT_CHAR_COLOR; + } + else if (vgabuf->param2 == 1) + { + vgabuf->color |= 0x8800; + } + else if (vgabuf->param2 == 2) + { + vgabuf->color &= 0x7700; + } + else if (30 <= vgabuf->param2 && vgabuf->param2 <= 37) + { + vgabuf->param2 -= 30; + param12vga_color(&(vgabuf->param2)); + vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param2); + } + else if (40 <= vgabuf->param2 && vgabuf->param2 <= 47) + { + vgabuf->param2 -= 40; + param12vga_color(&(vgabuf->param2)); + vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param2); + } + else if (90 <= vgabuf->param2 && vgabuf->param2 <= 97) + { + vgabuf->param2 -= 90; + param12vga_color(&(vgabuf->param2)); + vgabuf->param2 |= 0x8; + vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param2); + } + else if (100 <= vgabuf->param2 && vgabuf->param2 <= 107) + { + vgabuf->param2 -= 100; + param12vga_color(&(vgabuf->param2)); + vgabuf->param2 |= 0x8; + vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param2); + } + else + { + warn("unsupport CSI: color"); + } } } +static void CSI_Erase_handler(vga_buf *vgabuf, int n) +{ + if (n == 2) + { + vgabuf->scr_bot_line = ADDLINE(vgabuf->scr_top_line, SCR_HEIGHT - 1); + for (int i = 0; i < SCR_HEIGHT; i++) + { + vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line); + vgabuf->scr_bot_line = NEXTLINE(vgabuf->scr_bot_line); + // kprintf("af %x\n", vgabuf->scr_cur_line); + vgabuf->cur_row = CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_bot_line, SCR_MAXLINE); + if (vgabuf->cur_row == SCR_HEIGHT) + { + // auto scroll + vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line); + } + if (vgabuf->scr_bot_line == vgabuf->head_line) + { + vgabuf->head_line = NEXTLINE(vgabuf->head_line); + // remember to fill blank the old line + u32 *ptr_buf = (u32 *)(vgabuf->buf + sizeof(u16) * vgabuf->scr_bot_line * SCR_WIDTH); + for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) + { + *ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space + } + } + } + } + if (n == 3) + { + int line = vgabuf->head_line; + while (line != vgabuf->scr_top_line) + { + u32 *ptr_buf = (u32 *)(vgabuf->buf + sizeof(u16) * line * SCR_WIDTH); + for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) + { + *ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space + } + line = NEXTLINE(line); + } + vgabuf->head_line = vgabuf->scr_top_line; + } +} static void CSI_handler(u8 terminator, vga_buf *vgabuf) { vgabuf->CSI = CSI_ESC; @@ -429,11 +484,11 @@ static void CSI_handler(u8 terminator, vga_buf *vgabuf) break; case 'G': // added if (vgabuf->param1 == 0) - vgabuf->param1 == 1; - cursor_locate(vgabuf->scr_cur_line, vgabuf->param1 - 1, vgabuf); + cursor_locate(CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE), vgabuf->param1 - 1, vgabuf); break; case 'H': + case 'f': if (vgabuf->param1 == 0) vgabuf->param1 == 1; if (vgabuf->param2 == 0) @@ -446,18 +501,9 @@ static void CSI_handler(u8 terminator, vga_buf *vgabuf) else if (vgabuf->param1 == 1) clear_screen(vgabuf, vgabuf->scr_top_line, 0, vgabuf->scr_cur_line, vgabuf->cur_col); else if (vgabuf->param1 == 2) - { - clear_screen(vgabuf, vgabuf->scr_top_line, 0, ADDLINE(vgabuf->scr_top_line, SCR_HEIGHT - 1), SCR_WIDTH - 1); - vgabuf->cur_col = 0; - vgabuf->scr_cur_line = vgabuf->scr_top_line; - } + CSI_Erase_handler(vgabuf, 2); else if (vgabuf->param1 == 3) - { - clear_screen(vgabuf, 0, 0, SCR_MAXLINE - 1, SCR_WIDTH - 1); - vgabuf->cur_col = vgabuf->cur_row = 0; - vgabuf->scr_top_line = vgabuf->scr_cur_line = 0; - vgabuf->head_line = 0; - } + CSI_Erase_handler(vgabuf, 3); break; case 'K': if (vgabuf->param1 == 0) diff --git a/user/test.c b/user/test.c index a98d225..5221b5a 100644 --- a/user/test.c +++ b/user/test.c @@ -16,10 +16,10 @@ int main(int arg, char *argv[]) char buf[1024]; int pid; int times = 0; - for (int i = 0; i < 20; ++i) - { - printf("test %d\n", i); - } + // for (int i = 0; i < 20; ++i) + // { + // printf("test %d\n", i); + // } // for (int i = 0; i < 2; ++i) // { // printf("\x1b[42;31m1111111111"); @@ -34,14 +34,51 @@ int main(int arg, char *argv[]) // printf("8888888888"); // printf("9999999999\r\b\b\n"); // } - for (int i = 0; i < 10; i++) + printf("\x1b[36m"); + for (int i = 0; i < 40; i++) { + printf("%d", i); printf("11111111111111111\n"); } - printf("111111111"); - printf("\x1b[2S"); + printf("555555"); + + // Cursor Up + printf("\x1b[2A"); + + // Cursor down + // printf("\x1b[2B"); + + // Cursor Forward + // printf("\x1b[20C"); + + // Cursor Back + printf("\x1b[2D"); + + // Cursor Next Line + // printf("\x1b[3E"); + + // Cursor Previous Line + // printf("\x1b[3F"); + + // Cursor Horizontal Absolute + // printf("\x1b[2G"); + + // Cursor Position + // printf("\x1b[3;5H"); + + // Erase in Display + // printf("\x1b[3J"); + + // Erase in Line + printf("\x1b[K"); + + // Scroll Up + // printf("\x1b[13S"); + + // Scroll Down + // printf("\x1b[13T"); while (1) ; return 0; -} \ No newline at end of file +}