[comp.sys.nsc.32k] Fix to ICM3216 w/ UoTBSD4.2 clock problem

rusty@hocpa.UUCP (M.W.HADDOCK) (01/25/89)

OK, despite a nasty touch of the flu, or whatever it is that's going around
this week, it appears that I've found a fix for the rtc_clock.  My patches
are for the file "/usr/sys/16k/clock.c" and you'll need to recompile/relink
your kernal!  The symptom I was seeing (yours might differ but I can't see
how) was the console displaying

		rtc_clock: Off by 86400 seconds!!!

at a rate of about twice per minute which started on New Year's Eve.  Well,
the twice per minute comes from /etc/update which syncs the disks every
30-seconds.  If you kill this process you should not see this problem but
may Heaven help you if the system crashed.  Anyhow, this sync apparently
caused the real time clock to be compared to the file system time and the
differences 'tween the two were calculated to be around 86400 seconds.
Funny, that's the number of seconds in a day!  So, I traced though the above
file and did all the calendar/date crunching by hand until I discovered the
bug.  From the way I read the code, leap years were not handled correctly
when resetting the RT Clock and when calculating GMT-->seconds.  While I'm
not too sure of the consequences, the clock chip did not have the leap_year
counter in the Clock Setting Register properly set either so I fixed that as
well (the second change below).

As a side note, all of this code did come from NSC's SYS V R2R2 port which I
still have on tape.  I compared UoT's file to that of SysV and the code was
almost exactly the same 'cept that UoT's method to calculate seconds from
GMT didn't work for all cases and 1989 was the first year (in a while) that
caused things to break.  I can see how they made their mistakes in coding.
I guess someone stayed up to late one night.  :-)

Anyhoot, here's the patch to /usr/sys/16k/clock.c (or /sys/16k/clock.c).  It
can be applied by hand as it's simple enough.  It's been nearly 3 hours
since I rebooted with this patch and I haven't seen the clock complain about
being a day off yet.  I hope this really fixes the problem.  Let me know if
it doesn't!!!  Oh, in case there are source code differences, I bought my
BSD (binary license #2) around Feb-March of 1987 so it's possible that newer
versions of the distribution tape (WERE THERE ANY???) may already have this
fixed.  If so, please let me know about that too!

Oh well, enough for now and it's off to bed for me.  It's almost 1am and I'm
s'pose to be sick.

					-Rusty-

P.S. In disassembling the pcc's output it appears that any integer division
or multiplication by an integer power of two is done by division or
multiplication as opposed to simply shifting in the appropriate direction.
Phoo! :-)

====

% diff clock.c.old clock.c
151c151,152
< 	*rtc->rtc_csr = RTCCSR_24HOUR;
---
> 	/* *rtc->rtc_csr = RTCCSR_24HOUR;  I know SysVR2R2 does this too
> 			but it doesn't seem necessary since we do it RSN */
154c155
< 	*rtc->rtc_csr = RTCCSR_24HOUR | (gmtp->tm_year % 4);
---
> 	*rtc->rtc_csr = RTCCSR_24HOUR | ((gmtp->tm_year & 3) << 2);
243c244
< 		tim = (365 * y) + ((y - 1) / 4);
---
> 		tim = (365 * y) + ((y + 1) / 4);
253c254
< 		tim += (((i + 1) * 306) / 10) - ((y & 3) ? 64 : 63);
---
> 		tim += (((i + 1) * 306) / 10) - (((y+2) & 3) ? 64 : 63);


-- 
Rusty Haddock		{uunet!likewise,att,arpa}!hocpa!rusty
AT&T Consumer Products Laboratories - Human Factors Laboratory
Holmdel, New Joyzey 07733   (201) 834-1023  rusty@hocpa.att.com
** Genius may have its limitations but stupidity is not thus handicapped.

rusty@hocpa.UUCP (M.W.HADDOCK) (01/26/89)

In article <509@hocpa.UUCP> I write:
   >P.S. In disassembling the pcc's output it appears that any integer division
   >or multiplication by an integer power of two is done by division or
   >multiplication as opposed to simply shifting in the appropriate direction.
   >Phoo! :-)

Wow!  Did I really write that?  Amos Shapir at NSC Israel reminded me that
this just ain't always the case.   Sorry folks, guess it was ``all'' that
Alka Seltzer Plus and Vics Formula 44 I've been downing for the flu... :-)   
I really do know better than that.

See there kids, drugs'll do it to you every time. :-)))

				-Rusty-

P.S. But at least my patches are holding up!!!
-- 
Rusty Haddock		{uunet!likewise,att,arpa}!hocpa!rusty
AT&T Consumer Products Laboratories - Human Factors Laboratory
Holmdel, New Joyzey 07733   (201) 834-1023  rusty@hocpa.att.com
** Genius may have its limitations but stupidity is not thus handicapped.

funke@turing.toronto.edu (Mark Funkenhauser) (01/27/89)

 In article <509@hocpa.UUCP> rusty@hocpa.UUCP (M.W.HADDOCK) writes:
 >
 > ... it appears that I've found a fix for the rtc_clock.  My patches
 >are for the file "/usr/sys/16k/clock.c" and you'll need to recompile/relink
 >your kernal!  The symptom I was seeing (yours might differ but I can't see
 >how) was the console displaying
 >
 >		rtc_clock: Off by 86400 seconds!!!
 >
 >Anyhoot, here's the patch to /usr/sys/16k/clock.c (or /sys/16k/clock.c).

 >====
 >
 >% diff clock.c.old clock.c
 >151c151,152
 >< 	*rtc->rtc_csr = RTCCSR_24HOUR;
 >---
 >> 	/* *rtc->rtc_csr = RTCCSR_24HOUR;  I know SysVR2R2 does this too
 >> 			but it doesn't seem necessary since we do it RSN */

   Yes it does!  See below.


 >154c155
 >< 	*rtc->rtc_csr = RTCCSR_24HOUR | (gmtp->tm_year % 4);
 >---
 >> 	*rtc->rtc_csr = RTCCSR_24HOUR | ((gmtp->tm_year & 3) << 2);
 >243c244
 >< 		tim = (365 * y) + ((y - 1) / 4);
 >---
 >> 		tim = (365 * y) + ((y + 1) / 4);
 >253c254
 >< 		tim += (((i + 1) * 306) / 10) - ((y & 3) ? 64 : 63);
 >---
 >> 		tim += (((i + 1) * 306) / 10) - (((y+2) & 3) ? 64 : 63);

 =====

 I concur (well almost).
 I spent last night fixing it  ( sans the SysVR2R2 src ).
 I would have fixed it sooner but I wanted the data sheet on the clock chip
 before changing the code.

 You almost got it right.
 Line 151 (see above) MUST REMAIN.  (i.e.  *rtc->rtc_csr = RTCCSR_24HOUR; )
 DO NOT comment it out.
 The data sheet for the clock chip says that
 you cannot set the 12/24 hour clock mode in the csr register at the 
 *same* time as setting the leap year stuff.
 Therefore you must write to  *rtc->rtc_csr  twice!
  (* There's a lesson here somewhere *)


 Since RTC_CENTURY and RTC_STARTDATE are defined and used, 
 I prefer the following so that you can see how the algorithm works 
 and that if if these constants are ever changed (not too likely),
 the bug won't re-occur:

    tim = (365 * y) + (( (y + (RTC_STARTDATE & 3) - 1) )/ 4);
  and
    tim += (((i + 1) * 306) / 10) - (((y + (RTC_STARTDATE & 3)) & 3) ? 64 : 63);



 >Oh, in case there are source code differences, I bought my
 >BSD (binary license #2) around Feb-March of 1987 so it's possible that newer
 >versions of the distribution tape (WERE THERE ANY???) may already have this
 >fixed.  If so, please let me know about that too!

 I don't think there was more than 1 distribution tape.

-----------

 By the way, does anyone shutdown their system on a regular basis ?
 (i.e. every nite) and if so, has anyone had trouble with the date 
 when the machine is rebooted ?
 I have, and it looks like the 12/24 hr bit in the csr register toggles 
 on power-off (or power-on).
 Unix sets it up to be 24 hr mode, but on power-up, the chip is in 12 hr mode.
 It could be the battery but all the other data in the chip registers seem ok.


-------------------------------------------------------
Mark Funkenhauser          {decwrl,ihnp4}!utcsri!funke
CSRI                       funke@csri.toronto.edu
University of Toronto  
-------------------------------------------------------