diff options
Diffstat (limited to '')
| -rw-r--r-- | usr/uptime.c | 40 |
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(); +} |
