diff --git a/README.md b/README.md index 791dad6f..0964bbee 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,13 @@ #### Remote Console Facility A new capability has been added which allows a TELNET Connection to a user designated port so that some out of band commands can be entered to manipulate and/or adjust a running simulator. The commands which enable and control this capability are SET REMOTE TELNET=port, SET REMOTE CONNECTIONS=n, SET REMOTE TIMEOUT=seconds, and SHOW REMOTE. -A subset of normal simh commands are available for use in remote console sessions. These are: EXAMINE, IEXAMINE, DEPOSIT, EVALUATE, ATTACH, DETACH, ASSIGN, DEASSIGN, STEP, CONTINUE, PWD, SAVE, SET, SHOW, DIR, LS, ECHO, HELP +The remote console facility has two modes of operation: 1) single command mode. and 2) multiple command mode. +In single command mode you enter one command at a time and aren't concerned about what the simulated system is doing while you enter that command. The command is executed once you've hit return. +In multiple command mode you initiate your activities by entering the WRU character (usually ^E). This will suspend the current simulator execution. You then enter commands as needed and when you are done you enter a CONTINUE command. While entering Multiple Command commands, if you fail to enter a complete command before the timeout (specified by "SET REMOTE TIMEOUT=seconds"), a CONTINUE command is automatically processed and simulation proceeds. + +A subset of normal simh commands are available for use in remote console sessions. +The Single Command Mode commands are: ATTACH, DETACH, PWD, SHOW, DIR, LS, ECHO, HELP +The Multiple Command Mode commands are: EXAMINE, IEXAMINE, DEPOSIT, EVALUATE, ATTACH, DETACH, ASSIGN, DEASSIGN, STEP, CONTINUE, PWD, SAVE, SET, SHOW, DIR, LS, ECHO, HELP #### VAX/PDP11 Enhancements RQ has new disk types: RC25, RCF25, RA80 diff --git a/doc/simh_doc.doc b/doc/simh_doc.doc index 480365e7..02cec35b 100644 Binary files a/doc/simh_doc.doc and b/doc/simh_doc.doc differ diff --git a/sim_console.c b/sim_console.c index ccf0b45d..e804bf8c 100644 --- a/sim_console.c +++ b/sim_console.c @@ -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; }