mirror of
https://github.com/open-simh/simh.git
synced 2026-01-26 04:02:39 +00:00
Notes For V3.5-0
The source set has been extensively overhauled. For correct viewing, set Visual C++ or Emacs to have tab stops every 4 characters. 1. New Features in 3.4-1 1.1 All Ethernet devices - Added Windows user-defined adapter names (from Timothe Litt) 1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors - Added support for SET <unit>n DISCONNECT 1.3 VAX - Added latent QDSS support - Revised autoconfigure to handle QDSS 1.4 PDP-11 - Revised autoconfigure to handle more casees 2. Bugs Fixed in 3.4-1 2.1 SCP and libraries - Trim trailing spaces on all input (for example, attach file names) - Fixed sim_sock spurious SIGPIPE error in Unix/Linux - Fixed sim_tape misallocation of TPC map array for 64b simulators 2.2 1401 - Fixed bug, CPU reset was clearing SSB through SSG 2.3 PDP-11 - Fixed bug in VH vector display routine - Fixed XU runt packet processing (found by Tim Chapman) 2.4 Interdata - Fixed bug in SHOW PAS CONN/STATS - Fixed potential integer overflow exception in divide 2.5 SDS - Fixed bug in SHOW MUX CONN/STATS 2.6 HP - Fixed bug in SHOW MUX CONN/STATS 2.7 PDP-8 - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.8 PDP-18b - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.9 Nova, Eclipse - Fixed potential integer overflow exception in divide
This commit is contained in:
committed by
Mark Pizzolato
parent
ec60bbf329
commit
b7c1eae41f
180
sim_timer.c
180
sim_timer.c
@@ -1,6 +1,6 @@
|
||||
/* sim_timer.c: simulator timer library
|
||||
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,95 +19,26 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
02-Jan-04 RMS Split out from SCP
|
||||
21-Aug-05 RMS Added sim_rtcn_init_all
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
02-Jan-04 RMS Split out from SCP
|
||||
|
||||
This library includes the following routines:
|
||||
|
||||
sim_rtc_init - initialize calibration
|
||||
sim_rtc_calb - calibrate clock
|
||||
sim_os_msec - return elapsed time in msec
|
||||
sim_os_sleep - sleep specified number of seconds
|
||||
sim_rtc_init - initialize calibration
|
||||
sim_rtc_calb - calibrate clock
|
||||
sim_os_msec - return elapsed time in msec
|
||||
sim_os_sleep - sleep specified number of seconds
|
||||
|
||||
The calibration routines are OS-independent; the _os_ routines are not
|
||||
*/
|
||||
|
||||
#include "sim_defs.h"
|
||||
|
||||
/* OS independent clock calibration package */
|
||||
|
||||
static int32 rtc_ticks[SIM_NTIMERS] = { 0 }; /* ticks */
|
||||
static uint32 rtc_rtime[SIM_NTIMERS] = { 0 }; /* real time */
|
||||
static uint32 rtc_vtime[SIM_NTIMERS] = { 0 }; /* virtual time */
|
||||
static uint32 rtc_nxintv[SIM_NTIMERS] = { 0 }; /* next interval */
|
||||
static int32 rtc_based[SIM_NTIMERS] = { 0 }; /* base delay */
|
||||
static int32 rtc_currd[SIM_NTIMERS] = { 0 }; /* current delay */
|
||||
static int32 rtc_initd[SIM_NTIMERS] = { 0 }; /* initial delay */
|
||||
const t_bool rtc_avail;
|
||||
|
||||
int32 sim_rtcn_init (int32 time, int32 tmr)
|
||||
{
|
||||
if (time == 0) time = 1;
|
||||
if ((tmr < 0) || (tmr >= SIM_NTIMERS)) return time;
|
||||
rtc_rtime[tmr] = sim_os_msec ();
|
||||
rtc_vtime[tmr] = rtc_rtime[tmr];
|
||||
rtc_nxintv[tmr] = 1000;
|
||||
rtc_ticks[tmr] = 0;
|
||||
rtc_based[tmr] = time;
|
||||
rtc_currd[tmr] = time;
|
||||
rtc_initd[tmr] = time;
|
||||
return time;
|
||||
}
|
||||
|
||||
int32 sim_rtcn_calb (int32 ticksper, int32 tmr)
|
||||
{
|
||||
uint32 new_rtime, delta_rtime;
|
||||
int32 delta_vtime;
|
||||
|
||||
if ((tmr < 0) || (tmr >= SIM_NTIMERS)) return 10000;
|
||||
rtc_ticks[tmr] = rtc_ticks[tmr] + 1; /* count ticks */
|
||||
if (rtc_ticks[tmr] < ticksper) return rtc_currd[tmr]; /* 1 sec yet? */
|
||||
rtc_ticks[tmr] = 0; /* reset ticks */
|
||||
if (!rtc_avail) return rtc_currd[tmr]; /* no timer? */
|
||||
new_rtime = sim_os_msec (); /* wall time */
|
||||
if (new_rtime < rtc_rtime[tmr]) { /* time running backwards? */
|
||||
rtc_rtime[tmr] = new_rtime; /* reset wall time */
|
||||
return rtc_currd[tmr]; } /* can't calibrate */
|
||||
delta_rtime = new_rtime - rtc_rtime[tmr]; /* elapsed wtime */
|
||||
rtc_rtime[tmr] = new_rtime; /* adv wall time */
|
||||
rtc_vtime[tmr] = rtc_vtime[tmr] + 1000; /* adv sim time */
|
||||
if (delta_rtime > 30000) /* gap too big? */
|
||||
return rtc_initd[tmr]; /* can't calibr */
|
||||
if (delta_rtime == 0) /* gap too small? */
|
||||
rtc_based[tmr] = rtc_based[tmr] * ticksper; /* slew wide */
|
||||
else rtc_based[tmr] = (int32) (((double) rtc_based[tmr] * (double) rtc_nxintv[tmr]) /
|
||||
((double) delta_rtime)); /* new base rate */
|
||||
delta_vtime = rtc_vtime[tmr] - rtc_rtime[tmr]; /* gap */
|
||||
if (delta_vtime > SIM_TMAX) delta_vtime = SIM_TMAX; /* limit gap */
|
||||
else if (delta_vtime < -SIM_TMAX) delta_vtime = -SIM_TMAX;
|
||||
rtc_nxintv[tmr] = 1000 + delta_vtime; /* next wtime */
|
||||
rtc_currd[tmr] = (int32) (((double) rtc_based[tmr] * (double) rtc_nxintv[tmr]) /
|
||||
1000.0); /* next delay */
|
||||
if (rtc_based[tmr] <= 0) rtc_based[tmr] = 1; /* never negative or zero! */
|
||||
if (rtc_currd[tmr] <= 0) rtc_currd[tmr] = 1; /* never negative or zero! */
|
||||
return rtc_currd[tmr];
|
||||
}
|
||||
|
||||
/* Prior interfaces - default to timer 0 */
|
||||
|
||||
int32 sim_rtc_init (int32 time)
|
||||
{
|
||||
return sim_rtcn_init (time, 0);
|
||||
}
|
||||
|
||||
int32 sim_rtc_calb (int32 ticksper)
|
||||
{
|
||||
return sim_rtcn_calb (ticksper, 0);
|
||||
}
|
||||
|
||||
/* OS-dependent timer and clock routines */
|
||||
|
||||
/* VMS */
|
||||
@@ -128,7 +59,7 @@ uint32 sim_os_msec ()
|
||||
uint32 quo, htod, tod[2];
|
||||
int32 i;
|
||||
|
||||
sys$gettim (tod); /* time 0.1usec */
|
||||
sys$gettim (tod); /* time 0.1usec */
|
||||
|
||||
/* To convert to msec, must divide a 64b quantity by 10000. This is actually done
|
||||
by dividing the 96b quantity 0'time by 10000, producing 64b of quotient, the
|
||||
@@ -136,14 +67,16 @@ sys$gettim (tod); /* time 0.1usec */
|
||||
*/
|
||||
|
||||
quo = htod = 0;
|
||||
for (i = 0; i < 64; i++) { /* 64b quo */
|
||||
htod = (htod << 1) | ((tod[1] >> 31) & 1); /* shift divd */
|
||||
tod[1] = (tod[1] << 1) | ((tod[0] >> 31) & 1);
|
||||
tod[0] = tod[0] << 1;
|
||||
quo = quo << 1; /* shift quo */
|
||||
if (htod >= 10000) { /* divd work? */
|
||||
htod = htod - 10000; /* subtract */
|
||||
quo = quo | 1; } } /* set quo bit */
|
||||
for (i = 0; i < 64; i++) { /* 64b quo */
|
||||
htod = (htod << 1) | ((tod[1] >> 31) & 1); /* shift divd */
|
||||
tod[1] = (tod[1] << 1) | ((tod[0] >> 31) & 1);
|
||||
tod[0] = tod[0] << 1;
|
||||
quo = quo << 1; /* shift quo */
|
||||
if (htod >= 10000) { /* divd work? */
|
||||
htod = htod - 10000; /* subtract */
|
||||
quo = quo | 1; /* set quo bit */
|
||||
}
|
||||
}
|
||||
return quo;
|
||||
}
|
||||
|
||||
@@ -245,3 +178,74 @@ return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* OS independent clock calibration package */
|
||||
|
||||
static int32 rtc_ticks[SIM_NTIMERS] = { 0 }; /* ticks */
|
||||
static uint32 rtc_rtime[SIM_NTIMERS] = { 0 }; /* real time */
|
||||
static uint32 rtc_vtime[SIM_NTIMERS] = { 0 }; /* virtual time */
|
||||
static uint32 rtc_nxintv[SIM_NTIMERS] = { 0 }; /* next interval */
|
||||
static int32 rtc_based[SIM_NTIMERS] = { 0 }; /* base delay */
|
||||
static int32 rtc_currd[SIM_NTIMERS] = { 0 }; /* current delay */
|
||||
static int32 rtc_initd[SIM_NTIMERS] = { 0 }; /* initial delay */
|
||||
|
||||
int32 sim_rtcn_init (int32 time, int32 tmr)
|
||||
{
|
||||
if (time == 0) time = 1;
|
||||
if ((tmr < 0) || (tmr >= SIM_NTIMERS)) return time;
|
||||
rtc_rtime[tmr] = sim_os_msec ();
|
||||
rtc_vtime[tmr] = rtc_rtime[tmr];
|
||||
rtc_nxintv[tmr] = 1000;
|
||||
rtc_ticks[tmr] = 0;
|
||||
rtc_based[tmr] = time;
|
||||
rtc_currd[tmr] = time;
|
||||
rtc_initd[tmr] = time;
|
||||
return time;
|
||||
}
|
||||
|
||||
int32 sim_rtcn_calb (int32 ticksper, int32 tmr)
|
||||
{
|
||||
uint32 new_rtime, delta_rtime;
|
||||
int32 delta_vtime;
|
||||
|
||||
if ((tmr < 0) || (tmr >= SIM_NTIMERS)) return 10000;
|
||||
rtc_ticks[tmr] = rtc_ticks[tmr] + 1; /* count ticks */
|
||||
if (rtc_ticks[tmr] < ticksper) return rtc_currd[tmr]; /* 1 sec yet? */
|
||||
rtc_ticks[tmr] = 0; /* reset ticks */
|
||||
if (!rtc_avail) return rtc_currd[tmr]; /* no timer? */
|
||||
new_rtime = sim_os_msec (); /* wall time */
|
||||
if (new_rtime < rtc_rtime[tmr]) { /* time running backwards? */
|
||||
rtc_rtime[tmr] = new_rtime; /* reset wall time */
|
||||
return rtc_currd[tmr]; /* can't calibrate */
|
||||
}
|
||||
delta_rtime = new_rtime - rtc_rtime[tmr]; /* elapsed wtime */
|
||||
rtc_rtime[tmr] = new_rtime; /* adv wall time */
|
||||
rtc_vtime[tmr] = rtc_vtime[tmr] + 1000; /* adv sim time */
|
||||
if (delta_rtime > 30000) /* gap too big? */
|
||||
return rtc_initd[tmr]; /* can't calibr */
|
||||
if (delta_rtime == 0) /* gap too small? */
|
||||
rtc_based[tmr] = rtc_based[tmr] * ticksper; /* slew wide */
|
||||
else rtc_based[tmr] = (int32) (((double) rtc_based[tmr] * (double) rtc_nxintv[tmr]) /
|
||||
((double) delta_rtime)); /* new base rate */
|
||||
delta_vtime = rtc_vtime[tmr] - rtc_rtime[tmr]; /* gap */
|
||||
if (delta_vtime > SIM_TMAX) delta_vtime = SIM_TMAX; /* limit gap */
|
||||
else if (delta_vtime < -SIM_TMAX) delta_vtime = -SIM_TMAX;
|
||||
rtc_nxintv[tmr] = 1000 + delta_vtime; /* next wtime */
|
||||
rtc_currd[tmr] = (int32) (((double) rtc_based[tmr] * (double) rtc_nxintv[tmr]) /
|
||||
1000.0); /* next delay */
|
||||
if (rtc_based[tmr] <= 0) rtc_based[tmr] = 1; /* never negative or zero! */
|
||||
if (rtc_currd[tmr] <= 0) rtc_currd[tmr] = 1; /* never negative or zero! */
|
||||
return rtc_currd[tmr];
|
||||
}
|
||||
|
||||
/* Prior interfaces - default to timer 0 */
|
||||
|
||||
int32 sim_rtc_init (int32 time)
|
||||
{
|
||||
return sim_rtcn_init (time, 0);
|
||||
}
|
||||
|
||||
int32 sim_rtc_calb (int32 ticksper)
|
||||
{
|
||||
return sim_rtcn_calb (ticksper, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user