modify the state machine;change to multi-parameter

This commit is contained in:
xiaoxiao 2023-01-19 23:05:15 +08:00
parent f9a75fa1e4
commit 27c1d3c033
3 changed files with 104 additions and 168 deletions

View File

@ -27,6 +27,9 @@
#define TTY_STATE_WAIT_SPACE 2 /*010*/ #define TTY_STATE_WAIT_SPACE 2 /*010*/
#define TTY_STATE_DISPLAY 1 /*001*/ #define TTY_STATE_DISPLAY 1 /*001*/
#define MAXNUM_PARAM 16
#define MAXNUM_PARAM_CH 100
typedef struct n_tty typedef struct n_tty
{ {
int driver_type; // 1-vga&kbd; 2-serial int driver_type; // 1-vga&kbd; 2-serial
@ -42,8 +45,7 @@ enum CSI_state
{ {
CSI_ESC, CSI_ESC,
CSI_BRACKET, CSI_BRACKET,
CSI_PARAM1, CSI_PARAM
CSI_PARAM2
}; };
typedef struct vga_buf typedef struct vga_buf
{ {
@ -56,14 +58,13 @@ typedef struct vga_buf
int cur_row; int cur_row;
int cur_col; // cursor position, on screen int cur_col; // cursor position, on screen
bool Is2param;
bool IsColorReverse; bool IsColorReverse;
bool IsHide; bool IsHide;
enum CSI_state CSI; enum CSI_state CSI;
i16 param1; // the first param of CSI char param_c[MAXNUM_PARAM_CH]; // the params of CSI
i16 param2; // the second of CSI u16 param_num;
u16 color; u16 color;
u16 last_color; // 为了某些功能关闭后,恢复原属性 u16 last_color; // 为了某些功能关闭后,恢复原属性
} vga_buf; } vga_buf;

View File

@ -212,148 +212,71 @@ disable_hide(vga_buf *vgabuf)
} }
} }
void set_color(vga_buf *vgabuf) void set_color(i16 param_cnt, i16 param[], vga_buf *vgabuf)
{ {
if (vgabuf->param1 == 0) for (int i = 0; i <= param_cnt; i++)
{
if (param[i] == 0)
{ {
disable_reverse(vgabuf); disable_reverse(vgabuf);
disable_hide(vgabuf); disable_hide(vgabuf);
vgabuf->color = DEFAULT_CHAR_COLOR; vgabuf->color = DEFAULT_CHAR_COLOR;
} }
else if (vgabuf->param1 == 7) else if (param[i] == 7)
{ {
enable_reverse(vgabuf); enable_reverse(vgabuf);
} }
else if (vgabuf->param1 == 8) else if (param[i] == 8)
{ {
enable_hide(vgabuf); enable_hide(vgabuf);
} }
else if (vgabuf->param1 == 25) else if (param[i] == 27)
{
disable_blink();
vgabuf->color &= (~FLASH_CHAR);
}
else if (vgabuf->param1 == 27)
{ {
disable_reverse(vgabuf); disable_reverse(vgabuf);
} }
else if (vgabuf->param1 == 28) else if (param[i] == 28)
{ {
disable_hide(vgabuf); disable_hide(vgabuf);
} }
else if (30 <= vgabuf->param1 && vgabuf->param1 <= 37) else if (30 <= param[i] && param[i] <= 37)
{ {
vgabuf->param1 -= 30; param[i] -= 30;
param12vga_color(&(vgabuf->param1)); param12vga_color(&(param[i]));
vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param1); vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(param[i]);
} }
else if (vgabuf->param1 == 39) else if (param[i] == 39)
{ {
u16 default_foreground = DEFAULT_CHAR_COLOR & 0x0f00; u16 default_foreground = DEFAULT_CHAR_COLOR & 0x0f00;
vgabuf->color = (vgabuf->color & 0xf0ff) | default_foreground; vgabuf->color = (vgabuf->color & 0xf0ff) | default_foreground;
} }
else if (40 <= vgabuf->param1 && vgabuf->param1 <= 47) else if (40 <= param[i] && param[i] <= 47)
{ {
vgabuf->param1 -= 40; param[i] -= 40;
param12vga_color(&(vgabuf->param1)); param12vga_color(&(param[i]));
vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param1); vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(param[i]);
} }
else if (vgabuf->param1 == 49) else if (param[i] == 49)
{ {
u16 default_background = DEFAULT_CHAR_COLOR & 0xf000; u16 default_background = DEFAULT_CHAR_COLOR & 0xf000;
vgabuf->color = (vgabuf->color & 0x0fff) | default_background; vgabuf->color = (vgabuf->color & 0x0fff) | default_background;
} }
else if (90 <= vgabuf->param1 && vgabuf->param1 <= 97) else if (90 <= param[i] && param[i] <= 97)
{ {
vgabuf->param1 -= 90; param[i] -= 90;
param12vga_color(&(vgabuf->param1)); param12vga_color(&(param[i]));
vgabuf->param1 |= 0x8; param[i] |= 0x8;
vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param1); vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(param[i]);
} }
else if (100 <= vgabuf->param1 && vgabuf->param1 <= 107) else if (100 <= param[i] && param[i] <= 107)
{ {
vgabuf->param1 -= 100; param[i] -= 100;
param12vga_color(&(vgabuf->param1)); param12vga_color(&(param[i]));
vgabuf->param1 |= 0x8; param[i] |= 0x8;
vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param1); vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(param[i]);
} }
else else
{ {
warn("\x1b[47;93munsupport CSI: sgr param:%d\x1b[m\n", vgabuf->param1); warn("\x1b[47;93munsupport CSI: sgr param[%d]:%d\x1b[m\n", i, param[i]);
}
if (vgabuf->Is2param == true)
{
if (vgabuf->param2 == 0)
{
disable_reverse(vgabuf);
disable_hide(vgabuf);
vgabuf->color = DEFAULT_CHAR_COLOR;
}
// else if (vgabuf->param2 == 5 || vgabuf->param2 == 6)
// {
// enable_blink();
// vgabuf->color |= FLASH_CHAR;
// }
else if (vgabuf->param2 == 7)
{
enable_reverse(vgabuf);
}
else if (vgabuf->param2 == 8)
{
enable_hide(vgabuf);
}
else if (vgabuf->param2 == 25)
{
disable_blink();
vgabuf->color &= (~FLASH_CHAR);
}
else if (vgabuf->param2 == 27)
{
disable_reverse(vgabuf);
}
else if (vgabuf->param2 == 28)
{
disable_hide(vgabuf);
}
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 (vgabuf->param2 == 39)
{
u16 default_foreground = DEFAULT_CHAR_COLOR & 0x0f00;
vgabuf->color = (vgabuf->color & 0xf0ff) | default_foreground;
}
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 (vgabuf->param2 == 49)
{
u16 default_background = DEFAULT_CHAR_COLOR & 0xf000;
vgabuf->color = (vgabuf->color & 0x0fff) | default_background;
}
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("\x1b[47;93unsupport CSI: sgr param:%d\n", vgabuf->param2);
} }
} }
} }
@ -405,88 +328,103 @@ void CSI_Erase_handler(vga_buf *vgabuf, int n)
void CSI_handler(u8 terminator, vga_buf *vgabuf) void CSI_handler(u8 terminator, vga_buf *vgabuf)
{ {
vgabuf->CSI = CSI_ESC; vgabuf->CSI = CSI_ESC;
i16 param[MAXNUM_PARAM] = {0};
i16 param_cnt = 0;
for (int i = 0; i < vgabuf->param_num && param_cnt < MAXNUM_PARAM; i++)
{
u8 ch = vgabuf->param_c[i];
if (ch != ';')
{
param[param_cnt] = param[param_cnt] * 10 + ch - '0';
}
else
{
param_cnt++;
continue;
}
}
switch (terminator) switch (terminator)
{ {
case 'A': // Cursor Up case 'A': // Cursor Up
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
cursor_move(-vgabuf->param1, 0, vgabuf); cursor_move(-param[0], 0, vgabuf);
break; break;
case 'B': // Cursor Down case 'B': // Cursor Down
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
cursor_move(+vgabuf->param1, 0, vgabuf); cursor_move(+param[0], 0, vgabuf);
break; break;
case 'C': // Cursor Forward case 'C': // Cursor Forward
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
cursor_move(0, +vgabuf->param1, vgabuf); cursor_move(0, +param[0], vgabuf);
break; break;
case 'D': // Cursor Back case 'D': // Cursor Back
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
cursor_move(0, -vgabuf->param1, vgabuf); // nothing cursor_move(0, -param[0], vgabuf); // nothing
break; break;
case 'E': // Cursor Next Line case 'E': // Cursor Next Line
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
cursor_move(+vgabuf->param1, -vgabuf->cur_col, vgabuf); cursor_move(+param[0], -vgabuf->cur_col, vgabuf);
break; break;
case 'F': // Cursor Previous Line case 'F': // Cursor Previous Line
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
cursor_move(-vgabuf->param1, -vgabuf->cur_col, vgabuf); cursor_move(-param[0], -vgabuf->cur_col, vgabuf);
break; break;
case 'G': // Cursor Horizontal Absolute case 'G': // Cursor Horizontal Absolute
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
cursor_locate(CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE), vgabuf->param1 - 1, vgabuf); cursor_locate(CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE), param[0] - 1, vgabuf);
break; break;
case 'H': // Cursor Position case 'H': // Cursor Position
case 'f': case 'f':
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
if (vgabuf->param2 == 0) if (param[1] == 0)
vgabuf->param2 = 1; param[1] = 1;
cursor_locate(vgabuf->param1 - 1, vgabuf->param2 - 1, vgabuf); cursor_locate(param[0] - 1, param[1] - 1, vgabuf);
break; break;
case 'J': // Erase in Display case 'J': // Erase in Display
if (vgabuf->param1 == 0) if (param[0] == 0)
// from Cursor Position to the end of the screen // from Cursor Position to the end of the screen
clear_screen(vgabuf, vgabuf->scr_cur_line, vgabuf->cur_col, ADDLINE(vgabuf->scr_top_line, SCR_HEIGHT - 1), SCR_WIDTH - 1); clear_screen(vgabuf, vgabuf->scr_cur_line, vgabuf->cur_col, ADDLINE(vgabuf->scr_top_line, SCR_HEIGHT - 1), SCR_WIDTH - 1);
else if (vgabuf->param1 == 1) else if (param[0] == 1)
// from Cursor Position to the start of the screen // from Cursor Position to the start of the screen
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 (param[0] == 2)
// The whole screen // The whole screen
CSI_Erase_handler(vgabuf, 2); CSI_Erase_handler(vgabuf, 2);
else if (vgabuf->param1 == 3) else if (param[0] == 3)
// The whole screen and the buffer // The whole screen and the buffer
CSI_Erase_handler(vgabuf, 3); CSI_Erase_handler(vgabuf, 3);
break; break;
case 'K': // Erase in Line case 'K': // Erase in Line
if (vgabuf->param1 == 0) if (param[0] == 0)
// from Cursor Position to the end of the line // from Cursor Position to the end of the line
clear_screen(vgabuf, vgabuf->scr_cur_line, vgabuf->cur_col, vgabuf->scr_cur_line, SCR_WIDTH - 1); clear_screen(vgabuf, vgabuf->scr_cur_line, vgabuf->cur_col, vgabuf->scr_cur_line, SCR_WIDTH - 1);
else if (vgabuf->param1 == 1) else if (param[0] == 1)
// from Cursor Position to the start of the line // from Cursor Position to the start of the line
clear_screen(vgabuf, vgabuf->scr_cur_line, 0, vgabuf->scr_cur_line, vgabuf->cur_col); clear_screen(vgabuf, vgabuf->scr_cur_line, 0, vgabuf->scr_cur_line, vgabuf->cur_col);
else if (vgabuf->param1 == 2) else if (param[0] == 2)
// The whole line // The whole line
clear_screen(vgabuf, vgabuf->scr_cur_line, 0, vgabuf->scr_cur_line, SCR_WIDTH - 1); clear_screen(vgabuf, vgabuf->scr_cur_line, 0, vgabuf->scr_cur_line, SCR_WIDTH - 1);
break; break;
case 'S': // Scroll Up case 'S': // Scroll Up
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
csi_scroll(vgabuf, -vgabuf->param1); csi_scroll(vgabuf, -param[0]);
break; break;
case 'T': // Scroll Down case 'T': // Scroll Down
if (vgabuf->param1 == 0) if (param[0] == 0)
vgabuf->param1 = 1; param[0] = 1;
csi_scroll(vgabuf, +vgabuf->param1); csi_scroll(vgabuf, +param[0]);
break; break;
case 'm': // Select Graphic Rendition case 'm': // Select Graphic Rendition
set_color(vgabuf); set_color(param_cnt, param, vgabuf);
break; break;
} }
} }

View File

@ -133,10 +133,10 @@ void vga_tty_init(NTTY *tty)
// buf->max_line = SCR_BUFSIZE / SCR_WIDTH; // buf->max_line = SCR_BUFSIZE / SCR_WIDTH;
vga->scr_top_line = vga->scr_cur_line = vga->scr_bot_line = 0; vga->scr_top_line = vga->scr_cur_line = vga->scr_bot_line = 0;
vga->head_line = 0; vga->head_line = 0;
vga->Is2param = false;
vga->IsColorReverse = false; vga->IsColorReverse = false;
vga->IsHide = false; vga->IsHide = false;
vga->color = DEFAULT_CHAR_COLOR; vga->color = DEFAULT_CHAR_COLOR;
vga->CSI = CSI_ESC;
u32 *ptr_buf = (u32 *)vga->buf; u32 *ptr_buf = (u32 *)vga->buf;
for (int i = 0; i < SCR_BUFSIZE * sizeof(u16) / sizeof(u32); ++i) for (int i = 0; i < SCR_BUFSIZE * sizeof(u16) / sizeof(u32); ++i)
{ {
@ -217,7 +217,6 @@ void vga_tty_write(NTTY *tty, char ch)
break; break;
case '\x1b': case '\x1b':
vga->CSI = CSI_BRACKET; vga->CSI = CSI_BRACKET;
vga->Is2param = false;
break; break;
default: default:
buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(vga->color, ch); buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(vga->color, ch);
@ -231,8 +230,13 @@ void vga_tty_write(NTTY *tty, char ch)
switch (ch) switch (ch)
{ {
case '[': case '[':
vga->CSI = CSI_PARAM1; vga->CSI = CSI_PARAM;
vga->param1 = vga->param2 = 0; // init
for (int i = 0; i < MAXNUM_PARAM_CH; i++)
{
vga->param_c[i] = 0;
}
vga->param_num = 0;
break; break;
default: default:
vga->CSI = CSI_ESC; vga->CSI = CSI_ESC;
@ -253,18 +257,11 @@ void vga_tty_write(NTTY *tty, char ch)
case '7': case '7':
case '8': case '8':
case '9': case '9':
if (vga->CSI == CSI_PARAM1)
vga->param1 = vga->param1 * 10 + ch - '0';
else if (vga->CSI == CSI_PARAM2)
vga->param2 = vga->param2 * 10 + ch - '0';
else
; // do nothing
break;
case ';': case ';':
if (vga->CSI == CSI_PARAM1) if (vga->param_num < MAXNUM_PARAM_CH)
{ {
vga->CSI = CSI_PARAM2; vga->param_c[vga->param_num] = ch;
vga->Is2param = true; vga->param_num++;
} }
break; break;
default: default: