Skip to content

Commit 68373f9

Browse files
committed
Patches for the 2010 problem
- Adjust the time base for NewtonScript time related functions to 2008-01-01T00:00:00 from 1993-01-01T00:00:00 - Set the Newton's time to the host time
1 parent f64ccb9 commit 68373f9

2 files changed

Lines changed: 78 additions & 25 deletions

File tree

Emulator/JIT/Generic/TJITGenericROMPatch.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,81 @@ T_ROM_PATCH(0x0038CE70, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid, "Debugger"
104104
return 0L;
105105
}
106106

107+
/*
108+
* Set the time to the host time
109+
*/
110+
111+
static const KUInt32 delta1904to1970 = 2082844800;
112+
113+
T_ROM_PATCH(0x00255578, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid, "RealClockSeconds")
114+
{
115+
(void) ioUnit;
116+
time_t t = time(NULL);
117+
struct tm gm;
118+
struct tm local;
119+
#if TARGET_OS_WIN32
120+
gmtime_s(&gm, &t);
121+
localtime_s(&local, &t);
122+
#else
123+
gmtime_r(&t, &gm);
124+
localtime_r(&t, &local);
125+
#endif
126+
double tzoffset = difftime(mktime(&local), mktime(&gm));
127+
ioCPU->SetRegister(0, t + tzoffset + delta1904to1970);
128+
ioCPU->SetRegister(15, ioCPU->GetRegister(14) + 4);
129+
return 0L;
130+
}
131+
132+
/* Patches for the 2010 problem:
133+
*
134+
* The low level NewtonOS clock will continue to run with seconds since
135+
* 1904-01-01T00:00:00. The NewtonScript functions which have been using a time
136+
* base of 1993-01-01T00:00:00 will however be patched so that they will use a
137+
* new time base of 2008-01-01T00:00:00. The patches will add or substract the
138+
* delta between the time bases.
139+
*
140+
* The base year will need to be updated in 2026.
141+
*/
142+
143+
/* Delta from 2008-01-01T00:00:00 to 1993-01-01T00:00:00 */
144+
145+
static const KUInt32 safeIntervalDeltaSeconds = 473299200;
146+
147+
/*
148+
* Adjust seconds values returned to NS layer into safe interval
149+
*/
150+
151+
T_ROM_PATCH(0x00089B80, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid, "FTimeInSeconds")
152+
{
153+
ioCPU->SetRegister(0, (ioCPU->GetRegister(0) - safeIntervalDeltaSeconds) << 2);
154+
return ioUnit;
155+
}
156+
157+
/*
158+
* Fix date from seconds returned to NS layer
159+
*/
160+
161+
T_ROM_PATCH(0x0008A8A8, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid, "FDateFromSeconds")
162+
{
163+
ioCPU->SetRegister(1, ioCPU->GetRegister(1) + safeIntervalDeltaSeconds);
164+
ioCPU->SetRegister(0, ioCPU->GetRegister(13));
165+
return ioUnit;
166+
}
167+
168+
static const KUInt32 newTimeBaseMinutes = 218799360; /* 2008/1/1 in minutes from 1904/1/1 as NS integer */
169+
static const KUInt32 newTimeBaseSeconds = 3281990400; /* 2008/1/1 in seconds from 1904/1/1 as NS integer */
170+
171+
TJITGenericPatch timeBase1(0x420750, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid,
172+
newTimeBaseMinutes, "Time base (1/4)");
173+
TJITGenericPatch timeBase2(0x420798, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid,
174+
newTimeBaseMinutes, "Time base (2/4)");
175+
TJITGenericPatch timeBase3(0x4dca14, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid,
176+
newTimeBaseMinutes, "Time base (3/4)");
177+
TJITGenericPatch timeBase4(0x30F088, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid,
178+
newTimeBaseSeconds, "Time base (4/4)");
179+
TJITGenericPatch ignoreSettingTime(0x0008A20C, kROMPatchVoid, kROMPatchVoid, kROMPatchVoid,
180+
0xe1a0f00e, "Ignore setting time"); // mov pc, lr
181+
107182
// ========================================================================== //
108183
// MARK: -
109184
// TJITGenericPatchManager

app/FLTK/TFLApp.cpp

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -877,20 +877,16 @@ void TFLApp::UserActionInstallEssentials()
877877
// Y2K10
878878
addInstallerGroup("NewtonOS Y2K10 Fix");
879879
addInstallerText("NewtonOS has a bug in handling years past 18:48:31 on January 5, 2010. "
880-
"The patch below will fix all date issues until 2026.\n\n"
880+
"Einstein contains a fix for US MP2x00 MessagePads, but "
881+
"for eMates and German MP2x00 MessagePads, "
882+
"the patch below will fix all date issues until 2026.\n\n"
881883
"Please install this patch before installing anything else, "
882884
"as this will wipe your Newton's memory.");
883885
addInstallerLink("explained by Eckhart Köppen", new StringList {
884886
":https://40hz.org/Pages/newton/hacking/newton-year-2010-problem/"} );
885887
addInstallerLink("Readme file for the patch", new StringList {
886888
"MDownloads/Einstein/Essentials/y2k10/README.txt"} );
887889
addInstallerText("Please select the patch that matches the ROM image of your machine:");
888-
addInstallerPackage("US MP2x00 patch", new StringList {
889-
"WInstalling this patch may irreversibly erase all data\n"
890-
"on your MessagePad.\n\n"
891-
"Please proceed only if this a new device, or if your\n"
892-
"data is securely backed up!",
893-
"MDownloads/Einstein/Essentials/y2k10/Patch_US.pkg"} );
894890
addInstallerPackage("German MP2x00 patch", new StringList {
895891
"WInstalling this patch may irreversibly erase all data\n"
896892
"on your MessagePad.\n\n"
@@ -1318,24 +1314,6 @@ void TFLApp::StoreAppWindowSize()
13181314
*/
13191315
void TFLApp::DeferredOnPowerRestored()
13201316
{
1321-
static bool beenHere = false;
1322-
1323-
// We run this once at boot time. It would be correct to reset this whenever
1324-
// we reboot or load a different configuration.
1325-
if (!beenHere) {
1326-
if (mFLSettings->mFetchDateAndTime) {
1327-
std::time_t now = time(nullptr);
1328-
struct std::tm then_tm = { 0, 0, 0, 1, 0, 4 }; /* Midnight Jan 1 1904 */
1329-
std::time_t then = std::mktime(&then_tm);
1330-
auto diff_secs = std::difftime(now, then);
1331-
1332-
KUInt32 minutesSince1904 = (KUInt32)(diff_secs / 60);
1333-
char setTimeAndDateScript[256];
1334-
::snprintf(setTimeAndDateScript, 256, "SetTime(%u);", minutesSince1904);
1335-
mPlatformManager->EvalNewtonScript(setTimeAndDateScript);
1336-
}
1337-
beenHere = true;
1338-
}
13391317
}
13401318

13411319

0 commit comments

Comments
 (0)