1
0
mirror of https://github.com/simh/simh.git synced 2026-02-16 20:52:19 +00:00

FRONTPANEL: sim_frontpanel API version 4 release

Add simulator side register bit sampling with averaged sample values
delivered across the API at specified rates.
This commit is contained in:
Mark Pizzolato
2017-02-04 10:48:13 -08:00
parent f171055809
commit 665ebf0fd1
5 changed files with 627 additions and 82 deletions

View File

@@ -428,14 +428,18 @@ return SCPE_OK;
t_stat sim_rem_con_poll_svc (UNIT *uptr); /* remote console connection poll routine */
t_stat sim_rem_con_data_svc (UNIT *uptr); /* remote console connection data routine */
t_stat sim_rem_con_repeat_svc (UNIT *uptr); /* remote auto repeat command console timing routine */
t_stat sim_rem_con_smp_collect_svc (UNIT *uptr); /* remote remote register data sampling routine */
t_stat sim_rem_con_reset (DEVICE *dptr); /* remote console reset routine */
#define rem_con_poll_unit (&sim_remote_console.units[0])
#define rem_con_data_unit (&sim_remote_console.units[1])
#define REM_CON_BASE_UNITS 2
#define rem_con_repeat_units (&sim_remote_console.units[REM_CON_BASE_UNITS])
#define rem_con_smp_smpl_units (&sim_remote_console.units[REM_CON_BASE_UNITS+sim_rem_con_tmxr.lines])
#define DBG_MOD 0x00000004 /* Remote Console Mode activities */
#define DBG_REP 0x00000008 /* Remote Console Repeat activities */
#define DBG_CMD 0x00000010 /* Remote Console Command activities */
#define DBG_SAM 0x00000010 /* Remote Console Sample activities */
#define DBG_CMD 0x00000020 /* Remote Console Command activities */
DEBTAB sim_rem_con_debug[] = {
{"TRC", DBG_TRC, "routine calls"},
@@ -445,6 +449,7 @@ DEBTAB sim_rem_con_debug[] = {
{"CMD", DBG_CMD, "Remote Console Command activity"},
{"MODE", DBG_MOD, "Remote Console Mode activity"},
{"REPEAT", DBG_REP, "Remote Console Repeat activity"},
{"SAMPLE", DBG_SAM, "Remote Console Sample activity"},
{0}
};
@@ -464,6 +469,22 @@ DEVICE sim_remote_console = {
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_rem_con_debug,
NULL, NULL, NULL, NULL, NULL, sim_rem_con_description};
typedef struct BITSAMPLE BITSAMPLE;
struct BITSAMPLE {
int tot; /* total of all values */
int ptr; /* pointer to next value cell */
int depth; /* number of values */
int *vals; /* values */
};
typedef struct BITSAMPLE_REG BITSAMPLE_REG;
struct BITSAMPLE_REG {
REG *reg; /* Register to be sampled */
t_bool indirect; /* Register value points at memory */
DEVICE *dptr; /* Device register is part of */
UNIT *uptr; /* Unit Register is related to */
uint32 width; /* number of bits to sample */
BITSAMPLE *bits;
};
typedef struct REMOTE REMOTE;
struct REMOTE {
int32 buf_size;
@@ -474,16 +495,18 @@ struct REMOTE {
char *act;
t_bool single_mode;
uint32 read_timeout;
int line;
TMLN *lp;
UNIT *uptr;
uint32 repeat_interval;
t_bool repeat_pending;
char *repeat_action;
int line; /* remote console line number */
TMLN *lp; /* mux line/socket for remote session */
UNIT *uptr; /* remote console unit */
uint32 repeat_interval; /* usecs between repeat execution */
t_bool repeat_pending; /* repeat delivery pending */
char *repeat_action; /* command(s) to repeatedly execute */
int smp_sample_interval; /* cycles between samples */
uint32 smp_reg_count; /* sample register count */
BITSAMPLE_REG *smp_regs; /* registers being sampled */
};
REMOTE *sim_rem_consoles = NULL;
static TMXR sim_rem_con_tmxr = { 0, 0, 0, NULL, NULL, &sim_remote_console };/* remote console line mux */
static uint32 sim_rem_read_timeout = 30; /* seconds before automatic continue */
static uint32 *sim_rem_read_timeouts = NULL;/* per line read timeout (default from sim_rem_read_timeout) */
@@ -498,6 +521,26 @@ static t_bool sim_rem_master_was_enabled = FALSE; /* Master was Enabled */
static t_bool sim_rem_master_was_connected = FALSE; /* Master Mode has been connected */
static t_offset sim_rem_cmd_log_start = 0; /* Log File saved position */
static t_stat sim_rem_sample_output (FILE *st, int32 line)
{
REMOTE *rem = &sim_rem_consoles[line];
uint32 reg;
if (rem->smp_reg_count == 0) {
fprintf (st, "Samples are not being collected\n");
return SCPE_OK;
}
for (reg = 0; reg < rem->smp_reg_count; reg++) {
uint32 bit;
fprintf (st, "}%s %s%s %d:", rem->smp_regs[reg].dptr->name, rem->smp_regs[reg].reg->name, rem->smp_regs[reg].indirect ? " -I" : "", rem->smp_regs[reg].bits[0].depth);
for (bit = 0; bit < rem->smp_regs[reg].width; bit++)
fprintf (st, "%s%d", (bit != 0) ? "," : "", rem->smp_regs[reg].bits[bit].tot);
fprintf (st, "\n");
}
return SCPE_OK;
}
/* SET REMOTE CONSOLE command */
@@ -567,6 +610,24 @@ for (i=connections=0; i<sim_rem_con_tmxr.lines; i++) {
fprintf (st, "The Command: %s\n", rem->repeat_action);
fprintf (st, " is repeated every %s\n", sim_fmt_secs (rem->repeat_interval / 1000000.0));
}
if (rem->smp_reg_count) {
uint32 reg;
DEVICE *dptr = NULL;
fprintf (st, "Register Bit Sampling is occurring every %d cycles\n", rem->smp_sample_interval);
fprintf (st, " Registers being sampled are: ");
for (reg = 0; reg < rem->smp_reg_count; reg++) {
if (rem->smp_regs[reg].indirect)
fprintf (st, " indirect ");
if (dptr != rem->smp_regs[reg].dptr)
fprintf (st, "%s ", rem->smp_regs[reg].dptr->name);
fprintf (st, "%s%s", rem->smp_regs[reg].reg->name, ((reg + 1) < rem->smp_reg_count) ? ", " : "");
dptr = rem->smp_regs[reg].dptr;
}
fprintf (st, "\n");
if (sim_switches & SWMASK ('D'))
sim_rem_sample_output (st, rem->line);
}
}
return SCPE_OK;
}
@@ -620,16 +681,26 @@ static t_stat x_repeat_cmd (int32 flag, CONST char *cptr)
return 2+SCPE_IERR; /* This routine should never be called */
}
static t_stat x_step_cmd (int32 flag, CONST char *cptr)
static t_stat x_collect_cmd (int32 flag, CONST char *cptr)
{
return 3+SCPE_IERR; /* This routine should never be called */
}
static t_stat x_run_cmd (int32 flag, CONST char *cptr)
static t_stat x_sampleout_cmd (int32 flag, CONST char *cptr)
{
return 4+SCPE_IERR; /* This routine should never be called */
}
static t_stat x_step_cmd (int32 flag, CONST char *cptr)
{
return 5+SCPE_IERR; /* This routine should never be called */
}
static t_stat x_run_cmd (int32 flag, CONST char *cptr)
{
return 6+SCPE_IERR; /* This routine should never be called */
}
static t_stat x_help_cmd (int32 flag, CONST char *cptr);
static CTAB allowed_remote_cmds[] = {
@@ -642,6 +713,8 @@ static CTAB allowed_remote_cmds[] = {
{ "DEASSIGN", &deassign_cmd, 0 },
{ "CONTINUE", &x_continue_cmd, 0 },
{ "REPEAT", &x_repeat_cmd, 0 },
{ "COLLECT", &x_collect_cmd, 0 },
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
{ "STEP", &x_step_cmd, 0 },
{ "PWD", &pwd_cmd, 0 },
{ "SAVE", &save_cmd, 0 },
@@ -664,6 +737,8 @@ static CTAB allowed_master_remote_cmds[] = {
{ "DEASSIGN", &deassign_cmd, 0 },
{ "CONTINUE", &x_continue_cmd, 0 },
{ "REPEAT", &x_repeat_cmd, 0 },
{ "COLLECT", &x_collect_cmd, 0 },
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
{ "STEP", &x_step_cmd, 0 },
{ "PWD", &pwd_cmd, 0 },
{ "SAVE", &save_cmd, 0 },
@@ -693,6 +768,8 @@ static CTAB allowed_single_remote_cmds[] = {
{ "EXAMINE", &exdep_cmd, EX_E },
{ "EVALUATE", &eval_cmd, 0 },
{ "REPEAT", &x_repeat_cmd, 0 },
{ "COLLECT", &x_collect_cmd, 0 },
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
{ "PWD", &pwd_cmd, 0 },
{ "DIR", &dir_cmd, 0 },
{ "LS", &dir_cmd, 0 },
@@ -704,6 +781,8 @@ static CTAB allowed_single_remote_cmds[] = {
static CTAB remote_only_cmds[] = {
{ "REPEAT", &x_repeat_cmd, 0 },
{ "COLLECT", &x_collect_cmd, 0 },
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
{ NULL, NULL }
};
@@ -864,7 +943,7 @@ return buf;
Parse and setup Remote Console REPEAT command:
REPEAT EVERY nnn USECS Command {; command...}
*/
static t_stat _rem_repeat_cmd_setup (int32 line, CONST char **iptr)
static t_stat sim_rem_repeat_cmd_setup (int32 line, CONST char **iptr)
{
char gbuf[CBUFSIZE];
int32 val;
@@ -940,6 +1019,239 @@ if (stat == SCPE_OK) {
return stat;
}
/*
Parse and setup Remote Console REPEAT command:
COLLECT nnn SAMPLES EVERY nnn CYCLES reg{,reg...}
*/
static t_stat sim_rem_collect_cmd_setup (int32 line, CONST char **iptr)
{
char gbuf[CBUFSIZE];
int32 samples, cycles;
t_bool all_stop = FALSE;
t_stat stat = SCPE_OK;
CONST char *cptr = *iptr;
REMOTE *rem = &sim_rem_consoles[line];
sim_debug (DBG_SAM, &sim_remote_console, "Collect Setup: %s\n", cptr);
if (*cptr == 0) /* required argument? */
return SCPE_2FARG;
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
samples = (int32) get_uint (gbuf, 10, INT_MAX, &stat);
if ((stat != SCPE_OK) || (samples <= 0)) { /* error? */
if (MATCH_CMD (gbuf, "STOP") == 0) {
stat = SCPE_OK;
if (*cptr) { /* more command arguments? */
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
if ((MATCH_CMD (gbuf, "ALL") != 0) || /* */
(*cptr != 0) || /* */
(line != 0)) /* master line? */
stat = SCPE_ARG;
else
all_stop = TRUE;
}
if (stat == SCPE_OK) {
for (line = all_stop ? 0 : rem->line; line < (all_stop ? sim_rem_con_tmxr.lines : (rem->line + 1)); line++) {
uint32 i, j;
rem = &sim_rem_consoles[line];
for (i = 0; i< rem->smp_reg_count; i++) {
for (j = 0; j < rem->smp_regs[i].width; j++)
free (rem->smp_regs[i].bits[j].vals);
free (rem->smp_regs[i].bits);
}
free (rem->smp_regs);
rem->smp_regs = NULL;
rem->smp_reg_count = 0;
sim_cancel (&rem_con_smp_smpl_units[rem->line]);
rem->smp_sample_interval = 0;
}
}
}
else
stat = sim_messagef (SCPE_ARG, "Expected value or STOP found: %s\n", gbuf);
}
else {
const char *tptr;
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
if (MATCH_CMD (gbuf, "SAMPLES") != 0) {
*iptr = cptr;
return sim_messagef (SCPE_ARG, "Expected SAMPLES found: %s\n", gbuf);
}
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
if (MATCH_CMD (gbuf, "EVERY") != 0) {
*iptr = cptr;
return sim_messagef (SCPE_ARG, "Expected EVERY found: %s\n", gbuf);
}
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
cycles = (int32) get_uint (gbuf, 10, INT_MAX, &stat);
if ((stat != SCPE_OK) || (cycles <= 0)) { /* error? */
*iptr = cptr;
return sim_messagef (SCPE_ARG, "Expected value found: %s\n", gbuf);
}
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
if ((MATCH_CMD (gbuf, "CYCLES") != 0) || (*cptr == 0)) {
*iptr = cptr;
return sim_messagef (SCPE_ARG, "Expected CYCLES found: %s\n", gbuf);
}
tptr = strcpy (gbuf, "STOP"); /* Start from a clean slate */
sim_rem_collect_cmd_setup (rem->line, &tptr);
rem->smp_sample_interval = cycles;
rem->smp_reg_count = 0;
while (cptr && *cptr) {
const char *comma = strchr (cptr, ',');
char tbuf[2*CBUFSIZE];
uint32 bit, width;
REG *reg;
int32 saved_switches = sim_switches;
t_bool indirect = FALSE;
BITSAMPLE_REG *smp_regs;
if (comma) {
strncpy (tbuf, cptr, comma - cptr);
tbuf[comma - cptr] = '\0';
cptr = comma + 1;
}
else {
strcpy (tbuf, cptr);
cptr += strlen (cptr);
}
tptr = tbuf;
if (strchr (tbuf, ' ')) {
sim_switches = 0;
tptr = get_sim_opt (CMD_OPT_SW|CMD_OPT_DFT, tbuf, &stat); /* get switches and device */
indirect = ((sim_switches & SWMASK('I')) != 0);
sim_switches = saved_switches;
}
if (stat != SCPE_OK)
break;
tptr = get_glyph (tptr, gbuf, 0); /* get next glyph */
reg = find_reg (gbuf, &tptr, sim_dfdev);
if (reg == NULL) {
stat = sim_messagef (SCPE_NXREG, "Nonexistent Register: %s\n", gbuf);
break;
}
smp_regs = (BITSAMPLE_REG *)realloc (rem->smp_regs, (rem->smp_reg_count + 1) * sizeof(*smp_regs));
if (smp_regs == NULL) {
stat = SCPE_MEM;
break;
}
rem->smp_regs = smp_regs;
smp_regs[rem->smp_reg_count].reg = reg;
smp_regs[rem->smp_reg_count].dptr = sim_dfdev;
smp_regs[rem->smp_reg_count].uptr = sim_dfunit;
smp_regs[rem->smp_reg_count].indirect = indirect;
width = indirect ? sim_dfdev->dwidth : reg->width;
smp_regs[rem->smp_reg_count].width = width;
smp_regs[rem->smp_reg_count].bits = (BITSAMPLE *)calloc (width, sizeof (*smp_regs[rem->smp_reg_count - 1].bits));
if (smp_regs[rem->smp_reg_count].bits == NULL) {
stat = SCPE_MEM;
break;
}
rem->smp_reg_count += 1;
for (bit = 0; bit < width; bit++) {
smp_regs[rem->smp_reg_count - 1].bits[bit].depth = samples;
smp_regs[rem->smp_reg_count - 1].bits[bit].vals = (int *)calloc (samples, sizeof (int));
if (smp_regs[rem->smp_reg_count - 1].bits[bit].vals == NULL) {
stat = SCPE_MEM;
break;
}
}
if (stat != SCPE_OK)
break;
}
if (stat != SCPE_OK) { /* Error? */
*iptr = cptr;
cptr = strcpy (gbuf, "STOP");
sim_rem_collect_cmd_setup (line, &cptr);/* Cleanup mess */
return stat;
}
sim_activate (&rem_con_smp_smpl_units[rem->line], rem->smp_sample_interval);
}
*iptr = cptr;
return stat;
}
t_stat sim_rem_con_repeat_svc (UNIT *uptr)
{
int line = uptr - rem_con_repeat_units;
REMOTE *rem = &sim_rem_consoles[line];
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_repeat_svc(line=%d) - interval=%d\n", line, rem->repeat_interval);
if (rem->repeat_interval) {
rem->repeat_pending = TRUE;
sim_activate_after (uptr, rem->repeat_interval); /* reschedule */
sim_activate_abs (rem_con_data_unit, -1); /* wake up to process */
}
return SCPE_OK;
}
static void sim_rem_record_reg_bit (BITSAMPLE *bit, int val)
{
bit->tot -= bit->vals[bit->ptr]; /* remove retired value */
bit->tot += val; /* accumulate new value */
bit->vals[bit->ptr] = val; /* save new value */
++bit->ptr; /* increment next pointer */
if (bit->ptr >= bit->depth) /* if too big */
bit->ptr = 0; /* wrap around */
}
static void sim_rem_set_reg_bit (BITSAMPLE *bit, int val)
{
int i;
bit->tot = bit->depth * val; /* compute total */
for (i = 0; i < bit->depth; i++) /* set all value bits */
bit->vals[i] = val;
}
static void sim_rem_collect_reg_bits (BITSAMPLE_REG *reg)
{
uint32 i;
t_value val = get_rval (reg->reg, 0);
if (reg->indirect)
val = get_aval ((t_addr)val, reg->dptr, reg->uptr);
val = val >> reg->reg->offset;
for (i = 0; i < reg->width; i++) {
if (sim_is_running)
sim_rem_record_reg_bit (&reg->bits[i], val&1);
else
sim_rem_set_reg_bit (&reg->bits[i], val&1);
val = val >> 1;
}
}
static void sim_rem_collect_registers (REMOTE *rem)
{
uint32 i;
for (i = 0; i < rem->smp_reg_count; i++)
sim_rem_collect_reg_bits (&rem->smp_regs[i]);
}
static void sim_rem_collect_all_registers (void)
{
int32 line;
for (line = 0; line < sim_rem_con_tmxr.lines; line++)
sim_rem_collect_registers (&sim_rem_consoles[line]);
}
t_stat sim_rem_con_smp_collect_svc (UNIT *uptr)
{
int line = uptr - rem_con_smp_smpl_units;
REMOTE *rem = &sim_rem_consoles[line];
sim_debug (DBG_SAM, &sim_remote_console, "sim_rem_con_smp_collect_svc(line=%d) - interval=%d\n", line, rem->smp_sample_interval);
if (rem->smp_sample_interval && (rem->smp_reg_count != 0)) {
sim_rem_collect_registers (rem);
sim_activate (uptr, rem->smp_sample_interval); /* reschedule */
}
return SCPE_OK;
}
/* Unit service for remote console data polling */
t_stat sim_rem_con_data_svc (UNIT *uptr)
@@ -969,7 +1281,11 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
if (!lp->conn) {
if (rem->repeat_interval) { /* was repeated enabled? */
cptr = strcpy (gbuf, "STOP");
_rem_repeat_cmd_setup (i, &cptr); /* make sure it is now disabled */
sim_rem_repeat_cmd_setup (i, &cptr); /* make sure it is now disabled */
}
if (rem->smp_reg_count) { /* were bit samples being collected? */
cptr = strcpy (gbuf, "STOP");
sim_rem_collect_cmd_setup (i, &cptr); /* make sure it is now disabled */
}
continue;
}
@@ -996,6 +1312,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
}
else {
sim_is_running = 0;
sim_rem_collect_all_registers ();
sim_stop_timer_services ();
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
TMLN *lpj = &sim_rem_con_tmxr.ldsc[j];
@@ -1016,6 +1333,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
if (c == sim_int_char) { /* ^E (the interrupt character) must start continue mode console interaction */
rem->single_mode = FALSE; /* enter multi command mode */
sim_is_running = 0;
sim_rem_collect_all_registers ();
sim_stop_timer_services ();
stat = SCPE_STOP;
_sim_rem_message ("RUN", stat);
@@ -1254,7 +1572,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
}
else {
if ((cmdp = find_ctab (rem->single_mode ? allowed_single_remote_cmds : (master_session ? allowed_master_remote_cmds : allowed_remote_cmds), gbuf))) {/* lookup command */
sim_debug (DBG_CMD, &sim_remote_console, "gbuf='%s', basecmd='%s', cmd='%s', action=%p, continue_cmd=%p, repeat_cmd=%p\n", gbuf, basecmdp->name, cmdp->name, cmdp->action, &x_continue_cmd, &x_repeat_cmd);
sim_debug (DBG_CMD, &sim_remote_console, "gbuf='%s', basecmd='%s', cmd='%s'\n", gbuf, basecmdp->name, cmdp->name);
if (cmdp->action == &x_continue_cmd) {
sim_debug (DBG_CMD, &sim_remote_console, "continue_cmd executing\n");
stat = SCPE_OK;
@@ -1294,21 +1612,34 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
}
}
else {
if (cmdp->action == &x_repeat_cmd) {
sim_debug (DBG_CMD, &sim_remote_console, "repeat_cmd executing\n");
stat = _rem_repeat_cmd_setup (i, &cptr);
if (cmdp->action == &x_sampleout_cmd) {
sim_debug (DBG_CMD, &sim_remote_console, "sampleout_cmd executing\n");
sim_oline = lp; /* specify output socket */
stat = sim_rem_sample_output (NULL, i);
}
else {
if (sim_con_stable_registers &&
sim_rem_master_mode) { /* can we process command now? */
sim_debug (DBG_CMD, &sim_remote_console, "Processing Command directly\n");
sim_oline = lp; /* specify output socket */
sim_remote_process_command ();
stat = SCPE_OK; /* any message has already been emitted */
if (cmdp->action == &x_repeat_cmd) {
sim_debug (DBG_CMD, &sim_remote_console, "repeat_cmd executing\n");
stat = sim_rem_repeat_cmd_setup (i, &cptr);
}
else {
sim_debug (DBG_CMD, &sim_remote_console, "Processing Command via SCPE_REMOTE\n");
stat = SCPE_REMOTE; /* force processing outside of sim_instr() */
if (cmdp->action == &x_collect_cmd) {
sim_debug (DBG_CMD, &sim_remote_console, "sample_cmd executing\n");
stat = sim_rem_collect_cmd_setup (i, &cptr);
}
else {
if (sim_con_stable_registers &&
sim_rem_master_mode) { /* can we process command now? */
sim_debug (DBG_CMD, &sim_remote_console, "Processing Command directly\n");
sim_oline = lp; /* specify output socket */
sim_remote_process_command ();
stat = SCPE_OK; /* any message has already been emitted */
}
else {
sim_debug (DBG_CMD, &sim_remote_console, "Processing Command via SCPE_REMOTE\n");
stat = SCPE_REMOTE; /* force processing outside of sim_instr() */
}
}
}
}
}
@@ -1402,20 +1733,6 @@ else
return SCPE_OK; /* keep going */
}
t_stat sim_rem_con_repeat_svc (UNIT *uptr)
{
int line = uptr - rem_con_repeat_units;
REMOTE *rem = &sim_rem_consoles[line];
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_repeat_svc(line=%d) - interval=%d\n", line, rem->repeat_interval);
if (rem->repeat_interval) {
rem->repeat_pending = TRUE;
sim_activate_after (uptr, rem->repeat_interval); /* reschedule */
sim_activate_abs (rem_con_data_unit, -1); /* wake up to process */
}
return SCPE_OK;
}
t_stat sim_rem_con_reset (DEVICE *dptr)
{
if (sim_rem_con_tmxr.lines) {
@@ -1429,7 +1746,9 @@ if (sim_rem_con_tmxr.lines) {
continue;
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_reset(line=%d, usecs=%d)\n", i, rem->repeat_interval);
if (rem->repeat_interval)
sim_activate_after (rem_con_repeat_units + i, rem->repeat_interval);/* schedule */
sim_activate_after (&rem_con_repeat_units[rem->line], rem->repeat_interval); /* schedule */
if (rem->smp_reg_count)
sim_activate (&rem_con_smp_smpl_units[rem->line], rem->smp_sample_interval); /* schedule */
}
if (i != sim_rem_con_tmxr.lines)
sim_activate_after (rem_con_data_unit, 100000); /* continue polling for open sessions */
@@ -1501,13 +1820,14 @@ for (i=0; i<sim_rem_con_tmxr.lines; i++) {
free (rem->act);
free (rem->repeat_action);
sim_cancel (&rem_con_repeat_units[i]);
sim_cancel (&rem_con_smp_smpl_units[i]);
}
sim_rem_con_tmxr.lines = lines;
sim_rem_con_tmxr.ldsc = (TMLN *)realloc (sim_rem_con_tmxr.ldsc, sizeof(*sim_rem_con_tmxr.ldsc)*lines);
memset (sim_rem_con_tmxr.ldsc, 0, sizeof(*sim_rem_con_tmxr.ldsc)*lines);
sim_remote_console.units = (UNIT *)realloc (sim_remote_console.units, sizeof(*sim_remote_console.units)*(lines + REM_CON_BASE_UNITS));
memset (sim_remote_console.units, 0, sizeof(*sim_remote_console.units)*(lines + REM_CON_BASE_UNITS));
sim_remote_console.numunits = lines + REM_CON_BASE_UNITS;
sim_remote_console.units = (UNIT *)realloc (sim_remote_console.units, sizeof(*sim_remote_console.units)*((2 * lines) + REM_CON_BASE_UNITS));
memset (sim_remote_console.units, 0, sizeof(*sim_remote_console.units)*((2 * lines) + REM_CON_BASE_UNITS));
sim_remote_console.numunits = (2 * lines) + REM_CON_BASE_UNITS;
rem_con_poll_unit->action = &sim_rem_con_poll_svc;/* remote console connection polling unit */
rem_con_poll_unit->flags |= UNIT_IDLE;
rem_con_data_unit->action = &sim_rem_con_data_svc;/* console data handling unit */
@@ -1519,6 +1839,8 @@ memset (sim_rem_command_buf, 0, 4*CBUFSIZE+1);
for (i=0; i<lines; i++) {
rem_con_repeat_units[i].flags = UNIT_DIS;
rem_con_repeat_units[i].action = &sim_rem_con_repeat_svc;
rem_con_smp_smpl_units[i].flags = UNIT_DIS;
rem_con_smp_smpl_units[i].action = &sim_rem_con_smp_collect_svc;
rem = &sim_rem_consoles[i];
rem->line = i;
rem->lp = &sim_rem_con_tmxr.ldsc[i];