[snip some examples of changes that do and don't cause the Iyonix date to
jump forward two years after a reboot]
> > Caveat: I've only tried a few examples of the changes described to see
> > what happens - it could be that I've just fluked onto instances that do
> > or don't trigger this problem, but they do seem to be consistent.
> (Follow-ups set to csa.programmer, as we need some programmers to look
> into this!)
> Our experiments here were confined to setting the year (via Alarm) and
> resetting the Iyonix and seeing what the clock said afterwards, so it's
> really interesting seeing all the rest of this testing above.
I was fiddling with the time before reading csa* - TBH, I'm a little
surprised nobody had similarly experimented and posted results.
*After* posting, I had a few more little tinkles... um, and I also played
with the time some more, and noticed that it only happens in alternating
decades - as you say:
> From our testing, we discovered that if you set the year and date to
> anything, it worked fine until the machine was rebooted. But then if the
> year was in an odd-numbered decade, after reboot the year would be shown
> two years on from what it should have been.
I didn't check backwards, though, so didn't realise it happened in the 90s
as well (or would have done, had the Iyonix been around).
[...]
I wrote a program as a temporary fix here - I *now* see that you've also
written one and uploaded it. This is mine:
DIM Time5% 5, Ordinals% 32
?Time5%=3
SYS"OS_Word",14,Time5%
SYS"Territory_ConvertTimeToOrdinals",-1,Time5%,Ordinals%
IF(!(Ordinals%+24)/10) MOD 2<>0 THEN
!(Ordinals%+24)=!(Ordinals%+24)-2
SYS"Territory_ConvertOrdinalsToTime",-1,Time5%,Ordinals%
SYS"Territory_SetTime",Time5%
ENDIF
(I've just typed this in on this laptop from the StrongED window on the
Iyonix - so typos may have crept in!)
Like yours, it should be run as part of the boot sequence. It reads the 5
byte time, then uses the Territory_ SWIs to convert the 5 byte time to
ordinals, looks at the word containing the year and, if it's an odd decade,
deducts 2 before writing it back, converting the results back to a 5 byte
time and then setting the clock. It should therefore be time zone
independant, and not affected by leap years.
Hopefully. :)
--
Vince M Hudd - Soft Rock Software
http://www.softrock.co.uk
http://misc.vinceh.com
[snip my program to get around the problem]
> Like yours, it should be run as part of the boot sequence. It reads the 5
> byte time, then uses the Territory_ SWIs to convert the 5 byte time to
> ordinals, looks at the word containing the year and, if it's an odd
> decade, deducts 2 before writing it back, converting the results back to a
> 5 byte time and then setting the clock. It should therefore be time zone
> independant, and not affected by leap years.
I decided to copy it and some explanatory text to www.riscository.com - and
while I was writing the text I realised there was actually a different
problem (which presumably yours will suffer from as well).
Specifically, by working out if the decade is odd and the adjustment to the
year is needed, it will fail to adjust the clock on 2018 (which will be read
as 2020), 2019 (2021), 2038 (2040), 2039 (2041) and so on - but there's no
real way for it to know if it really *is* 2020, or if it's only 2020 because
of the bug.
Still, that does present a reasonable grace period for the problem to be
fixed properly. :)
Your program looks much more elegant. We didn't manage to find
Territory_SetTime and I was very surpised there seemed to be no way to set
the clock from a 5-byte UTC value.
However, your program could do with some improvement to make it safer to run
in the boot sequence (at least in the next two years). You ought to check
whether the year ends with a 0 or 1, because if it does then the clock is
already correct.
Many of those who have tried ClockFixer are also using NetTime or FreeTime to
set their clocks via NTP. The BASIC is still useful in the case when an NTP
server (or the internet connection) is unavailable.
Your program would have to be run before NetTime or FreeTime, not after,
because if it ran after NetTime it would end up setting the year back to
2008. I guarded against this (though forgot I had done so when it came to
the instructions!).
It will all go wrong sometime before 2018, however. When the actual date
reaches 29th February 2012, the clock will report 1st March 2014, and your
program and mine will set the date to 1st March 2012. I'm not sure what
happens for the rest of that year - it may well stay a day out. I'm not
intending to test just now, as I've ended up deleting recent news articles a
few times today by testing far into the future and then forgetting the clock
was still wrong!
--
Matthew Phillips
Dundee
> Still, that does present a reasonable grace period for the problem to be
> fixed properly. :)
The culprit is CheckYear in the kernel, which is called during system
init when the hardware clock's time&date are copied into memory and
when OS_Word is called to set the time&date. Source: http://bit.ly/8b4TnA
(specifically from line 801).
Basically, the code expects a Philips hardware clock chip to store the
year as a 2-bit value (0-3), but the Iyonix uses a Dallas device that
stores the year in BCD format. This causes the date to be
miscalculated and adjusted from 2009 to 2012.
A patch for the kernel should be submitted to ROOL.
C.
[quick year check/fix]
> However, your program could do with some improvement to make it safer to
> run in the boot sequence (at least in the next two years). You ought to
> check whether the year ends with a 0 or 1, because if it does then the
> clock is already correct.
Yes - the opposing problem to the 2018/19 (becoming 20/21) one that I
mentioned. In theory, *if* the program is only run durng the boot sequence,
then it should only see the time after the problem has caused the year to
progress; the program sets the year, so is one of the things that causes the
problem to manifest at the next boot. IYSWIM.
However, I'll add that check just to be sure.
> Many of those who have tried ClockFixer are also using NetTime or FreeTime
> to set their clocks via NTP. The BASIC is still useful in the case when
> an NTP server (or the internet connection) is unavailable.
> Your program would have to be run before NetTime or FreeTime, not after,
> because if it ran after NetTime it would end up setting the year back to
> 2008. I guarded against this (though forgot I had done so when it came to
> the instructions!).
I don't use either, so I've no idea how they work. Presumably, *this* would
be where the 2010/2011 situation *would* be a problem - so making that
change should solve it.
That change is to add an AND to the condition:
IF (!(Ordinals%+24)/10) MOD 2<>0 AND !(Ordinals%+24) MOD 10>1 THEN
So the whole program becomes:
DIM Time5% 5, Ordinals% 32
?Time5%=3
SYS"OS_Word",14,Time5%
SYS"Territory_ConvertTimeToOrdinals",-1,Time5%,Ordinals%
IF(!(Ordinals%+24)/10) MOD 2<>0 AND !(Ordinals%+24) MOD 10>1 THEN
!(Ordinals%+24)=!(Ordinals%+24)-2
SYS"Territory_ConvertOrdinalsToTime",-1,Time5%,Ordinals%
SYS"Territory_SetTime",Time5%
ENDIF
> It will all go wrong sometime before 2018, however. When the actual date
> reaches 29th February 2012, the clock will report 1st March 2014, and your
> program and mine will set the date to 1st March 2012.
Of course it will! Doh! I must have had a brain fart when I thought it
wouldn't be affected by leap years. What a plonker.
> I'm not sure what happens for the rest of that year - it may well stay a
> day out. I'm not intending to test just now, as I've ended up deleting
> recent news articles a few times today by testing far into the future and
> then forgetting the clock was still wrong!
Luckily, I no longer read news and email on RISC OS, so I can test to my
heart's content. Or until I get bored. Or spot something more interesting.
:)
<a few moments later>
Right. As you say, 29 Feb 2012 becomes 1 Mar 2014 becomes 1 Mar 2012.
It should be easy enough to build in a check for leap years +2, and if so
and it's 1st March to set it back a day. However, that means the clock will
be pushed back a day if it really *is* 1st March. So it's either leave it as
is in that respect or introduce another anomaly for the user to deal with. I
think I'll leave that as is, and just add in the check for years ending 0 or
1. Just over a year should be long enough for a proper fix.
Ugh. Assembler. Why did I look? I can't make sense of that any more! (I was
never too strong with it to start with!)
>
> > Your program would have to be run before NetTime or FreeTime, not after,
> > because if it ran after NetTime it would end up setting the year back to
> > 2008. I guarded against this (though forgot I had done so when it came
> > to the instructions!).
>
> I don't use either, so I've no idea how they work. Presumably, *this*
> would be where the 2010/2011 situation *would* be a problem - so making
> that change should solve it.
Grr. Another brain fart. Yes, that would solve it - in 2010/11, but not
subsequently - it definitely needs to be run before either of those to
prevent 'extra' corrections.
Doh!
Again.
I can't even use an ongoing hangover as an excuse (given that it's new years
day) - no alcohol has hit my system in the last few days. I'm just a bit
tired after playing Resistance: Fall of Man through to completion over the
last couple of days, finishing in the early hours last night. (I didn't even
realise ATT that it was past midnight and I'd blinked for the usual new year
celebratory noises).