SCP: Breakpoint enhancements
- Reliable support for multiple breakpoint types - Optional separate breakpoint types defined concurrently with the same address
This commit is contained in:
parent
c33abecf8b
commit
f82d3f8994
4 changed files with 195 additions and 74 deletions
Binary file not shown.
261
scp.c
261
scp.c
|
@ -393,7 +393,9 @@ t_stat sim_brk_clrall (int32 sw);
|
||||||
t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw);
|
t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw);
|
||||||
t_stat sim_brk_showall (FILE *st, int32 sw);
|
t_stat sim_brk_showall (FILE *st, int32 sw);
|
||||||
CONST char *sim_brk_getact (char *buf, int32 size);
|
CONST char *sim_brk_getact (char *buf, int32 size);
|
||||||
BRKTAB *sim_brk_new (t_addr loc);
|
BRKTAB *sim_brk_new (t_addr loc, uint32 btyp);
|
||||||
|
char *sim_brk_clract (void);
|
||||||
|
|
||||||
FILE *stdnul;
|
FILE *stdnul;
|
||||||
|
|
||||||
/* Command support routines */
|
/* Command support routines */
|
||||||
|
@ -475,12 +477,10 @@ uint32 sim_brk_types = 0;
|
||||||
uint32 sim_brk_dflt = 0;
|
uint32 sim_brk_dflt = 0;
|
||||||
char *sim_brk_act[MAX_DO_NEST_LVL];
|
char *sim_brk_act[MAX_DO_NEST_LVL];
|
||||||
char *sim_brk_act_buf[MAX_DO_NEST_LVL];
|
char *sim_brk_act_buf[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;
|
||||||
int32 sim_brk_ins = 0;
|
int32 sim_brk_ins = 0;
|
||||||
t_bool sim_brk_pend[SIM_BKPT_N_SPC] = { FALSE };
|
|
||||||
t_addr sim_brk_ploc[SIM_BKPT_N_SPC] = { 0 };
|
|
||||||
int32 sim_quiet = 0;
|
int32 sim_quiet = 0;
|
||||||
int32 sim_step = 0;
|
int32 sim_step = 0;
|
||||||
static double sim_time;
|
static double sim_time;
|
||||||
|
@ -4604,7 +4604,8 @@ t_stat r;
|
||||||
|
|
||||||
if (cptr && (*cptr != 0))
|
if (cptr && (*cptr != 0))
|
||||||
r = ssh_break (st, cptr, 1); /* more? */
|
r = ssh_break (st, cptr, 1); /* more? */
|
||||||
else r = sim_brk_showall (st, sim_switches);
|
else
|
||||||
|
r = sim_brk_showall (st, sim_switches);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5045,7 +5046,7 @@ t_addr lo, hi, max = uptr->capac - 1;
|
||||||
int32 cnt;
|
int32 cnt;
|
||||||
|
|
||||||
if (sim_brk_types == 0)
|
if (sim_brk_types == 0)
|
||||||
return SCPE_NOFNC;
|
return sim_messagef (SCPE_NOFNC, "No breakpoint support in this simulator\n");
|
||||||
if ((dptr == NULL) || (uptr == NULL))
|
if ((dptr == NULL) || (uptr == NULL))
|
||||||
return SCPE_IERR;
|
return SCPE_IERR;
|
||||||
abuf[sizeof(abuf)-1] = '\0';
|
abuf[sizeof(abuf)-1] = '\0';
|
||||||
|
@ -5077,9 +5078,11 @@ while (*cptr) {
|
||||||
if ((lo == 0) && (hi == max)) {
|
if ((lo == 0) && (hi == max)) {
|
||||||
if (flg == SSH_CL)
|
if (flg == SSH_CL)
|
||||||
sim_brk_clrall (sim_switches);
|
sim_brk_clrall (sim_switches);
|
||||||
else if (flg == SSH_SH)
|
else
|
||||||
sim_brk_showall (st, sim_switches);
|
if (flg == SSH_SH)
|
||||||
else return SCPE_ARG;
|
sim_brk_showall (st, sim_switches);
|
||||||
|
else
|
||||||
|
return SCPE_ARG;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for ( ; lo <= hi; lo = lo + 1) {
|
for ( ; lo <= hi; lo = lo + 1) {
|
||||||
|
@ -5094,6 +5097,8 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat ssh_break_one (FILE *st, int32 flg, t_addr lo, int32 cnt, CONST char *aptr)
|
t_stat ssh_break_one (FILE *st, int32 flg, t_addr lo, int32 cnt, CONST char *aptr)
|
||||||
{
|
{
|
||||||
|
if (!sim_brk_types)
|
||||||
|
return sim_messagef (SCPE_NOFNC, "No breakpoint support in this simulator\n");
|
||||||
switch (flg) {
|
switch (flg) {
|
||||||
|
|
||||||
case SSH_ST:
|
case SSH_ST:
|
||||||
|
@ -8917,7 +8922,7 @@ return cnt;
|
||||||
instruction breakpoint capability.
|
instruction breakpoint capability.
|
||||||
|
|
||||||
Breakpoints are stored in table sim_brk_tab, which is ordered by address for
|
Breakpoints are stored in table sim_brk_tab, which is ordered by address for
|
||||||
efficient binary searching. A breakpoint consists of a four entry structure:
|
efficient binary searching. A breakpoint consists of a six entry structure:
|
||||||
|
|
||||||
addr address of the breakpoint
|
addr address of the breakpoint
|
||||||
type types of breakpoints set on the address
|
type types of breakpoints set on the address
|
||||||
|
@ -8925,10 +8930,12 @@ return cnt;
|
||||||
cnt number of iterations before breakp is taken
|
cnt number of iterations before breakp is taken
|
||||||
action pointer command string to be executed
|
action pointer command string to be executed
|
||||||
when break is taken
|
when break is taken
|
||||||
|
next list of other breakpoints with the same addr specifier
|
||||||
|
time_fired array of when this breakpoint was fired for each class
|
||||||
|
|
||||||
sim_brk_summ is a summary of the types of breakpoints that are currently set (it
|
sim_brk_summ is a summary of the types of breakpoints that are currently set (it
|
||||||
is the bitwise OR of all the type fields). A simulator need only check for
|
is the bitwise OR of all the type fields). A simulator need only check for
|
||||||
a breakpoint of type X if bit SWMASK('X') is set in sim_brk_sum.
|
a breakpoint of type X if bit SWMASK('X') is set in sim_brk_summ.
|
||||||
|
|
||||||
The package contains the following public routines:
|
The package contains the following public routines:
|
||||||
|
|
||||||
|
@ -8948,10 +8955,25 @@ return cnt;
|
||||||
|
|
||||||
t_stat sim_brk_init (void)
|
t_stat sim_brk_init (void)
|
||||||
{
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
for (i=0; i<sim_brk_lnt; i++) {
|
||||||
|
BRKTAB *bp = sim_brk_tab[i];
|
||||||
|
|
||||||
|
while (bp) {
|
||||||
|
BRKTAB *bpt = bp->next;
|
||||||
|
|
||||||
|
free (bp->act);
|
||||||
|
free (bp);
|
||||||
|
bp = bpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset (sim_brk_tab, 0, sim_brk_lnt*sizeof (BRKTAB*));
|
||||||
sim_brk_lnt = SIM_BRK_INILNT;
|
sim_brk_lnt = SIM_BRK_INILNT;
|
||||||
sim_brk_tab = (BRKTAB *) calloc (sim_brk_lnt, sizeof (BRKTAB));
|
sim_brk_tab = (BRKTAB **) realloc (sim_brk_tab, sim_brk_lnt*sizeof (BRKTAB*));
|
||||||
if (sim_brk_tab == NULL)
|
if (sim_brk_tab == NULL)
|
||||||
return SCPE_MEM;
|
return SCPE_MEM;
|
||||||
|
memset (sim_brk_tab, 0, sim_brk_lnt*sizeof (BRKTAB*));
|
||||||
sim_brk_ent = sim_brk_ins = 0;
|
sim_brk_ent = sim_brk_ins = 0;
|
||||||
sim_brk_clract ();
|
sim_brk_clract ();
|
||||||
sim_brk_npc (0);
|
sim_brk_npc (0);
|
||||||
|
@ -8973,9 +8995,11 @@ lo = 0; /* initial bounds */
|
||||||
hi = sim_brk_ent - 1;
|
hi = sim_brk_ent - 1;
|
||||||
do {
|
do {
|
||||||
p = (lo + hi) >> 1; /* probe */
|
p = (lo + hi) >> 1; /* probe */
|
||||||
bp = sim_brk_tab + p; /* table addr */
|
bp = sim_brk_tab[p]; /* table addr */
|
||||||
if (loc == bp->addr) /* match? */
|
if (loc == bp->addr) { /* match? */
|
||||||
|
sim_brk_ins = p;
|
||||||
return bp;
|
return bp;
|
||||||
|
}
|
||||||
else if (loc < bp->addr) /* go down? p is upper */
|
else if (loc < bp->addr) /* go down? p is upper */
|
||||||
hi = p - 1;
|
hi = p - 1;
|
||||||
else lo = p + 1; /* go up? p is lower */
|
else lo = p + 1; /* go up? p is lower */
|
||||||
|
@ -8986,37 +9010,56 @@ else sim_brk_ins = p + 1; /* after last sch */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BRKTAB *sim_brk_fnd_ex (t_addr loc, uint32 btyp, t_bool any_typ)
|
||||||
|
{
|
||||||
|
BRKTAB *bp = sim_brk_fnd (loc);
|
||||||
|
|
||||||
|
while (bp) {
|
||||||
|
if (any_typ ? (bp->typ & btyp) : (bp->typ == btyp))
|
||||||
|
return bp;
|
||||||
|
bp = bp->next;
|
||||||
|
}
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Insert a breakpoint */
|
/* Insert a breakpoint */
|
||||||
|
|
||||||
BRKTAB *sim_brk_new (t_addr loc)
|
BRKTAB *sim_brk_new (t_addr loc, uint32 btyp)
|
||||||
{
|
{
|
||||||
int32 i, t;
|
int32 i, t;
|
||||||
BRKTAB *bp, *newp;
|
BRKTAB *bp, **newp;
|
||||||
|
|
||||||
if (sim_brk_ins < 0)
|
if (sim_brk_ins < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (sim_brk_ent >= sim_brk_lnt) { /* out of space? */
|
if (sim_brk_ent >= sim_brk_lnt) { /* out of space? */
|
||||||
t = sim_brk_lnt + SIM_BRK_INILNT; /* new size */
|
t = sim_brk_lnt + SIM_BRK_INILNT; /* new size */
|
||||||
newp = (BRKTAB *) calloc (t, sizeof (BRKTAB)); /* new table */
|
newp = (BRKTAB **) calloc (t, sizeof (BRKTAB*)); /* new table */
|
||||||
if (newp == NULL) /* can't extend */
|
if (newp == NULL) /* can't extend */
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < sim_brk_lnt; i++) /* copy table */
|
memcpy (newp, sim_brk_tab, sim_brk_lnt * sizeof (*sim_brk_tab));/* copy table */
|
||||||
*(newp + i) = *(sim_brk_tab + i);
|
memset (newp + sim_brk_lnt, 0, SIM_BRK_INILNT * sizeof (*newp));/* zero new entries */
|
||||||
free (sim_brk_tab); /* free old table */
|
free (sim_brk_tab); /* free old table */
|
||||||
sim_brk_tab = newp; /* new base, lnt */
|
sim_brk_tab = newp; /* new base, lnt */
|
||||||
sim_brk_lnt = t;
|
sim_brk_lnt = t;
|
||||||
}
|
}
|
||||||
if (sim_brk_ins != sim_brk_ent) { /* move needed? */
|
if ((sim_brk_ins == sim_brk_ent) ||
|
||||||
for (bp = sim_brk_tab + sim_brk_ent;
|
((sim_brk_ins != sim_brk_ent) &&
|
||||||
bp > sim_brk_tab + sim_brk_ins; bp--)
|
(sim_brk_tab[sim_brk_ins]->addr != loc))) { /* need to open a hole? */
|
||||||
*bp = *(bp - 1);
|
for (i = sim_brk_ent; i > sim_brk_ins; --i)
|
||||||
|
sim_brk_tab[i] = sim_brk_tab[i - 1];
|
||||||
|
sim_brk_tab[sim_brk_ins] = NULL;
|
||||||
}
|
}
|
||||||
bp = sim_brk_tab + sim_brk_ins;
|
bp = calloc (1, sizeof (*bp));
|
||||||
|
bp->next = sim_brk_tab[sim_brk_ins];
|
||||||
|
sim_brk_tab[sim_brk_ins] = bp;
|
||||||
|
if (bp->next == NULL)
|
||||||
|
sim_brk_ent += 1;
|
||||||
bp->addr = loc;
|
bp->addr = loc;
|
||||||
bp->typ = 0;
|
bp->typ = btyp;
|
||||||
bp->cnt = 0;
|
bp->cnt = 0;
|
||||||
bp->act = NULL;
|
bp->act = NULL;
|
||||||
sim_brk_ent = sim_brk_ent + 1;
|
for (i = 0; i < SIM_BKPT_N_SPC; i++)
|
||||||
|
bp->time_fired[i] = -1.0;
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9035,12 +9078,17 @@ if (~sim_brk_types & sw) {
|
||||||
}
|
}
|
||||||
if ((sw & BRK_TYP_DYN_ALL) && act) /* can't specify an action with a dynamic breakpoint */
|
if ((sw & BRK_TYP_DYN_ALL) && act) /* can't specify an action with a dynamic breakpoint */
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
bp = sim_brk_fnd (loc); /* present? */
|
bp = sim_brk_fnd (loc); /* loc present? */
|
||||||
if (!bp) /* no, allocate */
|
if (!bp) /* no, allocate */
|
||||||
bp = sim_brk_new (loc);
|
bp = sim_brk_new (loc, sw);
|
||||||
|
else {
|
||||||
|
while (bp && (bp->typ != sw))
|
||||||
|
bp = bp->next;
|
||||||
|
if (!bp)
|
||||||
|
bp = sim_brk_new (loc, sw);
|
||||||
|
}
|
||||||
if (!bp) /* still no? mem err */
|
if (!bp) /* still no? mem err */
|
||||||
return SCPE_MEM;
|
return SCPE_MEM;
|
||||||
bp->typ |= sw; /* set type */
|
|
||||||
bp->cnt = ncnt; /* set count */
|
bp->cnt = ncnt; /* set count */
|
||||||
if ((!(sw & BRK_TYP_DYN_ALL)) && /* Not Dynamic and */
|
if ((!(sw & BRK_TYP_DYN_ALL)) && /* Not Dynamic and */
|
||||||
(bp->act != NULL) && (act != NULL)) { /* replace old action? */
|
(bp->act != NULL) && (act != NULL)) { /* replace old action? */
|
||||||
|
@ -9054,7 +9102,7 @@ if ((act != NULL) && (*act != 0)) { /* new action? */
|
||||||
strncpy (newp, act, CBUFSIZE); /* copy action */
|
strncpy (newp, act, CBUFSIZE); /* copy action */
|
||||||
bp->act = newp; /* set pointer */
|
bp->act = newp; /* set pointer */
|
||||||
}
|
}
|
||||||
sim_brk_summ = sim_brk_summ | sw;
|
sim_brk_summ = sim_brk_summ | (sw & ~BRK_TYP_TEMP);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9062,23 +9110,42 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat sim_brk_clr (t_addr loc, int32 sw)
|
t_stat sim_brk_clr (t_addr loc, int32 sw)
|
||||||
{
|
{
|
||||||
BRKTAB *bp = sim_brk_fnd (loc);
|
BRKTAB *bpl, *bp = sim_brk_fnd (loc);
|
||||||
|
int32 i;
|
||||||
|
|
||||||
if (!bp) /* not there? ok */
|
if (!bp) /* not there? ok */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
if (sw == 0)
|
if (sw == 0)
|
||||||
sw = SIM_BRK_ALLTYP;
|
sw = SIM_BRK_ALLTYP;
|
||||||
bp->typ = bp->typ & ~sw;
|
|
||||||
if (bp->typ) /* clear all types? */
|
while (bp) {
|
||||||
return SCPE_OK;
|
if (bp->typ == (bp->typ & sw)) {
|
||||||
if (bp->act != NULL) /* deallocate action */
|
free (bp->act); /* deallocate action */
|
||||||
free (bp->act);
|
if (bp == sim_brk_tab[sim_brk_ins])
|
||||||
for ( ; bp < (sim_brk_tab + sim_brk_ent - 1); bp++) /* erase entry */
|
bpl = sim_brk_tab[sim_brk_ins] = bp->next;
|
||||||
*bp = *(bp + 1);
|
else
|
||||||
sim_brk_ent = sim_brk_ent - 1; /* decrement count */
|
bpl->next = bp->next;
|
||||||
|
free (bp);
|
||||||
|
bp = bpl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bpl = bp;
|
||||||
|
bp = bp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sim_brk_tab[sim_brk_ins] == NULL) { /* erased entry */
|
||||||
|
sim_brk_ent = sim_brk_ent - 1; /* decrement count */
|
||||||
|
for (i = sim_brk_ins; i < sim_brk_ent; i++) /* shuffle remaining entries */
|
||||||
|
sim_brk_tab[i] = sim_brk_tab[i+1];
|
||||||
|
}
|
||||||
sim_brk_summ = 0; /* recalc summary */
|
sim_brk_summ = 0; /* recalc summary */
|
||||||
for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++)
|
for (i = 0; i < sim_brk_ent; i++) {
|
||||||
sim_brk_summ = sim_brk_summ | bp->typ;
|
bp = sim_brk_tab[i];
|
||||||
|
while (bp) {
|
||||||
|
sim_brk_summ |= (bp->typ & ~BRK_TYP_TEMP);
|
||||||
|
bp = bp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9086,13 +9153,16 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat sim_brk_clrall (int32 sw)
|
t_stat sim_brk_clrall (int32 sw)
|
||||||
{
|
{
|
||||||
BRKTAB *bp;
|
int32 i;
|
||||||
|
|
||||||
if (sw == 0) sw = SIM_BRK_ALLTYP;
|
if (sw == 0)
|
||||||
for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); ) {
|
sw = SIM_BRK_ALLTYP;
|
||||||
if (bp->typ & sw)
|
for (i = 0; i < sim_brk_ent;) {
|
||||||
sim_brk_clr (bp->addr, sw);
|
t_addr loc = sim_brk_tab[i]->addr;
|
||||||
else bp++;
|
sim_brk_clr (loc, sw);
|
||||||
|
if ((i < sim_brk_ent) &&
|
||||||
|
(loc == sim_brk_tab[i]->addr))
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -9101,7 +9171,7 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw)
|
t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw)
|
||||||
{
|
{
|
||||||
BRKTAB *bp = sim_brk_fnd (loc);
|
BRKTAB *bp = sim_brk_fnd_ex (loc, sw & (~SWMASK ('C')), FALSE);
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
int32 i, any;
|
int32 i, any;
|
||||||
|
|
||||||
|
@ -9150,13 +9220,60 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat sim_brk_showall (FILE *st, int32 sw)
|
t_stat sim_brk_showall (FILE *st, int32 sw)
|
||||||
{
|
{
|
||||||
BRKTAB *bp;
|
int32 bit, mask, types;
|
||||||
|
BRKTAB **bpt;
|
||||||
|
|
||||||
if ((sw == 0) || (sw == SWMASK ('C')))
|
if ((sw == 0) || (sw == SWMASK ('C')))
|
||||||
sw = SIM_BRK_ALLTYP | ((sw == SWMASK ('C')) ? SWMASK ('C') : 0);
|
sw = SIM_BRK_ALLTYP | ((sw == SWMASK ('C')) ? SWMASK ('C') : 0);
|
||||||
for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++) {
|
for (types=bit=0; bit <= ('Z'-'A'); bit++)
|
||||||
if (bp->typ & sw)
|
if (sim_brk_types & (1 << bit))
|
||||||
sim_brk_show (st, bp->addr, sw);
|
++types;
|
||||||
|
if ((!(sw & SWMASK ('C'))) && sim_brk_types && (types > 1)) {
|
||||||
|
fprintf (st, "Supported Breakpoint Types:");
|
||||||
|
for (bit=0; bit <= ('Z'-'A'); bit++)
|
||||||
|
if (sim_brk_types & (1 << bit))
|
||||||
|
fprintf (st, " -%c", 'A' + bit);
|
||||||
|
fprintf (st, "\n");
|
||||||
|
}
|
||||||
|
if (((sw & sim_brk_types) != sim_brk_types) && (types > 1)) {
|
||||||
|
mask = (sw & sim_brk_types);
|
||||||
|
fprintf (st, "Displaying Breakpoint Types:");
|
||||||
|
for (bit=0; bit <= ('Z'-'A'); bit++)
|
||||||
|
if (mask & (1 << bit))
|
||||||
|
fprintf (st, " -%c", 'A' + bit);
|
||||||
|
fprintf (st, "\n");
|
||||||
|
}
|
||||||
|
for (bpt = sim_brk_tab; bpt < (sim_brk_tab + sim_brk_ent); bpt++) {
|
||||||
|
BRKTAB *prev = NULL;
|
||||||
|
BRKTAB *cur = *bpt;
|
||||||
|
BRKTAB *next;
|
||||||
|
/* First reverse the list */
|
||||||
|
while (cur) {
|
||||||
|
next = cur->next;
|
||||||
|
cur->next = prev;
|
||||||
|
prev = cur;
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
/* save reversed list in the head pointer so lookups work */
|
||||||
|
*bpt = prev;
|
||||||
|
/* Walk the reversed list and print it in the order it was defined in */
|
||||||
|
cur = prev;
|
||||||
|
while (cur) {
|
||||||
|
if (cur->typ & sw)
|
||||||
|
sim_brk_show (st, cur->addr, cur->typ | ((sw & SWMASK ('C')) ? SWMASK ('C') : 0));
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
/* reversing the list again */
|
||||||
|
cur = prev;
|
||||||
|
prev = NULL;
|
||||||
|
while (cur) {
|
||||||
|
next = cur->next;
|
||||||
|
cur->next = prev;
|
||||||
|
prev = cur;
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
/* restore original list */
|
||||||
|
*bpt = prev;
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -9172,22 +9289,19 @@ uint32 res = 0;
|
||||||
if (sim_brk_summ & BRK_TYP_DYN_ALL)
|
if (sim_brk_summ & BRK_TYP_DYN_ALL)
|
||||||
btyp |= BRK_TYP_DYN_ALL;
|
btyp |= BRK_TYP_DYN_ALL;
|
||||||
|
|
||||||
if ((bp = sim_brk_fnd (loc)) && (btyp & bp->typ)) { /* in table, and type match? */
|
if ((bp = sim_brk_fnd_ex (loc, btyp, TRUE))) { /* in table, and type match? */
|
||||||
if ((sim_brk_pend[spc] && (loc == sim_brk_ploc[spc])) || /* previous location? */
|
if (bp->time_fired[spc] == sim_gtime()) /* already taken? */
|
||||||
(--bp->cnt > 0)) /* count > 0? */
|
return 0;
|
||||||
|
bp->time_fired[spc] = sim_time; /* remember match time */
|
||||||
|
if (--bp->cnt > 0) /* count > 0? */
|
||||||
return 0;
|
return 0;
|
||||||
bp->cnt = 0; /* reset count */
|
bp->cnt = 0; /* reset count */
|
||||||
sim_brk_setact (bp->act); /* set up actions */
|
sim_brk_setact (bp->act); /* set up actions */
|
||||||
res = btyp & bp->typ; /* set return value */
|
res = btyp & bp->typ; /* set return value */
|
||||||
if (bp->typ & BRK_TYP_TEMP)
|
if (bp->typ & BRK_TYP_TEMP)
|
||||||
sim_brk_clr (loc, btyp | BRK_TYP_TEMP); /* delete one-shot breakpoint */
|
sim_brk_clr (loc, bp->typ); /* delete one-shot breakpoint */
|
||||||
else {
|
|
||||||
sim_brk_ploc[spc] = loc; /* save location */
|
|
||||||
sim_brk_pend[spc] = TRUE; /* don't do twice */
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
sim_brk_pend[spc] = FALSE;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9243,26 +9357,33 @@ else
|
||||||
|
|
||||||
void sim_brk_npc (uint32 cnt)
|
void sim_brk_npc (uint32 cnt)
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 spc;
|
||||||
|
BRKTAB **bpt, *bp;
|
||||||
|
|
||||||
if ((cnt == 0) || (cnt > SIM_BKPT_N_SPC))
|
if ((cnt == 0) || (cnt > SIM_BKPT_N_SPC))
|
||||||
cnt = SIM_BKPT_N_SPC;
|
cnt = SIM_BKPT_N_SPC;
|
||||||
for (i = 0; i < cnt; i++) {
|
for (bpt = sim_brk_tab; bpt < (sim_brk_tab + sim_brk_ent); bpt++) {
|
||||||
sim_brk_pend[i] = FALSE;
|
for (bp = *bpt; bp; bp = bp->next) {
|
||||||
sim_brk_ploc[i] = 0;
|
for (spc = 0; spc < cnt; spc++)
|
||||||
|
bp->time_fired[spc] = -1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear breakpoint space */
|
/* Clear breakpoint space */
|
||||||
|
|
||||||
void sim_brk_clrspc (uint32 spc)
|
void sim_brk_clrspc (uint32 spc, uint32 btyp)
|
||||||
{
|
{
|
||||||
|
BRKTAB **bpt, *bp;
|
||||||
|
|
||||||
if (spc < SIM_BKPT_N_SPC) {
|
if (spc < SIM_BKPT_N_SPC) {
|
||||||
sim_brk_pend[spc] = FALSE;
|
for (bpt = sim_brk_tab; bpt < (sim_brk_tab + sim_brk_ent); bpt++) {
|
||||||
sim_brk_ploc[spc] = 0;
|
for (bp = *bpt; bp; bp = bp->next) {
|
||||||
|
if (bp->typ & btyp)
|
||||||
|
bp->time_fired[spc] = -1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expect package. This code provides a mechanism to stop and control simulator
|
/* Expect package. This code provides a mechanism to stop and control simulator
|
||||||
|
|
5
scp.h
5
scp.h
|
@ -183,9 +183,8 @@ SHTAB *find_shtab (SHTAB *tab, const char *gbuf);
|
||||||
t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr);
|
t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr);
|
||||||
BRKTAB *sim_brk_fnd (t_addr loc);
|
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, uint32 btyp);
|
||||||
void sim_brk_npc (uint32 cnt);
|
void sim_brk_npc (uint32 cnt);
|
||||||
char *sim_brk_clract (void);
|
|
||||||
void sim_brk_setact (const char *action);
|
void sim_brk_setact (const char *action);
|
||||||
t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 after, uint32 delay);
|
t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 after, uint32 delay);
|
||||||
t_stat sim_show_send_input (FILE *st, const SEND *snd);
|
t_stat sim_show_send_input (FILE *st, const SEND *snd);
|
||||||
|
@ -273,8 +272,6 @@ extern volatile int32 stop_cpu;
|
||||||
extern uint32 sim_brk_types; /* breakpoint info */
|
extern uint32 sim_brk_types; /* breakpoint info */
|
||||||
extern uint32 sim_brk_dflt;
|
extern uint32 sim_brk_dflt;
|
||||||
extern uint32 sim_brk_summ;
|
extern uint32 sim_brk_summ;
|
||||||
extern t_bool sim_brk_pend[SIM_BKPT_N_SPC];
|
|
||||||
extern t_addr sim_brk_ploc[SIM_BKPT_N_SPC];
|
|
||||||
extern FILE *stdnul;
|
extern FILE *stdnul;
|
||||||
extern t_bool sim_asynch_enabled;
|
extern t_bool sim_asynch_enabled;
|
||||||
|
|
||||||
|
|
|
@ -714,6 +714,7 @@ struct SCHTAB {
|
||||||
struct BRKTAB {
|
struct BRKTAB {
|
||||||
t_addr addr; /* address */
|
t_addr addr; /* address */
|
||||||
uint32 typ; /* mask of types */
|
uint32 typ; /* mask of types */
|
||||||
|
#define BRK_TYP_USR_TYPES ((1 << ('Z'-'A'+1)) - 1)/* all types A-Z */
|
||||||
#define BRK_TYP_DYN_STEPOVER (SWMASK ('Z'+1))
|
#define BRK_TYP_DYN_STEPOVER (SWMASK ('Z'+1))
|
||||||
#define BRK_TYP_DYN_USR (SWMASK ('Z'+2))
|
#define BRK_TYP_DYN_USR (SWMASK ('Z'+2))
|
||||||
#define BRK_TYP_DYN_ALL (BRK_TYP_DYN_USR|BRK_TYP_DYN_STEPOVER) /* Mask of All Dynamic types */
|
#define BRK_TYP_DYN_ALL (BRK_TYP_DYN_USR|BRK_TYP_DYN_STEPOVER) /* Mask of All Dynamic types */
|
||||||
|
@ -721,6 +722,8 @@ struct BRKTAB {
|
||||||
#define BRK_TYP_MAX (('Z'-'A')+3) /* Maximum breakpoint type */
|
#define BRK_TYP_MAX (('Z'-'A')+3) /* Maximum breakpoint type */
|
||||||
int32 cnt; /* proceed count */
|
int32 cnt; /* proceed count */
|
||||||
char *act; /* action string */
|
char *act; /* action string */
|
||||||
|
double time_fired[SIM_BKPT_N_SPC]; /* instruction count when match occurred */
|
||||||
|
BRKTAB *next; /* list with same address value */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Expect rule */
|
/* Expect rule */
|
||||||
|
|
Loading…
Add table
Reference in a new issue