| Archive Archived Front Page Articles. |
12-31-2008, 03:16 PM
|
#1
|
|
R E D R U M
Development Front Retired Staff Expert Zuner
Join Date: May 2008
Posts: 2,975
|
Cause of Zune 30 leapyear problem ISOLATED!
After doing some poking around in the source code for the Zune's clock driver (available free from the Freescale website), I found the root cause of the now-infamous Zune 30 leapyear issue that struck everyone on New Year's Eve.
The Zune's real-time clock stores the time in terms of days and seconds since January 1st, 1980. When the Zune's clock is accessed, the driver turns the number of days into years/months/days and the number of seconds into hours/minutes/seconds. Likewise, when the clock is set, the driver does the opposite.
The Zune frontend first accesses the clock toward the end of the boot sequence. Doing this triggers the code that reads the clock and converts it to a date and time. Below is the part of this code that determines the year component of the date:
Code:
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
Under normal circumstances, this works just fine. The function keeps subtracting either 365 or 366 until it gets down to less than a year's worth of days, which it then turns into the month and day of month. Thing is, in the case of the last day of a leap year, it keeps going until it hits 366. Thanks to the if (days > 366), it stops subtracting anything if the loop happens to be on a leap year. But 366 is too large to break out of the main loop, meaning that the Zune keeps looping forever and doesn't do anything else.
The unfortunate part is that there isn't anything that can be done to fix this besides somehow changing what the clock is set to (which is exactly what the battery disconnection trick ends up doing). On the other hand, it shows that Microsoft is correct: tomorrow, everyone's Zunes will operate normally again. However, if Microsoft doesn't fix this part of the firmware, the whole thing will happen all over again in 4 more years.. Hopefully by then a fix will be in place.
/truck out
Last edited by itsnotabigtruck; 12-31-2008 at 03:26 PM.
Reason: switched to pastie


|
|
|
12-31-2008, 03:20 PM
|
#2
|
|
Squirt
Join Date: Jun 2007
Posts: 13
|
Is it even possible to fix?
Zune doesn't work when frozen and Zune doesn't work with a dead battery....
|
|
|
12-31-2008, 03:25 PM
|
#3
|
|
Retired Staff Expert Zuner
Join Date: Aug 2008
Posts: 2,510
|
|No, it will never be fixed.|
Anyway, good find!
|
|
|
12-31-2008, 03:27 PM
|
#4
|
|
Super Zuner
Join Date: Nov 2007
Location: In a hypocritical world
Posts: 1,653
|
I wonder how many people will still be using Zune 30's in 4 years.

|
|
|
12-31-2008, 03:33 PM
|
#5
|
|
Holy Zuner
Development Front Retired Staff Holy Zuner
Join Date: Jan 2007
Posts: 8,665
|
That code is pretty simple to correct, it's just a simple enough goof. Just have to recompile the driver, put it into the firmware and send out a firmware update, unless I'm missing something.
|
|
|
12-31-2008, 03:36 PM
|
#6
|
|
R E D R U M
Development Front Retired Staff Expert Zuner
Join Date: May 2008
Posts: 2,975
|
Quote:
Originally Posted by Tobososlow
I wonder how many people will still be using Zune 30's in 4 years.
|
Good point.
Quote:
Originally Posted by M&N
That code is pretty simple to correct, it's just a simple enough goof. Just have to recompile the driver, put it into the firmware and send out a firmware update, unless I'm missing something.
|
Yeah. The ZuneInsider post didn't seem to imply it was something they were planning on correcting right away though.


|
|
|
12-31-2008, 03:39 PM
|
#7
|
|
Experienced Member
Join Date: Jun 2007
Location: El Paso, TX
Posts: 941
|
wow, i got this....my zune keeps freezing at the load screen and have to let die wtf. oh well, not like im a constant user, meh.

|
|
|
12-31-2008, 03:49 PM
|
#8
|
|
Holy Zuner
Development Front Retired Staff Holy Zuner
Join Date: Jan 2007
Posts: 8,665
|
Quote:
Originally Posted by itsnotabigtruck
Good point.
Yeah. The ZuneInsider post didn't seem to imply it was something they were planning on correcting right away though.
|
They'll stick it in next update. I'm sure they will update it within 4 years...
|
|
|
12-31-2008, 04:41 PM
|
#9
|
|
Squirt
Join Date: Jun 2008
Posts: 23
|
so how does one disconnect the battery, and is there a way I can trick my zune into thinking its tomorrow by possibly changing the date on my PC?
|
|
|
12-31-2008, 04:45 PM
|
#10
|
|
R E D R U M
Development Front Retired Staff Expert Zuner
Join Date: May 2008
Posts: 2,975
|
Quote:
Originally Posted by gamefreak202
so how does one disconnect the battery, and is there a way I can trick my zune into thinking its tomorrow by possibly changing the date on my PC?
|
Disconnecting the battery requires opening it up, which is totally not worth it when it's going to start working again without any further action tomorrow.
AFAIK, the clock is set by downloading a file from Microsoft's DRM servers (to make it hard to mess with the clock and therefore listen to expired Zune Pass tracks), so your PC time doesn't even matter.


|
|
|
12-31-2008, 04:54 PM
|
#11
|
|
Squirt
Join Date: Jun 2008
Posts: 23
|
ok then so your saying it will be fine by tomorrow....? Guaranteed?
|
|
|
12-31-2008, 06:28 PM
|
#12
|
|
Squirt
Join Date: Dec 2008
Posts: 10
|
Great work itsnotabigtruck!
|
|
|
12-31-2008, 06:41 PM
|
#14
|
|
Squirt
Join Date: Dec 2008
Posts: 10
|
Quote:
Originally Posted by freshlogic
I think changing line 263 from "if(days > 366)" to "if(days >= 366)" might fix the bug...
|
I was thinking the same thing (edit: wrong...see below) when analyzing it.
--
The complete output from stepping through the loop starting 10593 days from January 1st 1980 can be found HERE.
Last edited by programphases; 12-31-2008 at 07:53 PM.
Reason: merged 2 consecutive posts (ffr, use edit)
|
|
|
12-31-2008, 07:30 PM
|
#15
|
|
Zewbie
Join Date: Dec 2008
Posts: 6
|
Quote:
Originally Posted by freshlogic
I think changing line 263 from "if(days > 366)" to "if(days >= 366)" might fix the bug:
|
That would prevent the infinite loop, but would introduce a new bug where it advances the year on the last day of a leap year. It would have thought today was December 31, 2009. That's better than locking up, but it also would mean that all time-limited DRM media would stop working. So, if you have a Zune Pass, none of your songs would play.
What's needed is a break within an else like this (I hope, my C's a little rusty, and was never that good to begin with):
Code:
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
else
{
break;
}
}
else
{
days -= 365;
year += 1;
}
}
Last edited by twhoffman; 12-31-2008 at 07:32 PM.
|
|
|
12-31-2008, 07:39 PM
|
#16
|
|
Zewbie
Join Date: May 2008
Posts: 1
|
wow, great work, I was so confused when I turned mine on today it was like "wtf?!" but I understand now.
|
|
|
12-31-2008, 07:46 PM
|
#17
|
|
Zuner
Join Date: Sep 2008
Location: Sacremento CA
Posts: 80
|
cool thats good. i thought my zune was done for good which would have really sucked.

|
|
|
12-31-2008, 07:52 PM
|
#18
|
|
Squirt
Join Date: Dec 2008
Posts: 10
|
Quote:
Originally Posted by twhoffman
That would prevent the infinite loop, but would introduce a new bug where it advances the year on the last day of a leap year. It would have thought today was December 31, 2009. That's better than locking up, but it also would mean that all time-limited DRM media would stop working. So, if you have a Zune Pass, none of your songs would play.
What's needed is a break within an else like this (I hope, my C's a little rusty, and was never that good to begin with):
Code:
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
else
{
break;
}
}
else
{
days -= 365;
year += 1;
}
}
|
Will the break release from the outer if statement? (edit: yes...see below)
This should work too:
Code:
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
else if (days == 366)
days -= 366;
}
else
{
days -= 365;
year += 1;
}
}
Last edited by programphases; 12-31-2008 at 08:10 PM.
|
|
|
12-31-2008, 07:54 PM
|
#19
|
|
R E D R U M
Development Front Retired Staff Expert Zuner
Join Date: May 2008
Posts: 2,975
|
Quote:
Originally Posted by programphases
Will the break release from the outer if statement?
Maybe this:
<snipped>
|
The break statement in C breaks out of the nearest loop (ignoring any ifs on the way back up).


|
|
|
12-31-2008, 08:07 PM
|
#20
|
|
Squirt
Join Date: Dec 2008
Posts: 10
|
Quote:
Originally Posted by itsnotabigtruck
The break statement in C breaks out of the nearest loop (ignoring any ifs on the way back up).
|
...silly me...
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|