mirror of
https://github.com/simh/simh.git
synced 2026-01-11 23:52:58 +00:00
Initial Merge of Dave Bryan's localfixes to run the HP diagnostics
This commit is contained in:
parent
7e68046c59
commit
693b75c00e
61
scp.c
61
scp.c
@ -57,10 +57,12 @@
|
||||
08-Feb-09 RMS Fixed warnings in help printouts
|
||||
29-Dec-08 RMS Fixed implementation of MTAB_NC
|
||||
24-Nov-08 RMS Revised RESTORE unit logic for consistency
|
||||
12-Sep-08 JDB [local fix 3] no SCPE_CHALT message if RUN from DO file without -V
|
||||
05-Sep-08 JDB "detach_all" ignores error status returns if shutting down
|
||||
17-Aug-08 RMS Revert RUN/BOOT to standard, rather than powerup, reset
|
||||
25-Jul-08 JDB DO cmd missing params now default to null string
|
||||
29-Jun-08 JDB DO cmd sub_args now allows "\\" to specify literal backslash
|
||||
04-Jun-08 JDB [local fix 8] Label the patch delta more clearly
|
||||
31-Mar-08 RMS Fixed bug in local/global register search (Mark Pizzolato)
|
||||
Fixed bug in restore of RO units (Mark Pizzolato)
|
||||
06-Feb-08 RMS Added SET/SHO/NO BR with default argument
|
||||
@ -72,6 +74,7 @@
|
||||
30-Jan-07 RMS Fixed bugs in get_ipaddr
|
||||
17-Oct-06 RMS Added idle support
|
||||
04-Oct-06 JDB DO cmd failure now echoes cmd unless -q
|
||||
30-Aug-06 JDB [local fix 7] detach_unit returns SCPE_UNATT if not attached
|
||||
14-Jul-06 RMS Added sim_activate_abs
|
||||
02-Jun-06 JDB Fixed do_cmd to exit nested files on assertion failure
|
||||
Added -E switch to do_cmd to exit on any error
|
||||
@ -88,6 +91,9 @@
|
||||
22-Mar-05 JDB Modified DO command to allow ten-level nesting
|
||||
18-Mar-05 RMS Moved DETACH tests into detach_unit (Dave Bryan)
|
||||
Revised interface to fprint_sym, fparse_sym
|
||||
13-Mar-05 JDB [local fix 4] ASSERT now requires a conditional operator
|
||||
25-Feb-05 JDB [local fix 3] Added SCPE_CHALT message string
|
||||
[local fix 3] Added halt unit support in show_queue
|
||||
07-Feb-05 RMS Added ASSERT command (Dave Bryan)
|
||||
02-Feb-05 RMS Fixed bug in global register search
|
||||
26-Dec-04 RMS Qualified SAVE examine, RESTORE deposit with SIM_SW_REST
|
||||
@ -99,6 +105,7 @@
|
||||
27-Sep-04 RMS Fixed comma-separation options in set (David Bryan)
|
||||
09-Sep-04 RMS Added -p option for RESET
|
||||
13-Aug-04 RMS Qualified RESTORE detach with SIM_SW_REST
|
||||
17-Jul-04 JDB [local fix 2] DO cmd file open failure retries with ".sim" appended
|
||||
17-Jul-04 RMS Added ECHO command (Dave Bryan)
|
||||
12-Jul-04 RMS Fixed problem ATTACHing to read only files
|
||||
(John Dundas)
|
||||
@ -290,6 +297,10 @@ int32 sim_asynch_latency = 4000; /* 4 usec interrupt latency */
|
||||
int32 sim_asynch_inst_latency = 20; /* assume 5 mip simulator */
|
||||
#endif
|
||||
|
||||
/* [JDB local fix 3] begin */
|
||||
extern UNIT sim_halt_unit;
|
||||
|
||||
/* [JDB local fix 3] end */
|
||||
/* VM interface */
|
||||
|
||||
extern char sim_name[];
|
||||
@ -517,6 +528,9 @@ const struct scp_error {
|
||||
{"TTMO", "Console Telnet connection timed out"},
|
||||
{"STALL", "Console Telnet output stall"},
|
||||
{"AFAIL", "Assertion failed"},
|
||||
/* [JDB local fix 3] begin */
|
||||
{"CHALT", "Console halt"}
|
||||
/* [JDB local fix 3] end */
|
||||
};
|
||||
|
||||
const size_t size_map[] = { sizeof (int8),
|
||||
@ -617,6 +631,17 @@ static CTAB cmd_table[] = {
|
||||
"set console NOLOG disable console logging\n"
|
||||
"set console DEBUG enable console debugging\n"
|
||||
"set console NODEBUG disable console debugging\n"
|
||||
"set console {-A}{-I} HALT=<string>\n"
|
||||
" set a console output string which\n"
|
||||
" will cause a simulator halt\n"
|
||||
"set console NOHALT disable console halt condition\n"
|
||||
"set console RESPONSE=<string>\n"
|
||||
" specify characters which will be\n"
|
||||
" presented as console input\n"
|
||||
"set console NORESPONSE cancels pending console input\n"
|
||||
"set console DELAY=<n> specifies a number of instructions to delay\n"
|
||||
" between when a console halt condition\n"
|
||||
" is satisfied and the halt occurs\n"
|
||||
"set break <list> set breakpoints\n"
|
||||
"set nobreak <list> clear breakpoints\n"
|
||||
"set throttle {x{M|K|%}}|{x/t}\n"
|
||||
@ -936,7 +961,7 @@ return SCPE_OK;
|
||||
|
||||
Note that SCPE_STEP ("Step expired") is considered a note and not an error
|
||||
and so does not abort command execution when using -E.
|
||||
|
||||
|
||||
Inputs:
|
||||
flag = caller and nesting level indicator
|
||||
fcptr = filename and optional arguments, space-separated
|
||||
@ -971,6 +996,7 @@ if (interactive) { /* get switches */
|
||||
}
|
||||
if (sim_switches & SWMASK ('V')) /* -v means echo */
|
||||
echo = 1;
|
||||
|
||||
errabort = sim_switches & SWMASK ('E'); /* -e means abort on error */
|
||||
|
||||
c = fcptr;
|
||||
@ -1036,6 +1062,10 @@ do {
|
||||
if (cmdp = find_cmd (gbuf)) { /* lookup command */
|
||||
if ((cmdp->action == &return_cmd)) /* RETURN command? */
|
||||
break; /* done! */
|
||||
/* [JDB local fix 3] begin */
|
||||
if ((cmdp->action == &run_cmd) && !echo) /* run command and not echoing? */
|
||||
sim_switches = SIM_SW_HIDE; /* suppress potential console halt message */
|
||||
/* [JDB local fix 3] end */
|
||||
isdo = (cmdp->action == &do_cmd);
|
||||
if (isdo) { /* DO command? */
|
||||
if (flag >= MAX_DO_NEST_LVL) /* nest too deep? */
|
||||
@ -1213,6 +1243,9 @@ t_value val;
|
||||
t_stat r;
|
||||
|
||||
cptr = get_sim_opt (CMD_OPT_SW|CMD_OPT_DFT, cptr, &r); /* get sw, default */
|
||||
/* [JDB local fix 4] begin */
|
||||
sim_stab.boolop = -1; /* no relational op dflt */
|
||||
/* [JDB local fix 4] end */
|
||||
if (*cptr == 0) /* must be more */
|
||||
return SCPE_2FARG;
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get register */
|
||||
@ -1239,7 +1272,10 @@ else {
|
||||
}
|
||||
if (*cptr != 0) /* must be done */
|
||||
return SCPE_2MARG;
|
||||
if (!get_search (gbuf, rptr->radix, &sim_stab)) /* parse condition */
|
||||
/* [JDB local fix 4] begin */
|
||||
if (!get_search (gbuf, rptr->radix, &sim_stab) || /* parse condition */
|
||||
(sim_stab.boolop == -1)) /* relational op reqd */
|
||||
/* [JDB local fix 4] end */
|
||||
return SCPE_MISVAL;
|
||||
val = get_rval (rptr, idx); /* get register value */
|
||||
if (test_search (val, &sim_stab)) /* test condition */
|
||||
@ -1889,7 +1925,9 @@ if (cptr && (*cptr != 0))
|
||||
return SCPE_2MARG;
|
||||
fprintf (st, "%s simulator V%d.%d-%d", sim_name, vmaj, vmin, vpat);
|
||||
if (vdelt)
|
||||
fprintf (st, "(%d)", vdelt);
|
||||
/* [JDB local fix 8] begin */
|
||||
fprintf (st, " delta %d", vdelt);
|
||||
/* [JDB local fix 8] end */
|
||||
if (flag)
|
||||
fprintf (st, " [%s, %s, %s]", sim_si64, sim_sa64, sim_snet);
|
||||
fprintf (st, "\n");
|
||||
@ -1949,6 +1987,10 @@ accum = 0;
|
||||
for (uptr = sim_clock_queue; uptr != NULL; uptr = uptr->next) {
|
||||
if (uptr == &sim_step_unit)
|
||||
fprintf (st, " Step timer");
|
||||
/* [JDB local fix 3] begin */
|
||||
else if (uptr == &sim_halt_unit)
|
||||
fprintf (st, " Console halt timer");
|
||||
/* [JDB local fix 3] end */
|
||||
else if ((dptr = find_dev_from_unit (uptr)) != NULL) {
|
||||
fprintf (st, " %s", sim_dname (dptr));
|
||||
if (dptr->numunits > 1)
|
||||
@ -2583,8 +2625,13 @@ if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
if (!(uptr->flags & UNIT_ATTABLE)) /* attachable? */
|
||||
return SCPE_NOATT;
|
||||
if (!(uptr->flags & UNIT_ATT)) /* attached? */
|
||||
return SCPE_OK;
|
||||
/* [JDB local fix 7] begin */
|
||||
if (!(uptr->flags & UNIT_ATT)) /* not attached? */
|
||||
if (sim_switches & SIM_SW_REST) /* restoring? */
|
||||
return SCPE_OK; /* allow detach */
|
||||
else
|
||||
return SCPE_UNATT; /* complain */
|
||||
/* [JDB local fix 7] end */
|
||||
if ((dptr = find_dev_from_unit (uptr)) == NULL)
|
||||
return SCPE_OK;
|
||||
if (uptr->flags & UNIT_BUF) {
|
||||
@ -3257,6 +3304,10 @@ else {
|
||||
#if defined (VMS)
|
||||
printf ("\n");
|
||||
#endif
|
||||
/* [JDB local fix 3] begin */
|
||||
if ((r == SCPE_CHALT) && (sim_switches & SIM_SW_HIDE)) /* hide console halt message? */
|
||||
return SCPE_OK; /* return quietly */
|
||||
/* [JDB local fix 3] end */
|
||||
fprint_stopped (stdout, r); /* print msg */
|
||||
if (sim_log) /* log if enabled */
|
||||
fprint_stopped (sim_log, r);
|
||||
|
||||
403
sim_console.c
403
sim_console.c
@ -24,6 +24,7 @@
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
18-Mar-12 RMS Removed unused reference to sim_switches (Dave Bryan)
|
||||
22-Dec-11 JDB [local fix 3] Fixed bug with anchored halt string matching
|
||||
07-Dec-11 MP Added sim_ttisatty to support reasonable behaviour (i.e.
|
||||
avoid in infinite loop) in the main command input
|
||||
loop when EOF is detected and input is coming from
|
||||
@ -57,6 +58,9 @@
|
||||
22-Jun-06 RMS Implemented SET/SHOW PCHAR
|
||||
31-May-06 JDB Fixed bug if SET CONSOLE DEBUG with no argument
|
||||
22-Nov-05 RMS Added central input/output conversion support
|
||||
05-Nov-04 JDB [local fix 3] Added SET/SHOW CONSOLE HALT=<string> command
|
||||
[local fix 3] Added SET/SHOW CONSOLE RESPONSE=<string> command
|
||||
[local fix 3] Added SET/SHOW CONSOLE DELAY=<n> command, halt svc
|
||||
05-Nov-04 RMS Moved SET/SHOW DEBUG under CONSOLE hierarchy
|
||||
28-Oct-04 JDB Fixed SET CONSOLE to allow comma-separated parameters
|
||||
20-Aug-04 RMS Added OS/2 EMX fixes (Holger Veit)
|
||||
@ -128,6 +132,12 @@
|
||||
#define KMAP_MASK 0377
|
||||
#define KMAP_NZ 0400
|
||||
|
||||
/* [JDB local fix 3] begin */
|
||||
#define CMD_WANTSTR 0100000
|
||||
|
||||
#define ESC_CHAR '~'
|
||||
/* [JDB local fix 3] end */
|
||||
|
||||
int32 sim_int_char = 005; /* interrupt character */
|
||||
int32 sim_brk_char = 000; /* break character */
|
||||
int32 sim_tt_pchar = 0x00002780;
|
||||
@ -139,11 +149,28 @@ int32 sim_del_char = 0177;
|
||||
TMLN sim_con_ldsc = { 0 }; /* console line descr */
|
||||
TMXR sim_con_tmxr = { 1, 0, 0, &sim_con_ldsc }; /* console line mux */
|
||||
|
||||
/* [JDB local fix 3] begin */
|
||||
UNIT sim_halt_unit = { UDATA (&halt_svc, 0, 0), 0 };
|
||||
/* [JDB local fix 3] end */
|
||||
|
||||
extern volatile int32 stop_cpu;
|
||||
extern int32 sim_quiet;
|
||||
extern FILE *sim_log, *sim_deb;
|
||||
extern FILEREF *sim_log_ref, *sim_deb_ref;
|
||||
extern DEVICE *sim_devices[];
|
||||
/* [JDB local fix 3] begin */
|
||||
extern int32 sim_switches;
|
||||
|
||||
static char mbuf [CBUFSIZE]; /* match buffer */
|
||||
static char rbuf [CBUFSIZE]; /* response buffer */
|
||||
static char *rptr = NULL;
|
||||
static t_bool halt_enabled = FALSE; /* console halt is enabled */
|
||||
static t_bool halt_anchored = FALSE; /* halt string is anchored */
|
||||
static t_bool halt_immediate = FALSE; /* halt match mode is immediate */
|
||||
static char *mptr = mbuf; /* current match string pointer */
|
||||
static t_bool match = FALSE; /* halt string has matched */
|
||||
static t_bool check = FALSE; /* halt string is to be checked */
|
||||
/* [JDB local fix 3] end */
|
||||
|
||||
/* Set/show data structures */
|
||||
|
||||
@ -158,6 +185,13 @@ static CTAB set_con_tab[] = {
|
||||
{ "NOLOG", &sim_set_logoff, 0 },
|
||||
{ "DEBUG", &sim_set_debon, 0 },
|
||||
{ "NODEBUG", &sim_set_deboff, 0 },
|
||||
/* [JDB local fix 3] begin */
|
||||
{ "HALT", &sim_set_halt, 1 | CMD_WANTSTR },
|
||||
{ "NOHALT", &sim_set_halt, 0 },
|
||||
{ "DELAY", &sim_set_delay, 0 },
|
||||
{ "RESPONSE", &sim_set_response, 1 | CMD_WANTSTR },
|
||||
{ "NORESPONSE", &sim_set_response, 0 },
|
||||
/* [JDB local fix 3] end */
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
@ -169,6 +203,11 @@ static SHTAB show_con_tab[] = {
|
||||
{ "LOG", &sim_show_cons_log, 0 },
|
||||
{ "TELNET", &sim_show_telnet, 0 },
|
||||
{ "DEBUG", &sim_show_debug, 0 },
|
||||
/* [JDB local fix 3] begin */
|
||||
{ "HALT", &sim_show_halt, 0 },
|
||||
{ "DELAY", &sim_show_delay, 0 },
|
||||
{ "RESPONSE", &sim_show_response, 0 },
|
||||
/* [JDB local fix 3] end */
|
||||
{ "BUFFERED", &sim_show_cons_buff, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
@ -188,6 +227,12 @@ static int32 *cons_kmap[] = {
|
||||
&sim_del_char
|
||||
};
|
||||
|
||||
/* [JDB local fix 3] begin */
|
||||
static void test_console_halt (int32 test_char);
|
||||
static void decode (char *decoded, const char *encoded);
|
||||
static void encode (char *encoded, const char *decoded);
|
||||
/* [JDB local fix 3] end */
|
||||
|
||||
/* Console I/O package.
|
||||
|
||||
The console terminal can be attached to the controlling window
|
||||
@ -203,16 +248,34 @@ t_stat sim_set_console (int32 flag, char *cptr)
|
||||
char *cvptr, gbuf[CBUFSIZE];
|
||||
CTAB *ctptr;
|
||||
t_stat r;
|
||||
/* [JDB local fix 3] begin */
|
||||
char *sptr;
|
||||
/* [JDB local fix 3] end */
|
||||
|
||||
if ((cptr == NULL) || (*cptr == 0))
|
||||
return SCPE_2FARG;
|
||||
while (*cptr != 0) { /* do all mods */
|
||||
/* [JDB local fix 3] begin */
|
||||
sptr = cptr;
|
||||
/* [JDB local fix 3] end */
|
||||
cptr = get_glyph_nc (cptr, gbuf, ','); /* get modifier */
|
||||
if (cvptr = strchr (gbuf, '=')) /* = value? */
|
||||
*cvptr++ = 0;
|
||||
get_glyph (gbuf, gbuf, 0); /* modifier to UC */
|
||||
if (ctptr = find_ctab (set_con_tab, gbuf)) { /* match? */
|
||||
r = ctptr->action (ctptr->arg, cvptr); /* do the rest */
|
||||
/* [JDB local fix 3] begin */
|
||||
if (ctptr->arg & CMD_WANTSTR) { /* need full string? */
|
||||
sptr = get_glyph_nc (sptr, gbuf, '='); /* everything after '=' */
|
||||
|
||||
while (isspace (*(sptr - 1))) /* restore any leading spaces */
|
||||
sptr--; /* (get_glyph_nc strips spaces after '=') */
|
||||
|
||||
r = ctptr->action (ctptr->arg, sptr);
|
||||
*cptr = 0; /* no more modifiers */
|
||||
}
|
||||
else
|
||||
r = ctptr->action (ctptr->arg, cvptr); /* do the rest */
|
||||
/* [JDB local fix 3] end */
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
}
|
||||
@ -627,6 +690,329 @@ if (!ref)
|
||||
return ref->name;
|
||||
}
|
||||
|
||||
/* [JDB local fix 3] begin */
|
||||
|
||||
/* Set console halt */
|
||||
|
||||
t_stat sim_set_halt (int32 flag, char *cptr)
|
||||
{
|
||||
if (flag == 0) /* no halt? */
|
||||
halt_enabled = FALSE; /* disable halt checks */
|
||||
|
||||
else {
|
||||
if (cptr == NULL || *cptr == 0) /* no match string? */
|
||||
return SCPE_2FARG; /* need an argument */
|
||||
|
||||
halt_enabled = TRUE; /* enable halt checks */
|
||||
|
||||
decode (mbuf, cptr); /* save decoded match string */
|
||||
|
||||
halt_anchored = ((sim_switches & SWMASK ('A')) != 0); /* set match type */
|
||||
halt_immediate = ((sim_switches & SWMASK ('I')) != 0); /* set match trigger */
|
||||
|
||||
mptr = mbuf; /* init match string pointer */
|
||||
check = TRUE; /* init check for match */
|
||||
match = FALSE; /* init match has occurred */
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Show console halt */
|
||||
|
||||
t_stat sim_show_halt (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
|
||||
{
|
||||
char pbuf [CBUFSIZE];
|
||||
|
||||
if (cptr && *cptr != 0) /* extra chars? */
|
||||
return SCPE_2MARG; /* too many arguments */
|
||||
|
||||
if (halt_enabled) { /* halt enabled? */
|
||||
encode (pbuf, mbuf); /* encode the string for printing */
|
||||
|
||||
fprintf (st, "Halt string is \"%s\", mode is %s %s\n",
|
||||
pbuf,
|
||||
halt_anchored ? "anchored" : "unanchored",
|
||||
halt_immediate ? "immediate" : "deferred");
|
||||
}
|
||||
|
||||
else
|
||||
fputs ("Halt disabled\n", st);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Set console response */
|
||||
|
||||
t_stat sim_set_response (int32 flag, char *cptr)
|
||||
{
|
||||
if (flag == 0) /* no response? */
|
||||
rptr = NULL; /* clear response ptr */
|
||||
|
||||
else {
|
||||
if (cptr == NULL || *cptr == 0)
|
||||
return SCPE_2FARG; /* need arg */
|
||||
|
||||
decode (rbuf, cptr); /* save decoded string */
|
||||
rptr = rbuf; /* set response ptr */
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Show console response */
|
||||
|
||||
t_stat sim_show_response (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
|
||||
{
|
||||
char pbuf [CBUFSIZE];
|
||||
|
||||
if (cptr && *cptr != 0) /* extra chars? */
|
||||
return SCPE_2MARG; /* too many arguments */
|
||||
|
||||
if (rptr) {
|
||||
encode (pbuf, rptr); /* encode match str */
|
||||
fprintf (st, "Response string is \"%s\"\n", pbuf);
|
||||
}
|
||||
|
||||
else
|
||||
fputs ("Response disabled\n", st);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Set console delay */
|
||||
|
||||
t_stat sim_set_delay (int32 flag, char *cptr)
|
||||
{
|
||||
int32 val;
|
||||
t_stat r;
|
||||
|
||||
if (cptr == NULL || *cptr == 0) /* no argument string? */
|
||||
return SCPE_2FARG; /* need an argument */
|
||||
|
||||
val = (int32) get_uint (cptr, 10, INT_MAX, &r); /* parse the argument */
|
||||
|
||||
if (r == SCPE_OK) /* parse OK? */
|
||||
sim_halt_unit.wait = val; /* save the delay value */
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* Show console delay */
|
||||
|
||||
t_stat sim_show_delay (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
|
||||
{
|
||||
if (cptr && *cptr != 0) /* extra chars? */
|
||||
return SCPE_2MARG; /* too many arguments */
|
||||
|
||||
fprintf (st, "Halt delay=%i\n", sim_halt_unit.wait); /* report delay value */
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Unit service for console halt timeout.
|
||||
|
||||
Scheduled by test_console_halt when the halt string is seen. Returns the
|
||||
halt timeout SCP code after the specified delay, which will cause the
|
||||
simulator to stop.
|
||||
*/
|
||||
|
||||
t_stat halt_svc (UNIT *uptr)
|
||||
{
|
||||
return SCPE_CHALT;
|
||||
}
|
||||
|
||||
|
||||
/* Check for a console halt.
|
||||
|
||||
The console halt string match mode may be specified as anchored (-a) or
|
||||
unanchored, and immediate (-i) or deferred. An anchored string must match at
|
||||
the start of the output buffer; an unanchored string may match anywhere. An
|
||||
immediate match halts as soon as the last character of the match string is
|
||||
seen in the output stream and may occur multiple times per line; a deferred
|
||||
match halts only after the trailing line feed character is output and occurs
|
||||
only once, regardless of the number of times the match string appears in the
|
||||
output stream.
|
||||
|
||||
Once a deferred match has occured, or an anchored match has failed, no
|
||||
further match checks are made on the current line.
|
||||
|
||||
An immediate, anchored match halts only once when the halt string first
|
||||
matches, even if the match string also occurs later in the line. For
|
||||
example, if the match string is "ABC" and the output characters are
|
||||
"ABC-ABC", the halt occurs after the first "C" is output but NOT after the
|
||||
second "C" is output, even though the halt string still matches the start of
|
||||
the output buffer. The second halt would occur if the immediate match was
|
||||
unanchored.
|
||||
|
||||
To summarize the match modes:
|
||||
|
||||
- unanchored, deferred: halt once if match occurs anywhere in the line
|
||||
- unanchored, immediate: halt each time the match occurs anywhere in the line
|
||||
- anchored, deferred: halt once if match occurs at the start of the line
|
||||
- anchored, immediate: halt once if match occurs at the start of the line
|
||||
|
||||
Implementation Notes:
|
||||
|
||||
1. This routine should be called only when console halts are enabled.
|
||||
|
||||
2. The passed character is checked against the current match character. If
|
||||
it matches, the match string pointer is advanced. If the end of the
|
||||
match string is reached, match success is indicated and further match
|
||||
checks are suppressed until the console halt occurs, which may be
|
||||
immediately or at the end of the line, depending on whether the "-i"
|
||||
switch was used.
|
||||
|
||||
3. If the character does not match, and the match is anchored, further match
|
||||
checks are suppressed until the start of the next line.
|
||||
|
||||
4. If the character does not match, and the match is unanchored, a check is
|
||||
made to see if any characters have matched. If not, then substrings need
|
||||
not be checked. Otherwise, the output stream is searched for substrings
|
||||
of the match string. For example, if the match string is "GAGAX" and the
|
||||
output characters are "GAGAG", then the match fails on the fifth
|
||||
character. However, the last three characters output match the leading
|
||||
substring "GAG" of the match string, so the match pointer is reset to
|
||||
point at the fourth character, rather than the second. Then, if an "AX"
|
||||
is subsequently output, the match will succeed.
|
||||
|
||||
5. Searching for the longest substring that matches the output stream would
|
||||
appear to require a history buffer. However, the fact that all of the
|
||||
prior output characters until the current one have matched means that the
|
||||
match string itself IS a history of the output stream. We need only
|
||||
search for substrings that equal the substring of the match string that
|
||||
ends with the last-matched character.
|
||||
|
||||
6. The search starts with the longest possible substring and then attempts
|
||||
shorter and shorter substrings until either a match occurs or no
|
||||
substring matches. In the first case, the match pointer is reset
|
||||
appropriately, and partial matching continues. In the second, the match
|
||||
pointer is reset to the beginning of the match string, and a new match is
|
||||
sought.
|
||||
*/
|
||||
|
||||
static void test_console_halt (int32 test_char)
|
||||
{
|
||||
char *history, *hptr, *sptr;
|
||||
|
||||
if (check) /* are we checking for a match? */
|
||||
if (*mptr == test_char) { /* does the search character match? */
|
||||
mptr++; /* point at the next character to match */
|
||||
|
||||
if (*mptr == '\0') { /* is the search string exhausted? */
|
||||
match = TRUE; /* the match has succeeded */
|
||||
check = FALSE; /* stop checking until console halt */
|
||||
mptr = mbuf; /* reset the search pointer */
|
||||
}
|
||||
}
|
||||
|
||||
else if (halt_anchored) /* match failed; is search anchored? */
|
||||
check = FALSE; /* yes, so done until end of line */
|
||||
|
||||
else if (mptr != mbuf) { /* unanchored failure; partial match? */
|
||||
history = --mptr; /* save pointer to output history */
|
||||
|
||||
do { /* search for a substring match */
|
||||
while (mptr >= mbuf && *mptr != test_char) /* back up in search string */
|
||||
mptr--; /* until a matching character found */
|
||||
|
||||
if (mptr < mbuf) { /* if no matching character found */
|
||||
mptr = mbuf; /* reset the search pointer */
|
||||
sptr = NULL; /* and exit the substring search */
|
||||
}
|
||||
|
||||
else { /* potential substring match */
|
||||
hptr = history; /* set up history */
|
||||
sptr = mptr - 1; /* and substring pointers */
|
||||
|
||||
while (sptr >= mbuf && *sptr == *hptr) { /* test substring in reverse */
|
||||
sptr--; /* until a match fails */
|
||||
hptr--; /* or the entire substring matches */
|
||||
}
|
||||
|
||||
if (sptr < mbuf) { /* if a substring was found */
|
||||
mptr++; /* point at the next character to match */
|
||||
sptr = NULL; /* and exit the substring search */
|
||||
}
|
||||
|
||||
else /* the substring did not match */
|
||||
mptr = sptr; /* so try the next shorter substring */
|
||||
}
|
||||
|
||||
} while (sptr);
|
||||
}
|
||||
|
||||
|
||||
if (test_char == '\n' && halt_anchored) { /* end of line for an anchored match? */
|
||||
mptr = mbuf; /* reset the search pointer */
|
||||
check = TRUE; /* and resume checking for matches */
|
||||
}
|
||||
|
||||
if (match && (halt_immediate || test_char == '\n')) { /* immediate or end-of-line match? */
|
||||
sim_activate (&sim_halt_unit, sim_halt_unit.wait); /* schedule the console halt */
|
||||
match = FALSE; /* reset the match flag */
|
||||
|
||||
if (! halt_anchored) /* if not anchored */
|
||||
check = TRUE; /* resume checking for matches */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Decode a string.
|
||||
|
||||
A string containing encoded control characters is decoded into the equivalent
|
||||
character string. Escape targets @, A-Z, and [\]^_ form control characters
|
||||
000-037.
|
||||
*/
|
||||
|
||||
static void decode (char *decoded, const char *encoded)
|
||||
{
|
||||
char c;
|
||||
|
||||
while (c = *decoded++ = *encoded++) /* copy the character */
|
||||
if (c == ESC_CHAR) /* does it start an escape? */
|
||||
if (isalpha (*encoded) || /* is next character "A-Z" or "a-z"? */
|
||||
*encoded == '@' || /* or "@"? */
|
||||
*encoded >= '[' && *encoded <= '_') /* or "[\]^_"? */
|
||||
|
||||
*(decoded - 1) = *encoded++ & 037; /* convert back to control character */
|
||||
|
||||
else if (*encoded == '\0' || /* single escape character at EOL? */
|
||||
*encoded++ != ESC_CHAR) /* or not followed by another escape? */
|
||||
decoded--; /* drop the encoding */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Encode a string.
|
||||
|
||||
A string containing control characters is encoded into the equivalent escaped
|
||||
form. Control characters 000-037 are encoded into the form "~<c>", where <c>
|
||||
is a character in the range 0100-0137.
|
||||
*/
|
||||
|
||||
static void encode (char *encoded, const char *decoded)
|
||||
{
|
||||
char c;
|
||||
|
||||
while (c = *encoded++ = *decoded++) /* copy the character */
|
||||
if (iscntrl (c) && c != 0177) { /* if a control character (but not DEL) */
|
||||
*(encoded - 1) = ESC_CHAR; /* change to the escape character */
|
||||
*encoded++ = c | 0100; /* followed by the encoded character */
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* [JDB local fix 3] end */
|
||||
|
||||
|
||||
/* Check connection before executing */
|
||||
|
||||
t_stat sim_check_console (int32 sec)
|
||||
@ -684,6 +1070,13 @@ t_stat sim_poll_kbd (void)
|
||||
{
|
||||
int32 c;
|
||||
|
||||
/* [JDB local fix 3] begin */
|
||||
if (rptr) /* response set? */
|
||||
if (c = *rptr++) /* more characters to send? */
|
||||
return (c | SCPE_KFLAG); /* return response char */
|
||||
else /* at end of string */
|
||||
rptr = NULL; /* terminate the response */
|
||||
/* [JDB local fix 3] end */
|
||||
c = sim_os_poll_kbd (); /* get character */
|
||||
if ((c == SCPE_STOP) || (sim_con_tmxr.master == 0)) /* ^E or not Telnet? */
|
||||
return c; /* in-window */
|
||||
@ -705,6 +1098,10 @@ return SCPE_OK;
|
||||
|
||||
t_stat sim_putchar (int32 c)
|
||||
{
|
||||
/* [JDB local fix 3] begin */
|
||||
if (halt_enabled)
|
||||
test_console_halt (c); /* check for a console halt */
|
||||
/* [JDB local fix 3] end */
|
||||
if (sim_con_tmxr.master == 0) { /* not Telnet? */
|
||||
if (sim_log) /* log file? */
|
||||
fputc (c, sim_log);
|
||||
@ -727,6 +1124,10 @@ t_stat sim_putchar_s (int32 c)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
/* [JDB local fix 3] begin */
|
||||
if (halt_enabled)
|
||||
test_console_halt (c); /* check for a console halt */
|
||||
/* [JDB local fix 3] end */
|
||||
if (sim_con_tmxr.master == 0) { /* not Telnet? */
|
||||
if (sim_log) /* log file? */
|
||||
fputc (c, sim_log);
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
17-Jan-11 MP Added buffered line capabilities
|
||||
22-Jun-06 RMS Implemented SET/SHOW PCHAR
|
||||
22-Nov-05 RMS Added central input/output conversion support
|
||||
05-Nov-04 JDB [local fix 3] Added SET/SHOW CONSOLE HALT/RESPONSE/DELAY, svc routine
|
||||
05-Nov-04 RMS Moved SET/SHOW DEBUG under CONSOLE hierarchy
|
||||
28-May-04 RMS Added SET/SHOW CONSOLE
|
||||
02-Jan-04 RMS Removed timer routines, added Telnet console routines
|
||||
@ -64,12 +65,23 @@ t_stat sim_set_cons_log (int32 flg, char *cptr);
|
||||
t_stat sim_set_cons_nolog (int32 flg, char *cptr);
|
||||
t_stat sim_set_deboff (int32 flag, char *cptr);
|
||||
t_stat sim_set_pchar (int32 flag, char *cptr);
|
||||
/* [JDB local fix 3] begin */
|
||||
t_stat sim_set_halt (int32 flag, char *cptr);
|
||||
t_stat sim_set_response (int32 flag, char *cptr);
|
||||
t_stat sim_set_delay (int32 flag, char *cptr);
|
||||
/* [JDB local fix 3] end */
|
||||
t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_kmap (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_telnet (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_pchar (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
/* [JDB local fix 3] begin */
|
||||
t_stat sim_show_halt (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_response (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_delay (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat halt_svc (UNIT *ptr);
|
||||
/* [JDB local fix 3] end */
|
||||
t_stat sim_show_cons_buff (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_show_cons_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||
t_stat sim_check_console (int32 sec);
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
Added REG_FIT flag
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
11-Mar-05 RMS Moved 64b data type definitions outside USE_INT64
|
||||
25-Feb-05 JDB [local fix 3] Added SCPE_CHALT error value
|
||||
07-Feb-05 RMS Added assertion fail stop
|
||||
05-Nov-04 RMS Added support for SHOW opt=val
|
||||
20-Oct-04 RMS Converted all base types to typedefs
|
||||
@ -248,8 +249,11 @@ typedef uint32 t_addr;
|
||||
#define SCPE_TTMO (SCPE_BASE + 40) /* Telnet conn timeout */
|
||||
#define SCPE_STALL (SCPE_BASE + 41) /* Telnet conn stall */
|
||||
#define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */
|
||||
/* [JDB local fix 3] begin */
|
||||
#define SCPE_CHALT (SCPE_BASE + 43) /* Console halt */
|
||||
/* [JDB local fix 3] end */
|
||||
|
||||
#define SCPE_MAX_ERR (SCPE_BASE + 43) /* Maximum SCPE Error Value */
|
||||
#define SCPE_MAX_ERR (SCPE_BASE + 44) /* Maximum SCPE Error Value */
|
||||
#define SCPE_KFLAG 0010000 /* tti data flag */
|
||||
#define SCPE_BREAK 0020000 /* tti break flag */
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user