FRONTPANEL: sim_frontpanel API version 6 release
- Add dithering option to bit sampling
This commit is contained in:
parent
733ac0d982
commit
8551a2d477
4 changed files with 86 additions and 23 deletions
|
@ -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)) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue