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:
parent
f171055809
commit
665ebf0fd1
5 changed files with 627 additions and 82 deletions
|
@ -59,6 +59,10 @@ const char *sim_config =
|
||||||
unsigned int PC, SP, FP, AP, PSL, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, atPC;
|
unsigned int PC, SP, FP, AP, PSL, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, atPC;
|
||||||
unsigned int PCQ[32];
|
unsigned int PCQ[32];
|
||||||
|
|
||||||
|
int PSL_bits[32];
|
||||||
|
int PC_bits[32];
|
||||||
|
int PC_indirect_bits[32];
|
||||||
|
|
||||||
int update_display = 1;
|
int update_display = 1;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -357,6 +361,35 @@ if (sim_panel_break_output_set (panel, "-P \"Device? [XQA0]: \"")) {
|
||||||
printf ("Unexpected error establishing an output breakpoint: %s\n", sim_panel_get_error());
|
printf ("Unexpected error establishing an output breakpoint: %s\n", sim_panel_get_error());
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
if (!sim_panel_set_sampling_parameters (panel, 0, 199)) {
|
||||||
|
printf ("Unexpected success setting sampling parameters to 0, 199\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (!sim_panel_set_sampling_parameters (panel, 199, 0)) {
|
||||||
|
printf ("Unexpected success setting sampling parameters to 199, 0\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (!sim_panel_add_register_bits (panel, "PSL", NULL, 32, PSL_bits)) {
|
||||||
|
printf ("Unexpected success setting PSL bits before setting sampling parameters\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (sim_panel_set_sampling_parameters (panel, 500, 100)) {
|
||||||
|
printf ("Unexpected error setting sampling parameters to 200, 100: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (sim_panel_add_register_indirect_bits (panel, "PC", NULL, 32, PC_indirect_bits)) {
|
||||||
|
printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (sim_panel_add_register_bits (panel, "PSL", NULL, 32, PSL_bits)) {
|
||||||
|
printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (sim_panel_add_register_bits (panel, "PC", NULL, 32, PC_bits)) {
|
||||||
|
printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
sim_panel_clear_error ();
|
sim_panel_clear_error ();
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
3
scp.h
3
scp.h
|
@ -195,6 +195,7 @@ CTAB *find_ctab (CTAB *tab, const char *gbuf);
|
||||||
C1TAB *find_c1tab (C1TAB *tab, const char *gbuf);
|
C1TAB *find_c1tab (C1TAB *tab, const char *gbuf);
|
||||||
SHTAB *find_shtab (SHTAB *tab, const char *gbuf);
|
SHTAB *find_shtab (SHTAB *tab, const char *gbuf);
|
||||||
t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr);
|
t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr);
|
||||||
|
t_value get_rval (REG *rptr, uint32 idx);
|
||||||
BRKTAB *sim_brk_fnd (t_addr loc);
|
BRKTAB *sim_brk_fnd (t_addr loc);
|
||||||
uint32 sim_brk_test (t_addr bloc, uint32 btyp);
|
uint32 sim_brk_test (t_addr bloc, uint32 btyp);
|
||||||
void sim_brk_clrspc (uint32 spc, uint32 btyp);
|
void sim_brk_clrspc (uint32 spc, uint32 btyp);
|
||||||
|
@ -264,6 +265,8 @@ t_stat scp_vhelpFromFile (FILE *st, DEVICE *dptr,
|
||||||
/* Global data */
|
/* Global data */
|
||||||
|
|
||||||
extern DEVICE *sim_dflt_dev;
|
extern DEVICE *sim_dflt_dev;
|
||||||
|
extern DEVICE *sim_dfdev;
|
||||||
|
extern UNIT *sim_dfunit;
|
||||||
extern int32 sim_interval;
|
extern int32 sim_interval;
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
extern int32 sim_quiet;
|
extern int32 sim_quiet;
|
||||||
|
|
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_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_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_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 */
|
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_poll_unit (&sim_remote_console.units[0])
|
||||||
#define rem_con_data_unit (&sim_remote_console.units[1])
|
#define rem_con_data_unit (&sim_remote_console.units[1])
|
||||||
#define REM_CON_BASE_UNITS 2
|
#define REM_CON_BASE_UNITS 2
|
||||||
#define rem_con_repeat_units (&sim_remote_console.units[REM_CON_BASE_UNITS])
|
#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_MOD 0x00000004 /* Remote Console Mode activities */
|
||||||
#define DBG_REP 0x00000008 /* Remote Console Repeat 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[] = {
|
DEBTAB sim_rem_con_debug[] = {
|
||||||
{"TRC", DBG_TRC, "routine calls"},
|
{"TRC", DBG_TRC, "routine calls"},
|
||||||
|
@ -445,6 +449,7 @@ DEBTAB sim_rem_con_debug[] = {
|
||||||
{"CMD", DBG_CMD, "Remote Console Command activity"},
|
{"CMD", DBG_CMD, "Remote Console Command activity"},
|
||||||
{"MODE", DBG_MOD, "Remote Console Mode activity"},
|
{"MODE", DBG_MOD, "Remote Console Mode activity"},
|
||||||
{"REPEAT", DBG_REP, "Remote Console Repeat activity"},
|
{"REPEAT", DBG_REP, "Remote Console Repeat activity"},
|
||||||
|
{"SAMPLE", DBG_SAM, "Remote Console Sample activity"},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -464,6 +469,22 @@ DEVICE sim_remote_console = {
|
||||||
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_rem_con_debug,
|
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_rem_con_debug,
|
||||||
NULL, NULL, NULL, NULL, NULL, sim_rem_con_description};
|
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;
|
typedef struct REMOTE REMOTE;
|
||||||
struct REMOTE {
|
struct REMOTE {
|
||||||
int32 buf_size;
|
int32 buf_size;
|
||||||
|
@ -474,16 +495,18 @@ struct REMOTE {
|
||||||
char *act;
|
char *act;
|
||||||
t_bool single_mode;
|
t_bool single_mode;
|
||||||
uint32 read_timeout;
|
uint32 read_timeout;
|
||||||
int line;
|
int line; /* remote console line number */
|
||||||
TMLN *lp;
|
TMLN *lp; /* mux line/socket for remote session */
|
||||||
UNIT *uptr;
|
UNIT *uptr; /* remote console unit */
|
||||||
uint32 repeat_interval;
|
uint32 repeat_interval; /* usecs between repeat execution */
|
||||||
t_bool repeat_pending;
|
t_bool repeat_pending; /* repeat delivery pending */
|
||||||
char *repeat_action;
|
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;
|
REMOTE *sim_rem_consoles = NULL;
|
||||||
|
|
||||||
|
|
||||||
static TMXR sim_rem_con_tmxr = { 0, 0, 0, NULL, NULL, &sim_remote_console };/* remote console line mux */
|
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_timeout = 30; /* seconds before automatic continue */
|
||||||
static uint32 *sim_rem_read_timeouts = NULL;/* per line read timeout (default from sim_rem_read_timeout) */
|
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_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_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 */
|
/* 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, "The Command: %s\n", rem->repeat_action);
|
||||||
fprintf (st, " is repeated every %s\n", sim_fmt_secs (rem->repeat_interval / 1000000.0));
|
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;
|
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 */
|
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 */
|
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 */
|
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 t_stat x_help_cmd (int32 flag, CONST char *cptr);
|
||||||
|
|
||||||
static CTAB allowed_remote_cmds[] = {
|
static CTAB allowed_remote_cmds[] = {
|
||||||
|
@ -642,6 +713,8 @@ static CTAB allowed_remote_cmds[] = {
|
||||||
{ "DEASSIGN", &deassign_cmd, 0 },
|
{ "DEASSIGN", &deassign_cmd, 0 },
|
||||||
{ "CONTINUE", &x_continue_cmd, 0 },
|
{ "CONTINUE", &x_continue_cmd, 0 },
|
||||||
{ "REPEAT", &x_repeat_cmd, 0 },
|
{ "REPEAT", &x_repeat_cmd, 0 },
|
||||||
|
{ "COLLECT", &x_collect_cmd, 0 },
|
||||||
|
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
|
||||||
{ "STEP", &x_step_cmd, 0 },
|
{ "STEP", &x_step_cmd, 0 },
|
||||||
{ "PWD", &pwd_cmd, 0 },
|
{ "PWD", &pwd_cmd, 0 },
|
||||||
{ "SAVE", &save_cmd, 0 },
|
{ "SAVE", &save_cmd, 0 },
|
||||||
|
@ -664,6 +737,8 @@ static CTAB allowed_master_remote_cmds[] = {
|
||||||
{ "DEASSIGN", &deassign_cmd, 0 },
|
{ "DEASSIGN", &deassign_cmd, 0 },
|
||||||
{ "CONTINUE", &x_continue_cmd, 0 },
|
{ "CONTINUE", &x_continue_cmd, 0 },
|
||||||
{ "REPEAT", &x_repeat_cmd, 0 },
|
{ "REPEAT", &x_repeat_cmd, 0 },
|
||||||
|
{ "COLLECT", &x_collect_cmd, 0 },
|
||||||
|
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
|
||||||
{ "STEP", &x_step_cmd, 0 },
|
{ "STEP", &x_step_cmd, 0 },
|
||||||
{ "PWD", &pwd_cmd, 0 },
|
{ "PWD", &pwd_cmd, 0 },
|
||||||
{ "SAVE", &save_cmd, 0 },
|
{ "SAVE", &save_cmd, 0 },
|
||||||
|
@ -693,6 +768,8 @@ static CTAB allowed_single_remote_cmds[] = {
|
||||||
{ "EXAMINE", &exdep_cmd, EX_E },
|
{ "EXAMINE", &exdep_cmd, EX_E },
|
||||||
{ "EVALUATE", &eval_cmd, 0 },
|
{ "EVALUATE", &eval_cmd, 0 },
|
||||||
{ "REPEAT", &x_repeat_cmd, 0 },
|
{ "REPEAT", &x_repeat_cmd, 0 },
|
||||||
|
{ "COLLECT", &x_collect_cmd, 0 },
|
||||||
|
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
|
||||||
{ "PWD", &pwd_cmd, 0 },
|
{ "PWD", &pwd_cmd, 0 },
|
||||||
{ "DIR", &dir_cmd, 0 },
|
{ "DIR", &dir_cmd, 0 },
|
||||||
{ "LS", &dir_cmd, 0 },
|
{ "LS", &dir_cmd, 0 },
|
||||||
|
@ -704,6 +781,8 @@ static CTAB allowed_single_remote_cmds[] = {
|
||||||
|
|
||||||
static CTAB remote_only_cmds[] = {
|
static CTAB remote_only_cmds[] = {
|
||||||
{ "REPEAT", &x_repeat_cmd, 0 },
|
{ "REPEAT", &x_repeat_cmd, 0 },
|
||||||
|
{ "COLLECT", &x_collect_cmd, 0 },
|
||||||
|
{ "SAMPLEOUT",&x_sampleout_cmd, 0 },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -864,7 +943,7 @@ return buf;
|
||||||
Parse and setup Remote Console REPEAT command:
|
Parse and setup Remote Console REPEAT command:
|
||||||
REPEAT EVERY nnn USECS Command {; 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];
|
char gbuf[CBUFSIZE];
|
||||||
int32 val;
|
int32 val;
|
||||||
|
@ -940,6 +1019,239 @@ if (stat == SCPE_OK) {
|
||||||
return stat;
|
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 */
|
/* Unit service for remote console data polling */
|
||||||
|
|
||||||
t_stat sim_rem_con_data_svc (UNIT *uptr)
|
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 (!lp->conn) {
|
||||||
if (rem->repeat_interval) { /* was repeated enabled? */
|
if (rem->repeat_interval) { /* was repeated enabled? */
|
||||||
cptr = strcpy (gbuf, "STOP");
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -996,6 +1312,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sim_is_running = 0;
|
sim_is_running = 0;
|
||||||
|
sim_rem_collect_all_registers ();
|
||||||
sim_stop_timer_services ();
|
sim_stop_timer_services ();
|
||||||
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
|
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
|
||||||
TMLN *lpj = &sim_rem_con_tmxr.ldsc[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 */
|
if (c == sim_int_char) { /* ^E (the interrupt character) must start continue mode console interaction */
|
||||||
rem->single_mode = FALSE; /* enter multi command mode */
|
rem->single_mode = FALSE; /* enter multi command mode */
|
||||||
sim_is_running = 0;
|
sim_is_running = 0;
|
||||||
|
sim_rem_collect_all_registers ();
|
||||||
sim_stop_timer_services ();
|
sim_stop_timer_services ();
|
||||||
stat = SCPE_STOP;
|
stat = SCPE_STOP;
|
||||||
_sim_rem_message ("RUN", stat);
|
_sim_rem_message ("RUN", stat);
|
||||||
|
@ -1254,7 +1572,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((cmdp = find_ctab (rem->single_mode ? allowed_single_remote_cmds : (master_session ? allowed_master_remote_cmds : allowed_remote_cmds), gbuf))) {/* lookup command */
|
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) {
|
if (cmdp->action == &x_continue_cmd) {
|
||||||
sim_debug (DBG_CMD, &sim_remote_console, "continue_cmd executing\n");
|
sim_debug (DBG_CMD, &sim_remote_console, "continue_cmd executing\n");
|
||||||
stat = SCPE_OK;
|
stat = SCPE_OK;
|
||||||
|
@ -1294,21 +1612,34 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (cmdp->action == &x_repeat_cmd) {
|
if (cmdp->action == &x_sampleout_cmd) {
|
||||||
sim_debug (DBG_CMD, &sim_remote_console, "repeat_cmd executing\n");
|
sim_debug (DBG_CMD, &sim_remote_console, "sampleout_cmd executing\n");
|
||||||
stat = _rem_repeat_cmd_setup (i, &cptr);
|
sim_oline = lp; /* specify output socket */
|
||||||
|
stat = sim_rem_sample_output (NULL, i);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (sim_con_stable_registers &&
|
if (cmdp->action == &x_repeat_cmd) {
|
||||||
sim_rem_master_mode) { /* can we process command now? */
|
sim_debug (DBG_CMD, &sim_remote_console, "repeat_cmd executing\n");
|
||||||
sim_debug (DBG_CMD, &sim_remote_console, "Processing Command directly\n");
|
stat = sim_rem_repeat_cmd_setup (i, &cptr);
|
||||||
sim_oline = lp; /* specify output socket */
|
|
||||||
sim_remote_process_command ();
|
|
||||||
stat = SCPE_OK; /* any message has already been emitted */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sim_debug (DBG_CMD, &sim_remote_console, "Processing Command via SCPE_REMOTE\n");
|
if (cmdp->action == &x_collect_cmd) {
|
||||||
stat = SCPE_REMOTE; /* force processing outside of sim_instr() */
|
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 */
|
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)
|
t_stat sim_rem_con_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
if (sim_rem_con_tmxr.lines) {
|
if (sim_rem_con_tmxr.lines) {
|
||||||
|
@ -1429,7 +1746,9 @@ if (sim_rem_con_tmxr.lines) {
|
||||||
continue;
|
continue;
|
||||||
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_reset(line=%d, usecs=%d)\n", i, rem->repeat_interval);
|
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_reset(line=%d, usecs=%d)\n", i, rem->repeat_interval);
|
||||||
if (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)
|
if (i != sim_rem_con_tmxr.lines)
|
||||||
sim_activate_after (rem_con_data_unit, 100000); /* continue polling for open sessions */
|
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->act);
|
||||||
free (rem->repeat_action);
|
free (rem->repeat_action);
|
||||||
sim_cancel (&rem_con_repeat_units[i]);
|
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.lines = lines;
|
||||||
sim_rem_con_tmxr.ldsc = (TMLN *)realloc (sim_rem_con_tmxr.ldsc, sizeof(*sim_rem_con_tmxr.ldsc)*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);
|
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));
|
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)*(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 = 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->action = &sim_rem_con_poll_svc;/* remote console connection polling unit */
|
||||||
rem_con_poll_unit->flags |= UNIT_IDLE;
|
rem_con_poll_unit->flags |= UNIT_IDLE;
|
||||||
rem_con_data_unit->action = &sim_rem_con_data_svc;/* console data handling unit */
|
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++) {
|
for (i=0; i<lines; i++) {
|
||||||
rem_con_repeat_units[i].flags = UNIT_DIS;
|
rem_con_repeat_units[i].flags = UNIT_DIS;
|
||||||
rem_con_repeat_units[i].action = &sim_rem_con_repeat_svc;
|
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 = &sim_rem_consoles[i];
|
||||||
rem->line = i;
|
rem->line = i;
|
||||||
rem->lp = &sim_rem_con_tmxr.ldsc[i];
|
rem->lp = &sim_rem_con_tmxr.ldsc[i];
|
||||||
|
|
188
sim_frontpanel.c
188
sim_frontpanel.c
|
@ -119,6 +119,8 @@ typedef struct {
|
||||||
size_t size;
|
size_t size;
|
||||||
int indirect;
|
int indirect;
|
||||||
size_t element_count;
|
size_t element_count;
|
||||||
|
int *bits;
|
||||||
|
size_t bit_count;
|
||||||
} REG;
|
} REG;
|
||||||
|
|
||||||
struct PANEL {
|
struct PANEL {
|
||||||
|
@ -158,6 +160,8 @@ struct PANEL {
|
||||||
int callback_thread_running;
|
int callback_thread_running;
|
||||||
void *callback_context;
|
void *callback_context;
|
||||||
int usecs_between_callbacks;
|
int usecs_between_callbacks;
|
||||||
|
unsigned int sample_frequency;
|
||||||
|
unsigned int sample_depth;
|
||||||
int debug;
|
int debug;
|
||||||
char *simulator_version;
|
char *simulator_version;
|
||||||
int radix;
|
int radix;
|
||||||
|
@ -175,6 +179,10 @@ static const char *register_repeat_stop = "repeat stop";
|
||||||
static const char *register_repeat_stop_all = "repeat stop all";
|
static const char *register_repeat_stop_all = "repeat stop all";
|
||||||
static const char *register_repeat_units = " usecs ";
|
static const char *register_repeat_units = " usecs ";
|
||||||
static const char *register_get_prefix = "show time";
|
static const char *register_get_prefix = "show time";
|
||||||
|
static const char *register_collect_prefix = "collect ";
|
||||||
|
static const char *register_collect_mid1 = " samples every ";
|
||||||
|
static const char *register_collect_mid2 = " cycles ";
|
||||||
|
static const char *register_get_postfix = "sampleout";
|
||||||
static const char *register_get_echo = "# REGISTERS-DONE";
|
static const char *register_get_echo = "# REGISTERS-DONE";
|
||||||
static const char *register_repeat_echo = "# REGISTERS-REPEAT-DONE";
|
static const char *register_repeat_echo = "# REGISTERS-REPEAT-DONE";
|
||||||
static const char *register_dev_echo = "# REGISTERS-FOR-DEVICE:";
|
static const char *register_dev_echo = "# REGISTERS-FOR-DEVICE:";
|
||||||
|
@ -374,18 +382,25 @@ _panel_sendf (PANEL *p, int *completion_status, char **response, const char *fmt
|
||||||
static int
|
static int
|
||||||
_panel_register_query_string (PANEL *panel, char **buf, size_t *buf_size)
|
_panel_register_query_string (PANEL *panel, char **buf, size_t *buf_size)
|
||||||
{
|
{
|
||||||
size_t i, j, buf_data, buf_needed = 0;
|
size_t i, j, buf_data, buf_needed = 0, reg_count = 0, bit_reg_count = 0;
|
||||||
const char *dev;
|
const char *dev;
|
||||||
|
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
pthread_mutex_lock (&panel->io_lock);
|
||||||
buf_needed = 2 + strlen (register_get_prefix); /* SHOW TIME */
|
buf_needed = 2 + strlen (register_get_prefix); /* SHOW TIME */
|
||||||
for (i=0; i<panel->reg_count; i++) {
|
for (i=0; i<panel->reg_count; i++) {
|
||||||
buf_needed += 9 + strlen (panel->regs[i].name) + (panel->regs[i].device_name ? strlen (panel->regs[i].device_name) : 0);
|
if (panel->regs[i].bits)
|
||||||
if (panel->regs[i].element_count > 0)
|
++bit_reg_count;
|
||||||
buf_needed += 4 + 6 /* 6 digit register array index */;
|
else {
|
||||||
if (panel->regs[i].indirect)
|
++reg_count;
|
||||||
buf_needed += 12 + strlen (register_ind_echo) + strlen (panel->regs[i].name);
|
buf_needed += 9 + strlen (panel->regs[i].name) + (panel->regs[i].device_name ? strlen (panel->regs[i].device_name) : 0);
|
||||||
|
if (panel->regs[i].element_count > 0)
|
||||||
|
buf_needed += 4 + 6 /* 6 digit register array index */;
|
||||||
|
if (panel->regs[i].indirect)
|
||||||
|
buf_needed += 12 + strlen (register_ind_echo) + strlen (panel->regs[i].name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (bit_reg_count)
|
||||||
|
buf_needed += 2 + strlen (register_get_postfix);
|
||||||
buf_needed += 10 + strlen (register_get_echo); /* # REGISTERS-DONE */
|
buf_needed += 10 + strlen (register_get_echo); /* # REGISTERS-DONE */
|
||||||
if (buf_needed > *buf_size) {
|
if (buf_needed > *buf_size) {
|
||||||
free (*buf);
|
free (*buf);
|
||||||
|
@ -398,13 +413,15 @@ if (buf_needed > *buf_size) {
|
||||||
*buf_size = buf_needed;
|
*buf_size = buf_needed;
|
||||||
}
|
}
|
||||||
buf_data = 0;
|
buf_data = 0;
|
||||||
sprintf (*buf + buf_data, "%s\r", register_get_prefix);
|
if (reg_count) {
|
||||||
buf_data += strlen (*buf + buf_data);
|
sprintf (*buf + buf_data, "%s\r", register_get_prefix);
|
||||||
|
buf_data += strlen (*buf + buf_data);
|
||||||
|
}
|
||||||
dev = "";
|
dev = "";
|
||||||
for (i=j=0; i<panel->reg_count; i++) {
|
for (i=j=0; i<panel->reg_count; i++) {
|
||||||
const char *reg_dev = panel->regs[i].device_name ? panel->regs[i].device_name : "";
|
const char *reg_dev = panel->regs[i].device_name ? panel->regs[i].device_name : "";
|
||||||
|
|
||||||
if (panel->regs[i].indirect)
|
if ((panel->regs[i].indirect) || (panel->regs[i].bits))
|
||||||
continue;
|
continue;
|
||||||
if (strcmp (dev, reg_dev)) {/* devices are different */
|
if (strcmp (dev, reg_dev)) {/* devices are different */
|
||||||
char *tbuf;
|
char *tbuf;
|
||||||
|
@ -447,11 +464,17 @@ if (buf_data && ((*buf)[buf_data-1] != '\r')) {
|
||||||
for (i=j=0; i<panel->reg_count; i++) {
|
for (i=j=0; i<panel->reg_count; i++) {
|
||||||
const char *reg_dev = panel->regs[i].device_name ? panel->regs[i].device_name : "";
|
const char *reg_dev = panel->regs[i].device_name ? panel->regs[i].device_name : "";
|
||||||
|
|
||||||
if (!panel->regs[i].indirect)
|
if ((!panel->regs[i].indirect) || (panel->regs[i].bits))
|
||||||
continue;
|
continue;
|
||||||
sprintf (*buf + buf_data, "%s%s\rE -H %s %s,$\r", register_ind_echo, panel->regs[i].name, reg_dev, panel->regs[i].name);
|
sprintf (*buf + buf_data, "%s%s\rE -H %s %s,$\r", register_ind_echo, panel->regs[i].name, reg_dev, panel->regs[i].name);
|
||||||
buf_data += strlen (*buf + buf_data);
|
buf_data += strlen (*buf + buf_data);
|
||||||
}
|
}
|
||||||
|
if (bit_reg_count) {
|
||||||
|
strcpy (*buf + buf_data, register_get_postfix);
|
||||||
|
buf_data += strlen (*buf + buf_data);
|
||||||
|
strcpy (*buf + buf_data, "\r");
|
||||||
|
buf_data += strlen (*buf + buf_data);
|
||||||
|
}
|
||||||
strcpy (*buf + buf_data, register_get_echo);
|
strcpy (*buf + buf_data, register_get_echo);
|
||||||
buf_data += strlen (*buf + buf_data);
|
buf_data += strlen (*buf + buf_data);
|
||||||
strcpy (*buf + buf_data, "\r");
|
strcpy (*buf + buf_data, "\r");
|
||||||
|
@ -461,6 +484,53 @@ pthread_mutex_unlock (&panel->io_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_panel_establish_register_bits_collection (PANEL *panel)
|
||||||
|
{
|
||||||
|
size_t i, buf_data, buf_needed = 0, reg_count = 0, bit_reg_count = 0;
|
||||||
|
int cmd_stat, bits_count = 0;
|
||||||
|
char *buf, *response = NULL;
|
||||||
|
|
||||||
|
pthread_mutex_lock (&panel->io_lock);
|
||||||
|
for (i=0; i<panel->reg_count; i++) {
|
||||||
|
if (panel->regs[i].bits)
|
||||||
|
buf_needed += 9 + strlen (panel->regs[i].name) + (panel->regs[i].device_name ? strlen (panel->regs[i].device_name) : 0);
|
||||||
|
}
|
||||||
|
buf = (char *)_panel_malloc (buf_needed);
|
||||||
|
if (!buf) {
|
||||||
|
panel->State = Error;
|
||||||
|
pthread_mutex_unlock (&panel->io_lock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*buf = '\0';
|
||||||
|
buf_data = 0;
|
||||||
|
for (i=0; i<panel->reg_count; i++) {
|
||||||
|
if (panel->regs[i].bits) {
|
||||||
|
++bits_count;
|
||||||
|
sprintf (buf + buf_data, "%s%s", (bits_count != 1) ? "," : "", panel->regs[i].indirect ? "-I " : "");
|
||||||
|
buf_data += strlen (buf + buf_data);
|
||||||
|
if (panel->regs[i].device_name) {
|
||||||
|
sprintf (buf + buf_data, "%s ", panel->regs[i].device_name);
|
||||||
|
buf_data += strlen (buf + buf_data);
|
||||||
|
}
|
||||||
|
sprintf (buf + buf_data, "%s", panel->regs[i].name);
|
||||||
|
buf_data += strlen (buf + buf_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock (&panel->io_lock);
|
||||||
|
if (_panel_sendf (panel, &cmd_stat, &response, "%s%u%s%u%s%s\r", register_collect_prefix, panel->sample_depth,
|
||||||
|
register_collect_mid1, panel->sample_frequency,
|
||||||
|
register_collect_mid2, buf)) {
|
||||||
|
sim_panel_set_error ("Error establishing bit data collection:%s", response);
|
||||||
|
free (response);
|
||||||
|
free (buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free (response);
|
||||||
|
free (buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PANEL **panels = NULL;
|
static PANEL **panels = NULL;
|
||||||
static int panel_count = 0;
|
static int panel_count = 0;
|
||||||
|
|
||||||
|
@ -927,7 +997,9 @@ _panel_add_register (PANEL *panel,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *addr,
|
void *addr,
|
||||||
int indirect,
|
int indirect,
|
||||||
size_t element_count)
|
size_t element_count,
|
||||||
|
int *bits,
|
||||||
|
size_t bit_count)
|
||||||
{
|
{
|
||||||
REG *regs, *reg;
|
REG *regs, *reg;
|
||||||
char *response = NULL;
|
char *response = NULL;
|
||||||
|
@ -942,6 +1014,10 @@ if (panel->State == Run) {
|
||||||
sim_panel_set_error ("Not Halted");
|
sim_panel_set_error ("Not Halted");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if ((bit_count != 0) && (panel->sample_depth == 0)) {
|
||||||
|
sim_panel_set_error ("sim_panel_set_sampling_parameters() must be called first");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
regs = (REG *)_panel_malloc ((1 + panel->reg_count)*sizeof(*regs));
|
regs = (REG *)_panel_malloc ((1 + panel->reg_count)*sizeof(*regs));
|
||||||
if (regs == NULL) {
|
if (regs == NULL) {
|
||||||
panel->State = Error;
|
panel->State = Error;
|
||||||
|
@ -959,6 +1035,11 @@ if (reg->name == NULL) {
|
||||||
}
|
}
|
||||||
strcpy (reg->name, name);
|
strcpy (reg->name, name);
|
||||||
reg->indirect = indirect;
|
reg->indirect = indirect;
|
||||||
|
reg->addr = addr;
|
||||||
|
reg->size = size;
|
||||||
|
reg->element_count = element_count;
|
||||||
|
reg->bits = bits;
|
||||||
|
reg->bit_count = bit_count;
|
||||||
for (i=0; i<strlen (reg->name); i++) {
|
for (i=0; i<strlen (reg->name); i++) {
|
||||||
if (islower (reg->name[i]))
|
if (islower (reg->name[i]))
|
||||||
reg->name[i] = toupper (reg->name[i]);
|
reg->name[i] = toupper (reg->name[i]);
|
||||||
|
@ -992,7 +1073,9 @@ for (i=0; i<panel->reg_count; i++) {
|
||||||
}
|
}
|
||||||
sprintf (t1, "%s %s", regs[i].device_name ? regs[i].device_name : "", regs[i].name);
|
sprintf (t1, "%s %s", regs[i].device_name ? regs[i].device_name : "", regs[i].name);
|
||||||
sprintf (t2, "%s %s", reg->device_name ? reg->device_name : "", reg->name);
|
sprintf (t2, "%s %s", reg->device_name ? reg->device_name : "", reg->name);
|
||||||
if ((!strcmp (t1, t2)) && (reg->indirect == regs[i].indirect)) {
|
if ((!strcmp (t1, t2)) &&
|
||||||
|
(reg->indirect == regs[i].indirect) &&
|
||||||
|
((reg->bits == NULL) == (regs[i].bits == NULL))) {
|
||||||
sim_panel_set_error ("Duplicate Register Declaration");
|
sim_panel_set_error ("Duplicate Register Declaration");
|
||||||
free (t1);
|
free (t1);
|
||||||
free (t2);
|
free (t2);
|
||||||
|
@ -1004,9 +1087,6 @@ for (i=0; i<panel->reg_count; i++) {
|
||||||
free (t1);
|
free (t1);
|
||||||
free (t2);
|
free (t2);
|
||||||
}
|
}
|
||||||
reg->addr = addr;
|
|
||||||
reg->size = size;
|
|
||||||
reg->element_count = element_count;
|
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
pthread_mutex_unlock (&panel->io_lock);
|
||||||
/* Validate existence of requested register/array */
|
/* Validate existence of requested register/array */
|
||||||
if (_panel_sendf (panel, &cmd_stat, &response, "EXAMINE %s %s%s\r", device_name? device_name : "", name, (element_count > 0) ? "[0]" : "")) {
|
if (_panel_sendf (panel, &cmd_stat, &response, "EXAMINE %s %s%s\r", device_name? device_name : "", name, (element_count > 0) ? "[0]" : "")) {
|
||||||
|
@ -1050,6 +1130,11 @@ pthread_mutex_unlock (&panel->io_lock);
|
||||||
/* Now build the register query string for the whole register list */
|
/* Now build the register query string for the whole register list */
|
||||||
if (_panel_register_query_string (panel, &panel->reg_query, &panel->reg_query_size))
|
if (_panel_register_query_string (panel, &panel->reg_query, &panel->reg_query_size))
|
||||||
return -1;
|
return -1;
|
||||||
|
if (bits) {
|
||||||
|
memset (bits, 0, sizeof (*bits) * bit_count);
|
||||||
|
if (_panel_establish_register_bits_collection (panel))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1060,7 +1145,17 @@ sim_panel_add_register (PANEL *panel,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *addr)
|
void *addr)
|
||||||
{
|
{
|
||||||
return _panel_add_register (panel, name, device_name, size, addr, 0, 0);
|
return _panel_add_register (panel, name, device_name, size, addr, 0, 0, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sim_panel_add_register_bits (PANEL *panel,
|
||||||
|
const char *name,
|
||||||
|
const char *device_name,
|
||||||
|
size_t bit_width,
|
||||||
|
int *bits)
|
||||||
|
{
|
||||||
|
return _panel_add_register (panel, name, device_name, 0, NULL, 0, 0, bits, bit_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1071,7 +1166,7 @@ sim_panel_add_register_array (PANEL *panel,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *addr)
|
void *addr)
|
||||||
{
|
{
|
||||||
return _panel_add_register (panel, name, device_name, size, addr, 0, element_count);
|
return _panel_add_register (panel, name, device_name, size, addr, 0, element_count, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1082,7 +1177,17 @@ sim_panel_add_register_indirect (PANEL *panel,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *addr)
|
void *addr)
|
||||||
{
|
{
|
||||||
return _panel_add_register (panel, name, device_name, size, addr, 1, 0);
|
return _panel_add_register (panel, name, device_name, size, addr, 1, 0, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sim_panel_add_register_indirect_bits (PANEL *panel,
|
||||||
|
const char *name,
|
||||||
|
const char *device_name,
|
||||||
|
size_t bit_width,
|
||||||
|
int *bits)
|
||||||
|
{
|
||||||
|
return _panel_add_register (panel, name, device_name, 0, NULL, 1, 0, bits, bit_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1165,6 +1270,24 @@ pthread_mutex_unlock (&panel->io_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sim_panel_set_sampling_parameters (PANEL *panel,
|
||||||
|
unsigned int sample_frequency,
|
||||||
|
unsigned int sample_depth)
|
||||||
|
{
|
||||||
|
if (sample_frequency == 0) {
|
||||||
|
sim_panel_set_error ("Invalid sample frequency value: %u", sample_frequency);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (sample_depth == 0) {
|
||||||
|
sim_panel_set_error ("Invalid sample depth value: %u", sample_depth);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
panel->sample_frequency = sample_frequency;
|
||||||
|
panel->sample_depth = sample_depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_exec_halt (PANEL *panel)
|
sim_panel_exec_halt (PANEL *panel)
|
||||||
{
|
{
|
||||||
|
@ -1760,6 +1883,8 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
e = strchr (s, ':');
|
e = strchr (s, ':');
|
||||||
if (e) {
|
if (e) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
char smp_dev[32], smp_reg[32], smp_ind[32];
|
||||||
|
unsigned int bit;
|
||||||
|
|
||||||
*e++ = '\0';
|
*e++ = '\0';
|
||||||
if (!strcmp("Time", s)) {
|
if (!strcmp("Time", s)) {
|
||||||
|
@ -1769,6 +1894,33 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
++s;
|
++s;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ((*s == '}') &&
|
||||||
|
(3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */
|
||||||
|
r = NULL;
|
||||||
|
for (i=0; i<p->reg_count; i++) {
|
||||||
|
if (p->regs[i].bits == NULL)
|
||||||
|
continue;
|
||||||
|
if ((!strcmp (smp_reg, p->regs[i].name)) &&
|
||||||
|
((!p->device_name) || (!strcmp (smp_dev, p->device_name)))) {
|
||||||
|
r = &p->regs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r) {
|
||||||
|
for (bit = 0; bit < r->bit_count; bit++) {
|
||||||
|
int val = (int)strtol (e, &e, 10);
|
||||||
|
r->bits[bit] = val;
|
||||||
|
if (*e == ',')
|
||||||
|
++e;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s = eol;
|
||||||
|
}
|
||||||
|
while (isspace(0xFF & (*s)))
|
||||||
|
++s;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) {
|
if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) {
|
||||||
e = s + strlen (sim_prompt) + strlen (register_ind_echo);
|
e = s + strlen (sim_prompt) + strlen (register_ind_echo);
|
||||||
r = NULL;
|
r = NULL;
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
into the application.
|
into the application.
|
||||||
4) Use a simh simulator built from the same version of simh that the
|
4) Use a simh simulator built from the same version of simh that the
|
||||||
sim_frontpanel and sim_sock modules came from.
|
sim_frontpanel and sim_sock modules came from.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SIM_FRONTPANEL_H_
|
#ifndef SIM_FRONTPANEL_H_
|
||||||
|
@ -57,7 +56,7 @@ extern "C" {
|
||||||
|
|
||||||
#if !defined(__VAX) /* Unsupported platform */
|
#if !defined(__VAX) /* Unsupported platform */
|
||||||
|
|
||||||
#define SIM_FRONTPANEL_VERSION 3
|
#define SIM_FRONTPANEL_VERSION 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
|
@ -78,7 +77,6 @@ extern "C" {
|
||||||
Note 2: - Configuration file specified should contain device setup
|
Note 2: - Configuration file specified should contain device setup
|
||||||
statements (enable, disable, CPU types and attach commands).
|
statements (enable, disable, CPU types and attach commands).
|
||||||
It should not start a simulator running.
|
It should not start a simulator running.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct PANEL PANEL;
|
typedef struct PANEL PANEL;
|
||||||
|
@ -101,8 +99,8 @@ sim_panel_start_simulator_debug (const char *sim_path,
|
||||||
|
|
||||||
simulator_panel the simulator panel to connect to
|
simulator_panel the simulator panel to connect to
|
||||||
device_name the simulator's name for the device
|
device_name the simulator's name for the device
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PANEL *
|
PANEL *
|
||||||
sim_panel_add_device_panel (PANEL *simulator_panel,
|
sim_panel_add_device_panel (PANEL *simulator_panel,
|
||||||
const char *device_name);
|
const char *device_name);
|
||||||
|
@ -113,8 +111,8 @@ sim_panel_add_device_panel (PANEL *simulator_panel,
|
||||||
|
|
||||||
Note: destroying a simulator panel will also destroy any
|
Note: destroying a simulator panel will also destroy any
|
||||||
related sub panels
|
related sub panels
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_destroy (PANEL *panel);
|
sim_panel_destroy (PANEL *panel);
|
||||||
|
|
||||||
|
@ -128,12 +126,14 @@ sim_panel_destroy (PANEL *panel);
|
||||||
simulator.
|
simulator.
|
||||||
|
|
||||||
The registers that a particular frontpanel application mught need
|
The registers that a particular frontpanel application mught need
|
||||||
access to are described by the application when it calls:
|
access to are specified by the application when it calls:
|
||||||
|
|
||||||
sim_panel_add_register
|
sim_panel_add_register
|
||||||
|
sim_panel_add_register_bits
|
||||||
sim_panel_add_register_array
|
sim_panel_add_register_array
|
||||||
and
|
and
|
||||||
sim_panel_add_register_indirect
|
sim_panel_add_register_indirect
|
||||||
|
sim_panel_add_register_indirect_bits
|
||||||
|
|
||||||
name the name the simulator knows this register by
|
name the name the simulator knows this register by
|
||||||
device_name the device this register is part of. Defaults to
|
device_name the device this register is part of. Defaults to
|
||||||
|
@ -144,8 +144,14 @@ and
|
||||||
receive the data in the simulator's register
|
receive the data in the simulator's register
|
||||||
addr a pointer to the location of the buffer which will
|
addr a pointer to the location of the buffer which will
|
||||||
be loaded with the data in the simulator's register
|
be loaded with the data in the simulator's register
|
||||||
|
bit_width the number of values to populate in the bits array
|
||||||
|
bits an array of integers which is bit_width long that
|
||||||
|
will receive each bit's current accumulated value.
|
||||||
|
The accumulated value will range from 0 thru the
|
||||||
|
the sample_depth specified when calling
|
||||||
|
sim_panel_set_sampling_parameters().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_add_register (PANEL *panel,
|
sim_panel_add_register (PANEL *panel,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
@ -153,6 +159,13 @@ sim_panel_add_register (PANEL *panel,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *addr);
|
void *addr);
|
||||||
|
|
||||||
|
int
|
||||||
|
sim_panel_add_register_bits (PANEL *panel,
|
||||||
|
const char *name,
|
||||||
|
const char *device_name,
|
||||||
|
size_t bit_width,
|
||||||
|
int *bits);
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_add_register_array (PANEL *panel,
|
sim_panel_add_register_array (PANEL *panel,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
@ -167,11 +180,19 @@ sim_panel_add_register_indirect (PANEL *panel,
|
||||||
const char *device_name,
|
const char *device_name,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *addr);
|
void *addr);
|
||||||
|
|
||||||
|
int
|
||||||
|
sim_panel_add_register_indirect_bits (PANEL *panel,
|
||||||
|
const char *name,
|
||||||
|
const char *device_name,
|
||||||
|
size_t bit_width,
|
||||||
|
int *bits);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
A panel application has a choice of two different methods of getting
|
A panel application has a choice of two different methods of getting
|
||||||
the values contained in the set of registers it has declared interest in via
|
the values contained in the set of registers it has declared interest in via
|
||||||
the sim_panel_add_register API.
|
the sim_panel_add_register APIs.
|
||||||
|
|
||||||
1) The values can be polled (when ever it is desired) by calling
|
1) The values can be polled (when ever it is desired) by calling
|
||||||
sim_panel_get_registers().
|
sim_panel_get_registers().
|
||||||
|
@ -189,15 +210,11 @@ sim_panel_add_register_indirect (PANEL *panel,
|
||||||
or frontpanel interactions with the simulator may be disrupted.
|
or frontpanel interactions with the simulator may be disrupted.
|
||||||
Setting a flag, signaling an event or posting a message are
|
Setting a flag, signaling an event or posting a message are
|
||||||
reasonable activities to perform in a callback routine.
|
reasonable activities to perform in a callback routine.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_get_registers (PANEL *panel, unsigned long long *simulation_time);
|
sim_panel_get_registers (PANEL *panel, unsigned long long *simulation_time);
|
||||||
|
|
||||||
/**
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
typedef void (*PANEL_DISPLAY_PCALLBACK)(PANEL *panel,
|
typedef void (*PANEL_DISPLAY_PCALLBACK)(PANEL *panel,
|
||||||
unsigned long long simulation_time,
|
unsigned long long simulation_time,
|
||||||
void *context);
|
void *context);
|
||||||
|
@ -208,6 +225,26 @@ sim_panel_set_display_callback_interval (PANEL *panel,
|
||||||
void *context,
|
void *context,
|
||||||
int usecs_between_callbacks);
|
int usecs_between_callbacks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
When a front panel application wants to get averaged bit sample
|
||||||
|
values, it must first declare the sampling parameters that will
|
||||||
|
be used while collecting the bit values.
|
||||||
|
|
||||||
|
sim_panel_set_sampling_parameters
|
||||||
|
|
||||||
|
sample_frequency cycles/instructions between sample captures
|
||||||
|
sample_depth how many samples to accumulate in the rolling
|
||||||
|
average for each bit sample. Returned bit
|
||||||
|
sample values will range from 0 thru this
|
||||||
|
value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
sim_panel_set_sampling_parameters (PANEL *panel,
|
||||||
|
unsigned int sample_frequency,
|
||||||
|
unsigned int sample_depth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
When a front panel application needs to change the running
|
When a front panel application needs to change the running
|
||||||
|
@ -218,8 +255,8 @@ sim_panel_set_display_callback_interval (PANEL *panel,
|
||||||
sim_panel_exec_boot - Boot a simulator from a specific device
|
sim_panel_exec_boot - Boot a simulator from a specific device
|
||||||
sim_panel_exec_run - Start/Resume a simulator running instructions
|
sim_panel_exec_run - Start/Resume a simulator running instructions
|
||||||
sim_panel_exec_step - Have a simulator execute a single step
|
sim_panel_exec_step - Have a simulator execute a single step
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_exec_halt (PANEL *panel);
|
sim_panel_exec_halt (PANEL *panel);
|
||||||
|
|
||||||
|
@ -249,7 +286,6 @@ sim_panel_exec_step (PANEL *panel);
|
||||||
|
|
||||||
Note: Any breakpoint switches/flags must be located at the
|
Note: Any breakpoint switches/flags must be located at the
|
||||||
beginning of the condition string
|
beginning of the condition string
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -277,7 +313,6 @@ sim_panel_break_output_clear (PANEL *panel, const char *condition);
|
||||||
sim_panel_mem_deposit - Deposit to memory location
|
sim_panel_mem_deposit - Deposit to memory location
|
||||||
sim_panel_set_register_value - Deposit to a register or memory
|
sim_panel_set_register_value - Deposit to a register or memory
|
||||||
location
|
location
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,6 +394,7 @@ sim_panel_mem_deposit (PANEL *panel,
|
||||||
const void *value);
|
const void *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
sim_panel_set_register_value
|
sim_panel_set_register_value
|
||||||
|
|
||||||
name the name of a simulator register or a memory address
|
name the name of a simulator register or a memory address
|
||||||
|
@ -366,7 +402,6 @@ sim_panel_mem_deposit (PANEL *panel,
|
||||||
value the new value in character string form. The string
|
value the new value in character string form. The string
|
||||||
must be in the native/natural radix that the simulator
|
must be in the native/natural radix that the simulator
|
||||||
uses when referencing that register
|
uses when referencing that register
|
||||||
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sim_panel_set_register_value (PANEL *panel,
|
sim_panel_set_register_value (PANEL *panel,
|
||||||
|
@ -375,24 +410,24 @@ sim_panel_set_register_value (PANEL *panel,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
When a front panel application may needs to change the media
|
When a front panel application needs to change the media
|
||||||
in a simulated removable media device one of the following
|
in a simulated removable media device one of the following
|
||||||
routines should be called:
|
routines should be called:
|
||||||
|
|
||||||
sim_panel_mount - mounts the indicated media file on a device
|
sim_panel_mount - mounts the indicated media file on a device
|
||||||
sim_panel_dismount - dismounts the currently mounted media file
|
sim_panel_dismount - dismounts the currently mounted media file
|
||||||
from a device
|
from a device
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
sim_panel_mount
|
sim_panel_mount
|
||||||
|
|
||||||
device the name of a simulator device/unit
|
device the name of a simulator device/unit
|
||||||
switches any switches appropriate for the desire attach
|
switches any switches appropriate for the desire attach
|
||||||
path the path on the local system to be attached
|
path the path on the local system to be attached
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_mount (PANEL *panel,
|
sim_panel_mount (PANEL *panel,
|
||||||
const char *device,
|
const char *device,
|
||||||
|
@ -400,11 +435,12 @@ sim_panel_mount (PANEL *panel,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
sim_panel_dismount
|
sim_panel_dismount
|
||||||
|
|
||||||
device the name of a simulator device/unit
|
device the name of a simulator device/unit
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_dismount (PANEL *panel,
|
sim_panel_dismount (PANEL *panel,
|
||||||
const char *device);
|
const char *device);
|
||||||
|
@ -430,7 +466,6 @@ sim_panel_get_state (PANEL *panel);
|
||||||
|
|
||||||
sim_panel_get_error - the details of the most recent error
|
sim_panel_get_error - the details of the most recent error
|
||||||
sim_panel_clear_error - clears the error buffer
|
sim_panel_clear_error - clears the error buffer
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char *sim_panel_get_error (void);
|
const char *sim_panel_get_error (void);
|
||||||
|
|
Loading…
Add table
Reference in a new issue