CLS Command
Added a CLS command and ANSI ED support
This commit is contained in:
parent
f904ed112b
commit
a14406b6de
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -53,3 +53,4 @@ dkms.conf
|
|||
samples/HelloPGX/hello.pgx
|
||||
samples/HelloPGX/hello.pgx
|
||||
samples/HelloPGX/hello.lst
|
||||
src/mapfile
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct s_cli_command {
|
|||
extern short cmd_gettime(short channel, int argc, char * argv[]);
|
||||
extern short cmd_settime(short channel, int argc, char * argv[]);
|
||||
extern short cmd_sysinfo(short channel, int argc, char * argv[]);
|
||||
extern short cmd_cls(short channel, int argc, char * argv[]);
|
||||
|
||||
/*
|
||||
* Variables
|
||||
|
@ -42,6 +43,7 @@ short g_current_channel = 0;
|
|||
const t_cli_command g_cli_commands[] = {
|
||||
{ "?", "? -- print this helpful message", cmd_help },
|
||||
{ "HELP", "HELP -- print this helpful message", cmd_help },
|
||||
{ "CLS", "CLS -- clear the screen", cmd_cls },
|
||||
{ "DIR", "DIR <path> -- print directory listing", cmd_dir },
|
||||
{ "DUMP", "DUMP <address> [<count>] -- print a memory dump", mem_cmd_dump},
|
||||
{ "LOAD", "LOAD <path> -- load a file into memory", cmd_load },
|
||||
|
@ -73,6 +75,16 @@ int cmd_help(short channel, int argc, char * argv[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the screen
|
||||
*/
|
||||
short cmd_cls(short channel, int argc, char * argv[]) {
|
||||
const char * ansi_cls = "\x1B[2J\x1B[H";
|
||||
|
||||
sys_chan_write(channel, ansi_cls, strlen(ansi_cls));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display information about the system
|
||||
*/
|
||||
|
|
|
@ -48,6 +48,8 @@ extern void ansi_cuu(p_channel chan, short arg_count, short args[]);
|
|||
extern void ansi_cuf(p_channel chan, short arg_count, short args[]);
|
||||
extern void ansi_cub(p_channel chan, short arg_count, short args[]);
|
||||
extern void ansi_cud(p_channel chan, short arg_count, short args[]);
|
||||
extern void ansi_cup(p_channel chan, short arg_count, short args[]);
|
||||
extern void ansi_ed(p_channel chan, short arg_count, short args[]);
|
||||
|
||||
/*
|
||||
* Console variables and constants
|
||||
|
@ -59,10 +61,13 @@ extern void ansi_cud(p_channel chan, short arg_count, short args[]);
|
|||
*
|
||||
*/
|
||||
const t_ansi_seq ansi_sequence[] = {
|
||||
{ "\x27[#A", ansi_cuu },
|
||||
{ "\x27[#B", ansi_cuf },
|
||||
{ "\x27[#C", ansi_cub },
|
||||
{ "\x27[#D", ansi_cud },
|
||||
{ "\x1B[H", ansi_cup },
|
||||
{ "\x1B[#A", ansi_cuu },
|
||||
{ "\x1B[#B", ansi_cuf },
|
||||
{ "\x1B[#C", ansi_cub },
|
||||
{ "\x1B[#D", ansi_cud },
|
||||
{ "\x1B[#J", ansi_ed },
|
||||
{ "\x1B[#;#H", ansi_cup },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -146,6 +151,43 @@ void ansi_cud(p_channel chan, short arg_count, short args[]) {
|
|||
text_set_xy(chan->dev, x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* ANSI Handler: cursor position
|
||||
*/
|
||||
void ansi_cup(p_channel chan, short arg_count, short args[]) {
|
||||
unsigned short x = 1;
|
||||
unsigned short y = 1;
|
||||
|
||||
TRACE("ansi_cup");
|
||||
|
||||
if (arg_count > 0) {
|
||||
x = args[0];
|
||||
if (arg_count > 1) {
|
||||
y = args[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (x == 0) x = 1;
|
||||
if (y == 0) y = 1;
|
||||
|
||||
text_set_xy(chan->dev, x - 1, y - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ANSI Handler: erase in display
|
||||
*/
|
||||
void ansi_ed(p_channel chan, short arg_count, short args[]) {
|
||||
unsigned short n = 2;
|
||||
|
||||
TRACE("ansi_ed");
|
||||
|
||||
if (arg_count > 0) {
|
||||
n = args[0];
|
||||
}
|
||||
|
||||
text_clear(chan->dev, n);
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the console... nothing needs to happen here
|
||||
//
|
||||
|
@ -223,7 +265,7 @@ short con_close(p_channel chan) {
|
|||
*/
|
||||
short ansi_start_code(char c) {
|
||||
switch (c) {
|
||||
case '\x27':
|
||||
case CHAR_ESC:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
@ -259,6 +301,11 @@ short ansi_match_pattern(p_channel chan, p_console_data con_data, p_ansi_seq seq
|
|||
} else if (pattern[i] == '#') {
|
||||
/* Parse a number of decimal digits */
|
||||
arg[arg_idx] = 0;
|
||||
if (buffer[j] == pattern[i+1]) {
|
||||
/* Parameter is missing... set to zero */
|
||||
arg_idx++;
|
||||
|
||||
} else {
|
||||
while (isdigit(buffer[j]) && (j < buffer_count)) {
|
||||
arg[arg_idx] = arg[arg_idx] * 10 + (buffer[j] - '0');
|
||||
j++;
|
||||
|
@ -271,6 +318,7 @@ short ansi_match_pattern(p_channel chan, p_console_data con_data, p_ansi_seq seq
|
|||
/* We've read a number */
|
||||
arg_idx++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ int text_init() {
|
|||
|
||||
text_setsizes(0);
|
||||
text_set_color(0, 15, 3);
|
||||
text_clear(0);
|
||||
text_clear(0, 2);
|
||||
text_set_cursor(0, 0xF3, 0xB1, 1, 1);
|
||||
text_set_xy(0, 0, 0);
|
||||
|
||||
|
@ -133,7 +133,7 @@ int text_init() {
|
|||
|
||||
text_setsizes(1);
|
||||
text_set_color(1, 15, 3);
|
||||
text_clear(1);
|
||||
text_clear(1, 2);
|
||||
text_set_cursor(1, 0xF3, 0xB1, 1, 1);
|
||||
text_set_xy(1, 0, 0);
|
||||
|
||||
|
@ -307,15 +307,41 @@ void text_set_color(short screen, short foreground, short background) {
|
|||
*
|
||||
* Inputs:
|
||||
* screen = the screen number 0 for channel A, 1 for channel B
|
||||
* mode = 0: erase from home to cursor, 1: erase from cursor to end of screen, 2: erase entire screen
|
||||
*/
|
||||
void text_clear(short screen) {
|
||||
void text_clear(short screen, short mode) {
|
||||
if (screen < MAX_TEXT_CHANNELS) {
|
||||
int i;
|
||||
p_text_channel chan = &text_channel[screen];
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
/* Clear from cursor to the end of the screen */
|
||||
for (i = chan->y * chan->columns_max + chan->x; i < chan->columns_max * chan->rows_max; i++) {
|
||||
chan->text_cells[i] = ' ';
|
||||
chan->color_cells[i] = chan->current_color;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Clear from (0, 0) to cursor */
|
||||
for (i = 0; i <= chan->y * chan->columns_max + chan->x; i++) {
|
||||
chan->text_cells[i] = ' ';
|
||||
chan->color_cells[i] = chan->current_color;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Clear entire screen */
|
||||
for (i = 0; i < chan->columns_max * chan->rows_max; i++) {
|
||||
chan->text_cells[i] = ' ';
|
||||
chan->color_cells[i] = chan->current_color;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ extern void text_set_color(short screen, short foreground, short background);
|
|||
* Inputs:
|
||||
* screen = the screen number 0 for channel A, 1 for channel B
|
||||
*/
|
||||
extern void text_clear(short screen);
|
||||
extern void text_clear(short screen, short mode);
|
||||
|
||||
/*
|
||||
* Scroll the text screen up one row
|
||||
|
|
|
@ -298,7 +298,7 @@ int main(int argc, char * argv[]) {
|
|||
|
||||
initialize();
|
||||
|
||||
const char * welcome = "Foenix/MCP Command Line Utility... online.\nType \"HELP\" or \"?\" for help.\n";
|
||||
const char * welcome = "\x1B[HFoenix/MCP Command Line Utility... online.\x1B[;2HType \"HELP\" or \"?\" for help.\n";
|
||||
sys_chan_write(0, welcome, strlen(welcome));
|
||||
cli_repl(0);
|
||||
|
||||
|
|
4227
src/foenixmcp.s68
4227
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,7 @@
|
|||
* Definitions of special characters
|
||||
*/
|
||||
|
||||
#define CHAR_ESC '\x2b' // Escape character
|
||||
#define CHAR_ESC '\x1B' // Escape character
|
||||
#define CHAR_CR '\x0D' // Carriage return
|
||||
#define CHAR_NL '\x0A' // Newline character
|
||||
#define CHAR_BS '\b' // Backspace
|
||||
|
|
9443
src/mapfile
9443
src/mapfile
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue