1
0
mirror of https://github.com/simh/simh.git synced 2026-01-11 23:52:58 +00:00

SCP: Correctly implement $ in all EXAMINE or DEPOSIT cases

This commit is contained in:
Mark Pizzolato 2023-06-21 14:36:16 -10:00
parent 07ea607e79
commit 008ecc4e8b

158
scp.c
View File

@ -653,7 +653,7 @@ static unsigned int sim_stop_sleep_ms = 250;
static char **sim_argv;
static int sim_exit_status = EXIT_SUCCESS; /* optionally set by EXIT command */
t_value *sim_eval = NULL;
static t_value sim_last_val;
static char sim_last_val[CBUFSIZE];
static t_addr sim_last_addr;
FILE *sim_log = NULL; /* log file */
FILEREF *sim_log_ref = NULL; /* log file file reference */
@ -690,6 +690,8 @@ static struct deleted_env_var {
char *value;
} *sim_external_env = NULL;
static int sim_external_env_count = 0;
static char *sim_tmpnam;
static FILE *sim_tmpfile = NULL;
t_stat sim_last_cmd_stat; /* Command Status */
struct timespec cmd_time; /* */
@ -959,7 +961,7 @@ static const char simh_help1[] =
"++STATE all registers in the device\n"
"++ALL all locations in the unit\n"
"++$ the last value displayed by an EXAMINE\n"
"++++++++ command interpreted as an address\n"
"++++++++ command\n"
"3Switches\n"
" Switches can be used to control the format of display information.\n"
" The actual interpretation and format of examine and deposit data is\n"
@ -974,7 +976,8 @@ static const char simh_help1[] =
"++-o or -8 display as octal\n"
"++-d or -10 display as decimal\n"
"++-h or -16 display as hexadecimal\n"
"++-2 display as binary\n\n"
"++-2 display as binary\n"
"++-q suppress examine output\n\n"
" The simulators typically accept symbolic input (see documentation with\n"
" each simulator).\n\n"
"3Examples\n"
@ -989,7 +992,9 @@ static const char simh_help1[] =
"++de all 0 set main memory to 0\n"
"++de &77>0 0 set all addresses whose low order\n"
"+++++++++ bits are non-zero to 0\n"
"++ex -m @memdump.txt 0-7777 dump memory to file\n\n"
"++ex -m @memdump.txt 0-7777 dump memory to file\n"
"++ex -q 200 get the contents of 200 available as $\n"
"++dep r0 $ store what was in 200 in r0\n\n"
" Note: to terminate an interactive command, simply type a bad value\n"
" (eg, XYZ) when input is requested.\n"
#define HLP_EVALUATE "*Commands Evaluating_Instructions"
@ -1022,14 +1027,14 @@ static const char simh_help1[] =
"3LOAD\n"
" The LOAD command (abbreviation LO) loads a file in binary loader format:\n\n"
"++LOAD <filename> {implementation options}\n\n"
" The types of formats supported are implementation specific. Options\n"
" (such as load within range) are also implementation specific.\n\n"
" The types of formats supported are simulator implementation specific.\n"
" Options: (such as load within range) are also implementation specific.\n\n"
#define HLP_DUMP "*Commands Loading_and_Saving_Programs DUMP"
"3DUMP\n"
" The DUMP command (abbreviation DU) dumps memory in binary loader format:\n\n"
"++DUMP <filename> {implementation options}\n\n"
" The types of formats supported are implementation specific. Options (such\n"
" as dump within range) are also implementation specific.\n"
" The types of formats supported are simulator implementation specific.\n"
" Options (such as dump within range) are also implementation specific.\n"
/***************** 80 character line width template *************************/
"2Saving and Restoring State\n"
#define HLP_SAVE "*Commands Saving_and_Restoring_State SAVE"
@ -2901,6 +2906,32 @@ free (*tmpname);
#endif
}
static t_stat sim_snprint_sym (char *buf, size_t bufsize, t_bool vm_flag, t_addr addr, t_value *val, UNIT *uptr, int32 sw, int32 dfltinc, int32 rdx, uint32 width, uint32 fmt)
{
t_stat reason;
size_t s;
rewind (sim_tmpfile);
if (vm_flag || ((reason = fprint_sym (sim_tmpfile, addr, val, uptr, sw)) > 0)) {
fprint_val (sim_tmpfile, val[0], rdx, width, fmt);
reason = dfltinc;
}
rewind (sim_tmpfile);
s = fread (buf, 1, bufsize - 1, sim_tmpfile);
buf[s] = '\0';
return reason;
}
static t_stat sim_fprint_sym (FILE *ofile, t_bool vm_flag, t_addr addr, t_value *val, UNIT *uptr, int32 sw, int32 dfltinc, int32 rdx, uint32 width, uint32 fmt)
{
char buf[CBUFSIZE];
t_stat r;
r = sim_snprint_sym (buf, sizeof (buf), vm_flag, addr, val, uptr, sw, dfltinc, rdx, width, fmt);
fprintf (ofile, "%s", buf);
return r;
}
t_stat process_stdin_commands (t_stat stat, char *argv[], t_bool do_called);
/* Main command loop */
@ -3033,6 +3064,12 @@ for (i = 0; cmd_table[i].name; i++) {
free (cmd_name);
}
setenv ("SIM_NAME", sim_name, 1); /* Publish simulator name */
sim_tmpfile = fopen_tempfile (&sim_tmpnam);
if (sim_tmpfile == NULL) {
fprintf (stderr, "Can't open working temp file: %s - %s\n", (sim_tmpnam == NULL) ? "" : sim_tmpnam, strerror (errno));
free (targv);
return EXIT_FAILURE;
}
stop_cpu = FALSE;
sim_interval = 0;
sim_time = sim_rtime = 0;
@ -3211,6 +3248,7 @@ sim_ttclose (); /* close console */
AIO_CLEANUP; /* Asynch I/O */
sim_cleanup_sock (); /* cleanup sockets */
fclose (stdnul); /* close bit bucket file handle */
fclose_tempfile (sim_tmpfile, &sim_tmpnam); /* close temporary work file */
free (targv); /* release any argv copy that was made */
return sim_exit_status;
}
@ -9914,8 +9952,7 @@ if ((dptr != NULL) && (dptr->examine != NULL)) {
}
if ((r == SCPE_OK) || (i > 0)) {
fprintf (st, " (");
if (fprint_sym (st, (t_addr) pcval, sim_eval, NULL, SWMASK ('M') | SIM_SW_STOP) > 0)
fprint_val (st, sim_eval[0], dptr->dradix, dptr->dwidth, PV_RZRO);
sim_fprint_sym (st, FALSE, (t_addr) pcval, sim_eval, NULL, SWMASK ('M') | SIM_SW_STOP, 0, dptr->dradix, dptr->dwidth, PV_RZRO);
fprintf (st, ")");
}
}
@ -10028,6 +10065,8 @@ cptr = get_glyph (cptr, gbuf, 0); /* get list */
if ((flag == EX_D) && (*cptr == 0)) /* deposit needs more */
return SCPE_2FARG;
ofile = sim_ofile? sim_ofile: stdout; /* no ofile? use stdout */
if (sim_switches & SWMASK ('Q')) /* Quiet mode to suppress output */
ofile = stdnul;
for (gptr = gbuf, reason = SCPE_OK;
(*gptr != 0) && (reason == SCPE_OK); gptr = tptr) {
@ -10154,7 +10193,7 @@ for (rptr = lowr; rptr <= highr; rptr++) {
fprintf (ofile, "%s[%d]: same as above\n", rptr->name, val_start+1);
}
}
sim_last_val = last_val = val;
last_val = val;
val_start = idx;
reason = ex_reg (ofile, val, flag, rptr, idx);
sim_switches = saved_switches;
@ -10257,15 +10296,17 @@ sim_eval[0] = val;
GET_RADIX (rdx, rptr->radix);
if ((rptr->flags & REG_VMAD) && sim_vm_fprint_addr)
sim_vm_fprint_addr (ofile, sim_dflt_dev, (t_addr) val);
else if (!(rptr->flags & REG_VMFLAGS) ||
(fprint_sym (ofile, (rptr->flags & REG_UFMASK) | rdx, sim_eval,
NULL, sim_switches | SIM_SW_REG) > 0)) {
fprint_val (ofile, val, rdx, rptr->width, rptr->flags & REG_FMT);
if (rptr->fields) {
fprintf (ofile, "\t");
fprint_fields (ofile, val, val, rptr->fields);
}
}
else {
sim_snprint_sym (sim_last_val, sizeof (sim_last_val), !(rptr->flags & REG_VMFLAGS),
(t_addr)((rptr->flags & REG_UFMASK) | rdx), sim_eval,
NULL, sim_switches | SIM_SW_REG, 0, rdx, rptr->width,
rptr->flags & REG_FMT);
fprintf (ofile, "%s", sim_last_val);
}
if (rptr->fields) {
fprintf (ofile, "\t");
fprint_fields (ofile, val, val, rptr->fields);
}
if (flag & EX_I)
fprintf (ofile, "\t");
else
@ -10361,6 +10402,8 @@ if (rptr->maxval > 0) /* if a maximum value is
else /* otherwise */
max = width_mask[rptr->width]; /* the mask defines the maximum value */
GET_RADIX (rdx, rptr->radix);
if (strcmp (cptr, "$") == 0)
cptr = sim_last_val;
if ((rptr->flags & REG_VMAD) && sim_vm_parse_addr) { /* address form? */
val = sim_vm_parse_addr (sim_dflt_dev, cptr, &tptr);
if ((tptr == cptr) || (*tptr != 0) || (val > max))
@ -10477,10 +10520,8 @@ if (!(flag & EX_E))
return dfltinc;
GET_RADIX (rdx, dptr->dradix);
if ((reason = fprint_sym (ofile, addr, sim_eval, uptr, sim_switches)) > 0) {
fprint_val (ofile, sim_eval[0], rdx, dptr->dwidth, PV_RZRO);
reason = dfltinc;
}
reason = sim_snprint_sym (sim_last_val, sizeof (sim_last_val), FALSE, addr, sim_eval, uptr, sim_switches, dfltinc, rdx, dptr->dwidth, PV_RZRO);
fprintf (ofile, "%s", sim_last_val);
if (flag & EX_I)
fprintf (ofile, "\t");
else
@ -10554,7 +10595,7 @@ for (i = 0, j = addr; i < sim_emax; i++, j = j + dptr->aincr) {
}
}
}
sim_last_val = sim_eval[i] = sim_eval[i] & mask;
sim_eval[i] = sim_eval[i] & mask;
}
if ((reason != SCPE_OK) && (i == 0))
return reason;
@ -10604,6 +10645,8 @@ if (uptr->flags & UNIT_RO) /* read only? */
mask = width_mask[dptr->dwidth];
GET_RADIX (rdx, dptr->dradix);
if (strcmp (cptr, "$") == 0)
cptr = sim_last_val;
if ((reason = parse_sym ((CONST char *)cptr, addr, uptr, sim_eval, sim_switches)) > 0) {
sim_eval[0] = get_uint (cptr, rdx, mask, &reason);
if (reason != SCPE_OK)
@ -10667,17 +10710,14 @@ if (*cptr == 0)
if ((r = parse_sym ((CONST char *)cptr, 0, dptr->units, sim_eval, sim_switches)) > 0) {
sim_eval[0] = get_uint (cptr, rdx, width_mask[dptr->dwidth], &r);
if (r != SCPE_OK)
return sim_messagef (r, "%s\nCan't be parsed as an instruction or data\n", cptr);
return sim_messagef (r, "'%s' - Can't be parsed as an instruction or data\n", cptr);
}
lim = 1 - r;
for (i = a = 0; a < lim; ) {
sim_printf ("%d:\t", a);
if ((r = fprint_sym (stdout, a, &sim_eval[i], dptr->units, sim_switches)) > 0)
r = fprint_val (stdout, sim_eval[i], rdx, dptr->dwidth, PV_RZRO);
if (sim_log && (!sim_oline)) {
if ((r = fprint_sym (sim_log, a, &sim_eval[i], dptr->units, sim_switches)) > 0)
r = fprint_val (sim_log, sim_eval[i], rdx, dptr->dwidth, PV_RZRO);
}
r = sim_fprint_sym (stdout, FALSE, a, &sim_eval[i], dptr->units, sim_switches, SCPE_OK, rdx, dptr->dwidth, PV_RZRO);
if (sim_log && (!sim_oline))
r = sim_fprint_sym (sim_log, FALSE, a, &sim_eval[i], dptr->units, sim_switches, SCPE_OK, rdx, dptr->dwidth, PV_RZRO);
sim_printf ("\n");
if (r < 0)
a = a + 1 - r;
@ -11001,15 +11041,15 @@ return val;
CONST char *get_range (DEVICE *dptr, CONST char *cptr, t_addr *lo, t_addr *hi,
uint32 rdx, t_addr max, char term)
{
CONST char *tptr;
CONST char *tptr, *ntptr;
if (max && strncmp (cptr, "ALL", strlen ("ALL")) == 0) { /* ALL? */
if (max && strncmp (cptr, "ALL", strlen ("ALL")) == 0) {/* ALL? */
tptr = cptr + strlen ("ALL");
*lo = 0;
*hi = max;
}
else {
if ((strncmp (cptr, ".", strlen (".")) == 0) && /* .? */
if ((strncmp (cptr, ".", strlen (".")) == 0) && /* .? */
((cptr[1] == '\0') ||
(cptr[1] == '-') ||
(cptr[1] == ':') ||
@ -11018,37 +11058,45 @@ else {
*lo = *hi = sim_last_addr;
}
else {
if (strncmp (cptr, "$", strlen ("$")) == 0) { /* $? */
tptr = cptr + strlen ("$");
*hi = *lo = (t_addr)sim_last_val;
}
else {
if (dptr && sim_vm_parse_addr) /* get low */
*lo = sim_vm_parse_addr (dptr, cptr, &tptr);
else
*lo = (t_addr) strtotv (cptr, &tptr, rdx);
if (cptr == tptr) /* error? */
return NULL;
}
ntptr = cptr + 1;
if (strncmp (cptr, "$", strlen ("$")) == 0) /* $? */
cptr = sim_last_val;
if (dptr && sim_vm_parse_addr) /* get low */
*lo = sim_vm_parse_addr (dptr, cptr, &tptr);
else
*lo = (t_addr) strtotv (cptr, &tptr, rdx);
if (cptr == tptr) /* error? */
return NULL;
if (cptr == sim_last_val)
tptr = ntptr;
}
if ((*tptr == '-') || (*tptr == ':')) { /* range? */
cptr = tptr + 1;
ntptr = cptr + 1;
if (strncmp (cptr, "$", strlen ("$")) == 0) /* $? */
cptr = sim_last_val;
if (dptr && sim_vm_parse_addr) /* get high */
*hi = sim_vm_parse_addr (dptr, cptr, &tptr);
else *hi = (t_addr) strtotv (cptr, &tptr, rdx);
else
*hi = (t_addr) strtotv (cptr, &tptr, rdx);
if (cptr == tptr)
return NULL;
if (*lo > *hi)
return NULL;
if (cptr == sim_last_val)
tptr = ntptr;
}
else if (*tptr == '/') { /* relative? */
cptr = tptr + 1;
*hi = (t_addr) strtotv (cptr, &tptr, rdx); /* get high */
if ((cptr == tptr) || (*hi == 0))
return NULL;
*hi = *lo + *hi - 1;
else {
if (*tptr == '/') { /* relative? */
cptr = tptr + 1;
*hi = (t_addr) strtotv (cptr, &tptr, rdx); /* get high */
if ((cptr == tptr) || (*hi == 0))
return NULL;
*hi = *lo + *hi - 1;
}
else
*hi = *lo;
}
else *hi = *lo;
}
sim_last_addr = *hi;
if (term && (*tptr++ != term))