FRONTPANEL: sim_frontpanel API version 6 release

- Add dithering option to bit sampling
This commit is contained in:
Mark Pizzolato 2017-11-09 23:02:39 -08:00
parent 733ac0d982
commit 8551a2d477
4 changed files with 86 additions and 23 deletions

View file

@ -401,20 +401,24 @@ 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)) { if (!sim_panel_set_sampling_parameters_ex (panel, 0, 0, 199)) {
printf ("Unexpected success setting sampling parameters to 0, 199\n"); printf ("Unexpected success setting sampling parameters to 0, 0, 199\n");
goto Done; goto Done;
} }
if (!sim_panel_set_sampling_parameters (panel, 199, 0)) { if (!sim_panel_set_sampling_parameters_ex (panel, 199, 0, 0)) {
printf ("Unexpected success setting sampling parameters to 199, 0\n"); printf ("Unexpected success setting sampling parameters to 199, 0, 0\n");
goto Done; goto Done;
} }
if (!sim_panel_add_register_bits (panel, "PSL", NULL, 32, PSL_bits)) { if (!sim_panel_add_register_bits (panel, "PSL", NULL, 32, PSL_bits)) {
printf ("Unexpected success setting PSL bits before setting sampling parameters\n"); printf ("Unexpected success setting PSL bits before setting sampling parameters\n");
goto Done; goto Done;
} }
if (sim_panel_set_sampling_parameters (panel, 500, 100)) { if (!sim_panel_set_sampling_parameters_ex (panel, 500, 40, 100)) {
printf ("Unexpected error setting sampling parameters to 200, 100: %s\n", sim_panel_get_error()); printf ("Unexpected success setting sampling parameters to 500, 40, 100\n");
goto Done;
}
if (sim_panel_set_sampling_parameters_ex (panel, 500, 10, 100)) {
printf ("Unexpected error setting sampling parameters to 500, 10, 100: %s\n", sim_panel_get_error());
goto Done; goto Done;
} }
if (sim_panel_add_register_indirect_bits (panel, "PC", NULL, 32, PC_indirect_bits)) { if (sim_panel_add_register_indirect_bits (panel, "PC", NULL, 32, PC_indirect_bits)) {

View file

@ -503,6 +503,7 @@ struct REMOTE {
t_bool repeat_pending; /* repeat delivery pending */ t_bool repeat_pending; /* repeat delivery pending */
char *repeat_action; /* command(s) to repeatedly execute */ char *repeat_action; /* command(s) to repeatedly execute */
int smp_sample_interval; /* cycles between samples */ int smp_sample_interval; /* cycles between samples */
int smp_sample_dither_pct; /* dithering of cycles interval */
uint32 smp_reg_count; /* sample register count */ uint32 smp_reg_count; /* sample register count */
BITSAMPLE_REG *smp_regs; /* registers being sampled */ BITSAMPLE_REG *smp_regs; /* registers being sampled */
}; };
@ -614,7 +615,10 @@ for (i=connections=0; i<sim_rem_con_tmxr.lines; i++) {
uint32 reg; uint32 reg;
DEVICE *dptr = NULL; DEVICE *dptr = NULL;
fprintf (st, "Register Bit Sampling is occurring every %d cycles\n", rem->smp_sample_interval); if (rem->smp_sample_dither_pct)
fprintf (st, "Register Bit Sampling is occurring every %d cycles (dithered %d percent)\n", rem->smp_sample_interval, rem->smp_sample_dither_pct);
else
fprintf (st, "Register Bit Sampling is occurring every %d cycles\n", rem->smp_sample_interval);
fprintf (st, " Registers being sampled are: "); fprintf (st, " Registers being sampled are: ");
for (reg = 0; reg < rem->smp_reg_count; reg++) { for (reg = 0; reg < rem->smp_reg_count; reg++) {
if (rem->smp_regs[reg].indirect) if (rem->smp_regs[reg].indirect)
@ -1027,7 +1031,7 @@ return stat;
static t_stat sim_rem_collect_cmd_setup (int32 line, CONST char **iptr) static t_stat sim_rem_collect_cmd_setup (int32 line, CONST char **iptr)
{ {
char gbuf[CBUFSIZE]; char gbuf[CBUFSIZE];
int32 samples, cycles; int32 samples, cycles, dither_pct;
t_bool all_stop = FALSE; t_bool all_stop = FALSE;
t_stat stat = SCPE_OK; t_stat stat = SCPE_OK;
CONST char *cptr = *iptr; CONST char *cptr = *iptr;
@ -1073,6 +1077,7 @@ if ((stat != SCPE_OK) || (samples <= 0)) { /* error? */
} }
else { else {
const char *tptr; const char *tptr;
int32 event_time = rem->smp_sample_interval;
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */ cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
if (MATCH_CMD (gbuf, "SAMPLES") != 0) { if (MATCH_CMD (gbuf, "SAMPLES") != 0) {
@ -1095,6 +1100,23 @@ else {
*iptr = cptr; *iptr = cptr;
return sim_messagef (SCPE_ARG, "Expected CYCLES found: %s\n", gbuf); return sim_messagef (SCPE_ARG, "Expected CYCLES found: %s\n", gbuf);
} }
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
if ((MATCH_CMD (gbuf, "DITHER") != 0) || (*cptr == 0)) {
*iptr = cptr;
return sim_messagef (SCPE_ARG, "Expected DITHER found: %s\n", gbuf);
}
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
dither_pct = (int32) get_uint (gbuf, 10, INT_MAX, &stat);
if ((stat != SCPE_OK) || /* error? */
(dither_pct < 0) || (dither_pct > 25)) {
*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, "PERCENT") != 0) || (*cptr == 0)) {
*iptr = cptr;
return sim_messagef (SCPE_ARG, "Expected PERCENT found: %s\n", gbuf);
}
tptr = strcpy (gbuf, "STOP"); /* Start from a clean slate */ tptr = strcpy (gbuf, "STOP"); /* Start from a clean slate */
sim_rem_collect_cmd_setup (rem->line, &tptr); sim_rem_collect_cmd_setup (rem->line, &tptr);
rem->smp_sample_interval = cycles; rem->smp_sample_interval = cycles;
@ -1167,7 +1189,9 @@ else {
sim_rem_collect_cmd_setup (line, &cptr);/* Cleanup mess */ sim_rem_collect_cmd_setup (line, &cptr);/* Cleanup mess */
return stat; return stat;
} }
sim_activate (&rem_con_smp_smpl_units[rem->line], rem->smp_sample_interval); if (rem->smp_sample_dither_pct)
event_time = (((rand() % (2 * rem->smp_sample_dither_pct)) - rem->smp_sample_dither_pct) * event_time) / 100;
sim_activate (&rem_con_smp_smpl_units[rem->line], event_time);
} }
*iptr = cptr; *iptr = cptr;
return stat; return stat;
@ -1244,10 +1268,14 @@ t_stat sim_rem_con_smp_collect_svc (UNIT *uptr)
int line = uptr - rem_con_smp_smpl_units; int line = uptr - rem_con_smp_smpl_units;
REMOTE *rem = &sim_rem_consoles[line]; 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); sim_debug (DBG_SAM, &sim_remote_console, "sim_rem_con_smp_collect_svc(line=%d) - interval=%d, dither=%d%%\n", line, rem->smp_sample_interval, rem->smp_sample_dither_pct);
if (rem->smp_sample_interval && (rem->smp_reg_count != 0)) { if (rem->smp_sample_interval && (rem->smp_reg_count != 0)) {
int32 event_time = rem->smp_sample_interval;
if (rem->smp_sample_dither_pct)
event_time = (((rand() % (2 * rem->smp_sample_dither_pct)) - rem->smp_sample_dither_pct) * event_time) / 100;
sim_rem_collect_registers (rem); sim_rem_collect_registers (rem);
sim_activate (uptr, rem->smp_sample_interval); /* reschedule */ sim_activate (uptr, event_time); /* reschedule */
} }
return SCPE_OK; return SCPE_OK;
} }

View file

@ -166,6 +166,7 @@ struct PANEL {
void *callback_context; void *callback_context;
int usecs_between_callbacks; int usecs_between_callbacks;
unsigned int sample_frequency; unsigned int sample_frequency;
unsigned int sample_dither_pct;
unsigned int sample_depth; unsigned int sample_depth;
int debug; int debug;
char *simulator_version; char *simulator_version;
@ -211,7 +212,8 @@ 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_prefix = "collect ";
static const char *register_collect_mid1 = " samples every "; static const char *register_collect_mid1 = " samples every ";
static const char *register_collect_mid2 = " cycles "; static const char *register_collect_mid2 = " cycles dither ";
static const char *register_collect_mid3 = " percent ";
static const char *register_get_postfix = "sampleout"; 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";
@ -550,9 +552,10 @@ for (i=0; i<panel->reg_count; i++) {
} }
} }
pthread_mutex_unlock (&panel->io_lock); 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, if (_panel_sendf (panel, &cmd_stat, &response, "%s%u%s%u%s%u%s%s\r", register_collect_prefix, panel->sample_depth,
register_collect_mid1, panel->sample_frequency, register_collect_mid1, panel->sample_frequency,
register_collect_mid2, buf)) { register_collect_mid2, panel->sample_dither_pct,
register_collect_mid3, buf)) {
sim_panel_set_error ("Error establishing bit data collection:%s", response); sim_panel_set_error ("Error establishing bit data collection:%s", response);
free (response); free (response);
free (buf); free (buf);
@ -1312,23 +1315,40 @@ return 0;
} }
int int
sim_panel_set_sampling_parameters (PANEL *panel, sim_panel_set_sampling_parameters_ex (PANEL *panel,
unsigned int sample_frequency, unsigned int sample_frequency,
unsigned int sample_depth) unsigned int sample_dither_pct,
unsigned int sample_depth)
{ {
if (sample_frequency == 0) { if (sample_frequency == 0) {
sim_panel_set_error ("Invalid sample frequency value: %u", sample_frequency); sim_panel_set_error ("Invalid sample frequency value: %u", sample_frequency);
return -1; return -1;
} }
if (sample_dither_pct > 25) {
sim_panel_set_error ("Invalid sample dither percentage value: %u", sample_dither_pct);
return -1;
}
if (sample_depth == 0) { if (sample_depth == 0) {
sim_panel_set_error ("Invalid sample depth value: %u", sample_depth); sim_panel_set_error ("Invalid sample depth value: %u", sample_depth);
return -1; return -1;
} }
panel->sample_frequency = sample_frequency; panel->sample_frequency = sample_frequency;
panel->sample_dither_pct = sample_dither_pct;
panel->sample_depth = sample_depth; panel->sample_depth = sample_depth;
return 0; return 0;
} }
int
sim_panel_set_sampling_parameters (PANEL *panel,
unsigned int sample_frequency,
unsigned int sample_depth)
{
return sim_panel_set_sampling_parameters_ex (panel,
sample_frequency,
5,
sample_depth);
}
int int
sim_panel_exec_halt (PANEL *panel) sim_panel_exec_halt (PANEL *panel)
{ {
@ -1888,7 +1908,7 @@ static void *
_panel_reader(void *arg) _panel_reader(void *arg)
{ {
PANEL *p = (PANEL*)arg; PANEL *p = (PANEL*)arg;
REG *r = NULL; REG *r;
int sched_policy; int sched_policy;
struct sched_param sched_priority; struct sched_param sched_priority;
char buf[4096]; char buf[4096];
@ -1957,6 +1977,7 @@ while ((p->sock != INVALID_SOCKET) &&
s = buf; s = buf;
while ((eol = strchr (s, '\n'))) { while ((eol = strchr (s, '\n'))) {
/* Line to process */ /* Line to process */
r = NULL;
*eol++ = '\0'; *eol++ = '\0';
while ((*s) && (s[strlen(s)-1] == '\r')) while ((*s) && (s[strlen(s)-1] == '\r'))
s[strlen(s)-1] = '\0'; s[strlen(s)-1] = '\0';

View file

@ -56,7 +56,7 @@ extern "C" {
#if !defined(__VAX) /* Unsupported platform */ #if !defined(__VAX) /* Unsupported platform */
#define SIM_FRONTPANEL_VERSION 5 #define SIM_FRONTPANEL_VERSION 6
/** /**
@ -68,7 +68,7 @@ extern "C" {
device_panel_count the number of sub panels for connected devices device_panel_count the number of sub panels for connected devices
Note 1: - The path specified must be either a fully specified path or Note 1: - The path specified must be either a fully specified path or
it could be merey the simulator name if the simulator binary it could be merely the simulator name if the simulator binary
is located in the current PATH. is located in the current PATH.
- The simulator binary must be built from the same version - The simulator binary must be built from the same version
simh source code that the frontpanel API was acquired fron simh source code that the frontpanel API was acquired fron
@ -229,22 +229,32 @@ sim_panel_set_display_callback_interval (PANEL *panel,
When a front panel application wants to get averaged bit sample When a front panel application wants to get averaged bit sample
values, it must first declare the sampling parameters that will values, it must first declare the sampling parameters that will
be used while collecting the bit values. be used while collecting the bit values. The dithering
percentage must be 25% or less and when non 0 causes the sample
frequency to vary by plus or minus a random percentage value up
to the specified value.
sim_panel_set_sampling_parameters sim_panel_set_sampling_parameters
sim_panel_set_sampling_parameters_ex
sample_frequency cycles/instructions between sample captures sample_frequency cycles/instructions between sample captures
sample_dither_pct percentage of sample_frequency to vary randomly
sample_depth how many samples to accumulate in the rolling sample_depth how many samples to accumulate in the rolling
average for each bit sample. Returned bit average for each bit sample. Returned bit
sample values will range from 0 thru this sample values will range from 0 thru this
value. value.
*/ */
int
sim_panel_set_sampling_parameters_ex (PANEL *panel,
unsigned int sample_frequency,
unsigned int sample_dither_pct,
unsigned int sample_depth);
int int
sim_panel_set_sampling_parameters (PANEL *panel, sim_panel_set_sampling_parameters (PANEL *panel,
unsigned int sample_frequency, unsigned int sample_frequency,
unsigned int sample_depth); unsigned int sample_depth);
/** /**
When a front panel application needs to change the running When a front panel application needs to change the running