SCP: Add SHOW -C BREAK to display the currently defined breakpoints as commands which can be used to redefine them later.
Note: This excludes the possibility of there being a -C breakpoint type. Since there are potentially 26 different breakpoint types, this exclusion is not likely to have a significant impact.
This commit is contained in:
parent
cde0be5573
commit
afcbea251d
1 changed files with 54 additions and 26 deletions
80
scp.c
80
scp.c
|
@ -261,7 +261,7 @@
|
||||||
#define MAX_DO_NEST_LVL 20 /* DO cmd nesting level */
|
#define MAX_DO_NEST_LVL 20 /* 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 0xFFFFFFFB
|
||||||
#define UPDATE_SIM_TIME \
|
#define UPDATE_SIM_TIME \
|
||||||
if (1) { \
|
if (1) { \
|
||||||
int32 _x; \
|
int32 _x; \
|
||||||
|
@ -799,25 +799,30 @@ static const char simh_help[] =
|
||||||
" decremented. If the count is less than or equal to 0, the breakpoint\n"
|
" decremented. If the count is less than or equal to 0, the breakpoint\n"
|
||||||
" occurs; otherwise, it is deferred. When the breakpoint occurs, the\n"
|
" occurs; otherwise, it is deferred. When the breakpoint occurs, the\n"
|
||||||
" optional actions are automatically executed.\n\n"
|
" optional actions are automatically executed.\n\n"
|
||||||
" A breakpoint is set by the BREAK command:\n"
|
" A breakpoint is set by the BREAK or the SET BREAK commands:\n\n"
|
||||||
"++BREAK {-types} {<addr range>{[count]},{addr range...}}{;action;action...}\n\n"
|
"++BREAK {-types} {<addr range>{[count]},{addr range...}}{;action;action...}\n"
|
||||||
|
"++SET BREAK {-types} {<addr range>{[count]},{addr range...}}{;action;action...}\n\n"
|
||||||
" If no type is specified, the simulator-specific default breakpoint type\n"
|
" If no type is specified, the simulator-specific default breakpoint type\n"
|
||||||
" (usually E for execution) is used. If no address range is specified, the\n"
|
" (usually E for execution) is used. If no address range is specified, the\n"
|
||||||
" current PC is used. As with EXAMINE and DEPOSIT, an address range may be a\n"
|
" current PC is used. As with EXAMINE and DEPOSIT, an address range may be a\n"
|
||||||
" single address, a range of addresses low-high, or a relative range of\n"
|
" single address, a range of addresses low-high, or a relative range of\n"
|
||||||
" address/length.\n"
|
" address/length.\n"
|
||||||
/***************** 80 character line width template *************************/
|
/***************** 80 character line width template *************************/
|
||||||
"5Examples:\n"
|
"5Displaying Breakpoints\n"
|
||||||
|
" Currently set breakpoints can be displayed with the SHOW BREAK command:\n\n"
|
||||||
|
"++SHOW {-C} {-types} BREAK {ALL|<addr range>{,<addr range>...}}\n\n"
|
||||||
|
" Locations with breakpoints of the specified type are displayed.\n\n"
|
||||||
|
" The -C switch displays the selected breakpoint(s) formatted as commands\n"
|
||||||
|
" which may be subsequently used to establish the same breakpoint(s).\n\n"
|
||||||
|
"5Removing Breakpoints\n"
|
||||||
|
" Breakpoints can be cleared by the NOBREAK or the SET NOBREAK commands.\n"
|
||||||
|
"5Examples\n"
|
||||||
"++BREAK set E break at current PC\n"
|
"++BREAK set E break at current PC\n"
|
||||||
"++BREAK -e 200 set E break at 200\n"
|
"++BREAK -e 200 set E break at 200\n"
|
||||||
"++BREAK 2000/2[2] set E breaks at 2000,2001 with count = 2\n"
|
"++BREAK 2000/2[2] set E breaks at 2000,2001 with count = 2\n"
|
||||||
"++BREAK 100;EX AC;D MQ 0 set E break at 100 with actions EX AC and\n"
|
"++BREAK 100;EX AC;D MQ 0 set E break at 100 with actions EX AC and\n"
|
||||||
"++ D MQ 0\n"
|
"+++++++++D MQ 0\n"
|
||||||
"++BREAK 100; delete action on break at 100\n\n"
|
"++BREAK 100; delete action on break at 100\n\n"
|
||||||
" Currently set breakpoints can be displayed with the SHOW BREAK command:\n\n"
|
|
||||||
"++SHOW {-types} BREAK {ALL|<addr range>{,<addr range>...}}\n\n"
|
|
||||||
" Locations with breakpoints of the specified type are displayed.\n\n"
|
|
||||||
" Finally, breakpoints can be cleared by the NOBREAK command.\n"
|
|
||||||
/***************** 80 character line width template *************************/
|
/***************** 80 character line width template *************************/
|
||||||
"2Connecting and Disconnecting Devices\n"
|
"2Connecting and Disconnecting Devices\n"
|
||||||
" Except for main memory and network devices, units are simulated as\n"
|
" Except for main memory and network devices, units are simulated as\n"
|
||||||
|
@ -974,10 +979,8 @@ static const char simh_help[] =
|
||||||
" switches to be relative to the start time of debugging. If neither\n"
|
" switches to be relative to the start time of debugging. If neither\n"
|
||||||
" -T or -A is explicitly specified, -T is implied.\n"
|
" -T or -A is explicitly specified, -T is implied.\n"
|
||||||
"5-P\n"
|
"5-P\n"
|
||||||
" The -P switch adds the output of the PC register variable to each debug\n"
|
" The -P switch adds the output of the PC (Program Counter) to each debug\n"
|
||||||
" message. This may not be useful on all simulators if they either don't\n"
|
" message.\n"
|
||||||
" have a register called PC, or if the PC register variable is actually\n"
|
|
||||||
" constructed from several different internal variables.\n"
|
|
||||||
#define HLP_SET_BREAK "*Commands SET Breakpoints"
|
#define HLP_SET_BREAK "*Commands SET Breakpoints"
|
||||||
"3Breakpoints\n"
|
"3Breakpoints\n"
|
||||||
"+set break <list> set breakpoints\n"
|
"+set break <list> set breakpoints\n"
|
||||||
|
@ -1047,7 +1050,7 @@ static const char simh_help[] =
|
||||||
/***************** 80 character line width template *************************/
|
/***************** 80 character line width template *************************/
|
||||||
#define HLP_SHOW "*Commands SHOW"
|
#define HLP_SHOW "*Commands SHOW"
|
||||||
"2SHOW\n"
|
"2SHOW\n"
|
||||||
"+sh{ow} br{eak} <list> show breakpoints\n"
|
"+sh{ow} {-c} br{eak} <list> show breakpoints\n"
|
||||||
"+sh{ow} con{figuration} show configuration\n"
|
"+sh{ow} con{figuration} show configuration\n"
|
||||||
"+sh{ow} cons{ole} {arg} show console options\n"
|
"+sh{ow} cons{ole} {arg} show console options\n"
|
||||||
"+sh{ow} dev{ices} show devices\n"
|
"+sh{ow} dev{ices} show devices\n"
|
||||||
|
@ -3342,6 +3345,7 @@ if ((dptr = find_dev (gbuf))) { /* device match? */
|
||||||
uptr = dptr->units; /* first unit */
|
uptr = dptr->units; /* first unit */
|
||||||
shtb = show_dev_tab; /* global table */
|
shtb = show_dev_tab; /* global table */
|
||||||
lvl = MTAB_VDV; /* device match */
|
lvl = MTAB_VDV; /* device match */
|
||||||
|
GET_SWITCHES (cptr); /* get more switches */
|
||||||
}
|
}
|
||||||
else if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
|
else if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
|
||||||
if (uptr == NULL) /* invalid unit */
|
if (uptr == NULL) /* invalid unit */
|
||||||
|
@ -3350,9 +3354,12 @@ else if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
|
||||||
return SCPE_UDIS;
|
return SCPE_UDIS;
|
||||||
shtb = show_unit_tab; /* global table */
|
shtb = show_unit_tab; /* global table */
|
||||||
lvl = MTAB_VUN; /* unit match */
|
lvl = MTAB_VUN; /* unit match */
|
||||||
|
GET_SWITCHES (cptr); /* get more switches */
|
||||||
}
|
}
|
||||||
else if ((shptr = find_shtab (show_glob_tab, gbuf))) /* global? */
|
else if ((shptr = find_shtab (show_glob_tab, gbuf))) { /* global? */
|
||||||
|
GET_SWITCHES (cptr); /* get more switches */
|
||||||
return shptr->action (ofile, NULL, NULL, shptr->arg, cptr);
|
return shptr->action (ofile, NULL, NULL, shptr->arg, cptr);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (sim_dflt_dev->modifiers)
|
if (sim_dflt_dev->modifiers)
|
||||||
for (mptr = sim_dflt_dev->modifiers; mptr->mask != 0; mptr++) {
|
for (mptr = sim_dflt_dev->modifiers; mptr->mask != 0; mptr++) {
|
||||||
|
@ -3378,6 +3385,7 @@ if (*cptr == 0) { /* now eol? */
|
||||||
}
|
}
|
||||||
if (dptr->modifiers == NULL) /* any modifiers? */
|
if (dptr->modifiers == NULL) /* any modifiers? */
|
||||||
return SCPE_NOPARAM;
|
return SCPE_NOPARAM;
|
||||||
|
GET_SWITCHES (cptr); /* get more switches */
|
||||||
|
|
||||||
while (*cptr != 0) { /* do all mods */
|
while (*cptr != 0) { /* do all mods */
|
||||||
cptr = get_glyph (cptr, gbuf, ','); /* get modifier */
|
cptr = get_glyph (cptr, gbuf, ','); /* get modifier */
|
||||||
|
@ -7490,25 +7498,39 @@ BRKTAB *bp = sim_brk_fnd (loc);
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
int32 i, any;
|
int32 i, any;
|
||||||
|
|
||||||
if (sw == 0)
|
if ((sw == 0) || (sw == SWMASK ('C')))
|
||||||
sw = SIM_BRK_ALLTYP;
|
sw = SIM_BRK_ALLTYP | ((sw == SWMASK ('C')) ? SWMASK ('C') : 0);
|
||||||
if (!bp || (!(bp->typ & sw)))
|
if (!bp || (!(bp->typ & sw)))
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
dptr = sim_dflt_dev;
|
dptr = sim_dflt_dev;
|
||||||
if (dptr == NULL)
|
if (dptr == NULL)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
if (sim_vm_fprint_addr)
|
if (sw & SWMASK ('C'))
|
||||||
sim_vm_fprint_addr (st, dptr, loc);
|
fprintf (st, "SET BREAK ");
|
||||||
else fprint_val (st, loc, dptr->aradix, dptr->awidth, PV_LEFT);
|
else {
|
||||||
fprintf (st, ":\t");
|
if (sim_vm_fprint_addr)
|
||||||
|
sim_vm_fprint_addr (st, dptr, loc);
|
||||||
|
else fprint_val (st, loc, dptr->aradix, dptr->awidth, PV_LEFT);
|
||||||
|
fprintf (st, ":\t");
|
||||||
|
}
|
||||||
for (i = any = 0; i < 26; i++) {
|
for (i = any = 0; i < 26; i++) {
|
||||||
if ((bp->typ >> i) & 1) {
|
if ((bp->typ >> i) & 1) {
|
||||||
if (any)
|
if ((sw & SWMASK ('C')) == 0) {
|
||||||
fprintf (st, ", ");
|
if (any)
|
||||||
fputc (i + 'A', st);
|
fprintf (st, ", ");
|
||||||
|
fputc (i + 'A', st);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (st, "-%c", i + 'A');
|
||||||
any = 1;
|
any = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sw & SWMASK ('C')) {
|
||||||
|
fprintf (st, " ");
|
||||||
|
if (sim_vm_fprint_addr)
|
||||||
|
sim_vm_fprint_addr (st, dptr, loc);
|
||||||
|
else fprint_val (st, loc, dptr->aradix, dptr->awidth, PV_LEFT);
|
||||||
|
}
|
||||||
if (bp->cnt > 0)
|
if (bp->cnt > 0)
|
||||||
fprintf (st, " [%d]", bp->cnt);
|
fprintf (st, " [%d]", bp->cnt);
|
||||||
if (bp->act != NULL)
|
if (bp->act != NULL)
|
||||||
|
@ -7523,8 +7545,8 @@ t_stat sim_brk_showall (FILE *st, int32 sw)
|
||||||
{
|
{
|
||||||
BRKTAB *bp;
|
BRKTAB *bp;
|
||||||
|
|
||||||
if (sw == 0)
|
if ((sw == 0) || (sw == SWMASK ('C')))
|
||||||
sw = SIM_BRK_ALLTYP;
|
sw = SIM_BRK_ALLTYP | ((sw == SWMASK ('C')) ? SWMASK ('C') : 0);
|
||||||
for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++) {
|
for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++) {
|
||||||
if (bp->typ & sw)
|
if (bp->typ & sw)
|
||||||
sim_brk_show (st, bp->addr, sw);
|
sim_brk_show (st, bp->addr, sw);
|
||||||
|
@ -7707,6 +7729,12 @@ if (sim_deb_switches & SWMASK ('A')) {
|
||||||
if (sim_deb_switches & SWMASK ('P')) {
|
if (sim_deb_switches & SWMASK ('P')) {
|
||||||
t_value val;
|
t_value val;
|
||||||
|
|
||||||
|
/* Some simulators expose the PC as a register, some don't expose it or expose a register
|
||||||
|
which is not a variable which is updated during instruction execution (i.e. only upon
|
||||||
|
exit of sim_instr()). For the -P debug option to be effective, such a simulator should
|
||||||
|
provide a routine which returns the value of the current PC and set the sim_vm_pc_value
|
||||||
|
routine pointer to that routine.
|
||||||
|
*/
|
||||||
if (sim_vm_pc_value)
|
if (sim_vm_pc_value)
|
||||||
val = (*sim_vm_pc_value)();
|
val = (*sim_vm_pc_value)();
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Reference in a new issue