aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blog/templeos-time-2019-06-21.markdown146
-rw-r--r--static/img/analog_clock.jpgbin0 -> 232779 bytes
2 files changed, 146 insertions, 0 deletions
diff --git a/blog/templeos-time-2019-06-21.markdown b/blog/templeos-time-2019-06-21.markdown
new file mode 100644
index 0000000..8d6b6b6
--- /dev/null
+++ b/blog/templeos-time-2019-06-21.markdown
@@ -0,0 +1,146 @@
+---
+title: "TempleOS: Date/Time Code"
+date: 2019-06-22
+---
+
+# TempleOS: Date/Time Code
+
+## Introduction
+
+In the [last post](https://christine.website/blog/templeos-2-god-the-rng-2019-05-30)
+we discussed `god`, the random number generator of TempleOS. This post is going to
+cover the time handling subsystem of the TempleOS kernel. As mentioned [before](https://christine.website/blog/sorting-time-2018-08-26),
+time is an unfortunately complicated thing, and legacy systems stapled onto
+legacy systems complicate this a lot. It also doesn't help that we consider
+one day 24 hours, even though it's more accurately slightly less than that.
+Most people consider a year to be 365 days, but the actual movement of the ball
+Earth around the Sun is closer to 365 days and about [six hours](https://www.scienceabc.com/eyeopeners/why-do-we-have-a-leap-day-leap-year-after-every-4-years.html).
+To compensate for this, every 4 years we add a day to the calendar called a
+Leap Day. This complicates time calculations. And this isn't even going to
+cover time zones because I want you readers to have some shred of sanity left.
+
+## Problem space description
+
+Time is an unfortunately complicated thing to handle. The goal of this part of
+the TempleOS kernel is to allow users to programmatically get the current "real
+time", or the time of the day. This is sometimes called "wall clock time",
+referring to the offices where Unix was developed having literal clocks on the
+wall to tell you the time. When you read a clock off the wall, you get the
+current time in hours, minutes and sometimes seconds. See this example below:
+
+![an analog clock](/static/img/analog_clock.jpg)
+
+This clock either says it is 2:51:59 or 14:51:59, as clocks only show a 12 hour
+view of 24 hour days for historical reasons.
+
+## How x86 hardware handles time
+
+The x86 real-time clock keeps track of time with a similar kind of API. The OS
+can query the real-time clock and get the following fields individually:
+
+* Seconds
+* Minutes
+* Hours
+* Weekday
+* Day of month
+* Month
+* Last two digits of the year
+* Sometimes the current century (19 or 20)
+
+Note the last two digits of the year. This is returned because computers
+historically did not keep track of the current century in order to save memory.
+This famously caused the Y2K bug that [almost caused chaos globally](https://en.wikipedia.org/wiki/Year_2000_problem). Thankfully this problem was averted.
+
+## How Linux handles time
+
+Linux handles time by keeping track of [the number of seconds since January 1, 1970](https://en.wikipedia.org/wiki/Unix_time).
+Traditionally programs use a signed 32 bit integer value for this. You might
+notice that this is a drastically different time format than what the real-time
+clock provides. When Linux reads from the real time clock, it does some math to
+convert these real time values to a unix timestamp.
+
+### The Rockchip calendar hack
+
+Of course, this assumes that the hardware is behaving correctly. There have been
+cases in the past where [buggy hardware required patches](https://lore.kernel.org/patchwork/patch/628142/).
+If the hardware calendar and the software understanding of that calendar get out
+of sync, things get really confused.
+
+## How TempleOS handles time
+
+TempleOS has two main time types, [CDateStruct](https://github.com/Xe/TempleOS/blob/master/Kernel/KernelA.HH#L193-L198)
+and [CDate](https://github.com/Xe/TempleOS/blob/master/Kernel/KernelA.HH#L186-L190).
+Let's look at each of these in more detail:
+
+```c++
+public class CDateStruct
+{
+ U8 sec10000,sec100,sec,min,hour,
+ day_of_week,day_of_mon,mon;
+ I32 year;
+};
+
+public I64 class CDate
+{
+ U32 time;
+ I32 date;
+};
+```
+
+The `I64 class CDate` part of the definition makes the HolyC compiler align
+instances of it across the size of a int64 value, or 8 bytes. This also makes
+the compiler treat instances of it like an integer value.
+
+Here are approximate Zig equivalents:
+
+```zig
+pub const CDateStruct = packed struct {
+ sec10000: u8,
+ sec100: u8,
+ sec: u8,
+ min: u8,
+ hour: u8,
+ day_of_week: u8,
+ day_of_mon: u8,
+ mon: u8,
+ year: i32,
+};
+
+pub const CDate = packed struct {
+ time: u32,
+ date: i32,
+}
+```
+
+The [TempleOS documentation](https://templeos.holyc.xyz/Wb/Doc/TimeDate.html)
+describes `CDate` like this:
+
+```
+TempleOS uses a 64-bit value, CDate, for date/time. The upper 32-bits are the
+days since Christ. The lower 32-bits store time of day divided by 4 billion
+which works out to 49710ths of a second. You can subtract two CDate's to get a
+time span.
+
+Use CDATE_FREQ to convert.
+```
+
+And it [describes the `date` field](https://templeos.holyc.xyz/Wb/Doc/Date.html)
+of `CDate` like this:
+
+```
+Dates are 32-bit signed ints representing the number of days since the birth of
+Christ. Negative values represent B.C.E. dates.
+```
+
+B.C.E. usually means "Before Common Era", which is a way to say "the time before
+Jesus Christ was born". Christianity ended up being such a core part of global
+culture that the calendar was reset because of it.
+
+
+
+* CMOS real time clock API
+ * NowDateTimeStruct();
+ * How to read from the CMOS clock
+ * The bug in the time code
+* Live Demo (Zig/wasm+JS)
+
diff --git a/static/img/analog_clock.jpg b/static/img/analog_clock.jpg
new file mode 100644
index 0000000..3bf2b74
--- /dev/null
+++ b/static/img/analog_clock.jpg
Binary files differ