Add support for command line editing

The current code for entering commands via the serial CLI is completely
refactored and moved out of rtlplayground.c into a separate file cmd_edit.c
putting code into BANK2.
The serial ring buffer sbuf[] is now exclusively used for receiving
keys, including escape sequences (DEL will generate a 4-byte escape
sequence). The command is now held in cmd_buffer. This reduces
XMEM use, because the serial buffer can be much smaller.

Supported is only editing the current command line via backspace, del,
cursor left and right.

Because the code cannot distinguish escape sequences which are not yet
complete (because the serial isr has not yet put all characters into
the serial buffer) from the dozens of unsupported ones (F-keys/home,
Page up/down, cursor up/down...) they are ignored and remain in the
serial buffer until the ring-pointer overwrites them. This is standard
behaviour for consoles, which will print out garbage for unsupported
characters. In this implementation, the command line buffer and the
visible command line in the terminal are always synced, so garbage
can be removed again by ediing the line.

The code makes several redundant checks in order to prevent race-conditions
between the serial ISR and the comand-editing code.
This commit is contained in:
logicog
2026-02-24 19:57:22 +01:00
parent 284b2b003d
commit 94d4ace88b
8 changed files with 176 additions and 56 deletions
+17 -15
View File
@@ -51,17 +51,16 @@ __xdata uint8_t hexvalue[4] = { 0 };
// Buffer for writing to flash 0x1fd000, copy to 0x1fe000
__xdata uint8_t cmd_buffer[SBUF_SIZE];
__xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
__xdata uint8_t cmd_available;
__xdata uint8_t l;
__xdata uint8_t line_ptr;
__xdata char is_white;
__xdata char save_cmd;
__xdata uint8_t ip[4];
#define N_WORDS SBUF_SIZE
#define N_WORDS CMD_BUF_SIZE
__xdata signed char cmd_words_b[N_WORDS];
__xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
@@ -93,7 +92,7 @@ uint8_t cmd_compare(uint8_t start, uint8_t * __code cmd)
signed char j = 0;
for (i = cmd_words_b[start]; i != cmd_words_b[start + 1] && cmd_buffer[i] != ' '; i++) {
i &= SBUF_SIZE - 1;
i &= CMD_BUF_SIZE - 1;
// print_byte(i); write_char(':'); print_byte(j); write_char('#'); print_string("\n");
// write_char('>'); write_char(cmd[j]); write_char('-'); write_char(cmd_buffer[i]); print_string("\n");
if (!cmd[j] && !isletter(cmd_buffer[i]))
@@ -710,7 +709,7 @@ uint8_t cmd_tokenize(void) __banked
is_white = 1;
uint8_t word = 0;
cmd_words_b[0] = -1;
while (cmd_buffer[line_ptr] && line_ptr < SBUF_SIZE - 1) {
while (cmd_buffer[line_ptr] && line_ptr < CMD_BUF_SIZE - 1) {
if (is_white && cmd_buffer[line_ptr] != ' ') {
is_white = 0;
cmd_words_b[word++] = line_ptr;
@@ -723,7 +722,7 @@ uint8_t cmd_tokenize(void) __banked
return 1;
}
}
if (line_ptr == SBUF_SIZE - 1)
if (line_ptr == CMD_BUF_SIZE - 1)
return 1;
cmd_words_b[word++] = line_ptr;
cmd_words_b[word++] = -1;
@@ -1001,6 +1000,16 @@ void cmd_parser(void) __banked
}
}
void clear_command_history(void) __banked
{
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
cmd_history[cmd_history_ptr] = 0;
cmd_history_ptr = 0;
return;
}
#define FLASH_READ_BURST_SIZE 0x100
#define PASSWORD "1234"
void execute_config(void) __banked
@@ -1020,7 +1029,7 @@ void execute_config(void) __banked
__xdata uint8_t cfg_idx = 0;
uint8_t c = 0;
do {
for (uint8_t cmd_idx = 0; cmd_idx < (SBUF_SIZE - 1); cmd_idx++) {
for (uint8_t cmd_idx = 0; cmd_idx < (CMD_BUF_SIZE - 1); cmd_idx++) {
c = flash_buf[cfg_idx++];
if (c == 0 || c == '\n') {
cmd_buffer[cmd_idx] = '\0';
@@ -1041,13 +1050,6 @@ void execute_config(void) __banked
config_done:
// Start saving commands to cmd_history
clear_command_history();
save_cmd = 1;
}
void clear_command_history(void) __banked
{
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
cmd_history[cmd_history_ptr] = 0;
cmd_history_ptr = 0;
return;
}