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:
Mark Pizzolato 2014-02-07 06:32:21 -08:00
parent cde0be5573
commit afcbea251d

80
scp.c
View file

@ -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