diff --git a/doc/simh.doc b/doc/simh.doc index 4b0fe9be..725ff299 100644 Binary files a/doc/simh.doc and b/doc/simh.doc differ diff --git a/scp.c b/scp.c index 43679d68..41ccc98b 100644 --- a/scp.c +++ b/scp.c @@ -386,7 +386,7 @@ if (AIO_QUEUE_VAL != QUEUE_LIST_END) { /* List !Empty */ q = AIO_QUEUE_VAL; } while (q != AIO_QUEUE_SET(QUEUE_LIST_END, q)); while (q != QUEUE_LIST_END) { /* List !Empty */ - sim_debug (SIM_DBG_AIO_QUEUE, &sim_scp_dev, "Migrating Asynch event for %s after %d instructions\n", sim_uname(q), q->a_event_time); + sim_debug (SIM_DBG_AIO_QUEUE, &sim_scp_dev, "Migrating Asynch event for %s after %d %s\n", sim_uname(q), q->a_event_time, sim_vm_interval_units); ++migrated; uptr = q; q = q->a_next; @@ -414,7 +414,7 @@ return migrated; void sim_aio_activate (ACTIVATE_API caller, UNIT *uptr, int32 event_time) { AIO_ILOCK; -sim_debug (SIM_DBG_AIO_QUEUE, &sim_scp_dev, "Queueing Asynch event for %s after %d instructions\n", sim_uname(uptr), event_time); +sim_debug (SIM_DBG_AIO_QUEUE, &sim_scp_dev, "Queueing Asynch event for %s after %d %s\n", sim_uname(uptr), event_time, sim_vm_interval_units); if (uptr->a_next) { uptr->a_activate_call = sim_activate_abs; } @@ -430,7 +430,7 @@ else { AIO_IUNLOCK; sim_asynch_check = 0; /* try to force check */ if (sim_idle_wait) { - sim_debug (TIMER_DBG_IDLE, &sim_timer_dev, "waking due to event on %s after %d instructions\n", sim_uname(uptr), event_time); + sim_debug (TIMER_DBG_IDLE, &sim_timer_dev, "waking due to event on %s after %d %s\n", sim_uname(uptr), event_time, sim_vm_interval_units); pthread_cond_signal (&sim_asynch_wake); } } @@ -573,6 +573,8 @@ const char *sim_prog_name = NULL; /* pointer to the execut DEVICE *sim_dflt_dev = NULL; UNIT *sim_clock_queue = QUEUE_LIST_END; int32 sim_interval = 0; +const char *sim_vm_interval_units = "instructions"; /* Simulator can change to "cycles" as needed */ +const char *sim_vm_step_unit = "instruction"; /* Simulator can change */ int32 sim_switches = 0; int32 sim_switch_number = 0; FILE *sim_ofile = NULL; @@ -1031,11 +1033,11 @@ static const char simh_help[] = #define HLP_STEP "*Commands Running_A_Simulated_Program STEP" "3STEP\n" " The STEP command (abbreviated S) resumes execution at the current PC for\n" - " the number of instructions given by its argument. If no argument is\n" - " supplied, one instruction is executed.\n" + " the number of %Is given by its argument. If no argument is\n" + " supplied, one %I is executed.\n" "4Switches\n" " If the STEP command is invoked with the -T switch, the step command will\n" - " cause execution to run for microseconds rather than instructions.\n" + " cause execution to run for microseconds rather than %I.\n" #define HLP_NEXT "*Commands Running_A_Simulated_Program NEXT" "3NEXT\n" " The NEXT command (abbreviated N) resumes execution at the current PC for\n" @@ -1330,7 +1332,7 @@ static const char simh_help[] = "+SET NODEBUG disables any currently active debug output\n" "4Switches\n" " Debug message output contains a timestamp which indicates the number of\n" - " simulated instructions which have been executed prior to the debug event.\n\n" + " simulated %C which have been executed prior to the debug event.\n\n" " Debug message output can be enhanced to contain additional, potentially\n" " useful information.\n" "5-T\n" @@ -1374,17 +1376,17 @@ static const char simh_help[] = "3Throttle\n" " Simulator instruction execution rate can be controlled by specifying\n" " one of the following throttle commands:\n\n" - "+SET THROTTLE xM execute x million instructions per second\n" - "+SET THROTTLE xK execute x thousand instructions per second\n" + "+SET THROTTLE xM execute x million %C per second\n" + "+SET THROTTLE xK execute x thousand %C per second\n" "+SET THROTTLE x%% occupy x percent of the host capacity\n" "++++++++executing instructions\n" "+SET THROTTLE x/t sleep for t milliseconds after executing x\n" - "++++++++instructions\n\n" + "++++++++%C\n\n" "+SET NOTHROTTLE set simulation rate to maximum\n\n" " Throttling is only available on host systems that implement a precision\n" " real-time delay function.\n\n" " xM, xK and x%% modes require the simulator to execute sufficient\n" - " instructions to actually calibrate the desired execution rate relative\n" + " %C to actually calibrate the desired execution rate relative\n" " to wall clock time. Very short running programs may complete before\n" " calibration completes and therefore before the simulated execution rate\n" " can match the desired rate.\n\n" @@ -1406,7 +1408,7 @@ static const char simh_help[] = "+SET CLOCK catchup enable catchup clock ticks\n" "+SET CLOCK calib=n%% specify idle calibration skip %%\n" "+SET CLOCK calib=ALWAYS specify calibration independent of idle\n" - "+SET CLOCK stop=n stop execution after n instructions\n\n" + "+SET CLOCK stop=n stop execution after n %C\n\n" " The SET CLOCK STOP command allows execution to have a bound when\n" " execution starts with a BOOT, NEXT or CONTINUE command.\n" #define HLP_SET_ASYNCH "*Commands SET Asynch" @@ -2041,7 +2043,7 @@ static const char simh_help[] = " a multiplier of 1000 or 1000000 respectively\n" /***************** 80 character line width template *************************/ "4After\n" - " Specifies an integer (>=0) representing a minimal number of instructions\n" + " Specifies an integer (>=0) representing a minimal number of %C\n" " which must execute before the first character in the string is sent.\n" " The after parameter value can be set by itself with:\n\n" "++SEND AFTER=n\n\n" @@ -2072,7 +2074,7 @@ static const char simh_help[] = " Switches can be used to influence the behavior of SEND commands\n\n" "5-t\n" " The -t switch indicates that the Delay and After values are in\n" - " units of microseconds rather than instructions.\n" + " units of microseconds rather than %C.\n" /***************** 80 character line width template *************************/ #define HLP_EXPECT "*Commands Executing_Command_Files Reacting_To_Console_Output" /***************** 80 character line width template *************************/ @@ -2138,7 +2140,7 @@ static const char simh_help[] = " The -i switch is only valid for regular expression expect rules.\n" "5-t\n" " The -t switch indicates that the value specified by the HaltAfter\n" - " parameter are in units of microseconds rather than instructions.\n" + " parameter are in units of microseconds rather than %C.\n" "4Determining Which Output Matched\n" " When an expect rule matches data in the output stream, the rule which\n" " matched is recorded in the environment variable _EXPECT_MATCH_PATTERN.\n" @@ -2168,7 +2170,7 @@ static const char simh_help[] = " and hext character values of the form:\n" "++\\xh{h} where each h is a hex digit (0-9A-Fa-f)\n" "4HaltAfter\n" - " Specifies the number of instructions which should be executed before\n" + " Specifies the number of %C which should be executed before\n" " simulator instruction execution should stop. The default is to stop\n" " executing instructions immediately (i.e. HALTAFTER=0).\n" " The default HaltAfter delay, once set, persists for all expect behaviors\n" @@ -6176,14 +6178,14 @@ memset (&buf, 0, sizeof (buf)); if (cptr && (*cptr != 0)) return SCPE_2MARG; if (sim_clock_queue == QUEUE_LIST_END) - fprintf (st, "%s event queue empty, time = %.0f, executing %s instructios/sec\n", - sim_name, sim_time, sim_fmt_numeric (sim_timer_inst_per_sec ())); + fprintf (st, "%s event queue empty, time = %.0f, executing %s %s/sec\n", + sim_name, sim_time, sim_fmt_numeric (sim_timer_inst_per_sec ()), sim_vm_interval_units); else { const char *tim = ""; double inst_per_sec = sim_timer_inst_per_sec (); - fprintf (st, "%s event queue status, time = %.0f, executing %s instructions/sec\n", - sim_name, sim_time, sim_fmt_numeric (inst_per_sec)); + fprintf (st, "%s event queue status, time = %.0f, executing %s %s/sec\n", + sim_name, sim_time, sim_fmt_numeric (inst_per_sec), sim_vm_interval_units); for (uptr = sim_clock_queue; uptr != QUEUE_LIST_END; uptr = uptr->next) { if (uptr == &sim_step_unit) fprintf (st, " Step timer"); @@ -6229,7 +6231,7 @@ else { } } fprintf (st, "asynch latency: %d nanoseconds\n", sim_asynch_latency); -fprintf (st, "asynch instruction latency: %d instructions\n", sim_asynch_inst_latency); +fprintf (st, "asynch instruction latency: %d %s\n", sim_asynch_inst_latency, sim_vm_interval_units); pthread_mutex_unlock (&sim_asynch_lock); sim_mfile = NULL; fprintf (st, "%*.*s", (int)buf.pos, (int)buf.pos, buf.buf); @@ -12365,7 +12367,7 @@ if (exp->buf_size) { fprintf (st, " Buffer Insert Offset: %d\n", exp->buf_ins); fprintf (st, " Buffer Contents: %s\n", bstr); if (default_haltafter) - fprintf (st, " Default HaltAfter: %u instructions\n", (unsigned)default_haltafter); + fprintf (st, " Default HaltAfter: %u %s\n", (unsigned)default_haltafter, sim_vm_interval_units); free (bstr); } if (exp->dptr && (exp->dbit & exp->dptr->dctrl)) @@ -12629,19 +12631,19 @@ else fprintf (st, " No Pending Input Data\n"); if ((snd->next_time - sim_gtime()) > 0) { if (((snd->next_time - sim_gtime()) > (sim_timer_inst_per_sec()/1000000.0)) && ((sim_timer_inst_per_sec()/1000000.0) > 0.0)) - fprintf (st, " Minimum of %d instructions (%d microseconds) before sending first character\n", (int)(snd->next_time - sim_gtime()), + fprintf (st, " Minimum of %d %s (%d microseconds) before sending first character\n", (int)(snd->next_time - sim_gtime()), sim_vm_interval_units, (int)((snd->next_time - sim_gtime())/(sim_timer_inst_per_sec()/1000000.0))); else - fprintf (st, " Minimum of %d instructions before sending first character\n", (int)(snd->next_time - sim_gtime())); + fprintf (st, " Minimum of %d %s before sending first character\n", (int)(snd->next_time - sim_gtime()), sim_vm_interval_units); } if ((snd->delay > (sim_timer_inst_per_sec()/1000000.0)) && ((sim_timer_inst_per_sec()/1000000.0) > 0.0)) - fprintf (st, " Minimum of %d instructions (%d microseconds) between characters\n", (int)snd->delay, (int)(snd->delay/(sim_timer_inst_per_sec()/1000000.0))); + fprintf (st, " Minimum of %d %s (%d microseconds) between characters\n", (int)snd->delay, sim_vm_interval_units, (int)(snd->delay/(sim_timer_inst_per_sec()/1000000.0))); else - fprintf (st, " Minimum of %d instructions between characters\n", (int)snd->delay); + fprintf (st, " Minimum of %d %s between characters\n", (int)snd->delay, sim_vm_interval_units); if (after) - fprintf (st, " Default delay before first character input is %u instructions\n", after); + fprintf (st, " Default delay before first character input is %u %s\n", after, sim_vm_interval_units); if (delay) - fprintf (st, " Default delay between character input is %u instructions\n", after); + fprintf (st, " Default delay between character input is %u %s\n", after, sim_vm_interval_units); if (snd->dptr && (snd->dbit & snd->dptr->dctrl)) fprintf (st, " Send Debugging via: SET %s DEBUG%s%s\n", sim_dname(snd->dptr), snd->dptr->debflags ? "=" : "", snd->dptr->debflags ? _get_dbg_verb (snd->dbit, snd->dptr, NULL) : ""); return SCPE_OK; @@ -13605,6 +13607,12 @@ for (hblock = astrings; (htext = *hblock) != NULL; hblock++) { case 'S': appendText (topic, sim_name, strlen (sim_name)); break; + case 'C': + appendText (topic, sim_vm_interval_units, strlen (sim_vm_interval_units)); + break; + case 'I': + appendText (topic, sim_vm_step_unit, strlen (sim_vm_step_unit)); + break; case '%': appendText (topic, "%", 1); break; diff --git a/scp.h b/scp.h index 120145d6..d9706124 100644 --- a/scp.h +++ b/scp.h @@ -365,6 +365,7 @@ extern int32 sim_switches; extern int32 sim_switch_number; extern int32 sim_quiet; extern int32 sim_step; +extern const char *sim_vm_step_units; /* Simulator can change this */ extern t_stat sim_last_cmd_stat; /* Command Status */ extern FILE *sim_log; /* log file */ extern FILEREF *sim_log_ref; /* log file file reference */ @@ -429,6 +430,7 @@ extern t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason); extern t_value (*sim_vm_pc_value) (void); extern t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs); extern const char **sim_clock_precalibrate_commands; +extern const char *sim_vm_interval_units; /* Core SCP libraries can potentially have unit test routines. diff --git a/scp_help.h b/scp_help.h index 19b46137..7b9504c2 100644 --- a/scp_help.h +++ b/scp_help.h @@ -47,6 +47,8 @@ * * %D - Inserts the name of the device (e.g. "DTA"). * * %U - Inserts the name of the unit (e.g. "DTA0"). * * %S - Inserts the current simulator name (e.g. "PDP-10") + * * %C - Inserts the current value of the sim_vm_interval_units string + * * %I - Inserts the current value of the sim_vm_step_units string * * %#s - Inserts the string suppled in the "#"th optional argument to the help * routine. # starts with 1. Any embedded newlines will cause following * text to be indented. diff --git a/sim_timer.c b/sim_timer.c index 61a5cae1..4684c840 100644 --- a/sim_timer.c +++ b/sim_timer.c @@ -1706,9 +1706,9 @@ if (w_ms > 1000) /* too long a wait (runa sim_debug (DBG_TIK, &sim_timer_dev, "waiting too long: w_ms=%d usecs, w_idle=%d usecs, sim_interval=%d, rtc->currd=%d\n", w_ms, w_idle, sim_interval, rtc->currd); in_nowait = FALSE; if (sim_clock_queue == QUEUE_LIST_END) - sim_debug (DBG_IDL, &sim_timer_dev, "sleeping for %d ms - pending event in %d instructions\n", w_ms, sim_interval); + sim_debug (DBG_IDL, &sim_timer_dev, "sleeping for %d ms - pending event in %d %s\n", w_ms, sim_interval, sim_vm_interval_units); else - sim_debug (DBG_IDL, &sim_timer_dev, "sleeping for %d ms - pending event on %s in %d instructions\n", w_ms, sim_uname(sim_clock_queue), sim_interval); + sim_debug (DBG_IDL, &sim_timer_dev, "sleeping for %d ms - pending event on %s in %d %s\n", w_ms, sim_uname(sim_clock_queue), sim_interval, sim_vm_interval_units); cyc_since_idle = sim_gtime() - sim_idle_end_time; /* time since prior idle */ act_ms = sim_idle_ms_sleep (w_ms); /* wait */ rtc->clock_time_idled += act_ms; @@ -1720,9 +1720,9 @@ else sim_interval = sim_interval - act_cyc; /* count down sim_interval to reflect idle period */ sim_idle_end_time = sim_gtime(); /* save idle completed time */ if (sim_clock_queue == QUEUE_LIST_END) - sim_debug (DBG_IDL, &sim_timer_dev, "slept for %d ms - pending event in %d instructions\n", act_ms, sim_interval); + sim_debug (DBG_IDL, &sim_timer_dev, "slept for %d ms - pending event in %d %s\n", act_ms, sim_interval, sim_vm_interval_units); else - sim_debug (DBG_IDL, &sim_timer_dev, "slept for %d ms - pending event on %s in %d instructions\n", act_ms, sim_uname(sim_clock_queue), sim_interval); + sim_debug (DBG_IDL, &sim_timer_dev, "slept for %d ms - pending event on %s in %d %s\n", act_ms, sim_uname(sim_clock_queue), sim_interval, sim_vm_interval_units); return TRUE; } @@ -1976,8 +1976,8 @@ switch (sim_throt_state) { sim_set_throt (0, NULL); /* disable throttling */ return SCPE_OK; } - sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Not enough time. %d ms executing %.f instructions.\n", - (int)delta_ms, delta_inst); + sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Not enough time. %d ms executing %.f %s.\n", + (int)delta_ms, delta_inst, sim_vm_interval_units); sim_throt_wait = (int32)(delta_inst * SIM_THROT_WMUL); sim_throt_inst_start = sim_gtime(); sim_idle_ms_sleep (sim_idle_rate_ms); /* start on a tick boundart to calibrate */ @@ -1997,8 +1997,8 @@ switch (sim_throt_state) { a_cps, d_cps); sim_throt_state = SIM_THROT_STATE_INIT; sim_printf ("*********** WARNING ***********\n"); - sim_printf ("Host CPU is too slow to simulate %s instructions per second\n", sim_fmt_numeric(d_cps)); - sim_printf ("Host CPU can only simulate %s instructions per second\n", sim_fmt_numeric(sim_throt_peak_cps)); + sim_printf ("Host CPU is too slow to simulate %s %s per second\n", sim_fmt_numeric(d_cps), sim_vm_interval_units); + sim_printf ("Host CPU can only simulate %s %s per second\n", sim_fmt_numeric(sim_throt_peak_cps), sim_vm_interval_units); sim_printf ("Throttling disabled.\n"); sim_set_throt (0, NULL); return SCPE_OK; @@ -2993,7 +2993,7 @@ else { } rtc = &rtcs[tmr]; if ((NULL == rtc->clock_unit) || (rtc->hz == 0)) { - sim_debug (DBG_TIM, &sim_timer_dev, "sim_clock_coschedule_tmr(%s, tmr=%d, ticks=%d) - no clock activating after %d instructions\n", sim_uname (uptr), tmr, ticks, ticks * (rtc->currd ? rtc->currd : rtcs[sim_rtcn_calibrated_tmr ()].currd)); + sim_debug (DBG_TIM, &sim_timer_dev, "sim_clock_coschedule_tmr(%s, tmr=%d, ticks=%d) - no clock activating after %d %s\n", sim_uname (uptr), tmr, ticks, ticks * (rtc->currd ? rtc->currd : rtcs[sim_rtcn_calibrated_tmr ()].currd), sim_vm_interval_units); return sim_activate (uptr, ticks * (rtc->currd ? rtc->currd : rtcs[sim_rtcn_calibrated_tmr ()].currd)); } else {