diff --git a/VAX/vax750_stddev.c b/VAX/vax750_stddev.c index 9e62811c..78355848 100644 --- a/VAX/vax750_stddev.c +++ b/VAX/vax750_stddev.c @@ -182,6 +182,7 @@ int32 tmr_poll = CLK_DELAY; /* pgm timer poll */ struct todr_battery_info { uint32 toy_gmtbase; /* GMT base of set value */ uint32 toy_gmtbasemsec; /* The milliseconds of the set value */ + uint32 toy_endian_plus2; /* 2 -> Big Endian, 3 -> Little Endian, invalid otherwise */ }; typedef struct todr_battery_info TOY; @@ -534,7 +535,7 @@ t_stat tti_svc (UNIT *uptr) { int32 c; -sim_clock_coschedule (uptr, tmxr_poll); /* continue poll */ +sim_clock_coschedule_tmr (uptr, TMR_CLK, tmxr_poll); /* continue poll */ if ((tti_csr & CSR_DONE) && /* input still pending and < 500ms? */ ((sim_os_msec () - tti_buftime) < 500)) @@ -842,6 +843,20 @@ const char *clk_description (DEVICE *dptr) return "time of year clock"; } +static uint32 sim_byteswap32 (uint32 data) +{ +uint8 *bdata = (uint8 *)&data; +uint8 tmp; + +tmp = bdata[0]; +bdata[0] = bdata[3]; +bdata[3] = tmp; +tmp = bdata[1]; +bdata[1] = bdata[2]; +bdata[2] = tmp; +return data; +} + /* CLK attach */ t_stat clk_attach (UNIT *uptr, CONST char *cptr) @@ -853,8 +868,21 @@ memset (uptr->filebuf, 0, (size_t)uptr->capac); r = attach_unit (uptr, cptr); if (r != SCPE_OK) uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE); -else +else { + TOY *toy = (TOY *)uptr->filebuf; + uptr->hwmark = (uint32) uptr->capac; + if ((toy->toy_endian_plus2 < 2) || (toy->toy_endian_plus2 > 3)) + memset (uptr->filebuf, 0, (size_t)uptr->capac); + else { + if (toy->toy_endian_plus2 != sim_end + 2) { /* wrong endian? */ + toy->toy_gmtbase = sim_byteswap32 (toy->toy_gmtbase); + toy->toy_gmtbasemsec = sim_byteswap32 (toy->toy_gmtbasemsec); + } + } + toy->toy_endian_plus2 = sim_end + 2; + todr_resync (); + } return r; } @@ -897,10 +925,18 @@ int32 todr_rd (void) TOY *toy = (TOY *)clk_unit.filebuf; struct timespec base, now, val; +/* Maximum number of seconds which can be represented as 10ms ticks + in the 32bit TODR. This is the 33bit value 0x100000000/100 to get seconds */ +#define TOY_MAX_SECS (0x40000000/25) + sim_rtcn_get_time(&now, TMR_CLK); /* get curr time */ base.tv_sec = toy->toy_gmtbase; base.tv_nsec = toy->toy_gmtbasemsec * 1000000; sim_timespec_diff (&val, &now, &base); + +if ((val.tv_sec >= TOY_MAX_SECS) || (!toy->toy_gmtbase))/* todr overflowed? */ + return 0; /* stop counting */ + return (int32)(val.tv_sec*100 + val.tv_nsec/10000000); /* 100hz Clock Ticks */ } @@ -910,15 +946,21 @@ void todr_wr (int32 data) TOY *toy = (TOY *)clk_unit.filebuf; struct timespec now, val, base; -/* Save the GMT time when set value was 0 to record the base for future - read operations in "battery backed-up" state */ +if (data) { + /* Save the GMT time when set value was not 0 to record the base for + future read operations in "battery backed-up" state */ -sim_rtcn_get_time(&now, TMR_CLK); /* get curr time */ -val.tv_sec = ((uint32)data) / 100; -val.tv_nsec = (((uint32)data) % 100) * 10000000; -sim_timespec_diff (&base, &now, &val); /* base = now - data */ -toy->toy_gmtbase = (uint32)base.tv_sec; -toy->toy_gmtbasemsec = base.tv_nsec/1000000; + sim_rtcn_get_time(&now, TMR_CLK); /* get curr time */ + val.tv_sec = ((uint32)data) / 100; + val.tv_nsec = (((uint32)data) % 100) * 10000000; + sim_timespec_diff (&base, &now, &val); /* base = now - data */ + toy->toy_gmtbase = (uint32)base.tv_sec; + toy->toy_gmtbasemsec = base.tv_nsec/1000000; + } +else { /* stop the clock */ + toy->toy_gmtbase = 0; + toy->toy_gmtbasemsec = 0; + } } t_stat todr_resync (void) diff --git a/VAX/vax780_stddev.c b/VAX/vax780_stddev.c index a6bf3738..68c3b707 100644 --- a/VAX/vax780_stddev.c +++ b/VAX/vax780_stddev.c @@ -213,6 +213,7 @@ int32 tmr_poll = CLK_DELAY; /* pgm timer poll */ struct todr_battery_info { uint32 toy_gmtbase; /* GMT base of set value */ uint32 toy_gmtbasemsec; /* The milliseconds of the set value */ + uint32 toy_endian_plus2; /* 2 -> Big Endian, 3 -> Little Endian, invalid otherwise */ }; typedef struct todr_battery_info TOY; @@ -502,7 +503,7 @@ t_stat tti_svc (UNIT *uptr) { int32 c; -sim_clock_coschedule (uptr, tmxr_poll); /* continue poll */ +sim_clock_coschedule_tmr (uptr, TMR_CLK, tmxr_poll); /* continue poll */ if ((tti_csr & CSR_DONE) && /* input still pending and < 500ms? */ ((sim_os_msec () - tti_buftime) < 500)) @@ -784,6 +785,20 @@ const char *clk_description (DEVICE *dptr) return "time of year clock"; } +static uint32 sim_byteswap32 (uint32 data) +{ +uint8 *bdata = (uint8 *)&data; +uint8 tmp; + +tmp = bdata[0]; +bdata[0] = bdata[3]; +bdata[3] = tmp; +tmp = bdata[1]; +bdata[1] = bdata[2]; +bdata[2] = tmp; +return data; +} + /* CLK attach */ t_stat clk_attach (UNIT *uptr, CONST char *cptr) @@ -795,8 +810,21 @@ memset (uptr->filebuf, 0, (size_t)uptr->capac); r = attach_unit (uptr, cptr); if (r != SCPE_OK) uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE); -else +else { + TOY *toy = (TOY *)uptr->filebuf; + uptr->hwmark = (uint32) uptr->capac; + if ((toy->toy_endian_plus2 < 2) || (toy->toy_endian_plus2 > 3)) + memset (uptr->filebuf, 0, (size_t)uptr->capac); + else { + if (toy->toy_endian_plus2 != sim_end + 2) { /* wrong endian? */ + toy->toy_gmtbase = sim_byteswap32 (toy->toy_gmtbase); + toy->toy_gmtbasemsec = sim_byteswap32 (toy->toy_gmtbasemsec); + } + } + toy->toy_endian_plus2 = sim_end + 2; + todr_resync (); + } return r; } @@ -850,8 +878,8 @@ void todr_wr (int32 data) TOY *toy = (TOY *)clk_unit.filebuf; struct timespec now, val, base; -/* Save the GMT time when set value was 0 to record the base for future - read operations in "battery backed-up" state */ +/* Save the GMT time when set value was written to record the base for + future read operations in "battery backed-up" state */ sim_rtcn_get_time(&now, TMR_CLK); /* get curr time */ val.tv_sec = ((uint32)data) / 100; @@ -881,9 +909,9 @@ else { /* Not-Attached means */ if (ctm == NULL) /* error? */ return SCPE_NOFNC; base = (((((ctm->tm_yday * 24) + /* sec since 1-Jan */ - ctm->tm_hour) * 60) + - ctm->tm_min) * 60) + - ctm->tm_sec; + ctm->tm_hour) * 60) + + ctm->tm_min) * 60) + + ctm->tm_sec; todr_wr ((base * 100) + 0x10000000); /* use VMS form */ } return SCPE_OK; diff --git a/VAX/vax860_stddev.c b/VAX/vax860_stddev.c index 4178f036..b3396932 100644 --- a/VAX/vax860_stddev.c +++ b/VAX/vax860_stddev.c @@ -212,6 +212,7 @@ int32 tmr_poll = CLK_DELAY; /* pgm timer poll */ struct todr_battery_info { uint32 toy_gmtbase; /* GMT base of set value */ uint32 toy_gmtbasemsec; /* The milliseconds of the set value */ + uint32 toy_endian_plus2; /* 2 -> Big Endian, 3 -> Little Endian, invalid otherwise */ }; typedef struct todr_battery_info TOY; @@ -590,7 +591,7 @@ int32 line = uptr - tti_dev.units; switch (line) { case ID_CT: /* console terminal */ - sim_clock_coschedule (uptr, tmxr_poll); /* continue poll */ + sim_clock_coschedule_tmr (uptr, TMR_CLK, tmxr_poll);/* continue poll */ if ((tti_csr & CSR_DONE) && /* input still pending and < 500ms? */ ((sim_os_msec () - tti_buftime) < 500)) return SCPE_OK; @@ -910,6 +911,20 @@ const char *clk_description (DEVICE *dptr) return "time of year clock"; } +static uint32 sim_byteswap32 (uint32 data) +{ +uint8 *bdata = (uint8 *)&data; +uint8 tmp; + +tmp = bdata[0]; +bdata[0] = bdata[3]; +bdata[3] = tmp; +tmp = bdata[1]; +bdata[1] = bdata[2]; +bdata[2] = tmp; +return data; +} + /* CLK attach */ t_stat clk_attach (UNIT *uptr, CONST char *cptr) @@ -921,8 +936,21 @@ memset (uptr->filebuf, 0, (size_t)uptr->capac); r = attach_unit (uptr, cptr); if (r != SCPE_OK) uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE); -else +else { + TOY *toy = (TOY *)uptr->filebuf; + uptr->hwmark = (uint32) uptr->capac; + if ((toy->toy_endian_plus2 < 2) || (toy->toy_endian_plus2 > 3)) + memset (uptr->filebuf, 0, (size_t)uptr->capac); + else { + if (toy->toy_endian_plus2 != sim_end + 2) { /* wrong endian? */ + toy->toy_gmtbase = sim_byteswap32 (toy->toy_gmtbase); + toy->toy_gmtbasemsec = sim_byteswap32 (toy->toy_gmtbasemsec); + } + } + toy->toy_endian_plus2 = sim_end + 2; + todr_resync (); + } return r; } @@ -976,8 +1004,8 @@ void todr_wr (int32 data) TOY *toy = (TOY *)clk_unit.filebuf; struct timespec now, val, base; -/* Save the GMT time when set value was 0 to record the base for future - read operations in "battery backed-up" state */ +/* Save the GMT time when set value was 0 to record the base for + future read operations in "battery backed-up" state */ sim_rtcn_get_time(&now, TMR_CLK); /* get curr time */ val.tv_sec = ((uint32)data) / 100; diff --git a/VAX/vax_stddev.c b/VAX/vax_stddev.c index eb124cc3..abfc8f72 100644 --- a/VAX/vax_stddev.c +++ b/VAX/vax_stddev.c @@ -103,6 +103,7 @@ int32 todr_blow = 1; /* TODR battery low */ struct todr_battery_info { uint32 toy_gmtbase; /* GMT base of set value */ uint32 toy_gmtbasemsec; /* The milliseconds of the set value */ + uint32 toy_endian_plus2; /* 2 -> Big Endian, 3 -> Little Endian, invalid otherwise */ }; typedef struct todr_battery_info TOY; int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */ @@ -344,7 +345,7 @@ t_stat tti_svc (UNIT *uptr) { int32 c; -sim_clock_coschedule (uptr, tmxr_poll); /* continue poll */ +sim_clock_coschedule_tmr (uptr, TMR_CLK, tmxr_poll); /* continue poll */ if ((tti_csr & CSR_DONE) && /* input still pending and < 500ms? */ ((sim_os_msec () - tti_buftime) < 500)) @@ -464,6 +465,7 @@ tmr_poll = t; /* set tmr poll */ tmxr_poll = t * TMXR_MULT; /* set mux poll */ if (!todr_blow && todr_reg) /* if running? */ todr_reg = todr_reg + 1; /* incr TODR */ +AIO_SET_INTERRUPT_LATENCY(tmr_poll*clk_tps); /* set interrrupt latency */ return SCPE_OK; } @@ -506,18 +508,23 @@ void todr_wr (int32 data) TOY *toy = (TOY *)clk_unit.filebuf; struct timespec now, val, base; -/* Save the GMT time when set value was 0 to record the base for future - read operations in "battery backed-up" state */ - -sim_rtcn_get_time(&now, TMR_CLK); /* get curr time */ -val.tv_sec = ((uint32)data) / 100; -val.tv_nsec = (((uint32)data) % 100) * 10000000; -sim_timespec_diff (&base, &now, &val); /* base = now - data */ -toy->toy_gmtbase = (uint32)base.tv_sec; -toy->toy_gmtbasemsec = base.tv_nsec/1000000; -todr_reg = data; -if (data) +if (data) { todr_blow = 0; + /* Save the GMT time when set value is not 0 to record the base for + future read operations in "battery backed-up" state */ + + sim_rtcn_get_time(&now, TMR_CLK); /* get curr time */ + val.tv_sec = ((uint32)data) / 100; + val.tv_nsec = (((uint32)data) % 100) * 10000000; + sim_timespec_diff (&base, &now, &val); /* base = now - data */ + toy->toy_gmtbase = (uint32)base.tv_sec; + toy->toy_gmtbasemsec = base.tv_nsec/1000000; + } +else { /* stop the clock */ + toy->toy_gmtbase = 0; + toy->toy_gmtbasemsec = 0; + } +todr_reg = data; sim_debug (DBG_REG, &clk_dev, "todr_wr(0x%X) - TODR=0x%X blow=%d\n", data, todr_reg, todr_blow); } @@ -543,9 +550,9 @@ else { /* Not-Attached means */ if (ctm == NULL) /* error? */ return SCPE_NOFNC; base = (((((ctm->tm_yday * 24) + /* sec since 1-Jan */ - ctm->tm_hour) * 60) + - ctm->tm_min) * 60) + - ctm->tm_sec; + ctm->tm_hour) * 60) + + ctm->tm_min) * 60) + + ctm->tm_sec; todr_wr ((base * 100) + 0x10000000); /* use VMS form */ } return SCPE_OK; @@ -610,6 +617,20 @@ const char *clk_description (DEVICE *dptr) return "time of year clock"; } +static uint32 sim_byteswap32 (uint32 data) +{ +uint8 *bdata = (uint8 *)&data; +uint8 tmp; + +tmp = bdata[0]; +bdata[0] = bdata[3]; +bdata[3] = tmp; +tmp = bdata[1]; +bdata[1] = bdata[2]; +bdata[2] = tmp; +return data; +} + /* CLK attach */ t_stat clk_attach (UNIT *uptr, CONST char *cptr) @@ -621,8 +642,21 @@ memset (uptr->filebuf, 0, (size_t)uptr->capac); r = attach_unit (uptr, cptr); if (r != SCPE_OK) uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE); -else +else { + TOY *toy = (TOY *)uptr->filebuf; + uptr->hwmark = (uint32) uptr->capac; + if ((toy->toy_endian_plus2 < 2) || (toy->toy_endian_plus2 > 3)) + memset (uptr->filebuf, 0, (size_t)uptr->capac); + else { + if (toy->toy_endian_plus2 != sim_end + 2) { /* wrong endian? */ + toy->toy_gmtbase = sim_byteswap32 (toy->toy_gmtbase); + toy->toy_gmtbasemsec = sim_byteswap32 (toy->toy_gmtbasemsec); + } + } + toy->toy_endian_plus2 = sim_end + 2; + todr_resync (); + } return r; }