SCP: Added debugging support for EXPECT and SEND activities. Fixed SEND buffer queuing bug.

This commit is contained in:
Mark Pizzolato 2014-10-17 11:34:06 -07:00
parent 02e90de6a4
commit ddc29fb2c9
4 changed files with 40 additions and 7 deletions

View file

@ -52,7 +52,7 @@ in the source module sim_rev.h.
This is the last release of SimH for which I will be lead editor. After this This is the last release of SimH for which I will be lead editor. After this
release, the source is moving to a public repository: release, the source is moving to a public repository:
https://github.com/markpizz/simh https://github.com/simh/simh
under the general editorship of Dave Hittner and Mark Pizzolato. The status under the general editorship of Dave Hittner and Mark Pizzolato. The status
of the individual simulators is as follows: of the individual simulators is as follows:

30
scp.c
View file

@ -8229,6 +8229,7 @@ return;
match the expect match string match the expect match string
size the number of bytes in the match string size the number of bytes in the match string
match_pattern the expect match string in display format
cnt number of iterations before match is declared cnt number of iterations before match is declared
action command string to be executed when match occurs action command string to be executed when match occurs
@ -8345,6 +8346,8 @@ exp->size += 1;
memset (ep, 0, sizeof(*ep)); memset (ep, 0, sizeof(*ep));
ep->match = match_buf; ep->match = match_buf;
ep->size = match_size; ep->size = match_size;
ep->match_pattern = (char *)malloc (strlen (match) + 1);
strcpy (ep->match_pattern, match);
/* Make sure that the production buffer is large enough to detect a match for all rules */ /* Make sure that the production buffer is large enough to detect a match for all rules */
for (i=0; i<exp->size; i++) { for (i=0; i<exp->size; i++) {
if (exp->rules[i].size > exp->buf_size) { if (exp->rules[i].size > exp->buf_size) {
@ -8405,6 +8408,7 @@ int32 i;
if (!ep) /* not there? ok */ if (!ep) /* not there? ok */
return SCPE_OK; return SCPE_OK;
free (ep->match); /* deallocate match string */ free (ep->match); /* deallocate match string */
free (ep->match_pattern); /* deallocate the display format match string */
free (ep->act); /* deallocate action */ free (ep->act); /* deallocate action */
for (i=ep-exp->rules; i<exp->size; i++) /* shuffle up remaining rules */ for (i=ep-exp->rules; i<exp->size; i++) /* shuffle up remaining rules */
exp->rules[i] = exp->rules[i+1]; exp->rules[i] = exp->rules[i+1];
@ -8429,6 +8433,7 @@ int32 i;
for (i=0; i<exp->size; i++) { for (i=0; i<exp->size; i++) {
free (exp->rules[i].match); /* deallocate match string */ free (exp->rules[i].match); /* deallocate match string */
free (exp->rules[i].match_pattern); /* deallocate display format match string */
free (exp->rules[i].act); /* deallocate action */ free (exp->rules[i].act); /* deallocate action */
} }
free (exp->rules); free (exp->rules);
@ -8508,9 +8513,19 @@ for (i=0; i < exp->size; i++) {
if (exp->buf_ins == exp->buf_size) /* At end of match buffer? */ if (exp->buf_ins == exp->buf_size) /* At end of match buffer? */
exp->buf_ins = 0; /* wrap around to beginning */ exp->buf_ins = 0; /* wrap around to beginning */
if (i != exp->size) { /* Found? */ if (i != exp->size) { /* Found? */
if (ep->cnt > 0) sim_debug (exp->dbit, exp->dptr, "Matched expect pattern: %s\n", ep->match_pattern);
if (ep->cnt > 0) {
ep->cnt -= 1; ep->cnt -= 1;
sim_debug (exp->dbit, exp->dptr, "Waiting for %d more match%s before stopping\n",
ep->cnt, (ep->cnt == 1) ? "" : "es");
}
else { else {
if (ep->act && *ep->act) {
sim_debug (exp->dbit, exp->dptr, "Initiating actions: %s\n", ep->act);
}
else {
sim_debug (exp->dbit, exp->dptr, "No actions specified, stopping...\n");
}
sim_brk_setact (ep->act); /* set up actions */ sim_brk_setact (ep->act); /* set up actions */
if (!(ep->switches & EXP_TYP_PERSIST)) /* One shot expect rule? */ if (!(ep->switches & EXP_TYP_PERSIST)) /* One shot expect rule? */
sim_exp_clr_tab (exp, ep); /* delete it */ sim_exp_clr_tab (exp, ep); /* delete it */
@ -8527,10 +8542,10 @@ return SCPE_OK;
t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 delay) t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 delay)
{ {
if (snd->extoff != 0) { if (snd->extoff != 0) {
if ((snd->insoff-snd->extoff) > 0) if (snd->insoff-snd->extoff > 0)
memmove(snd->buffer, snd->buffer+snd->extoff, snd->insoff-snd->extoff); memmove(snd->buffer, snd->buffer+snd->extoff, snd->insoff-snd->extoff);
snd->insoff -= snd->extoff; snd->insoff -= snd->extoff;
snd->extoff -= 0; snd->extoff -= snd->extoff;
} }
if (snd->insoff+size > snd->bufsize) { if (snd->insoff+size > snd->bufsize) {
snd->bufsize = snd->insoff+size; snd->bufsize = snd->insoff+size;
@ -8564,11 +8579,18 @@ return SCPE_OK;
t_bool sim_send_poll_data (SEND *snd, t_stat *stat) t_bool sim_send_poll_data (SEND *snd, t_stat *stat)
{ {
if (snd && (snd->extoff < snd->insoff)) { /* pending input characters available? */ if (snd && (snd->extoff < snd->insoff)) { /* pending input characters available? */
if (sim_gtime() < snd->next_time) /* too soon? */ if (sim_gtime() < snd->next_time) { /* too soon? */
*stat = SCPE_OK; *stat = SCPE_OK;
sim_debug (snd->dbit, snd->dptr, "Too soon to inject next byte\n");
}
else { else {
char dstr[8] = "";
*stat = snd->buffer[snd->extoff++] | SCPE_KFLAG;/* get one */ *stat = snd->buffer[snd->extoff++] | SCPE_KFLAG;/* get one */
snd->next_time = sim_gtime() + snd->delay; snd->next_time = sim_gtime() + snd->delay;
if (isgraph(*stat & 0xFF) || ((*stat & 0xFF) == ' '))
sprintf (dstr, " '%c'", *stat & 0xFF);
sim_debug (snd->dbit, snd->dptr, "Byte value: 0x%02X%s injected\n", *stat & 0xFF, dstr);
} }
return TRUE; return TRUE;
} }

View file

@ -163,8 +163,6 @@ int32 sim_del_char = '\b'; /* delete character */
#else #else
int32 sim_del_char = 0177; int32 sim_del_char = 0177;
#endif #endif
SEND sim_con_send = {SEND_DEFAULT_DELAY};
EXPECT sim_con_expect;
static t_stat sim_con_poll_svc (UNIT *uptr); /* console connection poll routine */ static t_stat sim_con_poll_svc (UNIT *uptr); /* console connection poll routine */
static t_stat sim_con_reset (DEVICE *dptr); /* console reset routine */ static t_stat sim_con_reset (DEVICE *dptr); /* console reset routine */
@ -175,6 +173,8 @@ UNIT sim_con_unit = { UDATA (&sim_con_poll_svc, 0, 0) }; /* console connectio
#define DBG_RCV TMXR_DBG_RCV /* display Received Data */ #define DBG_RCV TMXR_DBG_RCV /* display Received Data */
#define DBG_RET TMXR_DBG_RET /* display Returned Received Data */ #define DBG_RET TMXR_DBG_RET /* display Returned Received Data */
#define DBG_ASY TMXR_DBG_ASY /* asynchronous thread activity */ #define DBG_ASY TMXR_DBG_ASY /* asynchronous thread activity */
#define DBG_EXP 0x00000001 /* Expect match activity */
#define DBG_SND 0x00000002 /* Send (Inject) data activity */
static DEBTAB sim_con_debug[] = { static DEBTAB sim_con_debug[] = {
{"TRC", DBG_TRC}, {"TRC", DBG_TRC},
@ -182,6 +182,8 @@ static DEBTAB sim_con_debug[] = {
{"RCV", DBG_RCV}, {"RCV", DBG_RCV},
{"RET", DBG_RET}, {"RET", DBG_RET},
{"ASY", DBG_ASY}, {"ASY", DBG_ASY},
{"EXP", DBG_EXP},
{"SND", DBG_SND},
{0} {0}
}; };
@ -197,6 +199,10 @@ DEVICE sim_con_telnet = {
TMLN sim_con_ldsc = { 0 }; /* console line descr */ TMLN sim_con_ldsc = { 0 }; /* console line descr */
TMXR sim_con_tmxr = { 1, 0, 0, &sim_con_ldsc, NULL, &sim_con_telnet };/* console line mux */ TMXR sim_con_tmxr = { 1, 0, 0, &sim_con_ldsc, NULL, &sim_con_telnet };/* console line mux */
SEND sim_con_send = {SEND_DEFAULT_DELAY, &sim_con_telnet, DBG_SND};
EXPECT sim_con_expect = {&sim_con_telnet, DBG_EXP};
/* Unit service for console connection polling */ /* Unit service for console connection polling */
static t_stat sim_con_poll_svc (UNIT *uptr) static t_stat sim_con_poll_svc (UNIT *uptr)

View file

@ -638,6 +638,7 @@ struct sim_brktab {
struct sim_exptab { struct sim_exptab {
uint8 *match; /* match string */ uint8 *match; /* match string */
uint32 size; /* match string size */ uint32 size; /* match string size */
char *match_pattern; /* match pattern for format */
int32 cnt; /* proceed count */ int32 cnt; /* proceed count */
int32 switches; /* flags */ int32 switches; /* flags */
#define EXP_TYP_PERSIST (SWMASK ('P')) /* rule persists after match, default is once a rule matches, it is removed */ #define EXP_TYP_PERSIST (SWMASK ('P')) /* rule persists after match, default is once a rule matches, it is removed */
@ -648,6 +649,8 @@ struct sim_exptab {
/* Expect Context */ /* Expect Context */
struct sim_expect { struct sim_expect {
struct sim_device *dptr; /* Device (for Debug) */
uint32 dbit; /* Debugging Bit */
struct sim_exptab *rules; /* match rules */ struct sim_exptab *rules; /* match rules */
int32 size; /* count of match rules */ int32 size; /* count of match rules */
uint8 *buf; /* buffer of output data which has produced */ uint8 *buf; /* buffer of output data which has produced */
@ -659,6 +662,8 @@ struct sim_expect {
struct sim_send { struct sim_send {
uint32 delay; /* instruction delay before/between sent data */ uint32 delay; /* instruction delay before/between sent data */
struct sim_device *dptr; /* Device (for Debug) */
uint32 dbit; /* Debugging Bit */
#define SEND_DEFAULT_DELAY 1000 /* default delay instruction count */ #define SEND_DEFAULT_DELAY 1000 /* default delay instruction count */
double next_time; /* execution time when next data can be sent */ double next_time; /* execution time when next data can be sent */
uint8 *buffer; /* buffer */ uint8 *buffer; /* buffer */