mirror of
https://github.com/rcornwell/sims.git
synced 2026-03-29 02:55:02 +00:00
SCP: Updated to current.
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BuildROMs", "BuildROMs.vcproj", "{D40F3AF1-EEE7-4432-9807-2AD287B490F8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "B5500", "B5500.vcproj", "{BA514FA1-D029-4D25-91CC-255E5953FF6E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||
|
||||
2
makefile
2
makefile
@@ -149,7 +149,7 @@ find_exe = $(abspath $(strip $(firstword $(foreach dir,$(strip $(subst :, ,${PAT
|
||||
find_lib = $(abspath $(strip $(firstword $(foreach dir,$(strip ${LIBPATH}),$(wildcard $(dir)/lib$(1).${LIBEXT})))))
|
||||
find_include = $(abspath $(strip $(firstword $(foreach dir,$(strip ${INCPATH}),$(wildcard $(dir)/$(1).h)))))
|
||||
ifneq (0,$(TESTS))
|
||||
find_test = RegisterSanityCheck $(abspath $(wildcard $(1)/tests/$(2)_test.ini))
|
||||
find_test = RegisterSanityCheck $(abspath $(wildcard $(1)/tests/$(2)_test.ini)) </dev/null
|
||||
TESTING_FEATURES = - Per simulator tests will be run
|
||||
else
|
||||
TESTING_FEATURES = - Per simulator tests will be skipped
|
||||
|
||||
136
scp.c
136
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"
|
||||
@@ -1116,7 +1118,7 @@ static const char simh_help[] =
|
||||
" diagnostic which didn't achieve explicit success or failure within\n"
|
||||
" some user specified time. The RUNLIMIT command provides ways to\n"
|
||||
" limit execution.\n\n"
|
||||
"++RUNLIMIT n {CYCLES|MICROSECONDS|SECONDS|MINUTES|HOURS}\n"
|
||||
"++RUNLIMIT n {%C|MICROSECONDS|SECONDS|MINUTES|HOURS}\n"
|
||||
"++NORUNLIMIT\n\n"
|
||||
" Equivalently:\n\n"
|
||||
"++SET RUNLIMIT n {CYCLES|MICROSECONDS|SECONDS|MINUTES|HOURS}\n"
|
||||
@@ -1124,7 +1126,7 @@ static const char simh_help[] =
|
||||
" The run limit state can be examined with:\n\n"
|
||||
"++SHOW RUNLIMIT\n\n"
|
||||
" If the units of the run limit are not specified, the default units are\n"
|
||||
" cycles. Once an execution run limit has beenn reached, any subsequent\n"
|
||||
" %C. Once an execution run limit has beenn reached, any subsequent\n"
|
||||
" GO, RUN, CONTINUE, STEP or BOOT commands will cause the simulator to\n"
|
||||
" exit. A previously defined RUNLIMIT can be cleared with the NORUNLIMIT\n"
|
||||
" command or the establishment of a new run limit.\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"
|
||||
@@ -2582,7 +2584,7 @@ return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
t_stat process_stdin_commands (t_stat stat, char *argv[]);
|
||||
t_stat process_stdin_commands (t_stat stat, char *argv[], t_bool do_called);
|
||||
|
||||
/* Main command loop */
|
||||
|
||||
@@ -2679,7 +2681,8 @@ if (sim_emax <= 0)
|
||||
sim_emax = 1;
|
||||
if (sim_timer_init ()) {
|
||||
fprintf (stderr, "Fatal timer initialization error\n");
|
||||
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||
if (sim_ttisatty())
|
||||
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
sim_register_internal_device (&sim_scp_dev);
|
||||
@@ -2703,13 +2706,6 @@ if ((sim_eval = (t_value *) calloc (sim_emax, sizeof (t_value))) == NULL) {
|
||||
};
|
||||
if (sim_dflt_dev == NULL) /* if no default */
|
||||
sim_dflt_dev = sim_devices[0];
|
||||
if (sim_timer_init ()) {
|
||||
fprintf (stderr, "Fatal timer initialization error\n");
|
||||
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
/* Invoke power reset again in case some devices depend on timer
|
||||
initialization having occurred */
|
||||
if ((stat = reset_all_p (0)) != SCPE_OK) {
|
||||
fprintf (stderr, "Fatal simulator initialization error\n%s\n",
|
||||
sim_error_text (stat));
|
||||
@@ -2795,7 +2791,7 @@ if (SCPE_BARE_STATUS(stat) == SCPE_OPENERR) /* didn't exist/can't op
|
||||
stat = SCPE_OK;
|
||||
|
||||
if (SCPE_BARE_STATUS(stat) != SCPE_EXIT)
|
||||
process_stdin_commands (SCPE_BARE_STATUS(stat), argv);
|
||||
process_stdin_commands (SCPE_BARE_STATUS(stat), argv, FALSE);
|
||||
|
||||
detach_all (0, TRUE); /* close files */
|
||||
sim_set_deboff (0, NULL); /* close debug */
|
||||
@@ -2810,7 +2806,7 @@ free (targv); /* release any argv copy
|
||||
return sim_exit_status;
|
||||
}
|
||||
|
||||
t_stat process_stdin_commands (t_stat stat, char *argv[])
|
||||
t_stat process_stdin_commands (t_stat stat, char *argv[], t_bool do_called)
|
||||
{
|
||||
char cbuf[4*CBUFSIZE], gbuf[CBUFSIZE];
|
||||
CONST char *cptr;
|
||||
@@ -2866,8 +2862,11 @@ while (stat != SCPE_EXIT) { /* in case exit */
|
||||
}
|
||||
cptr = get_glyph_cmd (cptr, gbuf); /* get command glyph */
|
||||
sim_switches = 0; /* init switches */
|
||||
if ((cmdp = find_cmd (gbuf))) /* lookup command */
|
||||
if ((cmdp = find_cmd (gbuf))) { /* lookup command */
|
||||
if (do_called && (cmdp->action == &return_cmd)) /* RETURN command? */
|
||||
break;
|
||||
stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */
|
||||
}
|
||||
else
|
||||
stat = SCPE_UNK;
|
||||
stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */
|
||||
@@ -2884,6 +2883,14 @@ while (stat != SCPE_EXIT) { /* in case exit */
|
||||
if (sim_vm_post != NULL)
|
||||
(*sim_vm_post) (TRUE);
|
||||
} /* end while */
|
||||
if (do_called && cmdp &&
|
||||
(cmdp->action == &return_cmd) && (0 != *cptr)) { /* return command with argument? */
|
||||
sim_string_to_stat (cptr, &stat);
|
||||
sim_last_cmd_stat = stat; /* save explicit status as command error status */
|
||||
if (sim_switches & SWMASK ('Q'))
|
||||
stat |= SCPE_NOMESSAGE; /* suppress error message display (in caller) if requested */
|
||||
return stat; /* return with explicit return status */
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
@@ -3656,7 +3663,7 @@ t_stat do_cmd_label (int32 flag, CONST char *fcptr, CONST char *label)
|
||||
{
|
||||
char cbuf[4*CBUFSIZE], gbuf[CBUFSIZE], abuf[4*CBUFSIZE], quote, *c, *do_arg[11];
|
||||
CONST char *cptr;
|
||||
FILE *fpin;
|
||||
FILE *fpin = NULL;
|
||||
CTAB *cmdp = NULL;
|
||||
int32 echo, nargs, errabort, i;
|
||||
int32 saved_sim_do_echo = sim_do_echo,
|
||||
@@ -3699,7 +3706,8 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */
|
||||
|
||||
if (do_arg [0] == NULL) /* need at least 1 */
|
||||
return SCPE_2FARG;
|
||||
if ((fpin = fopen (do_arg[0], "r")) == NULL) { /* file failed to open? */
|
||||
if ((strcasecmp (do_arg[0], "<stdin>") != 0) &&
|
||||
((fpin = fopen (do_arg[0], "r")) == NULL)) { /* file failed to open? */
|
||||
strlcpy (cbuf, do_arg[0], sizeof (cbuf)); /* try again with .sim extension */
|
||||
strlcat (cbuf, ".sim", sizeof (cbuf));
|
||||
if ((fpin = fopen (cbuf, "r")) == NULL) { /* failed a second time? */
|
||||
@@ -3758,6 +3766,11 @@ if (label) {
|
||||
if (errabort) /* -e flag? */
|
||||
set_on (1, NULL); /* equivalent to ON ERROR RETURN */
|
||||
|
||||
if (strcasecmp (do_arg[0], "<stdin>") == 0) {
|
||||
stat = process_stdin_commands (SCPE_OK, do_arg, TRUE);
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
|
||||
do {
|
||||
if (stop_cpu) { /* SIGINT? */
|
||||
if (sim_on_actions[sim_do_depth][ON_SIGINT_ACTION]) {
|
||||
@@ -3872,7 +3885,8 @@ do {
|
||||
(*sim_vm_post) (TRUE);
|
||||
} while (staying);
|
||||
Cleanup_Return:
|
||||
fclose (fpin); /* close file */
|
||||
if (fpin)
|
||||
fclose (fpin); /* close file */
|
||||
sim_gotofile = NULL;
|
||||
if (flag >= 0) {
|
||||
sim_do_echo = saved_sim_do_echo; /* restore echo state we entered with */
|
||||
@@ -6169,14 +6183,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");
|
||||
@@ -6222,7 +6236,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);
|
||||
@@ -6954,7 +6968,7 @@ if ((r != SCPE_OK) || (num == 0)) /* error? */
|
||||
return sim_messagef (SCPE_ARG, "Invalid argument: %s\n", gbuf);
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
||||
if ((gbuf[0] == '\0') ||
|
||||
(MATCH_CMD (gbuf, "CYCLES") == 0))
|
||||
(MATCH_CMD (gbuf, sim_vm_interval_units) == 0))
|
||||
sim_switches &= ~SWMASK ('T');
|
||||
else {
|
||||
int i;
|
||||
@@ -7017,14 +7031,14 @@ if (sim_runlimit_enabled) {
|
||||
}
|
||||
else {
|
||||
if (sim_runlimit_initial != sim_runlimit) {
|
||||
fprintf (st, "%d cycles initially, ", sim_runlimit_initial);
|
||||
fprintf (st, "%d %s initially, ", sim_runlimit_initial, sim_vm_interval_units);
|
||||
if (sim_is_active (&sim_runlimit_unit))
|
||||
fprintf (st, "and %d cycles remaining\n", sim_activate_time (&sim_runlimit_unit));
|
||||
fprintf (st, "and %d %s remaining\n", sim_activate_time (&sim_runlimit_unit), sim_vm_interval_units);
|
||||
else
|
||||
fprintf (st, "expired now\n");
|
||||
}
|
||||
else
|
||||
fprintf (st, "%d cycles\n", sim_runlimit_initial);
|
||||
fprintf (st, "%d %s\n", sim_runlimit_initial, sim_vm_interval_units);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -12358,7 +12372,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))
|
||||
@@ -12622,19 +12636,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;
|
||||
@@ -13598,6 +13612,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;
|
||||
@@ -15087,9 +15107,9 @@ free (f);
|
||||
|
||||
static t_stat sim_sanity_check_register_declarations (void)
|
||||
{
|
||||
t_stat stat = SCPE_OK;
|
||||
int i;
|
||||
DEVICE *dptr;
|
||||
t_stat stat = SCPE_OK;
|
||||
MFILE *f = MOpen ();
|
||||
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
@@ -15149,13 +15169,19 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
}
|
||||
if ((rptr->obj_size != 0) && (rptr->ele_size != 0) && (rptr->depth != 0) && (rptr->macro != NULL)) {
|
||||
if (rptr->flags & REG_UNIT) {
|
||||
if (rptr->depth > udptr->numunits) {
|
||||
if (udptr == NULL) {
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\tthe depth of the UNIT array exceeds the number of units on the %s device which is %u\n", dptr->name, udptr->numunits);
|
||||
Mprintf (f, "\tthe indicated UNIT can't be found for this $u depth array\n", rptr->depth);
|
||||
}
|
||||
if (rptr->obj_size > sizeof (t_value)) {
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\t%u is larger than the size of the t_value type (%u)\n", (uint32)rptr->obj_size, (uint32)sizeof (t_value));
|
||||
else {
|
||||
if (rptr->depth > udptr->numunits) {
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\tthe depth of the UNIT array exceeds the number of units on the %s device which is %u\n", dptr->name, udptr->numunits);
|
||||
}
|
||||
if (rptr->obj_size > sizeof (t_value)) {
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\t%u is larger than the size of the t_value type (%u)\n", (uint32)rptr->obj_size, (uint32)sizeof (t_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
2
scp.h
2
scp.h
@@ -429,6 +429,8 @@ 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; /* Simulator can change this - default "instructions" */
|
||||
extern const char *sim_vm_step_unit; /* Simulator can change this - default "instruction" */
|
||||
|
||||
|
||||
/* Core SCP libraries can potentially have unit test routines.
|
||||
|
||||
@@ -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_unit 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.
|
||||
|
||||
@@ -639,9 +639,9 @@ for (i=connections=0; i<sim_rem_con_tmxr.lines; i++) {
|
||||
DEVICE *dptr = NULL;
|
||||
|
||||
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);
|
||||
fprintf (st, "Register Bit Sampling is occurring every %d %s (dithered %d percent)\n", rem->smp_sample_interval, sim_vm_interval_units, rem->smp_sample_dither_pct);
|
||||
else
|
||||
fprintf (st, "Register Bit Sampling is occurring every %d cycles\n", rem->smp_sample_interval);
|
||||
fprintf (st, "Register Bit Sampling is occurring every %d %s\n", rem->smp_sample_interval, sim_vm_interval_units);
|
||||
fprintf (st, " Registers being sampled are: ");
|
||||
for (reg = 0; reg < rem->smp_reg_count; reg++) {
|
||||
if (rem->smp_regs[reg].indirect)
|
||||
|
||||
31
sim_ether.c
31
sim_ether.c
@@ -1653,7 +1653,9 @@ static int _eth_get_system_id (char *buf, size_t buf_size)
|
||||
#endif
|
||||
if ((status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_QUERY_VALUE|KEY_WOW64_64KEY, ®hnd)) != ERROR_SUCCESS)
|
||||
return -1;
|
||||
reglen = buf_size;
|
||||
if (buf_size < 37)
|
||||
return -1;
|
||||
reglen = buf_size - 1;
|
||||
if ((status = RegQueryValueExA (reghnd, "MachineGuid", NULL, ®type, (LPBYTE)buf, ®len)) != ERROR_SUCCESS) {
|
||||
RegCloseKey (reghnd);
|
||||
return -1;
|
||||
@@ -1672,19 +1674,16 @@ static int _eth_get_system_id (char *buf, size_t buf_size)
|
||||
FILE *f;
|
||||
|
||||
memset (buf, 0, buf_size);
|
||||
if ((f = fopen ("/etc/machine-id", "r"))) {
|
||||
if (fread (buf, 1, buf_size - 1, f))
|
||||
fclose (f);
|
||||
else
|
||||
fclose (f);
|
||||
}
|
||||
else {
|
||||
if ((f = popen ("hostname", "r"))) {
|
||||
if (fread (buf, 1, buf_size - 1, f))
|
||||
pclose (f);
|
||||
else
|
||||
pclose (f);
|
||||
}
|
||||
if (buf_size < 37)
|
||||
return -1;
|
||||
if ((f = fopen ("/etc/machine-id", "r")) == NULL)
|
||||
f = popen ("hostname", "r");
|
||||
if (f) {
|
||||
size_t read_size;
|
||||
|
||||
read_size = fread (buf, 1, buf_size - 1, f);
|
||||
buf[read_size] = '\0';
|
||||
fclose (f);
|
||||
}
|
||||
while ((strlen (buf) > 0) && sim_isspace(buf[strlen (buf) - 1]))
|
||||
buf[strlen (buf) - 1] = '\0';
|
||||
@@ -2073,7 +2072,7 @@ if (0 == strncmp("tap:", savname, 4)) {
|
||||
strcpy(savname, devname);
|
||||
}
|
||||
#if defined (__APPLE__)
|
||||
if (1) {
|
||||
if (tun < 0) { /* Not good yet? */
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
|
||||
@@ -3840,7 +3839,7 @@ else
|
||||
/* test reflections. This is done early in this routine since eth_reflect */
|
||||
/* calls eth_filter recursively and thus changes the state of the device. */
|
||||
if (dev->reflections == -1)
|
||||
eth_reflect(dev);
|
||||
status = eth_reflect(dev);
|
||||
|
||||
/* set new filter addresses */
|
||||
for (i = 0; i < addr_count; i++)
|
||||
|
||||
@@ -381,6 +381,11 @@ t_stat ethq_destroy(ETH_QUE* que); /* release FIFO queue */
|
||||
const char *eth_capabilities(void);
|
||||
t_stat sim_ether_test (DEVICE *dptr); /* unit test routine */
|
||||
|
||||
#if !defined(SIM_TEST_INIT) /* Need stubs for test APIs */
|
||||
#define SIM_TEST_INIT
|
||||
#define SIM_TEST(xxx)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
73
sim_timer.c
73
sim_timer.c
@@ -943,9 +943,9 @@ if (rtc->hz != ticksper) { /* changing tick rate? */
|
||||
(rtc->last_hz != ticksper) &&
|
||||
(ticksper != 0))
|
||||
rtc->currd = (int32)(sim_timer_inst_per_sec () / ticksper);
|
||||
_rtcn_configure_calibrated_clock (tmr);
|
||||
rtc->last_hz = rtc->hz;
|
||||
rtc->hz = ticksper;
|
||||
_rtcn_configure_calibrated_clock (tmr);
|
||||
if (ticksper != 0) {
|
||||
RTC *crtc = &rtcs[sim_calb_tmr];
|
||||
|
||||
@@ -1124,12 +1124,18 @@ int tmr;
|
||||
uint32 clock_start, clock_last, clock_now;
|
||||
|
||||
sim_debug (DBG_TRC, &sim_timer_dev, "sim_timer_init()\n");
|
||||
/* Clear the event queue before initializing the timer subsystem */
|
||||
while (sim_clock_queue != QUEUE_LIST_END)
|
||||
sim_cancel (sim_clock_queue);
|
||||
for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
|
||||
RTC *rtc = &rtcs[tmr];
|
||||
|
||||
rtc->timer_unit = &sim_timer_units[tmr];
|
||||
rtc->timer_unit->action = &sim_timer_tick_svc;
|
||||
rtc->timer_unit->flags = UNIT_DIS | UNIT_IDLE;
|
||||
if (rtc->clock_cosched_queue)
|
||||
while (rtc->clock_cosched_queue != QUEUE_LIST_END)
|
||||
sim_cancel (rtc->clock_cosched_queue);
|
||||
rtc->clock_cosched_queue = QUEUE_LIST_END;
|
||||
}
|
||||
sim_stop_unit.action = &sim_timer_stop_svc;
|
||||
@@ -1188,7 +1194,7 @@ fprintf (st, "Minimum Host Sleep Time: %d ms (%dHz)\n", sim_os_sleep_min_
|
||||
if (sim_os_sleep_min_ms != sim_os_sleep_inc_ms)
|
||||
fprintf (st, "Minimum Host Sleep Incr Time: %d ms\n", sim_os_sleep_inc_ms);
|
||||
fprintf (st, "Host Clock Resolution: %d ms\n", sim_os_clock_resoluton_ms);
|
||||
fprintf (st, "Execution Rate: %s cycles/sec\n", sim_fmt_numeric (inst_per_sec));
|
||||
fprintf (st, "Execution Rate: %s %s/sec\n", sim_fmt_numeric (inst_per_sec), sim_vm_interval_units);
|
||||
if (sim_idle_enab) {
|
||||
fprintf (st, "Idling: Enabled\n");
|
||||
fprintf (st, "Time before Idling starts: %d seconds\n", sim_idle_stable);
|
||||
@@ -1638,10 +1644,10 @@ if ((!sim_idle_enab) || /* idling disabled */
|
||||
((sim_clock_queue != QUEUE_LIST_END) && /* or clock queue not empty */
|
||||
((sim_clock_queue->flags & UNIT_IDLE) == 0))|| /* and event not idle-able? */
|
||||
(rtc->elapsed < sim_idle_stable)) { /* or calibrated timer not stable? */
|
||||
sim_debug (DBG_IDL, &sim_timer_dev, "Can't idle: %s - elapsed: %d.%03d\n", !sim_idle_enab ? "idle disabled" :
|
||||
sim_debug (DBG_IDL, &sim_timer_dev, "Can't idle: %s - elapsed: %d and %d/%d\n", !sim_idle_enab ? "idle disabled" :
|
||||
((rtc->elapsed < sim_idle_stable) ? "not stable" :
|
||||
((sim_clock_queue != QUEUE_LIST_END) ? sim_uname (sim_clock_queue) :
|
||||
"")), rtc->elapsed, rtc->ticks);
|
||||
"")), rtc->elapsed, rtc->ticks, rtc->hz);
|
||||
sim_interval -= sin_cyc;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1700,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;
|
||||
@@ -1714,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;
|
||||
}
|
||||
|
||||
@@ -1838,21 +1844,21 @@ else {
|
||||
switch (sim_throt_type) {
|
||||
|
||||
case SIM_THROT_MCYC:
|
||||
fprintf (st, "Throttle: %d megacycles\n", sim_throt_val);
|
||||
fprintf (st, "Throttle: %d mega%s\n", sim_throt_val, sim_vm_interval_units);
|
||||
if (sim_throt_wait)
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d cycles\n", sim_throt_sleep_time, sim_throt_wait);
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d %s\n", sim_throt_sleep_time, sim_throt_wait, sim_vm_interval_units);
|
||||
break;
|
||||
|
||||
case SIM_THROT_KCYC:
|
||||
fprintf (st, "Throttle: %d kilocycles\n", sim_throt_val);
|
||||
fprintf (st, "Throttle: %d kilo%s\n", sim_throt_val, sim_vm_interval_units);
|
||||
if (sim_throt_wait)
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d cycles\n", sim_throt_sleep_time, sim_throt_wait);
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d %s\n", sim_throt_sleep_time, sim_throt_wait, sim_vm_interval_units);
|
||||
break;
|
||||
|
||||
case SIM_THROT_PCT:
|
||||
if (sim_throt_wait) {
|
||||
fprintf (st, "Throttle: %d%% of %s cycles per second\n", sim_throt_val, sim_fmt_numeric (sim_throt_peak_cps));
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d cycles\n", sim_throt_sleep_time, sim_throt_wait);
|
||||
fprintf (st, "Throttle: %d%% of %s %s per second\n", sim_throt_val, sim_fmt_numeric (sim_throt_peak_cps), sim_vm_interval_units);
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d %s\n", sim_throt_sleep_time, sim_throt_wait, sim_vm_interval_units);
|
||||
}
|
||||
else
|
||||
fprintf (st, "Throttle: %d%%\n", sim_throt_val);
|
||||
@@ -1860,7 +1866,7 @@ else {
|
||||
|
||||
case SIM_THROT_SPC:
|
||||
fprintf (st, "Throttle: %d/%d\n", sim_throt_val, sim_throt_sleep_time);
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d cycles\n", sim_throt_sleep_time, sim_throt_val);
|
||||
fprintf (st, "Throttling by sleeping for: %d ms every %d %s\n", sim_throt_sleep_time, sim_throt_val, sim_vm_interval_units);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1970,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 */
|
||||
@@ -1991,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;
|
||||
@@ -2451,6 +2457,16 @@ return SCPE_OK;
|
||||
clock with an appropriate tick rate, an internal clock is run that meets
|
||||
this requirement, OR when asynch clocks are enabled, the internal clock
|
||||
is always run.
|
||||
|
||||
Some simulators have clocks that have dynamically programmable tick
|
||||
rates. Such a clock is only a reliable candidate to be the calibrated
|
||||
clock if it uses a single tick rate rather than changing the tick rate
|
||||
on the fly. Generally most systems like this, under normal conditions
|
||||
don't change their tick rates unless they're running something that is
|
||||
examining the behavior of the clock system (like a diagnostic). Under
|
||||
these conditions this clock is removed from the potential selection as
|
||||
"the" calibrated clock all others are relative to and if necessary, an
|
||||
internal calibrated clock is selected.
|
||||
*/
|
||||
static void _rtcn_configure_calibrated_clock (int32 newtmr)
|
||||
{
|
||||
@@ -2461,9 +2477,11 @@ RTC *rtc, *crtc;
|
||||
sim_int_clk_tps = MIN(CLK_TPS, sim_os_tick_hz);
|
||||
for (tmr=0; tmr<SIM_NTIMERS; tmr++) {
|
||||
rtc = &rtcs[tmr];
|
||||
if ((rtc->hz) &&
|
||||
(rtc->hz <= (uint32)sim_os_tick_hz) &&
|
||||
(rtc->clock_unit))
|
||||
if ((rtc->hz) && /* is calibrated AND */
|
||||
(rtc->hz <= (uint32)sim_os_tick_hz) && /* slower than OS tick rate AND */
|
||||
(rtc->clock_unit) && /* clock has been registered AND */
|
||||
((rtc->last_hz == 0) || /* first calibration call OR */
|
||||
(rtc->last_hz == rtc->hz))) /* subsequent calibration call with an unchanged tick rate */
|
||||
break;
|
||||
}
|
||||
if (tmr == SIM_NTIMERS) { /* None found? */
|
||||
@@ -2499,7 +2517,7 @@ if (tmr == SIM_NTIMERS) { /* None found? */
|
||||
SIM_INTERNAL_UNIT.action = &sim_timer_clock_tick_svc;
|
||||
SIM_INTERNAL_UNIT.flags = UNIT_IDLE;
|
||||
sim_register_internal_device (&sim_int_timer_dev); /* Register Internal timer device */
|
||||
sim_rtcn_init_unit (&SIM_INTERNAL_UNIT, (int32)((CLK_INIT*CLK_TPS)/sim_int_clk_tps), SIM_INTERNAL_CLK);
|
||||
sim_rtcn_init_unit_ticks (&SIM_INTERNAL_UNIT, (int32)((CLK_INIT*CLK_TPS)/sim_int_clk_tps), SIM_INTERNAL_CLK, sim_int_clk_tps);
|
||||
SIM_INTERNAL_UNIT.action (&SIM_INTERNAL_UNIT); /* Force tick to activate timer */
|
||||
}
|
||||
return;
|
||||
@@ -2560,7 +2578,7 @@ return SCPE_OK;
|
||||
void sim_start_timer_services (void)
|
||||
{
|
||||
int32 tmr;
|
||||
uint32 sim_prompt_time = sim_os_msec () - sim_stop_time;
|
||||
uint32 sim_prompt_time = (sim_gtime () > 0) ? (sim_os_msec () - sim_stop_time) : 0;
|
||||
int32 registered_units = 0;
|
||||
|
||||
sim_time_at_sim_prompt += (((double)sim_prompt_time) / 1000.0);
|
||||
@@ -2585,7 +2603,8 @@ if (sim_calb_tmr == -1) {
|
||||
}
|
||||
else {
|
||||
if (sim_calb_tmr == SIM_NTIMERS) {
|
||||
sim_debug (DBG_CAL, &sim_timer_dev, "sim_start_timer_services() - restarting internal timer after %d cycles\n", sim_internal_timer_time);
|
||||
sim_debug (DBG_CAL, &sim_timer_dev, "sim_start_timer_services() - restarting internal timer after %d %s\n",
|
||||
sim_internal_timer_time, sim_vm_interval_units);
|
||||
sim_activate (&SIM_INTERNAL_UNIT, sim_internal_timer_time);
|
||||
}
|
||||
}
|
||||
@@ -2913,7 +2932,7 @@ if (NULL == uptr) { /* deregistering? */
|
||||
sim_cancel (rtc->timer_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (NULL == rtc->clock_unit)
|
||||
if (rtc->clock_unit == NULL)
|
||||
rtc->clock_cosched_queue = QUEUE_LIST_END;
|
||||
rtc->clock_unit = uptr;
|
||||
uptr->dynflags |= UNIT_TMR_UNIT;
|
||||
@@ -2976,7 +2995,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 {
|
||||
|
||||
Reference in New Issue
Block a user