1
0
mirror of https://github.com/simh/simh.git synced 2026-02-04 15:44:01 +00:00

Finish Merge branch 'master' into HP2100Extensions

Conflicts:
	scp.c
	sim_defs.h
This commit is contained in:
Mark Pizzolato
2012-04-10 06:59:14 -07:00
2 changed files with 438 additions and 239 deletions

267
scp.c
View File

@@ -105,7 +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 JDB 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)
@@ -245,7 +245,7 @@
#define SSH_SH 1 /* show */
#define SSH_CL 2 /* clear */
#define MAX_DO_NEST_LVL 10 /* DO cmd nesting level */
#define MAX_DO_NEST_LVL 20 /* DO cmd nesting level */
#define SRBSIZ 1024 /* save/restore buffer */
#define SIM_BRK_INILNT 4096 /* bpt tbl length */
#define SIM_BRK_ALLTYP 0xFFFFFFFF
@@ -411,8 +411,12 @@ t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr,
UNIT *uptr, int32 dfltinc);
t_stat step_svc (UNIT *ptr);
void sub_args (char *instr, char *tmpbuf, int32 maxstr, char *do_arg[]);
t_stat shift_args (char *do_arg[], size_t arg_count);
t_stat set_on (int32 flag, char *cptr);
t_stat set_verify (int32 flag, char *cptr);
t_stat set_message (int32 flag, char *cptr);
t_stat set_asynch (int32 flag, char *cptr);
t_stat do_cmd_label (int32 flag, char *cptr, char *label);
/* Global data */
@@ -449,7 +453,10 @@ FILEREF *sim_log_ref = NULL; /* log file file referen
FILE *sim_deb = NULL; /* debug file */
FILEREF *sim_deb_ref = NULL; /* debug file file reference */
static FILE *sim_gotofile; /* the currently open do file */
static int32 sim_goto_line; /* the current line number in the currently open do file */
static int32 sim_do_echo = 0; /* the echo status of the currently open do file */
static int32 sim_show_message = 1; /* the message display status of the currently open do file */
static int32 sim_on_inherit = 0; /* the inherit status of on state and conditions when executing do files */
int32 sim_do_depth = 0;
static int32 sim_on_check[MAX_DO_NEST_LVL+1];
@@ -619,7 +626,9 @@ static CTAB cmd_table[] = {
"set console DEL specify console delete char\n"
"set console PCHAR specify console printable chars\n"
"set console TELNET=port specify console telnet port\n"
"set console TELNET=LOG specify console telnet logging\n"
"set console TELNET=LOG=log_file\n"
" specify console telnet logging to the\n"
" specified destination {LOG,STDOUT,DEBUG or filename)\n"
"set console TELNET=NOLOG disables console telnet logging\n"
"set console TELNET=BUFFERED[=bufsize]\n"
" specify console telnet buffering\n"
@@ -628,11 +637,12 @@ static CTAB cmd_table[] = {
"set console TELNET=UNBUFFERED\n"
" disables console telnet buffering\n"
"set console NOTELNET disable console telnet\n"
"set console LOG enable console logging\n"
"set console LOG=log_file enable console logging to the\n"
" specified destination {STDOUT,DEBUG or filename)\n"
"set console NOLOG disable console logging\n"
"set console DEBUG=dbg_file\n"
" enable console debugging to the\n"
" specified destination {LOG,STDOUT,DEBUG or filename)\n"
" specified destination {LOG,STDOUT or filename)\n"
"set console NODEBUG disable console debugging\n"
"set console {-A}{-I} HALT=<string>\n"
" set a console output string which\n"
@@ -659,6 +669,14 @@ static CTAB cmd_table[] = {
"set asynch enable asynchronous I/O\n"
"set noasynch disable asynchronous I/O\n"
"set environment name=val set environment variable\n"
"set on enables error checking after command execution\n"
"set noon disables error checking after command execution\n"
"set on inherit enables inheritance of ON state and actions into do command files\n"
"set on noinherit disables inheritance of ON state and actions into do command files\n"
"set verify re-enables display of command file processed commands\n"
"set noverify disables display of command file processed commands\n"
"set message re-enables display of command file error messages\n"
"set nomessage disables display of command file error messages\n"
"set <dev> OCT|DEC|HEX set device display radix\n"
"set <dev> ENABLED enable device\n"
"set <dev> DISABLED disable device\n"
@@ -668,8 +686,6 @@ static CTAB cmd_table[] = {
"set <unit> ENABLED enable unit\n"
"set <unit> DISABLED disable unit\n"
"set <unit> arg{,arg...} set unit parameters (see show modifiers)\n"
"set on enables error checking after command execution\n"
"set noon disables error checking after command execution\n"
},
{ "SHOW", &show_cmd, 0,
"sh{ow} br{eak} <list> show breakpoints\n"
@@ -693,15 +709,25 @@ static CTAB cmd_table[] = {
"sh{ow} <unit> {arg,...} show unit parameters\n"
"sh{ow} on show on condition actions\n" },
{ "DO", &do_cmd, 1,
"do <file> {arg,arg...} process command file\n" },
"do {-V} {-O} {-E} <file> {arg,arg...}\b"
" process command file\n" },
{ "GOTO", &goto_cmd, 1,
"goto <label> goto label in command file\n" },
{ "RETURN", &return_cmd, 0,
"return return from command file with last command status\n"
"return {-Q} <status> return from command file with specific status\n" },
{ "SHIFT", &shift_cmd, 0,
"shift shift the command file's positional parameters\n" },
{ "CALL", &call_cmd, 0,
"call transfer control to a labeled subroutine\n"
" a command file.\n" },
{ "ON", &on_cmd, 0,
"on <condition> <action> perform action after condition\n"
"on <condition> <action> perform action(s) after condition\n"
"on <condition> clear action for specific condition\n" },
{ "PROCEED", &noop_cmd, 0,
"proceed continue command file execution without doing anything\n" },
{ "IGNORE", &noop_cmd, 0,
"ignore continue command file execution without doing anything\n" },
{ "ECHO", &echo_cmd, 0,
"echo <string> display <string>\n" },
{ "ASSERT", &assert_cmd, 0,
@@ -735,6 +761,7 @@ int setenv(const char *envname, const char *envval, int overwrite)
int main (int argc, char *argv[])
{
char cbuf[CBUFSIZE], gbuf[CBUFSIZE], *cptr;
char nbuf[PATH_MAX + 7];
int32 i, sw;
t_bool lookswitch;
t_stat stat, stat_nomessage;
@@ -758,13 +785,13 @@ for (i = 1; i < argc; i++) { /* loop thru args */
sim_switches = sim_switches | sw;
}
else {
if ((strlen (argv[i]) + strlen (cbuf) + 1) >= CBUFSIZE) {
if ((strlen (argv[i]) + strlen (cbuf) + 3) >= CBUFSIZE) {
fprintf (stderr, "Argument string too long\n");
return 0;
}
if (*cbuf) /* concat args */
strcat (cbuf, " ");
strcat (cbuf, argv[i]);
sprintf(&cbuf[strlen(cbuf)], "%s%s%s", strchr(argv[i], ' ') ? "\"" : "", argv[i], strchr(argv[i], ' ') ? "\"" : "");
lookswitch = FALSE; /* no more switches */
}
} /* end for */
@@ -812,10 +839,12 @@ if (!sim_quiet) {
if (sim_dflt_dev == NULL) /* if no default */
sim_dflt_dev = sim_devices[0];
sprintf(nbuf, "%s.rc", sim_name);
stat = do_cmd (-1, nbuf); /* {sim_name}.rc proc cmd file */
if (*cbuf) /* cmd file arg? */
stat = do_cmd (0, cbuf); /* proc cmd file */
else if (*argv[0]) { /* sim name arg? */
char nbuf[PATH_MAX + 7], *np; /* "path.ini" */
char *np; /* "path.ini" */
nbuf[0] = '"'; /* starting " */
strncpy (nbuf + 1, argv[0], PATH_MAX + 1); /* copy sim name */
if (np = match_ext (nbuf, "EXE")) /* remove .exe */
@@ -846,6 +875,7 @@ while (stat != SCPE_EXIT) { /* in case exit */
stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */
else stat = SCPE_UNK;
stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */
stat_nomessage = stat_nomessage || (!sim_show_message);/* Apply global suppression */
stat = stat & ~SCPE_NOMESSAGE; /* remove possible flag */
sim_last_cmd_stat = stat; /* save command error status */
if ((stat >= SCPE_BASE) && (!stat_nomessage)) { /* error? */
@@ -990,10 +1020,15 @@ return SCPE_OK;
t_stat do_cmd (int32 flag, char *fcptr)
{
return do_cmd_label (flag, fcptr, NULL);
}
t_stat do_cmd_label (int32 flag, char *fcptr, char *label)
{
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10];
FILE *fpin;
CTAB *cmdp;
int32 echo, saved_sim_do_echo = sim_do_echo, nargs, errabort, i;
int32 echo, saved_sim_do_echo = sim_do_echo, saved_sim_show_message = sim_show_message, nargs, errabort, i;
t_bool interactive, isdo, staying;
t_stat stat, stat_nomessage;
char *ocptr;
@@ -1001,9 +1036,8 @@ char *ocptr;
stat = SCPE_OK;
staying = TRUE;
interactive = (flag > 0); /* issued interactively? */
if (interactive) { /* get switches */
if (interactive) /* get switches */
GET_SWITCHES (fcptr);
}
echo = sim_switches & SWMASK ('V'); /* -v means echo */
errabort = sim_switches & SWMASK ('E'); /* -e means abort on error */
@@ -1028,8 +1062,7 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */
if (do_arg [0] == NULL) /* need at least 1 */
return SCPE_2FARG;
strcpy (cbuf, do_arg[0]);
if ((fpin = fopen (cbuf, "r")) == NULL) { /* file failed to open? */
if ((fpin = fopen (do_arg[0], "r")) == NULL) { /* file failed to open? */
strcat (strcpy (cbuf, do_arg[0]), ".sim"); /* try again with .sim extension */
if ((fpin = fopen (cbuf, "r")) == NULL) { /* failed a second time? */
if (flag == 0) /* cmd line file? */
@@ -1044,7 +1077,7 @@ if (flag < 1) /* start at level 1 */
flag = 1;
++sim_do_depth;
sim_on_check[sim_do_depth] = sim_on_check[sim_do_depth-1]; /* inherit On mode */
if (sim_switches & SWMASK ('O')) { /* -o means inherit ON condition actions */
if ((sim_switches & SWMASK ('O')) || sim_on_inherit) { /* -o means inherit ON condition actions */
for (i=0; i<SCPE_MAX_ERR; i++) { /* replicate any on commands */
if (sim_on_actions[sim_do_depth-1][i]) {
sim_on_actions[sim_do_depth][i] = malloc(1+strlen(sim_on_actions[sim_do_depth-1][i]));
@@ -1063,14 +1096,27 @@ if (sim_switches & SWMASK ('O')) { /* -o means inherit ON c
}
}
strcpy( sim_do_filename[sim_do_depth], cbuf); /* stash away do file name */
strcpy( sim_do_filename[sim_do_depth], do_arg[0]); /* stash away do file name for possible use by 'call' command */
if (label) {
sim_gotofile = fpin;
sim_do_echo = echo;
stat = goto_cmd (0, label);
if (stat != SCPE_OK) {
strcpy(cbuf, "RETURN SCPE_ARG");
cptr = get_glyph (cbuf, gbuf, 0); /* get command glyph */
cmdp = find_cmd (gbuf); /* return the errorStage things to the stat will be returned */
goto Cleanup_Return;
}
}
if (errabort) /* -e flag? */
set_on (1, NULL); /* equivalent to ON ERROR RETURN */
do {
ocptr = cptr = sim_brk_getact (cbuf, CBUFSIZE); /* get bkpt action */
if (!ocptr) /* no pending action? */
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
if (!ocptr) { /* no pending action? */
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
sim_goto_line += 1;
}
sub_args (cbuf, gbuf, CBUFSIZE, do_arg); /* substitute args */
if (cptr == NULL) { /* EOF? */
stat = SCPE_OK; /* set good return */
@@ -1091,22 +1137,24 @@ do {
sim_gotofile = fpin;
sim_do_echo = echo;
if (cmdp = find_cmd (gbuf)) { /* lookup command */
if ((cmdp->action == &return_cmd)) /* RETURN 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? */
stat = SCPE_NEST;
else stat = do_cmd (flag + 1, cptr); /* exec DO cmd */
else
stat = do_cmd (flag + 1, cptr); /* exec DO cmd */
}
else stat = cmdp->action (cmdp->arg, cptr); /* exec other cmd */
else
if (cmdp->action == &shift_cmd) /* SHIFT command */
stat = shift_args(do_arg, sizeof(do_arg)/sizeof(do_arg[0]));
else
stat = cmdp->action (cmdp->arg, cptr); /* exec other cmd */
}
else stat = SCPE_UNK; /* bad cmd given */
stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */
stat_nomessage = stat_nomessage || (!sim_show_message);/* Apply global suppression */
stat = stat & ~SCPE_NOMESSAGE; /* remove possible flag */
if ((stat != SCPE_OK) ||
((cmdp->action != &return_cmd) &&
@@ -1118,9 +1166,9 @@ do {
(stat != SCPE_STEP)) {
if (!echo && !sim_quiet && /* report if not echoing */
(!isdo || stat_nomessage)) { /* and not suppressing messages */
printf("%s> %s\n", do_arg[0], ocptr);
printf("%s%s%s-%d> %s\n", do_arg[0], sim_goto_line, label ? "::" : "", label ? label : "", sim_goto_line, ocptr);
if (sim_log)
fprintf (sim_log, "%s> %s\n", do_arg[0], ocptr);
fprintf (sim_log, "%s%s%s-%d> %s\n", do_arg[0], label ? "::" : "", label ? label : "", sim_goto_line, ocptr);
}
}
switch (stat) {
@@ -1154,10 +1202,12 @@ do {
if (sim_vm_post != NULL)
(*sim_vm_post) (TRUE);
} while (staying);
Cleanup_Return:
fclose (fpin); /* close file */
sim_gotofile = NULL;
sim_do_echo = saved_sim_do_echo; /* restore echo state we entered with */
if (flag >= 0)
sim_show_message = saved_sim_show_message; /* restore message display state we entered with */
for (i=0; i<SCPE_MAX_ERR; i++) { /* release any on commands */
free (sim_on_actions[sim_do_depth][i]);
sim_on_actions[sim_do_depth][i] = NULL;
@@ -1220,6 +1270,7 @@ void sub_args (char *instr, char *tmpbuf, int32 maxstr, char *do_arg[])
char gbuf[CBUFSIZE];
char *ip = instr, *op = tmpbuf, *ap, *oend = tmpbuf + maxstr - 2, *istart;
char rbuf[CBUFSIZE];
int i;
while (isspace (*ip)) /* skip leading spaces */
*op++ = *ip++;
@@ -1234,19 +1285,30 @@ for (; *ip && (op < oend); ) {
if (*ip == '%') { /* sub? */
if ((ip[1] >= '0') && (ip[1] <= ('9'))) { /* %n = sub */
ap = do_arg[ip[1] - '0'];
for (i=0; i<ip[1] - '0'; ++i) /* make sure we're not past the list end */
if (do_arg[i] == NULL) {
ap = NULL;
break;
}
ip = ip + 2;
}
else if (ip[1] == '*') { /* %1 ... %9 = sub */
int i;
memset (rbuf, '\0', sizeof(rbuf));
ap = rbuf;
for (i=1; i<=9; ++i)
if (do_arg[i] == NULL)
break;
else
if ((sizeof(rbuf)-strlen(rbuf)) < (2 + strlen(do_arg[i])))
sprintf(&rbuf[strlen(rbuf)], "%s%s", (i != 1) ? " " : "", do_arg[i]);
if ((sizeof(rbuf)-strlen(rbuf)) < (2 + strlen(do_arg[i]))) {
if (strchr(do_arg[i], ' ')) { /* need to surround this argument with quotes */
char quote = '"';
if (strchr(do_arg[i], quote))
quote = '\'';
sprintf(&rbuf[strlen(rbuf)], "%s%s\"", (i != 1) ? " " : "", quote, do_arg[i], quote);
}
else
sprintf(&rbuf[strlen(rbuf)], "%s%s", (i != 1) ? " " : "", do_arg[i]);
}
else
break;
}
@@ -1291,6 +1353,10 @@ for (; *ip && (op < oend); ) {
sprintf (rbuf, "%s", sim_do_echo ? "-V" : "");
ap = rbuf;
}
else if (!strcmp ("SIM_MESSAGE", gbuf)) {
sprintf (rbuf, "%s", sim_show_message ? "" : "-Q");
ap = rbuf;
}
}
}
if (ap) { /* non-null arg? */
@@ -1318,6 +1384,15 @@ strcpy (instr, tmpbuf);
return;
}
t_stat shift_args (char *do_arg[], size_t arg_count)
{
size_t i;
for (i=1; i<arg_count; ++i)
do_arg[i] = do_arg[i+1];
return SCPE_OK;
}
/* Assert command
Syntax: ASSERT {<dev>} <reg>{<logical-op><value>}<conditional-op><value>
@@ -1383,16 +1458,19 @@ t_stat goto_cmd (int32 flag, char *fcptr)
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], gbuf1[CBUFSIZE];
long fpos;
int32 saved_do_echo = sim_do_echo;
int32 saved_goto_line = sim_goto_line;
if (NULL == sim_gotofile) return SCPE_UNK; /* only valid inside of do_cmd */
if (NULL == sim_gotofile) return SCPE_UNK; /* only valid inside of do_cmd */
get_glyph (fcptr, gbuf1, 0);
if ('\0' == gbuf1[0]) return SCPE_ARG; /* unspecified goto target */
fpos = ftell(sim_gotofile); /* Save start position */
rewind(sim_gotofile); /* start search for label */
sim_goto_line = 0; /* reset line number */
sim_do_echo = 0; /* Don't echo while searching for label */
while (1) {
cptr = read_line (cbuf, CBUFSIZE, sim_gotofile); /* get cmd line */
if (cptr == NULL) break; /* exit on eof */
sim_goto_line += 1; /* record line number */
if (*cptr == 0) continue; /* ignore blank */
if (*cptr != ':') continue; /* ignore non-labels */
++cptr; /* skip : */
@@ -1410,6 +1488,7 @@ while (1) {
}
sim_do_echo = saved_do_echo; /* restore echo mode */
fseek(sim_gotofile, fpos, SEEK_SET); /* resture start position */
sim_goto_line = saved_goto_line; /* restore start line number */
return SCPE_ARG;
}
@@ -1424,6 +1503,36 @@ t_stat return_cmd (int32 flag, char *fcptr)
return SCPE_UNK; /* only valid inside of do_cmd */
}
/* Shift command */
/* The shift command is invalid unless encountered in a do_cmd context, */
/* and in that context, it is handled as a special case inside of do_cmd() */
/* and not dispatched here, so if we get here a shift has been issued from */
/* interactive input (it is not valid interactively since it would have to */
/* mess with the program's argv which is owned by the C runtime library */
t_stat shift_cmd (int32 flag, char *fcptr)
{
return SCPE_UNK; /* only valid inside of do_cmd */
}
/* Call command */
/* The call command is invalid unless encountered in a do_cmd context, */
/* and in that context, it is handled as a special case inside of do_cmd() */
/* and not dispatched here, so if we get here a call has been issued from */
/* interactive input */
t_stat call_cmd (int32 flag, char *fcptr)
{
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE];
if (NULL == sim_gotofile) return SCPE_UNK; /* only valid inside of do_cmd */
cptr = get_glyph (fcptr, gbuf, 0);
if ('\0' == gbuf[0]) return SCPE_ARG; /* unspecified goto target */
sprintf(cbuf, "%s %s", sim_do_filename[sim_do_depth], cptr);
sim_switches |= SWMASK ('O'); /* inherit ON state and actions */
return do_cmd_label (flag, cbuf, gbuf);
}
/* On command */
t_stat on_cmd (int32 flag, char *cptr)
@@ -1449,8 +1558,34 @@ else {
return SCPE_OK;
}
/* noop command */
/* The noop command (IGNORE, PROCEED) does nothing */
t_stat noop_cmd (int32 flag, char *cptr)
{
if (cptr && (*cptr != 0)) /* now eol? */
return SCPE_2MARG;
return SCPE_OK; /* we're happy doing nothing */
}
/* Set on/noon routine */
t_stat set_on (int32 flag, char *cptr)
{
if ((flag) && (cptr)) { /* Set ON with arg */
char gbuf[CBUFSIZE];
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
if (((MATCH_CMD(gbuf,"INHERIT")) &&
(MATCH_CMD(gbuf,"NOINHERIT"))) ||
(*cptr))
return SCPE_2MARG;
if (0 == MATCH_CMD(gbuf,"INHERIT"))
sim_on_inherit = 1;
if (0 == MATCH_CMD(gbuf,"NOINHERIT"))
sim_on_inherit = 0;
return SCPE_OK;
}
if (cptr && (*cptr != 0)) /* now eol? */
return SCPE_2MARG;
sim_on_check[sim_do_depth] = flag;
@@ -1469,6 +1604,30 @@ if ((sim_do_depth != 0) &&
return SCPE_OK;
}
/* Set verify/noverify routine */
t_stat set_verify (int32 flag, char *cptr)
{
if (cptr && (*cptr != 0)) /* now eol? */
return SCPE_2MARG;
if (flag == sim_do_echo) /* already set correctly? */
return SCPE_OK;
sim_do_echo = flag;
return SCPE_OK;
}
/* Set message/nomessage routine */
t_stat set_message (int32 flag, char *cptr)
{
if (cptr && (*cptr != 0)) /* now eol? */
return SCPE_2MARG;
if (flag == sim_show_message) /* already set correctly? */
return SCPE_OK;
sim_show_message = flag;
return SCPE_OK;
}
/* Set asynch/noasynch routine */
t_stat sim_set_asynch (int32 flag, char *cptr)
@@ -1567,6 +1726,10 @@ static CTAB set_glob_tab[] = {
{ "ENV", &sim_set_environment, 1 },
{ "ON", &set_on, 1 },
{ "NOON", &set_on, 0 },
{ "VERIFY", &set_verify, 1 },
{ "NOVERIFY", &set_verify, 0 },
{ "MESSAGE", &set_message, 1 },
{ "NOMESSAGE", &set_message, 0 },
{ NULL, NULL, 0 }
};
@@ -2095,17 +2258,17 @@ for (uptr = sim_clock_queue; uptr != NULL; uptr = uptr->next) {
#if defined (SIM_ASYNCH_IO)
pthread_mutex_lock (&sim_asynch_lock);
fprintf (st, "asynchronous pending event queue\n");
if (sim_asynch_queue == (void *)-1)
if (sim_asynch_queue == AIO_LIST_END)
fprintf (st, "Empty\n");
else {
for (uptr = sim_asynch_queue; uptr != (void *)-1; uptr = uptr->a_next) {
for (uptr = sim_asynch_queue; uptr != AIO_LIST_END; uptr = uptr->a_next) {
if ((dptr = find_dev_from_unit (uptr)) != NULL) {
fprintf (st, " %s", sim_dname (dptr));
if (dptr->numunits > 1) fprintf (st, " unit %d",
(int32) (uptr - dptr->units));
}
else fprintf (st, " Unknown");
fprintf (st, " event delay %d, queue time %d\n", uptr->a_event_time, uptr->a_sim_interval);
fprintf (st, " event delay %d\n", uptr->a_event_time);
}
}
fprintf (st, "asynch latency: %d nanoseconds\n", sim_asynch_latency);
@@ -2188,6 +2351,8 @@ for (lvl=sim_do_depth; lvl >= 0; --lvl) {
fprintf(st, " on ERROR %s\n", sim_on_actions[lvl][0]);
fprintf(st, "\n");
}
if (sim_on_inherit)
fprintf(st, "on state and actions are inherited by nested do commands and subroutines\n");
return SCPE_OK;
}
@@ -5055,6 +5220,30 @@ sim_cancel (uptr);
return sim_activate (uptr, event_time);
}
/* sim_activate_notbefore - activate (queue) event even if event already scheduled
but not before the specified time
Inputs:
uptr = pointer to unit
rtime = relative timeout
Outputs:
reason = result (SCPE_OK if ok)
*/
t_stat sim_activate_notbefore (UNIT *uptr, int32 rtime)
{
uint32 rtimenow, urtime = (uint32)rtime;
AIO_ACTIVATE (sim_activate_notbefore, uptr, rtime);
sim_cancel (uptr);
rtimenow = sim_grtime();
sim_cancel (uptr);
if (0x80000000 <= urtime-rtimenow)
return sim_activate (uptr, 0);
else
return sim_activate (uptr, urtime-rtimenow);
}
/* sim_cancel - cancel (dequeue) event
Inputs: