[comp.sys.handhelds] Clock program for HP28

neil@kcl-cs.UUCP (Neil Faulks) (05/30/90)

Some time ago someone posted a clock program for the 28C
Does anyone have a version for the 28S ?

-- 
Neil Faulks
..!ukc!kcl-cs!neil
neil%cs.kcl.ac.uk

howard@lysator.liu.se (M V Howard) (05/31/90)

neil@kcl-cs.UUCP (Neil Faulks) writes:

>Some time ago someone posted a clock program for the 28C
>Does anyone have a version for the 28S ?

>-- 
>Neil Faulks
>..!ukc!kcl-cs!neil
>neil%cs.kcl.ac.uk

NOSTALGIA_BIT = ON

Ah, I remember, back in the good old days, when it was one man and his
HP-28S, there was this amazing clock program which displayed digits the
height of the display. Truly stunning, utterly facinating and suitably
impressive.

NOSTALGIA_BIT = OFF

Maybe someone knows where to get hold of this ?  I've lost my copy ;-(

/MHd

--
Programming isn't a science,         | EMAIL: howard@lage.lysator.liu.se
it's an art.                         |        howard@lysator.liu.se
Why is it called common sense,       |        Martin_Howard.d89.lith@xns.liu.se
when so few possess it ?             |

jdg@hpqtdla.HP.COM (James Gentles) (06/01/90)

There follows a clock utility for the 28S (version 2BB) as posted by Aaron
Dinwiddle in January 1990 to the net. Only the syseval call to #4554d is
rom dependant, so it should be able to work on other 28S's and even 28C's
if youve got enough memory. 

I have corrected various mistakes in the original posting, however I don't
guarantee to have got them all!
At the end I have re-posted a utility I wrote called EXACT that allows
the 28 clock speed to be varied slightly to account for errors in the
crystal oscillator that it uses to derive the time.

If anyone knows the author of the original code, please post their name so
they can have some credit.
Regards
James Gentles

---------------------------------------------------------------------
      I have no professional connection with Hewlett-Packard's 
    calculator operations other than as a user of their products.
---------------------------------------------------------------------
Opinions expressed are my own, and are not intended to be an official
              statement by Hewlett-Packard Company
---------------------------------------------------------------------
Name:         James Gentles   GM4WZP
Organization: Hewlett-Packard  Queensferry Telecomunications Division
Email:        jdg@hpqtdla.hpsqf.hp.com                         hp-sdd 
Address:      Station Road, South Queensferry, West Lothian, Scotland
---------------------------------------------------------------------


CLOCK UTILITY
=============

     CLOCK and all the other programs in that directory perform the function
of turning the HP28S into a clock and calendar.  This works by calling a
syseval at #4554d (version 2BB) which is a continuous counter register.  The
time and date is calibrated off the counter using the SETTIME and SETDATE
programs.

To set time and date to : 2:27.50 pm, Nov. 12, 1989

                    ENTER...  14.2750 SETTIME
                    THEN....  11.121989 SETDATE

pressing CLOCK yields

          +---------------------+
          |                     |
          |Sun, Nov  12, 1989   |
          |                     |  <- The time will continuously update
          |     2:27:50 pm      |
          +---------------------+

Press any key other than ON to restore display (Pressing ON leaves garbage
on the stack).

     CLDR displays a scrolling calendar of the current month.


           CLOCK   C2BD     TM      5A2F     JC2     5E06     MTHLST  66D5
           FMTTIME 5ACF     CJ2     CF65     DM      4247
           CLDR    66A6?    FMTDATE 57B8     DOW2    3034     TMSTMP  59DA
           SETTIME CEB3     JC      EEA3     DAYS    3ADB     CKOR    var?
           SETDATE 6138     CJ      B4B4     NDAYS   F062     DKOR    var?
           TIME    A651     MTHS    4398
           DATE    FD70     DOW     34F7?    CAL     EE76


  CLOCK:    << RCWS 64 STWS LCD-> CLLCD WHILE KEY NOT REPEAT " " DATE
               FMTDATE + 2 DISP TIME SWAP DROP FMTTIME "      " SWAP
               + 4 DISP END DROP ->LCD STWS CLMF >>

SETTIME:    << 0 'CKOR' STO TIME SWAP DROP HMS-> SWAP HMS-> DUP2
               IF > THEN 24 + END SWAP - 'CKOR' STO >>

SETDATE:    << -> d << DM d CJ2 707788800 * - 'DKOR' STO >> >>

   TIME:    << TM DUP B->R 29491199 / 24 MOD CKOR + 24 MOD ->HMS >>

   DATE:    << DM DKOR - 707788800 / JC2 >>

     TM:    << RCWS 64 STWS # 4554d SYSEVAL SWAP STWS >>

FMTTIME:    << RCLF 58 CHR -> t f c << t 10000 * IP 10000 / 't' STO
               IF t 12 >= THEN t 12 - 't' STO " pm" ELSE " am" END
               IF t 1 < THEN t 12 + 't' STO END t IP STD ->STR c + t
               FP 4 FIX ->STR DUP 3 4 SUB c + SWAP 5 6 SUB + + SWAP
               + f STOF >> >>

FMTDATE:    << RCLF STD -> d f << d DOW2 SWAP DROP ", " + MTHS d IP
               GET + " " + d FP 100 * IP ->STR + ", " + d 100 * FP
               10000 * ->STR + f STOF >> >>

     JC:    << 1721119.2 - DUP DUP 36524.25 / IP SWAP OVER + SWAP 4
               / IP - DUP ROT DROP 365.25 SWAP OVER / IP SWAP OVER *
               SWAP ROT ROT IP - .3 - DUP 30.6 SWAP OVER / IP SWAP
               OVER * SWAP -> k << SWAP OVER - 1 + SWAP DROP k >>
               DUP 9 IF > THEN ROT 1 + SWAP 9 - ELSE ROT SWAP 3 + END
               ROT IP >>

     CJ:    << << 2.85 - 12 / + >> -> y m d yp << 367 y m yp EVAL *
               IP y m yp EVAL IP - .75 y m yp EVAL IP * - d + IP .75
               y m yp EVAL 100 / IP * - IP 1721115 + >> >>

    DOW:    << CJ 1 + 7 MOD DUP 1 + DAYS SWAP GET >>

    JC2:    << JC 100 / + SWAP 1000000 / + >>

    CJ2:    << DUP IP SWAP FP 100 * DUP IP SWAP FP 10000 * ROT ROT CJ >>

   DOW2:    << CJ2 1 + 7 MOD DUP 1 + DAYS SWAP GET >>

   DAYS:    { "Sun" "Mon" "Tues" "Weds" "Thur" "Fri" "Sat" }

  NDAYS:    { 31 28 31 30 31 30 31 31 30 31 30 31 }

   MTHS:    { "Jan " "Feb " "Mar " "Apr " "May " "June" "July" "Aug "
              "Sept" "Oct " "Nov " "Dec " }

 MTHLST:    << RCLF STD -> f << DUP IP SWAP FP 10000 * -> mm yy << yy
               mm 1 DOW DROP -> dow << "      " -> s << { } s MTHS
               mm GET + " " + yy ->STR + s + + "  S  M  T  W  T  F  S"
               + -> ml << "" IF dow 0 <> THEN IF 1 dow <= THEN 1 dow
               START "   " + NEXT END END 1 NDAYS mm GET IF mm 2 ==
               yy 4 MOD 0 == AND THEN 1 + END FOR x " " + IF x 10 <
               THEN " " + END x ->STR + NEXT DUP SIZE -> dl s
               << 0 s 21 / IP FOR x ml dl x 21 * 1 + DUP 20 + SUB +
               'ml' STO NEXT ml " " + >> >> >> >> >> f STOF >> >>

     DM:    << RCWS -> w << 64 STWS TIME HMS-> 12 SWAP - 29491200 * DUP
               IF 0 < THEN NEG - ELSE + END B->R w STWS >> >>

 TMSTMP:    << DATE FMTDATE PR1 TIME FMTTIME PR1 3 DROPN CR CR >>

   CLDR:    << LCD-> SWAP MTHLST DUP SIZE -> l s << WHILE KEY NOT
               REPEAT 0 s 1 - FOR k 1 4 FOR d l k d + IF DUP s >
               THEN s - END GET d DISP NEXT .5 WAIT NEXT END DROP
               ->LCD CLMF >> >>

   CKOR:    13.2727633333          ;  Varies when time is set.

   DKOR:    -1.46830298706E15


----------------------------------------------------------------------------

EXACT: A utility addition to the clock function to improve accuracy

This routine when added to the suite of programs for the clock on the 
HP28S will allow you to automatically increase the accuracy of the clock.
It works as follows. It has stored in EXLST the binary when the clock was
last known to be correct. If you tell it the time now it then knows the
length of time since the last EXACT and the error between your entry and 
its time. This is used to offset DIVR which is a variable which translates
the clock binary into a real of the format H.MMSS. This has been written
for one particular clock routine, author unknown, but it was last posted
to notes in Jan.  It could be easilty modified for other clock routines.

Modification to existion programs:
TIME and SETTIME both contain 29491199, which is the divisor to get from
   the 28S binary to H.MMSS. This is really 60*60*8192 ( the 28S clock
   is incremented 8192ish times a second ). These should be replaced with
   DIVR, and DIVR should contain 29491200.
DATE and SETDATE similarily contain 707788800 which is 24*DIVR. Replace 
   this with DIVR 24 * in both routines

The first time you use the routine:
1. Set the time exactly using the old method SETTIME and immediately execute
   syseval #4554d (2BB). Store it in EXLST.
2. Any subsequent setting enter H.MMSS then press EXACT instead of SETTIME.

A warning:
1. Allow a reasonable error (>5 seconds) to build up between pressing
   EXACTs. 
2. Make sure you do get the time exact when you use EXACT or you'll make
   the accuracy worse. You could save off old versions of DIVR if you
   want to be save. If however you then reinstate them you will then have
   to reset the time with SETTIME and SETDATE.
3. I cannot guarantee the code, I am using it myself but it takes many days
   of waiting to check that the accuracy is improving!

Footnote:
   DIVR should be 29491200 for a perfect crystal ( I think ), thats 60 *
   60 * 8192. That gave me an increase of about 1 second/day, My 28
   seems to like 29491600 better, less than 1 second/5days so far.
   Thats 13ppm off frequency


Uses:  TIME: Returns the binary obtained by calling syseval #4554d (2BB) 
             in level 2 and the current time in H.MMSS in level 1.  
      EXLST: A variable containing the binary returned from syseval #4554d 
             (2BB) at a time in the past when the time was known exactly.
    SETTIME: Accepts a number H.MMSS and sets up the clock
       DIVR: A constant 29491200 ( or thereabouts)

EXACT  C2F7
<< TIME EXLST -> s bn n bo
  << n s HMS- HMS-> bn B->R bo B->R - DIVR 
  / -> er tm
    << er tm / 8192 * DIVR + 'DIVR' STO TIME 
    SWAP DROP er ->HMS HMS- SETTIME bn 'EXLST'
     STO
    >>
  >>
>>
 
SYMBOL KEY:
->  141:-Right_hand_arrow 
<<  146:-Start_program_construct 
>>  147:-End_program_construct *