aboutsummaryrefslogtreecommitdiffstats
path: root/usr/uptime.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--usr/uptime.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/usr/uptime.c b/usr/uptime.c
new file mode 100644
index 0000000..1062217
--- /dev/null
+++ b/usr/uptime.c
@@ -0,0 +1,40 @@
+#include "gbos.h"
+/* uptime: time since boot, from the kernel's 64 Hz tick (SYS_UPTIME).
+
+ No long division/shifts: SDCC pulls those from sm83.lib, whose modules
+ link into their own areas that land in the $A000 RAM window (see
+ usr/build.sh). Everything here is inlined 8/32-bit add/sub/compare:
+ ticks>>6 done bytewise, then day/hour/minute by bounded subtraction. */
+
+static void two(unsigned int v) { /* zero-padded 2-digit field */
+ if (v < 10) putc('0');
+ putu(v);
+}
+
+void main(void) {
+ unsigned char t[4];
+ union { unsigned long l; unsigned char b[4]; } u; /* sm83 is LE */
+ unsigned long sec;
+ unsigned int d, h, m;
+
+ gticks(t); /* 32-bit LE tick count, 64 Hz */
+
+ /* seconds = ticks >> 6, composed a byte at a time (24 bits is 194 days) */
+ u.b[0] = (unsigned char)((t[0] >> 6) | (t[1] << 2));
+ u.b[1] = (unsigned char)((t[1] >> 6) | (t[2] << 2));
+ u.b[2] = (unsigned char)((t[2] >> 6) | (t[3] << 2));
+ u.b[3] = 0;
+ sec = u.l;
+
+ d = 0;
+ while (sec >= 86400UL) { sec -= 86400UL; d++; } /* <= 194 rounds */
+ h = 0;
+ while (sec >= 3600UL) { sec -= 3600UL; h++; } /* <= 23 rounds */
+ m = 0;
+ while (sec >= 60UL) { sec -= 60UL; m++; } /* <= 59 rounds */
+
+ puts("up ");
+ if (d) { putu(d); puts("d "); }
+ putu(h); putc(':'); two(m); putc(':'); two((unsigned int)sec);
+ nl();
+}