Open AussieSusan opened 3 years ago
I'm aware of this time resetting problem, I suspect the real time clock code naively copies system time when starting the VM and OpenVMS expects it to be set to local time. Not sure though, but I'll check the OpenVMS documentation and the RTC implementation in AXPbox to find the answer.
AFAIK, the SRM (the Alpha "BIOS") does not have a way to set the RTC; it's all left to the OS. And VMS expects and stores the time as local time (without timezone information) - see e.g. DCL command SET TIME when called without parameters.
The emulator, OTOH, initializes the RTC using UTC (AliM1543C.cpp:700). I have changed the one usage of gmtime_s() to localtime_s(), and VMS is happy with it. I've noted that the Microsoft CRT reverses the parameters - which I've taken care of, too.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 34d99e6..4243460 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -55,12 +55,12 @@ check_symbol_exists(fseeko64 "stdio.h" HAVE_FSEEKO64)
check_symbol_exists(ftell "stdio.h" HAVE_FTELL)
check_symbol_exists(ftello "stdio.h" HAVE_FTELLO)
check_symbol_exists(ftello64 "stdio.h" HAVE_FTELLO64)
-check_symbol_exists(gmtime_s "time.h" HAVE_GMTIME_S)
check_symbol_exists(inet_aton "arpa/inet.h" HAVE_INET_ATON)
check_include_file("inet.h" HAVE_INET_H)
check_include_file("inttypes.h" HAVE_INTTYPES_H)
check_include_file("in.h" HAVE_IN_H)
check_symbol_exists(isblank "ctype.h" HAVE_ISBLANK)
+check_symbol_exists(localtime_s "time.h" HAVE_LOCALTIME_S)
check_symbol_exists(malloc "stdlib.h" HAVE_MALLOC)
check_include_file("malloc.h" HAVE_MALLOC_H)
check_include_file("memory.h" HAVE_MEMORY_H)
diff --git a/src/AliM1543C.cpp b/src/AliM1543C.cpp
index 700a28b..825a706 100644
--- a/src/AliM1543C.cpp
+++ b/src/AliM1543C.cpp
@@ -697,7 +697,11 @@ void CAliM1543C::toy_write(u32 address, u8 data) {
// Update time
time(<ime);
- gmtime_s(&stime, <ime);
+#ifdef _WIN32
+ localtime_s(&stime, <ime);
+#else
+ localtime_s(<ime, &stime);
+#endif
if (state.toy_stored_data[RTC_REG_B] & RTC_DM) {
// binary
state.toy_stored_data[0] = (u8)(stime.tm_sec);
diff --git a/src/StdAfx.hpp b/src/StdAfx.hpp
index 9c6a9b2..eec4533 100644
--- a/src/StdAfx.hpp
+++ b/src/StdAfx.hpp
@@ -248,11 +248,16 @@
#include <ctype.h>
#endif
-#if !defined(HAVE_GMTIME_S)
-inline void gmtime_s(struct tm *t1, time_t *t2) {
- struct tm *t3;
- t3 = gmtime(t2);
- memcpy(t1, t3, sizeof(struct tm));
+#if !defined(HAVE_LOCALTIME_S)
+#ifdef _WIN32
+inline struct tm *localtime_s(struct tm *buf, time_t *timer)
+#else
+inline struct tm *localtime_s(time_t *timer, struct tm *buf)
+#endif
+{
+ struct tm *tmp;
+ tmp = localtime(timer);
+ return (struct tm*) memcpy(buf, tmp, sizeof(struct tm));
}
#endif
diff --git a/src/config.hpp.in b/src/config.hpp.in
index 2418522..0d658f8 100644
--- a/src/config.hpp.in
+++ b/src/config.hpp.in
@@ -46,8 +46,8 @@
/* Define to 1 if you have the `ftello64' function. */
#cmakedefine HAVE_FTELLO64
-/* Define to 1 if you have the `gmtime_s' function. */
-#cmakedefine HAVE_GMTIME_S
+/* Define to 1 if you have the `localtime_s' function. */
+#cmakedefine HAVE_LOCALTIME_S
/* Define to 1 if you have the `inet_aton' function. */
#cmakedefine HAVE_INET_ATON
Would it be feasible to add a configuration option, on which to initialize the time? Context: I have an expired HP license and I now have to re-do the entire procedure every bootup, which adds a long time to the entire process. By default, with no config option, use the standard path and init the clock with the current time from the host. If the option is there, initialize it with that instead?
The emulator, OTOH, initializes the RTC using UTC (AliM1543C.cpp:700). I have changed the one usage of gmtime_s() to localtime_s(), and VMS is happy with it. I've noted that the Microsoft CRT reverses the parameters - which I've taken care of, too.
This is certainly better than using UTC time, but the problem isn't fully solved: the VM may be set to a timezone that is different from the one on the host, or to a different time altogether.
I'll try to implement a configuration option that would enable adding/subtracting from either UTC or local time and setting the time to a constant value. (By the way all of this is possible inside OpenVMS itself by modifying the startup script.)
Would it be feasible to add a configuration option, on which to initialize the time? Context: I have an expired HP license and I now have to re-do the entire procedure every bootup, which adds a long time to the entire process. By default, with no config option, use the standard path and init the clock with the current time from the host. If the option is there, initialize it with that instead?
Done, see the example configuration file, e.g. for subtracting 10 years:
pci0.7 = ali
{
timezone = "local+-10y";
}
I have set the timezone information correctly when installing OpenVMS and is seems to be set up correctly:
$ @sys$manager:utc$time_setup show
AUTO_DLIGHT_SAV is set to "1". OpenVMS will automatically change to/from Daylight Saving Time. (in time zones that use Daylight Saving Time)
However when I boot it seems to do something 'strange' with the time:
Please enter date and time (DD-MMM-YYYY HH:MM) 22-JAN-2021 15:34 %STDRV-I-STARTUP, OpenVMS startup begun at 22-JAN-2021 04:34:21.94
It seems to be taking whatever I enter and converting it back to UTC and using that.
What am I doing wrong??
(Running the VSI Alpha image in axpbox in an iMac running MacOS 10.13.6 (as fully patched as Apple provide for this old version that I can't upgrade as it is a mid-2011 iMac)
Susan