Local Sidereal Time
This code from block 1170 is loaded into node 512. It computes sidereal time for 120o west longitude (Reno).
More importantly, it is my first use of interpreted code (see init below).
*.16
Multiply by a 16-bit fraction. It's similar to (actually uses) *.17 but allows fractions greater than 1.
d/mod
Basic divide code with a 36-bit positive dividend; 18-bit negative divisor, 18-bit positive quotient and remainder. (This is a classic example of trying to describe a word in its name. The ROM name is --u/mod, which is merely cryptic.)
/mod
- Convert an 18-bit unsigned number to a 36-bit number
- d/mod returns remainder and quotient
*.
Fraction multiply discarding buried multiplicand.
nip
Discard 2nd number on stack. Used twice.
*
Multiply 18-bit positive numbers for a 36-bit product.
leap
Correct days for leap year. Works from 1901 to 2099 since 2000 is a leap year.
- Input is day and 4-digit yymm
- Separate year. If not divisible by 4, return
- Otherwise if month is less than 3, return
- Otherwise add 1 to day
This is a good example of how conditional returns can simplify logic.
days
yymmdd on stack. Computes days since 000101 (2000/01/01):
- Separate days and call leap
- Multiply years by 365.25 (1461 as 2-bit fraction). Add 3 (round) since 2000 is a leap year. Discard fraction
- Fetch zeroth day of month from table starting at RAM address 1
- Add to days
lst
Takes minute and yymmdd on the stack and returns LST in minutes:
- Multiplies days since 2000 (scaled by 4) by sidereal minutes/day (unsigned fraction 258382). Result is minutes in high-order product
- Time is corrected to UTC (420) and adjusted to sidereal (fraction 65714)
- Sidereal time at 2000/01/01 is added (402). (This number had to be fudged to get the correct answer, so there might be an error somewhere. Appreciate feedback.)
- Longitude is added (120oW: -480)
- Minutes so far are positive; are returned modulo 1440 (minutes/day)
init
This code is still compiled by native colorForth on the PC, which can access the CMOS clock and defines minute of the day and yymmdd.
These numbers are compiled by lit into the code specified by init to be executed. It jumps to lst with them on the stack and returns with LST on the stack. Node 512 does this and then awaits further instructions, since the return from lst is to the 4-port execute from reset.
That's the end of this block of code. It leaves a number on the stack. Another block of code will be loaded into this node. It will find LST on the stack, since loading code disturbs only the bottom-of-stack.
This procedure is effectively the Forth interpreter. Code is executed at compile time. Unlimited code can be executed by a node, provided only that it's factored into 64-word chunks.
Options
If lst is commented out, over will retrieve PDT. If 420 is added, it becomes UTC. This is useful for debugging, but a civil clock doesn't need this code at all.
Replacing minute lit and yymmdd lit with numbers will compute LST for a particular time. Useful for debugging.