mirror of
https://github.com/simh/simh.git
synced 2026-01-25 19:56:25 +00:00
Notes For V3.7-0
1. New Features 1.1 3.7-0 1.1.1 SCP - Added SET THROTTLE and SET NOTHROTTLE commands to regulate simulator execution rate and host resource utilization. - Added idle support (based on work by Mark Pizzolato). - Added -e to control error processing in nested DO commands (from Dave Bryan). 1.1.2 HP2100 - Added Double Integer instructions, 1000-F CPU, and Floating Point Processor (from Dave Bryan). - Added 2114 and 2115 CPUs, 12607B and 12578A DMA controllers, and 21xx binary loader protection (from Dave Bryan). 1.1.3 Interdata - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state. 1.1.4 PDP-11 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (WAIT instruction executed). - Added TA11/TU60 cassette support. 1.1.5 PDP-8 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (keyboard poll loop or jump-to-self). - Added TA8E/TU60 cassette support. 1.1.6 PDP-1 - Added support for 16-channel sequence break system. - Added support for PDP-1D extended features and timesharing clock. - Added support for Type 630 data communications subsystem. 1.1.6 PDP-4/7/9/15 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (keyboard poll loop or jump-to-self). 1.1.7 VAX, VAX780 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (more than 200 cycles at IPL's 0, 1, or 3 in kernel mode). 1.1.8 PDP-10 - Added SET IDLE and SET NOIDLE commands to idle the simulator in wait state (operating system dependent). - Added CD20 (CD11) support. 2. Bugs Fixed Please see the revision history on http://simh.trailing-edge.com or in the source module sim_rev.h.
This commit is contained in:
committed by
Mark Pizzolato
parent
15919a2dd7
commit
53d02f7fa7
154
scp.c
154
scp.c
@@ -1,6 +1,6 @@
|
||||
/* scp.c: simulator control program
|
||||
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
Copyright (c) 1993-2007, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -23,7 +23,12 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
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
|
||||
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
|
||||
14-Feb-06 RMS Upgraded save file format to V3.5
|
||||
18-Jan-06 RMS Added fprint_stopped_gen
|
||||
Added breakpoint spaces
|
||||
@@ -310,7 +315,7 @@ char *read_line (char *ptr, int32 size, FILE *stream);
|
||||
REG *find_reg_glob (char *ptr, char **optr, DEVICE **gdptr);
|
||||
char *sim_trim_endspc (char *cptr);
|
||||
|
||||
/* Forward references within commands */
|
||||
/* Forward references */
|
||||
|
||||
t_stat scp_attach_unit (DEVICE *dptr, UNIT *uptr, char *cptr);
|
||||
t_stat scp_detach_unit (DEVICE *dptr, UNIT *uptr);
|
||||
@@ -430,7 +435,7 @@ const char *scp_error_messages[] = {
|
||||
"Console Telnet connection lost",
|
||||
"Console Telnet connection timed out",
|
||||
"Console Telnet output stall",
|
||||
"" /* printed by assert */
|
||||
"Assertion failed"
|
||||
};
|
||||
|
||||
const size_t size_map[] = { sizeof (int8),
|
||||
@@ -513,6 +518,10 @@ static CTAB cmd_table[] = {
|
||||
{ "BYE", &exit_cmd, 0, NULL },
|
||||
{ "SET", &set_cmd, 0,
|
||||
"set console arg{,arg...} set console options\n"
|
||||
"set break <list> set breakpoints\n"
|
||||
"set nobreak <list> clear breakpoints\n"
|
||||
"set throttle x{M|K|%} set simulation rate\n"
|
||||
"set nothrottle set simulation rate to maximum\n"
|
||||
"set <dev> OCT|DEC|HEX set device display radix\n"
|
||||
"set <dev> ENABLED enable device\n"
|
||||
"set <dev> DISABLED disable device\n"
|
||||
@@ -524,14 +533,15 @@ static CTAB cmd_table[] = {
|
||||
"set <unit> arg{,arg...} set unit parameters\n"
|
||||
},
|
||||
{ "SHOW", &show_cmd, 0,
|
||||
"sh{ow} br{eak} <list> show breakpoints on address list\n"
|
||||
"sh{ow} br{eak} <list> show breakpoints\n"
|
||||
"sh{ow} con{figuration} show configuration\n"
|
||||
"sh{ow} cons{ole} {arg} show console options\n"
|
||||
"sh{ow} dev{ices} show devices\n"
|
||||
"sh{ow} m{odifiers} show modifiers\n"
|
||||
"sh{ow} n{ames} show logical names\n"
|
||||
"sh{ow} q{ueue} show event queue\n"
|
||||
"sh{ow} ti{me} show simulated time\n"
|
||||
"sh{ow} ti{me} show simulated time\n"
|
||||
"sh{ow} th{rottle} show simulation rate\n"
|
||||
"sh{ow} ve{rsion} show simulator version\n"
|
||||
"sh{ow} <dev> RADIX show device display radix\n"
|
||||
"sh{ow} <dev> DEBUG show device debug flags\n"
|
||||
@@ -602,6 +612,7 @@ sim_clock_queue = NULL;
|
||||
sim_is_running = 0;
|
||||
sim_log = NULL;
|
||||
if (sim_emax <= 0) sim_emax = 1;
|
||||
sim_timer_init ();
|
||||
|
||||
if ((stat = sim_ttinit ()) != SCPE_OK) {
|
||||
fprintf (stderr, "Fatal terminal initialization error\n%s\n",
|
||||
@@ -628,18 +639,15 @@ if (!sim_quiet) {
|
||||
}
|
||||
if (sim_dflt_dev == NULL) sim_dflt_dev = sim_devices[0]; /* if no default */
|
||||
|
||||
if (*cbuf) { /* cmd file arg? */
|
||||
if (*cbuf) /* cmd file arg? */
|
||||
stat = do_cmd (0, cbuf); /* proc cmd file */
|
||||
if (stat == SCPE_OPENERR) /* error? */
|
||||
fprintf (stderr, "Can't open file %s\n", cbuf);
|
||||
}
|
||||
else if (*argv[0]) { /* sim name arg? */
|
||||
char nbuf[PATH_MAX + 7], *np; /* "path.ini" */
|
||||
nbuf[0] = '"'; /* starting " */
|
||||
strncpy (nbuf + 1, argv[0], PATH_MAX + 1); /* copy sim name */
|
||||
if (np = match_ext (nbuf, "EXE")) *np = 0; /* remove .exe */
|
||||
strcat (nbuf, ".ini\""); /* add .ini" */
|
||||
stat = do_cmd (0, nbuf); /* proc cmd file */
|
||||
stat = do_cmd (-1, nbuf); /* proc cmd file */
|
||||
}
|
||||
|
||||
while (stat != SCPE_EXIT) { /* in case exit */
|
||||
@@ -757,19 +765,50 @@ if (sim_log) fprintf (sim_log, "%s\n", cptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Do command */
|
||||
/* Do command
|
||||
|
||||
Syntax: DO {-E} {-V} <filename> {<arguments>...}
|
||||
|
||||
-E causes all command errors to be fatal; without it, only EXIT and ASSERT
|
||||
failure will stop a command file.
|
||||
|
||||
-V causes commands to be echoed before execution.
|
||||
|
||||
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
|
||||
Outputs:
|
||||
status = error status
|
||||
|
||||
The "flag" input value indicates the source of the call, as follows:
|
||||
|
||||
-1 = initialization file (no error if not found)
|
||||
0 = command line file
|
||||
1 = "DO" command
|
||||
>1 = nested "DO" command
|
||||
*/
|
||||
|
||||
#define SCPE_DOFAILED 0040000 /* fail in DO, not subproc */
|
||||
|
||||
t_stat do_cmd (int32 flag, char *fcptr)
|
||||
{
|
||||
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10];
|
||||
FILE *fpin;
|
||||
CTAB *cmdp;
|
||||
int32 echo, nargs;
|
||||
t_stat stat = SCPE_OK;
|
||||
int32 echo, nargs, errabort;
|
||||
t_bool interactive, isdo, staying;
|
||||
t_stat stat;
|
||||
char *ocptr;
|
||||
|
||||
if (flag > 0) { GET_SWITCHES (fcptr); } /* get switches */
|
||||
else flag = 1; /* start at level 1 */
|
||||
stat = SCPE_OK;
|
||||
staying = TRUE;
|
||||
interactive = (flag > 0); /* issued interactively? */
|
||||
if (interactive) { GET_SWITCHES (fcptr); } /* get switches */
|
||||
echo = sim_switches & SWMASK ('V'); /* -v means echo */
|
||||
errabort = sim_switches & SWMASK ('E'); /* -e means abort on error */
|
||||
|
||||
c = fcptr;
|
||||
for (nargs = 0; nargs < 10; ) { /* extract arguments */
|
||||
@@ -782,36 +821,62 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */
|
||||
if (*c) *c++ = 0; /* term at quote/spc */
|
||||
} /* end for */
|
||||
if (nargs <= 0) return SCPE_2FARG; /* need at least 1 */
|
||||
if ((fpin = fopen (do_arg[0], "r")) == NULL) /* cmd file failed to open? */
|
||||
return SCPE_OPENERR;
|
||||
if ((fpin = fopen (do_arg[0], "r")) == NULL) { /* file failed to open? */
|
||||
if (flag == 0) /* cmd line file? */
|
||||
fprintf (stderr, "Can't open file %s\n", do_arg[0]);
|
||||
if (flag > 1)
|
||||
return SCPE_OPENERR | SCPE_DOFAILED; /* return failure with flag */
|
||||
else
|
||||
return SCPE_OPENERR; /* return failure */
|
||||
}
|
||||
if (flag < 1) flag = 1; /* start at level 1 */
|
||||
|
||||
do {
|
||||
cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
|
||||
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
|
||||
sub_args (cbuf, gbuf, CBUFSIZE, nargs, do_arg);
|
||||
if (cptr == NULL) break; /* exit on eof */
|
||||
if (cptr == NULL) { /* EOF? */
|
||||
stat = SCPE_OK; /* set good return */
|
||||
break;
|
||||
}
|
||||
if (*cptr == 0) continue; /* ignore blank */
|
||||
if (echo) printf("do> %s\n", cptr); /* echo if -v */
|
||||
if (echo && sim_log) fprintf (sim_log, "do> %s\n", cptr);
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
|
||||
sim_switches = 0; /* init switches */
|
||||
isdo = FALSE;
|
||||
if (cmdp = find_cmd (gbuf)) { /* lookup command */
|
||||
if (cmdp->action == &do_cmd) { /* DO command? */
|
||||
isdo = (cmdp->action == &do_cmd);
|
||||
if (isdo) { /* DO command? */
|
||||
if (flag >= DO_NEST_LVL) stat = SCPE_NEST; /* nest too deep? */
|
||||
else stat = do_cmd (flag + 1, cptr); /* exec DO cmd */
|
||||
}
|
||||
else stat = cmdp->action (cmdp->arg, cptr); /* exec other cmd */
|
||||
}
|
||||
else stat = SCPE_UNK; /* bad cmd given */
|
||||
if (stat >= SCPE_BASE) { /* error? */
|
||||
staying = (stat != SCPE_EXIT) && /* decide if staying */
|
||||
(stat != SCPE_AFAIL) &&
|
||||
(!errabort || (stat < SCPE_BASE) || (stat == SCPE_STEP));
|
||||
if ((stat >= SCPE_BASE) && (stat != SCPE_EXIT) && /* error from cmd? */
|
||||
(stat != SCPE_STEP)) {
|
||||
if (!echo && !sim_quiet && /* report if not echoing */
|
||||
(!isdo || (stat & SCPE_DOFAILED))) { /* and not from DO return */
|
||||
printf("%s> %s\n", do_arg[0], ocptr);
|
||||
if (sim_log)
|
||||
fprintf (sim_log, "%s> %s\n", do_arg[0], ocptr);
|
||||
}
|
||||
stat = stat & ~SCPE_DOFAILED; /* remove possible flag */
|
||||
}
|
||||
if ((staying || !interactive) && /* report error if staying */
|
||||
(stat >= SCPE_BASE)) { /* or in cmdline file */
|
||||
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
|
||||
if (sim_log) fprintf (sim_log, "%s\n",
|
||||
scp_error_messages[stat - SCPE_BASE]);
|
||||
}
|
||||
if (sim_vm_post != NULL) (*sim_vm_post) (TRUE);
|
||||
} while ((stat != SCPE_EXIT) && (stat != SCPE_AFAIL));
|
||||
} while (staying);
|
||||
|
||||
fclose (fpin); /* close file */
|
||||
return (stat == SCPE_EXIT)? SCPE_EXIT: SCPE_OK;
|
||||
return stat;
|
||||
}
|
||||
|
||||
/* Substitute_args - replace %n tokens in 'instr' with the do command's arguments
|
||||
@@ -886,8 +951,6 @@ if (!get_search (gbuf, rptr->radix, &sim_stab)) /* parse condition */
|
||||
return SCPE_MISVAL;
|
||||
val = get_rval (rptr, idx); /* get register value */
|
||||
if (test_search (val, &sim_stab)) return SCPE_OK; /* test condition */
|
||||
printf ("Assertion failed (%s)", aptr); /* report failing assertion */
|
||||
if (sim_log) fprintf (sim_log, "Assertion failed (%s)", aptr);
|
||||
return SCPE_AFAIL; /* condition fails */
|
||||
}
|
||||
|
||||
@@ -913,6 +976,8 @@ static CTAB set_glob_tab[] = {
|
||||
{ "NOLOG", &sim_set_logoff, 0 }, /* deprecated */
|
||||
{ "DEBUG", &sim_set_debon, 0 }, /* deprecated */
|
||||
{ "NODEBUG", &sim_set_deboff, 0 }, /* deprecated */
|
||||
{ "THROTTLE", &sim_set_throt, 1 },
|
||||
{ "NOTHROTTLE", &sim_set_throt, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
@@ -1143,6 +1208,7 @@ static SHTAB show_glob_tab[] = {
|
||||
{ "LOG", &sim_show_log, 0 }, /* deprecated */
|
||||
{ "TELNET", &sim_show_telnet, 0 }, /* deprecated */
|
||||
{ "DEBUG", &sim_show_debug, 0 }, /* deprecated */
|
||||
{ "THROTTLE", &sim_show_throt, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
@@ -2313,6 +2379,7 @@ if ((r = sim_check_console (30)) != SCPE_OK) { /* check console, error?
|
||||
return r;
|
||||
}
|
||||
if (sim_step) sim_activate (&sim_step_unit, sim_step); /* set step timer */
|
||||
sim_throt_sched (); /* set throttle */
|
||||
sim_is_running = 1; /* flag running */
|
||||
sim_brk_clract (); /* defang actions */
|
||||
r = sim_instr();
|
||||
@@ -2321,6 +2388,7 @@ sim_is_running = 0; /* flag idle */
|
||||
sim_ttcmd (); /* restore console */
|
||||
signal (SIGINT, SIG_DFL); /* cancel WRU */
|
||||
sim_cancel (&sim_step_unit); /* cancel step timer */
|
||||
sim_throt_cancel (); /* cancel throttle */
|
||||
if (sim_clock_queue != NULL) { /* update sim time */
|
||||
UPDATE_SIM_TIME (sim_clock_queue->time);
|
||||
}
|
||||
@@ -3166,7 +3234,7 @@ return tptr;
|
||||
cptr = pointer to input string
|
||||
Outputs:
|
||||
ipa = pointer to IP address (may be NULL), 0 = none
|
||||
ipp = pointer to IP port (may be NULL)
|
||||
ipp = pointer to IP port (may be NULL), 0 = none
|
||||
result = status
|
||||
*/
|
||||
|
||||
@@ -3177,27 +3245,28 @@ char *addrp, *portp, *octetp;
|
||||
uint32 i, addr, port, octet;
|
||||
t_stat r;
|
||||
|
||||
if ((cptr == NULL) || (*cptr == 0) || (ipa == NULL) || (ipp == NULL))
|
||||
if ((cptr == NULL) || (*cptr == 0))
|
||||
return SCPE_ARG;
|
||||
strncpy (gbuf, cptr, CBUFSIZE);
|
||||
addrp = gbuf; /* default addr */
|
||||
if (portp = strchr (gbuf, ':')) *portp++ = '.'; /* x:y? */
|
||||
if (portp = strchr (gbuf, ':')) *portp++ = 0; /* x:y? split */
|
||||
else if (strchr (gbuf, '.')) portp = NULL; /* x.y...? */
|
||||
else {
|
||||
portp = gbuf; /* port only */
|
||||
addrp = NULL; /* x is port */
|
||||
addrp = NULL; /* no addr */
|
||||
}
|
||||
if (portp) { /* port string? */
|
||||
if (ipp == NULL) return SCPE_ARG; /* not wanted? */
|
||||
port = (int32) get_uint (portp, 10, 65535, &r);
|
||||
if ((r != SCPE_OK) || (port == 0)) return SCPE_ARG;
|
||||
*ipp = port;
|
||||
}
|
||||
else *ipp = 0;
|
||||
if (addrp) {
|
||||
for (i = addr = 0; i < 4; i++) {
|
||||
octetp = strchr (addrp, '.');
|
||||
if (octetp == NULL) return SCPE_ARG;
|
||||
*octetp++ = 0;
|
||||
else port = 0;
|
||||
if (addrp) { /* addr string? */
|
||||
if (ipa == NULL) return SCPE_ARG; /* not wanted? */
|
||||
for (i = addr = 0; i < 4; i++) { /* four octets */
|
||||
octetp = strchr (addrp, '.'); /* find octet end */
|
||||
if (octetp != NULL) *octetp++ = 0; /* split string */
|
||||
else if (i < 3) return SCPE_ARG; /* except last */
|
||||
octet = (int32) get_uint (addrp, 10, 255, &r);
|
||||
if (r != SCPE_OK) return SCPE_ARG;
|
||||
addr = (addr << 8) | octet;
|
||||
@@ -3205,9 +3274,10 @@ if (addrp) {
|
||||
}
|
||||
if (((addr & 0377) == 0) || ((addr & 0377) == 255))
|
||||
return SCPE_ARG;
|
||||
*ipa = addr;
|
||||
}
|
||||
else *ipa = 0;
|
||||
else addr = 0;
|
||||
if (ipp) *ipp = port; /* return req values */
|
||||
if (ipa) *ipa = addr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -3629,7 +3699,8 @@ nodigit = 1;
|
||||
for (c = *inptr; isalnum(c); c = *++inptr) { /* loop through char */
|
||||
if (islower (c)) c = toupper (c);
|
||||
if (isdigit (c)) digit = c - (uint32) '0'; /* digit? */
|
||||
else digit = c + 10 - (uint32) 'A'; /* no, letter */
|
||||
else if (radix <= 10) break; /* stop if not expected */
|
||||
else digit = c + 10 - (uint32) 'A'; /* convert letter */
|
||||
if (digit >= radix) return 0; /* valid in radix? */
|
||||
val = (val * radix) + digit; /* add to value */
|
||||
nodigit = 0;
|
||||
@@ -3844,7 +3915,10 @@ int32 accum;
|
||||
|
||||
accum = 0;
|
||||
for (cptr = sim_clock_queue; cptr != NULL; cptr = cptr->next) {
|
||||
accum = accum + cptr->time;
|
||||
if (cptr == sim_clock_queue) {
|
||||
if (sim_interval > 0) accum = accum + sim_interval;
|
||||
}
|
||||
else accum = accum + cptr->time;
|
||||
if (cptr == uptr) return accum + 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user