fix bug(Erase,Scorll)

This commit is contained in:
xiaoxiao 2022-12-30 00:44:31 +08:00
parent b3f160accf
commit 220b36f4e3
2 changed files with 171 additions and 88 deletions

View File

@ -150,35 +150,47 @@ void vga_tty_init(NTTY *tty)
// called by csi // called by csi
static void csi_scroll(vga_buf *vgabuf, i16 scroll_num) static void csi_scroll(vga_buf *vgabuf, i16 scroll_num)
{ {
u16 *buf = vgabuf->buf; while (scroll_num > 0) // down
while (scroll_num > 0)
{ {
// down
scroll_num--; 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); int line_dst = ADDLINE(vgabuf->scr_top_line, i);
if (vgabuf->scr_top_line == vgabuf->head_line) 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); *ptr_buf_dst++ = *ptr_buf_src++;
return;
} }
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++; scroll_num++;
if (vgabuf->scr_top_line == vgabuf->head_line)
return; for (int i = 0; i < SCR_HEIGHT - 1; i++)
vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line); {
if (CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE) == SCR_HEIGHT) int line_dst = ADDLINE(vgabuf->scr_top_line, i);
vgabuf->scr_cur_line = LASTLINE(vgabuf->scr_cur_line); int line_src = ADDLINE(vgabuf->scr_top_line, i + 1);
// if (CYCLE_SUB(vgabuf->scr_bot_line, vgabuf->scr_bot_line, SCR_MAXLINE) == SCR_HEIGHT) u32 *ptr_buf_dst = (u32 *)(vgabuf->buf + sizeof(u16) * line_dst * SCR_WIDTH);
// vgabuf->scr_bot_line = LASTLINE(vgabuf->scr_bot_line); 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) static void cursor_locate(i16 row, i16 col, vga_buf *vgabuf)
{ {
if (row == 0)
{ vgabuf->scr_cur_line = vgabuf->scr_top_line;
vgabuf->scr_cur_line = vgabuf->scr_top_line; while (row > 0 && row < SCR_HEIGHT)
}
while (row > 0 && row < SCR_HEIGHT - 1)
{ {
row--; 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) if (vgabuf->scr_cur_line == vgabuf->scr_bot_line)
break; break;
} }
@ -347,51 +357,96 @@ static void set_color(vga_buf *vgabuf)
{ {
warn("unsupport CSI: color"); warn("unsupport CSI: color");
} }
if (vgabuf->CSI == CSI_PARAM2)
if (vgabuf->param2 == 0 && vgabuf->param1 == 0)
{ {
vgabuf->color = DEFAULT_CHAR_COLOR; if (vgabuf->param2 == 0 && vgabuf->param1 == 0)
} {
else if (vgabuf->param2 == 1) vgabuf->color = DEFAULT_CHAR_COLOR;
{ }
vgabuf->color |= 0x8800; else if (vgabuf->param2 == 1)
} {
else if (vgabuf->param2 == 2) vgabuf->color |= 0x8800;
{ }
vgabuf->color &= 0x7700; else if (vgabuf->param2 == 2)
} {
else if (30 <= vgabuf->param2 && vgabuf->param2 <= 37) vgabuf->color &= 0x7700;
{ }
vgabuf->param2 -= 30; else if (30 <= vgabuf->param2 && vgabuf->param2 <= 37)
param12vga_color(&(vgabuf->param2)); {
vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param2); vgabuf->param2 -= 30;
} param12vga_color(&(vgabuf->param2));
else if (40 <= vgabuf->param2 && vgabuf->param2 <= 47) vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param2);
{ }
vgabuf->param2 -= 40; else if (40 <= vgabuf->param2 && vgabuf->param2 <= 47)
param12vga_color(&(vgabuf->param2)); {
vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param2); vgabuf->param2 -= 40;
} param12vga_color(&(vgabuf->param2));
else if (90 <= vgabuf->param2 && vgabuf->param2 <= 97) vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param2);
{ }
vgabuf->param2 -= 90; else if (90 <= vgabuf->param2 && vgabuf->param2 <= 97)
param12vga_color(&(vgabuf->param2)); {
vgabuf->param2 |= 0x8; vgabuf->param2 -= 90;
vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param2); param12vga_color(&(vgabuf->param2));
} vgabuf->param2 |= 0x8;
else if (100 <= vgabuf->param2 && vgabuf->param2 <= 107) vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param2);
{ }
vgabuf->param2 -= 100; else if (100 <= vgabuf->param2 && vgabuf->param2 <= 107)
param12vga_color(&(vgabuf->param2)); {
vgabuf->param2 |= 0x8; vgabuf->param2 -= 100;
vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param2); param12vga_color(&(vgabuf->param2));
} vgabuf->param2 |= 0x8;
else vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param2);
{ }
warn("unsupport CSI: color"); 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) static void CSI_handler(u8 terminator, vga_buf *vgabuf)
{ {
vgabuf->CSI = CSI_ESC; vgabuf->CSI = CSI_ESC;
@ -429,11 +484,11 @@ static void CSI_handler(u8 terminator, vga_buf *vgabuf)
break; break;
case 'G': // added case 'G': // added
if (vgabuf->param1 == 0) if (vgabuf->param1 == 0)
vgabuf->param1 == 1; 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; break;
case 'H': case 'H':
case 'f':
if (vgabuf->param1 == 0) if (vgabuf->param1 == 0)
vgabuf->param1 == 1; vgabuf->param1 == 1;
if (vgabuf->param2 == 0) if (vgabuf->param2 == 0)
@ -446,18 +501,9 @@ static void CSI_handler(u8 terminator, vga_buf *vgabuf)
else if (vgabuf->param1 == 1) else if (vgabuf->param1 == 1)
clear_screen(vgabuf, vgabuf->scr_top_line, 0, vgabuf->scr_cur_line, vgabuf->cur_col); clear_screen(vgabuf, vgabuf->scr_top_line, 0, vgabuf->scr_cur_line, vgabuf->cur_col);
else if (vgabuf->param1 == 2) else if (vgabuf->param1 == 2)
{ CSI_Erase_handler(vgabuf, 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;
}
else if (vgabuf->param1 == 3) else if (vgabuf->param1 == 3)
{ CSI_Erase_handler(vgabuf, 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;
}
break; break;
case 'K': case 'K':
if (vgabuf->param1 == 0) if (vgabuf->param1 == 0)

View File

@ -16,10 +16,10 @@ int main(int arg, char *argv[])
char buf[1024]; char buf[1024];
int pid; int pid;
int times = 0; int times = 0;
for (int i = 0; i < 20; ++i) // for (int i = 0; i < 20; ++i)
{ // {
printf("test %d\n", i); // printf("test %d\n", i);
} // }
// for (int i = 0; i < 2; ++i) // for (int i = 0; i < 2; ++i)
// { // {
// printf("\x1b[42;31m1111111111"); // printf("\x1b[42;31m1111111111");
@ -34,12 +34,49 @@ int main(int arg, char *argv[])
// printf("8888888888"); // printf("8888888888");
// printf("9999999999\r\b\b\n"); // 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("11111111111111111\n");
} }
printf("111111111"); printf("555555");
printf("\x1b[2S");
// 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) while (1)
; ;