diff --git a/frontpanel/FrontPanelTest.c b/frontpanel/FrontPanelTest.c index 349ac05a..abbe1e8b 100644 --- a/frontpanel/FrontPanelTest.c +++ b/frontpanel/FrontPanelTest.c @@ -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()); goto Done; } -if (!sim_panel_set_sampling_parameters (panel, 0, 199)) { - printf ("Unexpected success setting sampling parameters to 0, 199\n"); +if (!sim_panel_set_sampling_parameters_ex (panel, 0, 0, 199)) { + printf ("Unexpected success setting sampling parameters to 0, 0, 199\n"); goto Done; } -if (!sim_panel_set_sampling_parameters (panel, 199, 0)) { - printf ("Unexpected success setting sampling parameters to 199, 0\n"); +if (!sim_panel_set_sampling_parameters_ex (panel, 199, 0, 0)) { + printf ("Unexpected success setting sampling parameters to 199, 0, 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()); +if (!sim_panel_set_sampling_parameters_ex (panel, 500, 40, 100)) { + 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; } if (sim_panel_add_register_indirect_bits (panel, "PC", NULL, 32, PC_indirect_bits)) { diff --git a/sim_console.c b/sim_console.c index 1642cd0b..134d379f 100644 --- a/sim_console.c +++ b/sim_console.c @@ -503,6 +503,7 @@ struct REMOTE { t_bool repeat_pending; /* repeat delivery pending */ char *repeat_action; /* command(s) to repeatedly execute */ int smp_sample_interval; /* cycles between samples */ + int smp_sample_dither_pct; /* dithering of cycles interval */ uint32 smp_reg_count; /* sample register count */ BITSAMPLE_REG *smp_regs; /* registers being sampled */ }; @@ -614,7 +615,10 @@ for (i=connections=0; ismp_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: "); for (reg = 0; reg < rem->smp_reg_count; reg++) { 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) { char gbuf[CBUFSIZE]; -int32 samples, cycles; +int32 samples, cycles, dither_pct; t_bool all_stop = FALSE; t_stat stat = SCPE_OK; CONST char *cptr = *iptr; @@ -1073,6 +1077,7 @@ if ((stat != SCPE_OK) || (samples <= 0)) { /* error? */ } else { const char *tptr; + int32 event_time = rem->smp_sample_interval; cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */ if (MATCH_CMD (gbuf, "SAMPLES") != 0) { @@ -1095,6 +1100,23 @@ else { *iptr = cptr; 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 */ sim_rem_collect_cmd_setup (rem->line, &tptr); rem->smp_sample_interval = cycles; @@ -1167,7 +1189,9 @@ else { sim_rem_collect_cmd_setup (line, &cptr);/* Cleanup mess */ 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; return stat; @@ -1244,10 +1268,14 @@ 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); +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)) { + 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_activate (uptr, rem->smp_sample_interval); /* reschedule */ + sim_activate (uptr, event_time); /* reschedule */ } return SCPE_OK; } diff --git a/sim_frontpanel.c b/sim_frontpanel.c index 68d4f56b..384e33eb 100644 --- a/sim_frontpanel.c +++ b/sim_frontpanel.c @@ -166,6 +166,7 @@ struct PANEL { void *callback_context; int usecs_between_callbacks; unsigned int sample_frequency; + unsigned int sample_dither_pct; unsigned int sample_depth; int debug; 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_collect_prefix = "collect "; 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_echo = "# REGISTERS-DONE"; static const char *register_repeat_echo = "# REGISTERS-REPEAT-DONE"; @@ -550,9 +552,10 @@ for (i=0; ireg_count; i++) { } } 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)) { +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_mid2, panel->sample_dither_pct, + register_collect_mid3, buf)) { sim_panel_set_error ("Error establishing bit data collection:%s", response); free (response); free (buf); @@ -1312,23 +1315,40 @@ return 0; } int -sim_panel_set_sampling_parameters (PANEL *panel, - unsigned int sample_frequency, - unsigned int sample_depth) +sim_panel_set_sampling_parameters_ex (PANEL *panel, + unsigned int sample_frequency, + unsigned int sample_dither_pct, + unsigned int sample_depth) { if (sample_frequency == 0) { sim_panel_set_error ("Invalid sample frequency value: %u", sample_frequency); 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) { sim_panel_set_error ("Invalid sample depth value: %u", sample_depth); return -1; } panel->sample_frequency = sample_frequency; +panel->sample_dither_pct = sample_dither_pct; panel->sample_depth = sample_depth; 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 sim_panel_exec_halt (PANEL *panel) { @@ -1888,7 +1908,7 @@ static void * _panel_reader(void *arg) { PANEL *p = (PANEL*)arg; -REG *r = NULL; +REG *r; int sched_policy; struct sched_param sched_priority; char buf[4096]; @@ -1957,6 +1977,7 @@ while ((p->sock != INVALID_SOCKET) && s = buf; while ((eol = strchr (s, '\n'))) { /* Line to process */ + r = NULL; *eol++ = '\0'; while ((*s) && (s[strlen(s)-1] == '\r')) s[strlen(s)-1] = '\0'; diff --git a/sim_frontpanel.h b/sim_frontpanel.h index c3f46052..ea862450 100644 --- a/sim_frontpanel.h +++ b/sim_frontpanel.h @@ -56,7 +56,7 @@ extern "C" { #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 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. - The simulator binary must be built from the same version 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 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_ex 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 average for each bit sample. Returned bit sample values will range from 0 thru this value. */ +int +sim_panel_set_sampling_parameters_ex (PANEL *panel, + unsigned int sample_frequency, + unsigned int sample_dither_pct, + unsigned int sample_depth); + 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