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:
406
sim_console.c
406
sim_console.c
@@ -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 (®->bits[i], val&1);
|
||||
else
|
||||
sim_rem_set_reg_bit (®->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];
|
||||
|
||||
Reference in New Issue
Block a user