Added SET ON, SET NOON, ON, GOTO and RETURN command support
The ControlFlow changes fix a potential bug in breakpoint handling which arguably merely could be “not supported”. That bug is that if a breakpoint’s actions have multiple actions AND an action early in the list invokes a do command file, the subsequent pending breakpoint actions are not performed. The ControlFlow patch/changes implement the following extensions to the SCP command language without affecting prior behavior: GOTO <Label> Command is now available. Labels are lines in which the first non whitespace character is a “:”. The target of a goto is the first matching label in the current do command file which is encountered. Since labels don’t do anything else besides being the targets of goto’s, they could be used to provide comments in do command files, for example (“:: This is a comment”) SET ON Enables error trapping for currently defined traps (by ON commands) SET NOON Disables error trapping for currently defined traps (by ON commands) RETURN Return from the current do command file execution with the status from the last executed command RETURN <statusvalue> Return from the current do command file execution with the indicated status. Status can be a number or a SCPE_<conditionname> name string. ON <statusvalue> commandtoprocess{; additionalcommandtoprocess} Sets the action(s) to take when the specific error status is returned by a command in the currently running do command file. Multiple actions can be specified with each delimited by a semicolon character (just like breakpoint action commands). ON ERROR commandtoprocess{; additionalcommandtoprocess} Sets the default action(s) to take when any otherwise unspecified error status is returned by a command in the currently running do command file. Multiple actions can be specified with each delimited by a semicolon character (just like breakpoint action commands). ON <statusvalue> ON ERROR Clears the default actions to take when any otherwise unspecified error status is returned by a command in the currently running do command file. Error traps can be taken for any command which returns a status other than SCPE_STEP, SCPE_OK, and SCPE_EXIT. ON Traps can specify any status value from the following list: NXM, UNATT, IOERR, CSUM, FMT, NOATT, OPENERR, MEM, ARG, STEP, UNK, RO, INCOMP, STOP, TTIERR, TTOERR, EOF, REL, NOPARAM, ALATT, TIMER, SIGERR, TTYERR, SUB, NOFNC, UDIS, NORO, INVSW, MISVAL, 2FARG, 2MARG, NXDEV, NXUN, NXREG, NXPAR, NEST, IERR, MTRLNT, LOST, TTMO, STALL, AFAIL. These values can be indicated by name or by their internal numeric value (not recommended). Interactions with ASSERT command and “DO –e”: DO –e is equivalent to SET ON, which by itself it equivalent to “SET ON; ON ERROR RETURN”. ASSERT failure have several different actions: If error trapping is not enabled then AFAIL causes exit from the current do command file. If error trapping is enabled and an explicit “ON AFAIL” action is defined, then the specified action is performed. If error trapping is enabled and no “ON AFAIL” action is defined, then an AFAIL causes exit from the current do command file. Other related changes/extensions: • The “!” command (execute a command on the local OS), now returns the command’s exit status as the status from the “!” command. This allows ON conditions to handle error status responses from OS commands and act as desired. • Argument substitution has been extended for do command file execution. The extended argument substitution include substitution of any program environment variable (referenced by %ENVVARNAME%) along with dynamic expansion of several pseudo environment variables: %DATE% expands to a string of the form: yyyy/mm/dd (i.e. 2011/01/23) %TIME% expands to a string of the form: hh:mm:ss (i.e. 17:23:44) %CTIME% expands to a string of the form: www mmm dd hh:mm:ss yyyy (i.e. Mon Jan 24 08:22:33 2010) %ENVNAME% expands to a string which has the value of the environment variable ENVNAME
This commit is contained in:
parent
35eac703c3
commit
766e7058f1
4 changed files with 339 additions and 87 deletions
|
@ -148,7 +148,6 @@ extern const t_bool rtc_avail;
|
||||||
extern uint32 PCX;
|
extern uint32 PCX;
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
extern int32 sim_quiet;
|
extern int32 sim_quiet;
|
||||||
extern const char *scp_error_messages[];
|
|
||||||
extern int32 SR;
|
extern int32 SR;
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
extern volatile int32 stop_cpu;
|
extern volatile int32 stop_cpu;
|
||||||
|
@ -1180,7 +1179,7 @@ static void attachCPM(UNIT *uptr) {
|
||||||
sim_quiet = sim_switches & SWMASK ('Q'); /* -q means quiet */
|
sim_quiet = sim_switches & SWMASK ('Q'); /* -q means quiet */
|
||||||
lastCPMStatus = attach_unit(uptr, cpmCommandLine);
|
lastCPMStatus = attach_unit(uptr, cpmCommandLine);
|
||||||
if ((lastCPMStatus != SCPE_OK) && (simh_device.dctrl & VERBOSE_MSG))
|
if ((lastCPMStatus != SCPE_OK) && (simh_device.dctrl & VERBOSE_MSG))
|
||||||
printf("SIMH: " ADDRESS_FORMAT " Cannot open '%s' (%s)." NLP, PCX, cpmCommandLine, scp_error_messages[lastCPMStatus - SCPE_BASE]);
|
printf("SIMH: " ADDRESS_FORMAT " Cannot open '%s' (%s)." NLP, PCX, cpmCommandLine, sim_error_text(lastCPMStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setClockZSDOSAdr points to 6 byte block in M: YY MM DD HH MM SS in BCD notation */
|
/* setClockZSDOSAdr points to 6 byte block in M: YY MM DD HH MM SS in BCD notation */
|
||||||
|
|
402
scp.c
402
scp.c
|
@ -23,6 +23,7 @@
|
||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
22-Jan-11 MP Added SET ON, SET NOON, ON, GOTO and RETURN command support
|
||||||
08-Feb-09 RMS Fixed warnings in help printouts
|
08-Feb-09 RMS Fixed warnings in help printouts
|
||||||
29-Dec-08 RMS Fixed implementation of MTAB_NC
|
29-Dec-08 RMS Fixed implementation of MTAB_NC
|
||||||
24-Nov-08 RMS Revised RESTORE unit logic for consistency
|
24-Nov-08 RMS Revised RESTORE unit logic for consistency
|
||||||
|
@ -182,6 +183,7 @@
|
||||||
#include "sim_rev.h"
|
#include "sim_rev.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#define EX_D 0 /* deposit */
|
#define EX_D 0 /* deposit */
|
||||||
#define EX_E 1 /* examine */
|
#define EX_E 1 /* examine */
|
||||||
|
@ -201,7 +203,7 @@
|
||||||
#define SSH_SH 1 /* show */
|
#define SSH_SH 1 /* show */
|
||||||
#define SSH_CL 2 /* clear */
|
#define SSH_CL 2 /* clear */
|
||||||
|
|
||||||
#define DO_NEST_LVL 10 /* DO cmd nesting level */
|
#define MAX_DO_NEST_LVL 10 /* DO cmd nesting level */
|
||||||
#define SRBSIZ 1024 /* save/restore buffer */
|
#define SRBSIZ 1024 /* save/restore buffer */
|
||||||
#define SIM_BRK_INILNT 4096 /* bpt tbl length */
|
#define SIM_BRK_INILNT 4096 /* bpt tbl length */
|
||||||
#define SIM_BRK_ALLTYP 0xFFFFFFFF
|
#define SIM_BRK_ALLTYP 0xFFFFFFFF
|
||||||
|
@ -286,6 +288,7 @@ t_stat show_dev_logicals (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *
|
||||||
t_stat show_dev_modifiers (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat show_dev_modifiers (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat show_version (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat show_version (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat show_break (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat show_break (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
|
t_stat show_on (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat show_device (FILE *st, DEVICE *dptr, int32 flag);
|
t_stat show_device (FILE *st, DEVICE *dptr, int32 flag);
|
||||||
t_stat show_unit (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag);
|
t_stat show_unit (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag);
|
||||||
t_stat show_all_mods (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flg);
|
t_stat show_all_mods (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flg);
|
||||||
|
@ -347,6 +350,8 @@ t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr,
|
||||||
UNIT *uptr, int32 dfltinc);
|
UNIT *uptr, int32 dfltinc);
|
||||||
t_stat step_svc (UNIT *ptr);
|
t_stat step_svc (UNIT *ptr);
|
||||||
void sub_args (char *instr, char *tmpbuf, int32 maxstr, char *do_arg[]);
|
void sub_args (char *instr, char *tmpbuf, int32 maxstr, char *do_arg[]);
|
||||||
|
t_stat set_on (int32 flag, char *cptr);
|
||||||
|
|
||||||
|
|
||||||
/* Global data */
|
/* Global data */
|
||||||
|
|
||||||
|
@ -363,7 +368,7 @@ int32 sim_is_running = 0;
|
||||||
uint32 sim_brk_summ = 0;
|
uint32 sim_brk_summ = 0;
|
||||||
uint32 sim_brk_types = 0;
|
uint32 sim_brk_types = 0;
|
||||||
uint32 sim_brk_dflt = 0;
|
uint32 sim_brk_dflt = 0;
|
||||||
char *sim_brk_act = NULL;
|
char *sim_brk_act[MAX_DO_NEST_LVL];
|
||||||
BRKTAB *sim_brk_tab = NULL;
|
BRKTAB *sim_brk_tab = NULL;
|
||||||
int32 sim_brk_ent = 0;
|
int32 sim_brk_ent = 0;
|
||||||
int32 sim_brk_lnt = 0;
|
int32 sim_brk_lnt = 0;
|
||||||
|
@ -380,6 +385,13 @@ t_value *sim_eval = NULL;
|
||||||
int32 sim_deb_close = 0; /* 1 = close debug */
|
int32 sim_deb_close = 0; /* 1 = close debug */
|
||||||
FILE *sim_log = NULL; /* log file */
|
FILE *sim_log = NULL; /* log file */
|
||||||
FILE *sim_deb = NULL; /* debug file */
|
FILE *sim_deb = NULL; /* debug file */
|
||||||
|
|
||||||
|
static FILE *sim_gotofile;
|
||||||
|
static int32 sim_do_depth = 0;
|
||||||
|
|
||||||
|
static int32 sim_on_check[MAX_DO_NEST_LVL+1];
|
||||||
|
static char *sim_on_actions[MAX_DO_NEST_LVL+1][SCPE_MAX_ERR+1];
|
||||||
|
|
||||||
static SCHTAB sim_stab;
|
static SCHTAB sim_stab;
|
||||||
|
|
||||||
static UNIT sim_step_unit = { UDATA (&step_svc, 0, 0) };
|
static UNIT sim_step_unit = { UDATA (&step_svc, 0, 0) };
|
||||||
|
@ -393,7 +405,7 @@ static const char *sim_sa64 = "64b addresses";
|
||||||
#else
|
#else
|
||||||
static const char *sim_sa64 = "32b addresses";
|
static const char *sim_sa64 = "32b addresses";
|
||||||
#endif
|
#endif
|
||||||
#if defined USE_NETWORK
|
#if defined USE_NETWORK || defined USE_SHARED
|
||||||
static const char *sim_snet = "Ethernet support";
|
static const char *sim_snet = "Ethernet support";
|
||||||
#else
|
#else
|
||||||
static const char *sim_snet = "no Ethernet";
|
static const char *sim_snet = "no Ethernet";
|
||||||
|
@ -404,50 +416,53 @@ static const char *sim_snet = "no Ethernet";
|
||||||
const char save_vercur[] = "V3.5";
|
const char save_vercur[] = "V3.5";
|
||||||
const char save_ver32[] = "V3.2";
|
const char save_ver32[] = "V3.2";
|
||||||
const char save_ver30[] = "V3.0";
|
const char save_ver30[] = "V3.0";
|
||||||
const char *scp_error_messages[] = {
|
const struct scp_error {
|
||||||
"Address space exceeded",
|
char *code;
|
||||||
"Unit not attached",
|
char *message;
|
||||||
"I/O error",
|
} scp_errors[1+SCPE_MAX_ERR-SCPE_BASE] =
|
||||||
"Checksum error",
|
{{"NXM", "Address space exceeded"},
|
||||||
"Format error",
|
{"UNATT", "Unit not attached"},
|
||||||
"Unit not attachable",
|
{"IOERR", "I/O error"},
|
||||||
"File open error",
|
{"CSUM", "Checksum error"},
|
||||||
"Memory exhausted",
|
{"FMT", "Format error"},
|
||||||
"Invalid argument",
|
{"NOATT", "Unit not attachable"},
|
||||||
"Step expired",
|
{"OPENERR", "File open error"},
|
||||||
"Unknown command",
|
{"MEM", "Memory exhausted"},
|
||||||
"Read only argument",
|
{"ARG", "Invalid argument"},
|
||||||
"Command not completed",
|
{"STEP", "Step expired"},
|
||||||
"Simulation stopped",
|
{"UNK", "Unknown command"},
|
||||||
"Goodbye",
|
{"RO", "Read only argument"},
|
||||||
"Console input I/O error",
|
{"INCOMP", "Command not completed"},
|
||||||
"Console output I/O error",
|
{"STOP", "Simulation stopped"},
|
||||||
"End of file",
|
{"EXIT", "Goodbye"},
|
||||||
"Relocation error",
|
{"TTIERR", "Console input I/O error"},
|
||||||
"No settable parameters",
|
{"TTOERR", "Console output I/O error"},
|
||||||
"Unit already attached",
|
{"EOF", "End of file"},
|
||||||
"Hardware timer error",
|
{"REL", "Relocation error"},
|
||||||
"SIGINT handler setup error",
|
{"NOPARAM", "No settable parameters"},
|
||||||
"Console terminal setup error",
|
{"ALATT", "Unit already attached"},
|
||||||
"Subscript out of range",
|
{"TIMER", "Hardware timer error"},
|
||||||
"Command not allowed",
|
{"SIGERR", "SIGINT handler setup error"},
|
||||||
"Unit disabled",
|
{"TTYERR", "Console terminal setup error"},
|
||||||
"Read only operation not allowed",
|
{"SUB", "Subscript out of range"},
|
||||||
"Invalid switch",
|
{"NOFNC", "Command not allowed"},
|
||||||
"Missing value",
|
{"UDIS", "Unit disabled"},
|
||||||
"Too few arguments",
|
{"NORO", "Read only operation not allowed"},
|
||||||
"Too many arguments",
|
{"INVSW", "Invalid switch"},
|
||||||
"Non-existent device",
|
{"MISVAL", "Missing value"},
|
||||||
"Non-existent unit",
|
{"2FARG", "Too few arguments"},
|
||||||
"Non-existent register",
|
{"2MARG", "Too many arguments"},
|
||||||
"Non-existent parameter",
|
{"NXDEV", "Non-existent device"},
|
||||||
"Nested DO command limit exceeded",
|
{"NXUN", "Non-existent unit"},
|
||||||
"Internal error",
|
{"NXREG", "Non-existent register"},
|
||||||
"Invalid magtape record length",
|
{"NXPAR", "Non-existent parameter"},
|
||||||
"Console Telnet connection lost",
|
{"NEST", "Nested DO command limit exceeded"},
|
||||||
"Console Telnet connection timed out",
|
{"IERR", "Internal error"},
|
||||||
"Console Telnet output stall",
|
{"MTRLNT", "Invalid magtape record length"},
|
||||||
"Assertion failed"
|
{"LOST", "Console Telnet connection lost"},
|
||||||
|
{"TTMO", "Console Telnet connection timed out"},
|
||||||
|
{"STALL", "Console Telnet output stall"},
|
||||||
|
{"AFAIL", "Assertion failed"},
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t size_map[] = { sizeof (int8),
|
const size_t size_map[] = { sizeof (int8),
|
||||||
|
@ -543,6 +558,8 @@ static CTAB cmd_table[] = {
|
||||||
"set <unit> ENABLED enable unit\n"
|
"set <unit> ENABLED enable unit\n"
|
||||||
"set <unit> DISABLED disable unit\n"
|
"set <unit> DISABLED disable unit\n"
|
||||||
"set <unit> arg{,arg...} set unit parameters\n"
|
"set <unit> arg{,arg...} set unit parameters\n"
|
||||||
|
"set on enables error checking after command execution\n"
|
||||||
|
"set noon disables error checking after command execution\n"
|
||||||
},
|
},
|
||||||
{ "SHOW", &show_cmd, 0,
|
{ "SHOW", &show_cmd, 0,
|
||||||
"sh{ow} br{eak} <list> show breakpoints\n"
|
"sh{ow} br{eak} <list> show breakpoints\n"
|
||||||
|
@ -560,9 +577,18 @@ static CTAB cmd_table[] = {
|
||||||
"sh{ow} <dev> MODIFIERS show device modifiers\n"
|
"sh{ow} <dev> MODIFIERS show device modifiers\n"
|
||||||
"sh{ow} <dev} NAMES show device logical name\n"
|
"sh{ow} <dev} NAMES show device logical name\n"
|
||||||
"sh{ow} <dev> {arg,...} show device parameters\n"
|
"sh{ow} <dev> {arg,...} show device parameters\n"
|
||||||
"sh{ow} <unit> {arg,...} show unit parameters\n" },
|
"sh{ow} <unit> {arg,...} show unit parameters\n"
|
||||||
|
"sh{ow} on show on condition actions\n" },
|
||||||
{ "DO", &do_cmd, 1,
|
{ "DO", &do_cmd, 1,
|
||||||
"do <file> {arg,arg...} process command file\n" },
|
"do <file> {arg,arg...} 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 <status> return from command file with specific status\n" },
|
||||||
|
{ "ON", &on_cmd, 0,
|
||||||
|
"on <condition> <action> perform action after condition\n"
|
||||||
|
"on <condition> clear action for specific condition\n" },
|
||||||
{ "ECHO", &echo_cmd, 0,
|
{ "ECHO", &echo_cmd, 0,
|
||||||
"echo <string> display <string>\n" },
|
"echo <string> display <string>\n" },
|
||||||
{ "ASSERT", &assert_cmd, 0,
|
{ "ASSERT", &assert_cmd, 0,
|
||||||
|
@ -632,7 +658,7 @@ sim_timer_init ();
|
||||||
|
|
||||||
if ((stat = sim_ttinit ()) != SCPE_OK) {
|
if ((stat = sim_ttinit ()) != SCPE_OK) {
|
||||||
fprintf (stderr, "Fatal terminal initialization error\n%s\n",
|
fprintf (stderr, "Fatal terminal initialization error\n%s\n",
|
||||||
scp_error_messages[stat - SCPE_BASE]);
|
sim_error_text (stat));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((sim_eval = (t_value *) calloc (sim_emax, sizeof (t_value))) == NULL) {
|
if ((sim_eval = (t_value *) calloc (sim_emax, sizeof (t_value))) == NULL) {
|
||||||
|
@ -641,12 +667,12 @@ if ((sim_eval = (t_value *) calloc (sim_emax, sizeof (t_value))) == NULL) {
|
||||||
};
|
};
|
||||||
if ((stat = reset_all_p (0)) != SCPE_OK) {
|
if ((stat = reset_all_p (0)) != SCPE_OK) {
|
||||||
fprintf (stderr, "Fatal simulator initialization error\n%s\n",
|
fprintf (stderr, "Fatal simulator initialization error\n%s\n",
|
||||||
scp_error_messages[stat - SCPE_BASE]);
|
sim_error_text (stat));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((stat = sim_brk_init ()) != SCPE_OK) {
|
if ((stat = sim_brk_init ()) != SCPE_OK) {
|
||||||
fprintf (stderr, "Fatal breakpoint table initialization error\n%s\n",
|
fprintf (stderr, "Fatal breakpoint table initialization error\n%s\n",
|
||||||
scp_error_messages[stat - SCPE_BASE]);
|
sim_error_text (stat));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!sim_quiet) {
|
if (!sim_quiet) {
|
||||||
|
@ -687,9 +713,9 @@ while (stat != SCPE_EXIT) { /* in case exit */
|
||||||
stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */
|
stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */
|
||||||
else stat = SCPE_UNK;
|
else stat = SCPE_UNK;
|
||||||
if (stat >= SCPE_BASE) { /* error? */
|
if (stat >= SCPE_BASE) { /* error? */
|
||||||
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
|
printf ("%s\n", sim_error_text (stat));
|
||||||
if (sim_log)
|
if (sim_log)
|
||||||
fprintf (sim_log, "%s\n", scp_error_messages[stat - SCPE_BASE]);
|
fprintf (sim_log, "%s\n", sim_error_text (stat));
|
||||||
}
|
}
|
||||||
if (sim_vm_post != NULL)
|
if (sim_vm_post != NULL)
|
||||||
(*sim_vm_post) (TRUE);
|
(*sim_vm_post) (TRUE);
|
||||||
|
@ -769,6 +795,7 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat spawn_cmd (int32 flag, char *cptr)
|
t_stat spawn_cmd (int32 flag, char *cptr)
|
||||||
{
|
{
|
||||||
|
t_stat status;
|
||||||
if ((cptr == NULL) || (strlen (cptr) == 0))
|
if ((cptr == NULL) || (strlen (cptr) == 0))
|
||||||
cptr = getenv("SHELL");
|
cptr = getenv("SHELL");
|
||||||
if ((cptr == NULL) || (strlen (cptr) == 0))
|
if ((cptr == NULL) || (strlen (cptr) == 0))
|
||||||
|
@ -780,12 +807,12 @@ if ((cptr == NULL) || (strlen (cptr) == 0))
|
||||||
fflush(stdout); /* flush stdout */
|
fflush(stdout); /* flush stdout */
|
||||||
if (sim_log) /* flush log if enabled */
|
if (sim_log) /* flush log if enabled */
|
||||||
fflush (sim_log);
|
fflush (sim_log);
|
||||||
system (cptr);
|
status = system (cptr);
|
||||||
#if defined (VMS)
|
#if defined (VMS)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return SCPE_OK;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Echo command */
|
/* Echo command */
|
||||||
|
@ -831,7 +858,7 @@ t_stat do_cmd (int32 flag, char *fcptr)
|
||||||
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10];
|
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10];
|
||||||
FILE *fpin;
|
FILE *fpin;
|
||||||
CTAB *cmdp;
|
CTAB *cmdp;
|
||||||
int32 echo, nargs, errabort;
|
int32 echo, nargs, errabort, i;
|
||||||
t_bool interactive, isdo, staying;
|
t_bool interactive, isdo, staying;
|
||||||
t_stat stat;
|
t_stat stat;
|
||||||
char *ocptr;
|
char *ocptr;
|
||||||
|
@ -875,6 +902,9 @@ if ((fpin = fopen (do_arg[0], "r")) == NULL) { /* file failed to open?
|
||||||
}
|
}
|
||||||
if (flag < 1) /* start at level 1 */
|
if (flag < 1) /* start at level 1 */
|
||||||
flag = 1;
|
flag = 1;
|
||||||
|
++sim_do_depth;
|
||||||
|
if (errabort) /* -e flag? */
|
||||||
|
set_on (1, NULL); /* equivalent to ON ERROR RETURN */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ocptr = cptr = sim_brk_getact (cbuf, CBUFSIZE); /* get bkpt action */
|
ocptr = cptr = sim_brk_getact (cbuf, CBUFSIZE); /* get bkpt action */
|
||||||
|
@ -891,13 +921,18 @@ do {
|
||||||
printf("do> %s\n", cptr);
|
printf("do> %s\n", cptr);
|
||||||
if (echo && sim_log)
|
if (echo && sim_log)
|
||||||
fprintf (sim_log, "do> %s\n", cptr);
|
fprintf (sim_log, "do> %s\n", cptr);
|
||||||
|
if (*cptr == ':') /* ignore label */
|
||||||
|
continue;
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
|
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
|
||||||
sim_switches = 0; /* init switches */
|
sim_switches = 0; /* init switches */
|
||||||
isdo = FALSE;
|
isdo = FALSE;
|
||||||
|
sim_gotofile = fpin;
|
||||||
if (cmdp = find_cmd (gbuf)) { /* lookup command */
|
if (cmdp = find_cmd (gbuf)) { /* lookup command */
|
||||||
|
if ((cmdp->action == &return_cmd)) /* RETURN command? */
|
||||||
|
break; /* done! */
|
||||||
isdo = (cmdp->action == &do_cmd);
|
isdo = (cmdp->action == &do_cmd);
|
||||||
if (isdo) { /* DO command? */
|
if (isdo) { /* DO command? */
|
||||||
if (flag >= DO_NEST_LVL) /* nest too deep? */
|
if (flag >= MAX_DO_NEST_LVL) /* nest too deep? */
|
||||||
stat = SCPE_NEST;
|
stat = SCPE_NEST;
|
||||||
else stat = do_cmd (flag + 1, cptr); /* exec DO cmd */
|
else stat = do_cmd (flag + 1, cptr); /* exec DO cmd */
|
||||||
}
|
}
|
||||||
|
@ -907,6 +942,10 @@ do {
|
||||||
staying = (stat != SCPE_EXIT) && /* decide if staying */
|
staying = (stat != SCPE_EXIT) && /* decide if staying */
|
||||||
(stat != SCPE_AFAIL) &&
|
(stat != SCPE_AFAIL) &&
|
||||||
(!errabort || (stat < SCPE_BASE) || (stat == SCPE_STEP));
|
(!errabort || (stat < SCPE_BASE) || (stat == SCPE_STEP));
|
||||||
|
if ((stat == SCPE_AFAIL) && /* handle special case AFAIL */
|
||||||
|
sim_on_check[sim_do_depth] && /* and use trap action if defined */
|
||||||
|
sim_on_actions[sim_do_depth][stat]) /* otherwise exit */
|
||||||
|
staying = TRUE;
|
||||||
if ((stat >= SCPE_BASE) && (stat != SCPE_EXIT) && /* error from cmd? */
|
if ((stat >= SCPE_BASE) && (stat != SCPE_EXIT) && /* error from cmd? */
|
||||||
(stat != SCPE_STEP)) {
|
(stat != SCPE_STEP)) {
|
||||||
if (!echo && !sim_quiet && /* report if not echoing */
|
if (!echo && !sim_quiet && /* report if not echoing */
|
||||||
|
@ -919,19 +958,42 @@ do {
|
||||||
}
|
}
|
||||||
if ((staying || !interactive) && /* report error if staying */
|
if ((staying || !interactive) && /* report error if staying */
|
||||||
(stat >= SCPE_BASE)) { /* or in cmdline file */
|
(stat >= SCPE_BASE)) { /* or in cmdline file */
|
||||||
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
|
printf ("%s\n", sim_error_text (stat));
|
||||||
if (sim_log)
|
if (sim_log)
|
||||||
fprintf (sim_log, "%s\n", scp_error_messages[stat - SCPE_BASE]);
|
fprintf (sim_log, "%s\n", sim_error_text (stat));
|
||||||
}
|
}
|
||||||
|
if (staying &&
|
||||||
|
(sim_on_check[sim_do_depth]) &&
|
||||||
|
(stat != SCPE_OK) &&
|
||||||
|
(stat != SCPE_STEP))
|
||||||
|
if (sim_on_actions[sim_do_depth][stat])
|
||||||
|
sim_brk_act[sim_do_depth] = sim_on_actions[sim_do_depth][stat];
|
||||||
|
else
|
||||||
|
sim_brk_act[sim_do_depth] = sim_on_actions[sim_do_depth][0];
|
||||||
if (sim_vm_post != NULL)
|
if (sim_vm_post != NULL)
|
||||||
(*sim_vm_post) (TRUE);
|
(*sim_vm_post) (TRUE);
|
||||||
} while (staying);
|
} while (staying);
|
||||||
|
|
||||||
fclose (fpin); /* close file */
|
fclose (fpin); /* close file */
|
||||||
return stat;
|
sim_gotofile = NULL;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
sim_on_check[sim_do_depth] = 0; /* clear on mode */
|
||||||
|
sim_brk_clract (); /* defang breakpoint actions */
|
||||||
|
--sim_do_depth; /* unwind nesting */
|
||||||
|
if (cmdp && (cmdp->action == &return_cmd)) { /* return command? */
|
||||||
|
if (0 == *cptr)
|
||||||
|
return stat; /* return with last command status */
|
||||||
|
sim_string_to_stat (cptr, &stat);
|
||||||
|
return stat; /* return with explicit return status */
|
||||||
|
}
|
||||||
|
return (stat == SCPE_EXIT) ? SCPE_EXIT : SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Substitute_args - replace %n tokens in 'instr' with the do command's arguments
|
/* Substitute_args - replace %n tokens in 'instr' with the do command's arguments
|
||||||
|
and other enviroment variables
|
||||||
|
|
||||||
Calling sequence
|
Calling sequence
|
||||||
instr = input string
|
instr = input string
|
||||||
|
@ -957,16 +1019,49 @@ for (ip = instr, op = tmpbuf; *ip && (op < oend); ) {
|
||||||
ip++; /* skip '\' */
|
ip++; /* skip '\' */
|
||||||
*op++ = *ip++; /* copy escaped char */
|
*op++ = *ip++; /* copy escaped char */
|
||||||
}
|
}
|
||||||
else if ((*ip == '%') && /* %n = sub */
|
else
|
||||||
((ip[1] >= '0') && (ip[1] <= ('9')))) {
|
if (*ip == '%') { /* sub? */
|
||||||
|
if ((ip[1] >= '0') && (ip[1] <= ('9'))) { /* %n = sub */
|
||||||
ap = do_arg[ip[1] - '0'];
|
ap = do_arg[ip[1] - '0'];
|
||||||
ip = ip + 2;
|
ip = ip + 2;
|
||||||
|
}
|
||||||
|
else { /* environment variable */
|
||||||
|
char gbuf[CBUFSIZE];
|
||||||
|
|
||||||
|
ap = NULL;
|
||||||
|
get_glyph_gen (ip+1, gbuf, '%', FALSE);
|
||||||
|
ip += 1 + strlen (gbuf);
|
||||||
|
if (*ip == '%') ++ip;
|
||||||
|
ap = getenv(gbuf);
|
||||||
|
if (!ap) {
|
||||||
|
static char rbuf[CBUFSIZE];
|
||||||
|
time_t now;
|
||||||
|
struct tm *tmnow;
|
||||||
|
|
||||||
|
time(&now);
|
||||||
|
tmnow = localtime(&now);
|
||||||
|
if (!strcmp ("DATE", gbuf)) {
|
||||||
|
sprintf (rbuf, "%4d/%02d/%02d", tmnow->tm_year+1900, tmnow->tm_mon+1, tmnow->tm_mday);
|
||||||
|
ap = rbuf;
|
||||||
|
}
|
||||||
|
else if (!strcmp ("TIME", gbuf)) {
|
||||||
|
sprintf (rbuf, "%02d:%02d:%02d", tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec);
|
||||||
|
ap = rbuf;
|
||||||
|
}
|
||||||
|
else if (!strcmp ("CTIME", gbuf)) {
|
||||||
|
strcpy (rbuf, ctime(&now));
|
||||||
|
rbuf[strlen (rbuf)-1] = '\0'; /* remove trailing \n */
|
||||||
|
ap = rbuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ap) { /* non-null arg? */
|
if (ap) { /* non-null arg? */
|
||||||
while (*ap && (op < oend)) /* copy the argument */
|
while (*ap && (op < oend)) /* copy the argument */
|
||||||
*op++ = *ap++;
|
*op++ = *ap++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else *op++ = *ip++; /* literal character */
|
else
|
||||||
|
*op++ = *ip++; /* literal character */
|
||||||
}
|
}
|
||||||
*op = 0; /* term buffer */
|
*op = 0; /* term buffer */
|
||||||
strcpy (instr, tmpbuf);
|
strcpy (instr, tmpbuf);
|
||||||
|
@ -1025,6 +1120,92 @@ if (test_search (val, &sim_stab)) /* test condition */
|
||||||
return SCPE_AFAIL; /* condition fails */
|
return SCPE_AFAIL; /* condition fails */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Goto command */
|
||||||
|
|
||||||
|
t_stat goto_cmd (int32 flag, char *fcptr)
|
||||||
|
{
|
||||||
|
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], gbuf1[CBUFSIZE];
|
||||||
|
long fpos;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
while (1) {
|
||||||
|
cptr = read_line (cbuf, CBUFSIZE, sim_gotofile); /* get cmd line */
|
||||||
|
if (cptr == NULL) break; /* exit on eof */
|
||||||
|
if (*cptr == 0) continue; /* ignore blank */
|
||||||
|
if (*cptr != ':') continue; /* ignore non-labels */
|
||||||
|
++cptr; /* skip : */
|
||||||
|
while (isspace (*cptr)) ++cptr; /* skip blanks */
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get label glyph */
|
||||||
|
if (0 == strcmp(gbuf, gbuf1)) {
|
||||||
|
sim_brk_clract (); /* goto defangs current actions */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fseek(sim_gotofile, fpos, SEEK_SET); /* resture start position */
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return command */
|
||||||
|
/* The return 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 return has been issued from */
|
||||||
|
/* interactive input */
|
||||||
|
|
||||||
|
t_stat return_cmd (int32 flag, char *fcptr)
|
||||||
|
{
|
||||||
|
return SCPE_UNK; /* only valid inside of do_cmd */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* On command */
|
||||||
|
|
||||||
|
t_stat on_cmd (int32 flag, char *cptr)
|
||||||
|
{
|
||||||
|
char gbuf[CBUFSIZE];
|
||||||
|
int32 cond;
|
||||||
|
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0);
|
||||||
|
if ('\0' == gbuf[0]) return SCPE_ARG; /* unspecified condition */
|
||||||
|
if (0 == strcmp("ERROR", gbuf))
|
||||||
|
cond = 0;
|
||||||
|
else
|
||||||
|
if (SCPE_OK != sim_string_to_stat (gbuf, &cond))
|
||||||
|
return SCPE_ARG;
|
||||||
|
if ((NULL == cptr) || ('\0' == *cptr)) { /* Empty Action */
|
||||||
|
free(sim_on_actions[sim_do_depth][cond]); /* Clear existing condition */
|
||||||
|
sim_on_actions[sim_do_depth][cond] = NULL; }
|
||||||
|
else {
|
||||||
|
sim_on_actions[sim_do_depth][cond] =
|
||||||
|
realloc(sim_on_actions[sim_do_depth][cond], 1+strlen(cptr));
|
||||||
|
strcpy(sim_on_actions[sim_do_depth][cond], cptr);
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat set_on (int32 flag, char *cptr)
|
||||||
|
{
|
||||||
|
if (cptr && (*cptr != 0)) /* now eol? */
|
||||||
|
return SCPE_2MARG;
|
||||||
|
sim_on_check[sim_do_depth] = flag;
|
||||||
|
if ((sim_do_depth != 0) &&
|
||||||
|
(NULL == sim_on_actions[sim_do_depth][0])) { /* default handler set? */
|
||||||
|
sim_on_actions[sim_do_depth][0] = /* No, so make "RETURN" */
|
||||||
|
malloc(1+strlen("RETURN")); /* be the default action */
|
||||||
|
strcpy(sim_on_actions[sim_do_depth][0], "RETURN");
|
||||||
|
}
|
||||||
|
if ((sim_do_depth != 0) &&
|
||||||
|
(NULL == sim_on_actions[sim_do_depth][SCPE_AFAIL])) {/* handler set for AFAIL? */
|
||||||
|
sim_on_actions[sim_do_depth][SCPE_AFAIL] = /* No, so make "RETURN" */
|
||||||
|
malloc(1+strlen("RETURN")); /* be the action */
|
||||||
|
strcpy(sim_on_actions[sim_do_depth][SCPE_AFAIL], "RETURN");
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set command */
|
/* Set command */
|
||||||
|
|
||||||
t_stat set_cmd (int32 flag, char *cptr)
|
t_stat set_cmd (int32 flag, char *cptr)
|
||||||
|
@ -1049,6 +1230,8 @@ static CTAB set_glob_tab[] = {
|
||||||
{ "NODEBUG", &sim_set_deboff, 0 }, /* deprecated */
|
{ "NODEBUG", &sim_set_deboff, 0 }, /* deprecated */
|
||||||
{ "THROTTLE", &sim_set_throt, 1 },
|
{ "THROTTLE", &sim_set_throt, 1 },
|
||||||
{ "NOTHROTTLE", &sim_set_throt, 0 },
|
{ "NOTHROTTLE", &sim_set_throt, 0 },
|
||||||
|
{ "ON", &set_on, 1 },
|
||||||
|
{ "NOON", &set_on, 0 },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1311,6 +1494,7 @@ static SHTAB show_glob_tab[] = {
|
||||||
{ "TELNET", &sim_show_telnet, 0 }, /* deprecated */
|
{ "TELNET", &sim_show_telnet, 0 }, /* deprecated */
|
||||||
{ "DEBUG", &sim_show_debug, 0 }, /* deprecated */
|
{ "DEBUG", &sim_show_debug, 0 }, /* deprecated */
|
||||||
{ "THROTTLE", &sim_show_throt, 0 },
|
{ "THROTTLE", &sim_show_throt, 0 },
|
||||||
|
{ "ON", &show_on, 0 },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1618,6 +1802,31 @@ if (dptr->flags & DEV_DEBUG) {
|
||||||
else return SCPE_NOFNC;
|
else return SCPE_NOFNC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Show On actions */
|
||||||
|
|
||||||
|
t_stat show_on (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
|
||||||
|
{
|
||||||
|
int32 lvl, i;
|
||||||
|
if (cptr && (*cptr != 0)) return SCPE_2MARG; /* now eol? */
|
||||||
|
for (lvl=sim_do_depth; lvl >= 0; --lvl) {
|
||||||
|
if (lvl > 0)
|
||||||
|
fprintf(st, "On Processing at Do Nest Level: %d", lvl);
|
||||||
|
else
|
||||||
|
fprintf(st, "On Processing for input commands");
|
||||||
|
fprintf(st, " is %s\n", (sim_on_check[lvl]) ? "enabled" : "disabled");
|
||||||
|
for (i=1; i<SCPE_BASE; ++i) {
|
||||||
|
if (sim_on_actions[lvl][i])
|
||||||
|
fprintf(st, " on %5d %s\n", i, sim_on_actions[lvl][i]); }
|
||||||
|
for (i=SCPE_BASE; i<=SCPE_MAX_ERR; ++i) {
|
||||||
|
if (sim_on_actions[lvl][i])
|
||||||
|
fprintf(st, " on %-5s %s\n", scp_errors[i-SCPE_BASE].code, sim_on_actions[lvl][i]); }
|
||||||
|
if (sim_on_actions[lvl][0])
|
||||||
|
fprintf(st, " on ERROR %s\n", sim_on_actions[lvl][0]);
|
||||||
|
fprintf(st, "\n");
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Show modifiers */
|
/* Show modifiers */
|
||||||
|
|
||||||
t_stat show_mod_names (FILE *st, DEVICE *dnotused, UNIT *unotused, int32 flag, char *cptr)
|
t_stat show_mod_names (FILE *st, DEVICE *dnotused, UNIT *unotused, int32 flag, char *cptr)
|
||||||
|
@ -2686,7 +2895,7 @@ t_addr k;
|
||||||
t_value pcval;
|
t_value pcval;
|
||||||
|
|
||||||
if (v >= SCPE_BASE) fprintf (st, "\n%s, %s: ",
|
if (v >= SCPE_BASE) fprintf (st, "\n%s, %s: ",
|
||||||
scp_error_messages[v - SCPE_BASE], pc->name);
|
sim_error_text (v), pc->name);
|
||||||
else fprintf (st, "\n%s, %s: ", sim_stop_messages[v], pc->name);
|
else fprintf (st, "\n%s, %s: ", sim_stop_messages[v], pc->name);
|
||||||
pcval = get_rval (pc, 0);
|
pcval = get_rval (pc, 0);
|
||||||
if (sim_vm_fprint_addr)
|
if (sim_vm_fprint_addr)
|
||||||
|
@ -4397,7 +4606,7 @@ sim_brk_tab = (BRKTAB *) calloc (sim_brk_lnt, sizeof (BRKTAB));
|
||||||
if (sim_brk_tab == NULL)
|
if (sim_brk_tab == NULL)
|
||||||
return SCPE_MEM;
|
return SCPE_MEM;
|
||||||
sim_brk_ent = sim_brk_ins = 0;
|
sim_brk_ent = sim_brk_ins = 0;
|
||||||
sim_brk_act = NULL;
|
sim_brk_act[sim_do_depth] = NULL;
|
||||||
sim_brk_npc (0);
|
sim_brk_npc (0);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -4598,7 +4807,7 @@ if ((bp = sim_brk_fnd (loc)) && (btyp & bp->typ)) { /* in table, type match?
|
||||||
bp->cnt = 0; /* reset count */
|
bp->cnt = 0; /* reset count */
|
||||||
sim_brk_ploc[spc] = loc; /* save location */
|
sim_brk_ploc[spc] = loc; /* save location */
|
||||||
sim_brk_pend[spc] = TRUE; /* don't do twice */
|
sim_brk_pend[spc] = TRUE; /* don't do twice */
|
||||||
sim_brk_act = bp->act; /* set up actions */
|
sim_brk_act[sim_do_depth] = bp->act; /* set up actions */
|
||||||
return (btyp & bp->typ);
|
return (btyp & bp->typ);
|
||||||
}
|
}
|
||||||
sim_brk_pend[spc] = FALSE;
|
sim_brk_pend[spc] = FALSE;
|
||||||
|
@ -4612,21 +4821,21 @@ char *sim_brk_getact (char *buf, int32 size)
|
||||||
char *ep;
|
char *ep;
|
||||||
size_t lnt;
|
size_t lnt;
|
||||||
|
|
||||||
if (sim_brk_act == NULL) /* any action? */
|
if (sim_brk_act[sim_do_depth] == NULL) /* any action? */
|
||||||
return NULL;
|
return NULL;
|
||||||
while (isspace (*sim_brk_act)) /* skip spaces */
|
while (isspace (*sim_brk_act[sim_do_depth])) /* skip spaces */
|
||||||
sim_brk_act++;
|
sim_brk_act[sim_do_depth]++;
|
||||||
if (*sim_brk_act == 0) /* now empty? */
|
if (*sim_brk_act[sim_do_depth] == 0) /* now empty? */
|
||||||
return (sim_brk_act = NULL);
|
return (sim_brk_act[sim_do_depth] = NULL);
|
||||||
if (ep = strchr (sim_brk_act, ';')) { /* cmd delimiter? */
|
if (ep = strchr (sim_brk_act[sim_do_depth], ';')) { /* cmd delimiter? */
|
||||||
lnt = ep - sim_brk_act; /* cmd length */
|
lnt = ep - sim_brk_act[sim_do_depth]; /* cmd length */
|
||||||
memcpy (buf, sim_brk_act, lnt + 1); /* copy with ; */
|
memcpy (buf, sim_brk_act[sim_do_depth], lnt + 1); /* copy with ; */
|
||||||
buf[lnt] = 0; /* erase ; */
|
buf[lnt] = 0; /* erase ; */
|
||||||
sim_brk_act = sim_brk_act + lnt + 1; /* adv ptr */
|
sim_brk_act[sim_do_depth] += lnt + 1; /* adv ptr */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strncpy (buf, sim_brk_act, size); /* copy action */
|
strncpy (buf, sim_brk_act[sim_do_depth], size); /* copy action */
|
||||||
sim_brk_act = NULL; /* no more */
|
sim_brk_act[sim_do_depth] = NULL; /* no more */
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -4635,7 +4844,7 @@ return buf;
|
||||||
|
|
||||||
void sim_brk_clract (void)
|
void sim_brk_clract (void)
|
||||||
{
|
{
|
||||||
sim_brk_act = NULL;
|
sim_brk_act[sim_do_depth] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New PC */
|
/* New PC */
|
||||||
|
@ -4664,6 +4873,43 @@ if (spc < SIM_BKPT_N_SPC) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Message Text */
|
||||||
|
|
||||||
|
char *sim_error_text (t_stat stat)
|
||||||
|
{
|
||||||
|
static char msgbuf[64];
|
||||||
|
|
||||||
|
stat &= ~(SCPE_KFLAG|SCPE_BREAK); /* remove any flags */
|
||||||
|
if ((stat >= SCPE_BASE) && (stat <= SCPE_MAX_ERR))
|
||||||
|
return scp_errors[stat-SCPE_BASE].message;
|
||||||
|
sprintf(msgbuf, "Error %d", stat);
|
||||||
|
return msgbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat sim_string_to_stat (char *cptr, t_stat *stat)
|
||||||
|
{
|
||||||
|
char gbuf[CBUFSIZE];
|
||||||
|
int32 cond;
|
||||||
|
|
||||||
|
*stat = SCPE_ARG;
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0);
|
||||||
|
if (0 == memcmp("SCPE_", gbuf, 5))
|
||||||
|
strcpy (gbuf, gbuf+5); /* skip leading SCPE_ */
|
||||||
|
for (cond=0; cond < (SCPE_MAX_ERR-SCPE_BASE); cond++)
|
||||||
|
if (0 == strcmp(scp_errors[cond].code, gbuf)) {
|
||||||
|
cond += SCPE_BASE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (cond == (SCPE_MAX_ERR-SCPE_BASE)) { /* not found? */
|
||||||
|
if (0 == (cond = strtol(gbuf, NULL, 0))) /* try explicit number */
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
|
if (cond > SCPE_MAX_ERR)
|
||||||
|
return SCPE_ARG;
|
||||||
|
*stat = cond;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Debug printout routines, from Dave Hittner */
|
/* Debug printout routines, from Dave Hittner */
|
||||||
|
|
||||||
const char* debug_bstates = "01_^";
|
const char* debug_bstates = "01_^";
|
||||||
|
|
5
scp.h
5
scp.h
|
@ -69,6 +69,9 @@ t_stat set_cmd (int32 flag, char *ptr);
|
||||||
t_stat show_cmd (int32 flag, char *ptr);
|
t_stat show_cmd (int32 flag, char *ptr);
|
||||||
t_stat brk_cmd (int32 flag, char *ptr);
|
t_stat brk_cmd (int32 flag, char *ptr);
|
||||||
t_stat do_cmd (int32 flag, char *ptr);
|
t_stat do_cmd (int32 flag, char *ptr);
|
||||||
|
t_stat goto_cmd (int32 flag, char *ptr);
|
||||||
|
t_stat return_cmd (int32 flag, char *ptr);
|
||||||
|
t_stat on_cmd (int32 flag, char *ptr);
|
||||||
t_stat assert_cmd (int32 flag, char *ptr);
|
t_stat assert_cmd (int32 flag, char *ptr);
|
||||||
t_stat help_cmd (int32 flag, char *ptr);
|
t_stat help_cmd (int32 flag, char *ptr);
|
||||||
t_stat spawn_cmd (int32 flag, char *ptr);
|
t_stat spawn_cmd (int32 flag, char *ptr);
|
||||||
|
@ -113,6 +116,8 @@ BRKTAB *sim_brk_fnd (t_addr loc);
|
||||||
uint32 sim_brk_test (t_addr bloc, uint32 btyp);
|
uint32 sim_brk_test (t_addr bloc, uint32 btyp);
|
||||||
void sim_brk_clrspc (uint32 spc);
|
void sim_brk_clrspc (uint32 spc);
|
||||||
char *match_ext (char *fnam, char *ext);
|
char *match_ext (char *fnam, char *ext);
|
||||||
|
char *sim_error_text (t_stat stat);
|
||||||
|
t_stat sim_string_to_stat (char *cptr, t_stat *cond);
|
||||||
t_stat sim_cancel_step (void);
|
t_stat sim_cancel_step (void);
|
||||||
void sim_debug_u16 (uint32 dbits, DEVICE* dptr, const char* const* bitdefs,
|
void sim_debug_u16 (uint32 dbits, DEVICE* dptr, const char* const* bitdefs,
|
||||||
uint16 before, uint16 after, int terminate);
|
uint16 before, uint16 after, int terminate);
|
||||||
|
|
|
@ -242,6 +242,8 @@ typedef uint32 t_addr;
|
||||||
#define SCPE_TTMO (SCPE_BASE + 40) /* Telnet conn timeout */
|
#define SCPE_TTMO (SCPE_BASE + 40) /* Telnet conn timeout */
|
||||||
#define SCPE_STALL (SCPE_BASE + 41) /* Telnet conn stall */
|
#define SCPE_STALL (SCPE_BASE + 41) /* Telnet conn stall */
|
||||||
#define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */
|
#define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */
|
||||||
|
|
||||||
|
#define SCPE_MAX_ERR (SCPE_BASE + 43) /* Maximum SCPE Error Value */
|
||||||
#define SCPE_KFLAG 0010000 /* tti data flag */
|
#define SCPE_KFLAG 0010000 /* tti data flag */
|
||||||
#define SCPE_BREAK 0020000 /* tti break flag */
|
#define SCPE_BREAK 0020000 /* tti break flag */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue