SCP: Add optional VM routine that is invoked on specific REGister updates

The new REG_DEPOSIT register flag bit indicates that updates to a
REGister with this flag specified will invoke the sim_vm_reg_update
routine after the data has been updated.
This commit is contained in:
Mark Pizzolato 2021-03-02 05:35:04 -08:00
parent 1a54a2515d
commit a1785ac1d0
4 changed files with 25 additions and 3 deletions

Binary file not shown.

26
scp.c
View file

@ -451,6 +451,7 @@ void (*sim_vm_fprint_addr) (FILE *st, DEVICE *dptr, t_addr addr) = NULL;
t_addr (*sim_vm_parse_addr) (DEVICE *dptr, CONST char *cptr, CONST char **tptr) = NULL;
t_value (*sim_vm_pc_value) (void) = NULL;
t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs) = NULL;
void (*sim_vm_reg_update) (REG *rptr, uint32 idx, t_value prev_val, t_value new_val) = NULL;
t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason) = NULL;
const char *sim_vm_release = NULL;
const char *sim_vm_release_message = NULL;
@ -3148,11 +3149,13 @@ DEVICE *tdptr;
CONST char *tptr;
char *namebuf;
char rangebuf[32];
int side_effects = 0;
if (dptr->registers)
for (rptr = dptr->registers; rptr->name != NULL; rptr++) {
if (rptr->flags & REG_HIDDEN)
continue;
side_effects += ((rptr->flags & REG_DEPOSIT) != 0);
if (rptr->depth > 1)
sprintf (rangebuf, "[%d:%d]", 0, rptr->depth-1);
else
@ -3172,8 +3175,11 @@ else {
namebuf = (char *)calloc (max_namelen + 1, sizeof (*namebuf));
fprintf (st, "\nThe %s device implements these registers:\n\n", dptr->name);
for (rptr = dptr->registers; rptr->name != NULL; rptr++) {
char note[2];
if (rptr->flags & REG_HIDDEN)
continue;
strlcpy (note, (side_effects != 0) ? ((rptr->flags & REG_DEPOSIT) ? "+" : " ") : "", sizeof (note));
if (rptr->depth <= 1)
sprintf (namebuf, "%*s", -((int)max_namelen), rptr->name);
else {
@ -3181,16 +3187,22 @@ else {
sprintf (namebuf, "%s%*s", rptr->name, (int)(strlen(rptr->name))-((int)max_namelen), rangebuf);
}
if (all_unique) {
fprintf (st, " %s %4d %s\n", namebuf, rptr->width, rptr->desc ? rptr->desc : "");
fprintf (st, " %s %4d %s %s\n", namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
continue;
}
trptr = find_reg_glob (rptr->name, &tptr, &tdptr);
if ((trptr == NULL) || (tdptr != dptr))
fprintf (st, " %s %s %4d %s\n", dptr->name, namebuf, rptr->width, rptr->desc ? rptr->desc : "");
fprintf (st, " %s %s %4d %s %s\n", dptr->name, namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
else
fprintf (st, " %*s %s %4d %s\n", (int)strlen(dptr->name), "", namebuf, rptr->width, rptr->desc ? rptr->desc : "");
fprintf (st, " %*s %s %4d %s %s\n", (int)strlen(dptr->name), "", namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
}
free (namebuf);
if (side_effects)
fprintf (st, "\n + Deposits to %s register%s will have some additional\n"
" side effects which can be suppressed if the deposit is\n"
" done with the -Z switch specified\n",
(side_effects == 1) ? "this" : "these",
(side_effects == 1) ? "" : "s");
}
}
@ -9441,6 +9453,11 @@ void put_rval_pcchk (REG *rptr, uint32 idx, t_value val, t_bool pc_chk)
size_t sz;
t_value mask;
uint32 *ptr;
t_value prev_val;
if ((!(sim_switches & SWMASK ('Z'))) &&
(rptr->flags & REG_DEPOSIT) && sim_vm_reg_update)
prev_val = get_rval (rptr, idx);
#define PUT_RVAL(sz,rp,id,v,m) \
*(((sz *) rp->loc) + id) = \
@ -9499,6 +9516,9 @@ else PUT_RVAL (t_uint64, rptr, idx, val, mask);
#else
else PUT_RVAL (uint32, rptr, idx, val, mask);
#endif
if ((!(sim_switches & SWMASK ('Z'))) &&
(rptr->flags & REG_DEPOSIT) && sim_vm_reg_update)
sim_vm_reg_update (rptr, idx, prev_val, val);
}
void put_rval (REG *rptr, uint32 idx, t_value val)

1
scp.h
View file

@ -371,6 +371,7 @@ extern t_addr (*sim_vm_parse_addr) (DEVICE *dptr, CONST char *cptr, CONST char *
extern t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason);
extern t_value (*sim_vm_pc_value) (void);
extern t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs);
extern void (*sim_vm_reg_update) (REG *rptr, uint32 idx, t_value prev_val, t_value new_val);
extern const char **sim_clock_precalibrate_commands;
extern int32 sim_vm_initial_ips; /* base estimate of simulated instructions per second */
extern const char *sim_vm_interval_units; /* Simulator can change this - default "instructions" */

View file

@ -710,6 +710,7 @@ struct REG {
#define REG_VMIO 00400 /* use VM data print/parse */
#define REG_VMAD 01000 /* use VM addr print/parse */
#define REG_FIT 02000 /* fit access to size */
#define REG_DEPOSIT 04000 /* call VM routine after update */
#define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
#define REG_V_UF 16 /* device specific */