1
0
mirror of https://github.com/simh/simh.git synced 2026-01-25 19:56:25 +00:00

Enhanced Remote Console support to allow two separate command processing modes.

1) Single Command Mode:  commands are processed between simulated instructions once CR is received.
 2) Multiple Command Mode: commands are initiated with the WRU character (usually *E) which suspends simulation execution and commands are processed until a CONTINUE command is entered (or automatically provided if the SET REMOTE TIMEOUT=seconds interval has elapsed).
This commit is contained in:
Mark Pizzolato
2013-05-10 16:10:07 -07:00
parent 782bec605d
commit 80289e1e3b
3 changed files with 102 additions and 56 deletions

View File

@@ -346,6 +346,7 @@ DEVICE sim_remote_console = {
static int32 *sim_rem_buf_size = NULL;
static int32 *sim_rem_buf_ptr = NULL;
static char **sim_rem_buf = NULL;
static t_bool *sim_rem_single_mode = NULL; /* per line command mode (single command or must continue) */
static TMXR sim_rem_con_tmxr = { 0, 0, 0, NULL, NULL, &sim_remote_console };/* remote console line mux */
static uint32 sim_rem_read_timeout = 30; /* seconds before automatic continue */
static int32 sim_rem_step_line = -1; /* step in progress on line # */
@@ -419,7 +420,9 @@ if (c >= 0) { /* poll connect */
sim_activate_after(uptr+1, 1000000); /* start data poll after 100ms */
lp->rcve = 1; /* rcv enabled */
sim_rem_buf_ptr[c] = 0; /* start with empty command buffer */
tmxr_linemsgf (lp, "%s Remote Console\r\nSimulator Running...", sim_name);
tmxr_linemsgf (lp, "%s Remote Console\r\n"
"Enter single commands or to enter multiple command mode enter the WRU character\r\n"
"Simulator Running...", sim_name);
tmxr_send_buffered_data (lp); /* flush buffered data */
}
sim_activate_after(uptr, 1000000); /* check again in 1 second */
@@ -465,6 +468,18 @@ static CTAB allowed_remote_cmds[] = {
{ NULL, NULL }
};
static CTAB allowed_single_remote_cmds[] = {
{ "ATTACH", &attach_cmd, 0 },
{ "DETACH", &detach_cmd, 0 },
{ "PWD", &pwd_cmd, 0 },
{ "DIR", &dir_cmd, 0 },
{ "LS", &dir_cmd, 0 },
{ "ECHO", &echo_cmd, 0 },
{ "SHOW", &show_cmd, 0 },
{ "HELP", &x_help_cmd, 0 },
{ NULL, NULL }
};
static t_stat x_help_cmd (int32 flag, char *cptr)
{
CTAB *cmdp, *cmdph;
@@ -539,52 +554,63 @@ for (i=(was_stepping ? sim_rem_step_line : 0);
if (!(TMXR_VALID & c))
continue;
c = c & ~TMXR_VALID;
if (c != sim_int_char)
continue; /* ^E (the interrupt character) must start console interaction */
sim_is_running = 0;
sim_stop_timer_services ();
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
lp = &sim_rem_con_tmxr.ldsc[j];
if ((i == j) || (!lp->conn))
continue;
tmxr_linemsgf (lp, "\nRemote Console(%s) Entering Commands\n", lp->ipad);
if (!sim_rem_single_mode[i]) {
if (c == sim_int_char) { /* ^E (the interrupt character) must start continue mode console interaction */
sim_is_running = 0;
sim_stop_timer_services ();
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
lp = &sim_rem_con_tmxr.ldsc[j];
if ((i == j) || (!lp->conn))
continue;
tmxr_linemsgf (lp, "\nRemote Console(%s) Entering Commands\n", lp->ipad);
tmxr_send_buffered_data (lp); /* flush any buffered data */
}
lp = &sim_rem_con_tmxr.ldsc[i];
tmxr_linemsg (lp, "\r\nSimulator paused.\r\n");
if (sim_rem_read_timeout)
tmxr_linemsgf (lp, "Simulation will resume automatically if input is not received in %d seconds\n", sim_rem_read_timeout);
}
else {
sim_rem_single_mode[i] = TRUE;
tmxr_linemsg (lp, "\r\nsim> ");
tmxr_send_buffered_data (lp); /* flush any buffered data */
}
}
}
got_command = FALSE;
while (1) {
if (!sim_rem_single_mode[i]) {
read_start_time = sim_os_msec();
tmxr_linemsg (lp, "sim> ");
tmxr_send_buffered_data (lp); /* flush any buffered data */
}
lp = &sim_rem_con_tmxr.ldsc[i];
tmxr_linemsg (lp, "\r\nSimulator paused.\r\n");
if (sim_rem_read_timeout)
tmxr_linemsgf (lp, "Simulation will resume automatically if input is not received in %d seconds\n", sim_rem_read_timeout);
}
while (1) {
read_start_time = sim_os_msec();
tmxr_linemsg (lp, "sim> ");
tmxr_send_buffered_data (lp); /* flush any buffered data */
got_command = FALSE;
while (!got_command) {
c = tmxr_getc_ln (lp);
if (!(TMXR_VALID & c)) {
tmxr_send_buffered_data (lp); /* flush any buffered data */
if (sim_rem_read_timeout &&
((sim_os_msec() - read_start_time)/1000 >= sim_rem_read_timeout)) {
while (sim_rem_buf_ptr[i] > 0) { /* Erase current input line */
tmxr_linemsg (lp, "\b \b");
--sim_rem_buf_ptr[i];
do {
if (!sim_rem_single_mode[i]) {
c = tmxr_getc_ln (lp);
if (!(TMXR_VALID & c)) {
tmxr_send_buffered_data (lp); /* flush any buffered data */
if (sim_rem_read_timeout &&
((sim_os_msec() - read_start_time)/1000 >= sim_rem_read_timeout)) {
while (sim_rem_buf_ptr[i] > 0) { /* Erase current input line */
tmxr_linemsg (lp, "\b \b");
--sim_rem_buf_ptr[i];
}
if (sim_rem_buf_ptr[i]+80 >= sim_rem_buf_size[i]) {
sim_rem_buf_size[i] += 1024;
sim_rem_buf[i] = realloc (sim_rem_buf[i], sim_rem_buf_size[i]);
}
strcpy (sim_rem_buf[i], "CONTINUE ! Automatic continue due to timeout");
tmxr_linemsgf (lp, "%s\n", sim_rem_buf[i]);
got_command = TRUE;
break;
}
if (sim_rem_buf_ptr[i]+80 >= sim_rem_buf_size[i]) {
sim_rem_buf_size[i] += 1024;
sim_rem_buf[i] = realloc (sim_rem_buf[i], sim_rem_buf_size[i]);
}
strcpy (sim_rem_buf[i], "CONTINUE ! Automatic continue due to timeout");
tmxr_linemsgf (lp, "%s\n", sim_rem_buf[i]);
got_command = TRUE;
break;
sim_os_ms_sleep (100);
tmxr_poll_rx (&sim_rem_con_tmxr);/* poll input */
continue;
}
sim_os_ms_sleep (100);
tmxr_poll_rx (&sim_rem_con_tmxr);/* poll input */
continue;
read_start_time = sim_os_msec();
c = c & ~TMXR_VALID;
}
read_start_time = sim_os_msec();
c = c & ~TMXR_VALID;
switch (c) {
case 0: /* no data */
break;
@@ -626,8 +652,10 @@ for (i=(was_stepping ? sim_rem_step_line : 0);
got_command = TRUE; /* command too long */
break;
}
}
} while ((!got_command) && (!sim_rem_single_mode[i]));
tmxr_send_buffered_data (lp); /* flush any buffered data */
if ((sim_rem_single_mode[i]) && !got_command)
break;
printf ("Remote Console Command from %s> %s\r\n", lp->ipad, sim_rem_buf[i]);
if (sim_log)
fprintf (sim_log, "Remote Console Command from %s> %s\n", lp->ipad, sim_rem_buf[i]);
@@ -643,7 +671,12 @@ for (i=(was_stepping ? sim_rem_step_line : 0);
sim_rem_buf_ptr[i] = 0;
sim_rem_buf[i][sim_rem_buf_ptr[i]] = '\0';
if (cbuf[0] == '\0')
continue;
if (sim_rem_single_mode[i]) {
sim_rem_single_mode[i] = FALSE;
break;
}
else
continue;
sim_sub_args (cbuf, sizeof(cbuf), argv);
cptr = cbuf;
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
@@ -661,7 +694,7 @@ for (i=(was_stepping ? sim_rem_step_line : 0);
if (!find_cmd (gbuf)) /* validate command */
stat = SCPE_UNK;
else {
if ((cmdp = find_ctab (allowed_remote_cmds, gbuf))) {/* lookup command */
if ((cmdp = find_ctab (sim_rem_single_mode[i] ? allowed_single_remote_cmds : allowed_remote_cmds, gbuf))) {/* lookup command */
if (cmdp->action == &x_continue_cmd)
stat = SCPE_OK;
else {
@@ -709,28 +742,32 @@ for (i=(was_stepping ? sim_rem_step_line : 0);
tmxr_linemsgf (lp, "%s", cbuf);
tmxr_send_buffered_data (lp);
}
if (cmdp && (cmdp->action == &x_continue_cmd)) {
if ((cmdp && (cmdp->action == &x_continue_cmd)) ||
(sim_rem_single_mode[i])) {
sim_rem_step_line = -1; /* Not stepping */
if (sim_log_temp) { /* If we setup a temporary log, clean it now */
int32 save_quiet = sim_quiet;
sim_quiet = 0;
sim_quiet = 1;
sim_set_logoff (0, NULL);
sim_quiet = save_quiet;
remove (sim_rem_con_temp_name);
sim_log_temp = FALSE;
}
tmxr_linemsg (lp, "Simulator Running...");
tmxr_send_buffered_data (lp);
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
lp = &sim_rem_con_tmxr.ldsc[j];
if ((i == j) || (!lp->conn))
continue;
if (!sim_rem_single_mode[i]) {
tmxr_linemsg (lp, "Simulator Running...");
tmxr_send_buffered_data (lp);
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
lp = &sim_rem_con_tmxr.ldsc[j];
if ((i == j) || (!lp->conn))
continue;
tmxr_linemsg (lp, "Simulator Running...");
tmxr_send_buffered_data (lp);
}
sim_is_running = 1;
sim_start_timer_services ();
}
sim_is_running = 1;
sim_start_timer_services ();
sim_rem_single_mode[i] = FALSE;
break;
}
if (cmdp && (cmdp->action == &x_step_cmd)) {
@@ -782,6 +819,7 @@ else {
sim_rem_buf[i] = NULL;
sim_rem_buf_size[i] = 0;
sim_rem_buf_ptr[i] = 0;
sim_rem_single_mode[i] = FALSE;
}
}
}
@@ -812,6 +850,8 @@ sim_rem_buf_size = realloc (sim_rem_buf_size, sizeof(*sim_rem_buf_size)*lines);
memset (sim_rem_buf_size, 0, sizeof(*sim_rem_buf_size)*lines);
sim_rem_buf_ptr = realloc (sim_rem_buf_ptr, sizeof(*sim_rem_buf_ptr)*lines);
memset (sim_rem_buf_ptr, 0, sizeof(*sim_rem_buf_ptr)*lines);
sim_rem_single_mode = realloc (sim_rem_single_mode, sizeof(*sim_rem_single_mode)*lines);
memset (sim_rem_single_mode, 0, sizeof(*sim_rem_single_mode)*lines);
return SCPE_OK;
}