summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2019-02-26 10:56:52 +0000
committerfishsoupisgood <github@madingley.org>2019-02-26 10:56:52 +0000
commit9b0002fc40f4d8b97cf2064910a9ded467f29276 (patch)
tree637a1cc1dd9c21c8f486dbe03db6a830ebbe768c
downloadgen_msf-9b0002fc40f4d8b97cf2064910a9ded467f29276.tar.gz
gen_msf-9b0002fc40f4d8b97cf2064910a9ded467f29276.tar.bz2
gen_msf-9b0002fc40f4d8b97cf2064910a9ded467f29276.zip
fish
-rw-r--r--Makefile35
-rw-r--r--main.c45
-rw-r--r--msf.c72
-rw-r--r--project.h13
-rw-r--r--prototypes.h14
-rw-r--r--time_fn.c232
-rw-r--r--time_fn.h19
-rw-r--r--util.c38
8 files changed, 468 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..01a4471
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,35 @@
+CSRCS=time_fn.c msf.c util.c main.c
+HSRCS=time_fn.h project.h
+
+OBJS=${CSRCS:%.c=%.o}
+
+PROG=msf
+
+CPPFLAGS=
+CFLAGS=-Wall ${CPPFLAGS}
+
+CPROTO=cproto
+
+DEPFLAGS = -MT $@ -MMD -MP -MF $*.d
+
+${PROG}:${OBJS}
+ ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${OBJS} ${LIBS}
+
+%.o:%.c
+ ${CC} ${CFLAGS} ${DEPFLAGS} -c -o $@ $<
+
+
+protos:
+ echo -n > prototypes.h
+ ${CPROTO} ${CPPFLAGS} -v -e ${CSRCS} > prototypes.h.new
+ cat prototypes.h.new > prototypes.h
+ /bin/rm -f prototypes.h.new
+
+clean:
+ /bin/rm -f *% *~ ${OBJS} ${PROG} *.d *.orig
+
+tidy:
+ astyle -A3 -s2 --attach-extern-c -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} ${LXCSRCS}
+
+-include $(patsubst %,%.d,$(basename $(CSRCS)))
+
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..5eae5ea
--- /dev/null
+++ b/main.c
@@ -0,0 +1,45 @@
+#include "project.h"
+
+
+
+int main (int argc, char *argv[])
+{
+ EPOCH e;
+ UTC u;
+ struct timeval tv;
+ uint8_t s[600];
+
+ unsigned i;
+
+
+ gettimeofday (&tv, NULL);
+
+ e.s = tv.tv_sec;
+ e.ns = tv.tv_usec * 1000;
+
+ u = time_epoch_to_utc (e);
+
+
+ time_print_utc ("Now:\n", u);
+
+ {
+ uint8_t a[60], b[60];
+ msf_make_bits (u, a, b);
+
+ msf_make_stream (s, a, b);
+ }
+
+
+ for (i = 0; i < 600; ++i) {
+ putchar ('0' + s[i]);
+
+ if ((i % 10) == 9) putchar (' ');
+ }
+
+ printf ("\n");
+
+
+
+ return 0;
+
+}
diff --git a/msf.c b/msf.c
new file mode 100644
index 0000000..47e5188
--- /dev/null
+++ b/msf.c
@@ -0,0 +1,72 @@
+#include "project.h"
+
+
+
+
+static void msf_set_ident (uint8_t *i)
+{
+ i[0] = 0;
+ i[1] = 1;
+ i[2] = 1;
+ i[3] = 1;
+ i[4] = 1;
+ i[5] = 1;
+ i[6] = 1;
+ i[7] = 0;
+}
+
+
+
+
+
+void msf_make_bits (UTC u, uint8_t *a, uint8_t *b)
+{
+
+ bzero (a, 60);
+ bzero (b, 60);
+
+
+ a[0] = 1;
+ b[0] = 1;
+
+
+ bcd_set (a, 17, 24, u.year % 100);
+ bcd_set (a, 25, 29, u.month);
+ bcd_set (a, 30, 35, u.mday);
+ bcd_set (a, 36, 38, u.wday - 1);
+ bcd_set (a, 39, 44, u.hour);
+ bcd_set (a, 45, 51, u.minute);
+
+ msf_set_ident (&a[52]);
+
+
+ b[53] = 0; /* about to be BST */
+
+ b[54] = set_parity (a, 17, 24);
+ b[55] = set_parity (a, 25, 35);
+ b[56] = set_parity (a, 36, 38);
+ b[57] = set_parity (a, 39, 51);
+
+ b[58] = 0; /*BST vs GMT */
+
+}
+
+
+
+void msf_make_stream (uint8_t *v, uint8_t *a, uint8_t *b)
+{
+ unsigned s;
+ bzero (v, 600);
+
+ for (s = 0; s < 60; ++s, v += 10, ++a, ++b) {
+
+ if (!s)
+ memset (v, 1, 5);
+
+
+ v[0] = 1;
+ v[1] = *a;
+ v[2] = *b;
+ }
+}
+
diff --git a/project.h b/project.h
new file mode 100644
index 0000000..9492bac
--- /dev/null
+++ b/project.h
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#include <string.h>
+#include <strings.h>
+
+
+#include "time_fn.h"
+
+#include "prototypes.h"
diff --git a/prototypes.h b/prototypes.h
new file mode 100644
index 0000000..fc09337
--- /dev/null
+++ b/prototypes.h
@@ -0,0 +1,14 @@
+/* time_fn.c */
+extern UTC time_epoch_to_utc(EPOCH epoch);
+extern EPOCH time_utc_to_epoch(UTC u);
+extern void utc_to_str(char *dst, UTC u);
+extern void time_print_utc(const char *p, UTC u);
+extern void time_print_epoch(const char *p, EPOCH e);
+/* msf.c */
+extern void msf_make_bits(UTC u, uint8_t *a, uint8_t *b);
+extern void msf_make_stream(uint8_t *v, uint8_t *a, uint8_t *b);
+/* util.c */
+extern int set_parity(uint8_t *d, unsigned s, unsigned e);
+extern void bcd_set(uint8_t *d, unsigned s, unsigned e, unsigned v);
+/* main.c */
+extern int main(int argc, char *argv[]);
diff --git a/time_fn.c b/time_fn.c
new file mode 100644
index 0000000..957bc47
--- /dev/null
+++ b/time_fn.c
@@ -0,0 +1,232 @@
+#include "project.h"
+
+static int is_leap (unsigned year)
+{
+ if (year % 4)
+ return 0;
+
+ if (year % 100)
+ return 1;
+
+ if (year % 400)
+ return 0;
+
+ return 1;
+}
+
+
+UTC time_epoch_to_utc (EPOCH epoch)
+{
+ UTC u;
+ uint64_t day;
+ unsigned y400, y100, y4;
+
+ day = epoch.s / 86400;
+ epoch.s -= day * 86400;
+
+ day += 134774;
+
+ u.wday = day % 7;
+ u.wday++;
+
+
+ y400 = day / 146097; /*146097 days in 400 years */
+ day -= (y400 * 146097);
+
+ y100 = day / 36524; /*36524 days in 100 years */
+ day -= (y100 * 36524);
+
+ y4 = day / 1461; /*1461 days in 4 years */
+ day -= (y4 * 1461);
+
+ /* This may look redundant but 31 Dec in year 4 is special case */
+ if (day < 1095) { /*1095 days in 3 years */
+ u.year = day / 365; /*365 days in a year */
+ day -= (365 * u.year);
+ } else {
+ u.year = 3;
+ day -= 1095;
+ }
+
+
+ /* Now put it all back together */
+ u.year += 1601;
+ u.year += 4 * y4;
+ u.year += 100 * y100;
+ u.year += 400 * y400;
+
+
+ u.jday = day + 1;
+
+ u.is_leap = is_leap (u.year);
+
+
+ if (!u.is_leap) {
+ /*Days and months for ordinary years */
+ if (u.jday < 32) {
+ u.month = 1;
+ u.mday = u.jday;
+ } else if (u.jday < 60) {
+ u.month = 2;
+ u.mday = u.jday - 31;
+ } else if (u.jday < 91) {
+ u.month = 3;
+ u.mday = u.jday - 59;
+ } else if (u.jday < 121) {
+ u.month = 4;
+ u.mday = u.jday - 90;
+ } else if (u.jday < 152) {
+ u.month = 5;
+ u.mday = u.jday - 120;
+ } else if (u.jday < 182) {
+ u.month = 6;
+ u.mday = u.jday - 151;
+ } else if (u.jday < 213) {
+ u.month = 7;
+ u.mday = u.jday - 181;
+ } else if (u.jday < 244) {
+ u.month = 8;
+ u.mday = u.jday - 212;
+ } else if (u.jday < 274) {
+ u.month = 9;
+ u.mday = u.jday - 243;
+ } else if (u.jday < 305) {
+ u.month = 10;
+ u.mday = u.jday - 273;
+ } else if (u.jday < 335) {
+ u.month = 11;
+ u.mday = u.jday - 304;
+ } else {
+ u.month = 12;
+ u.mday = u.jday - 334;
+ }
+ } else {
+ /*And leap years */
+ if (u.jday < 32) {
+ u.month = 1;
+ u.mday = u.jday;
+ } else if (u.jday < 61) {
+ u.month = 2;
+ u.mday = u.jday - 31;
+ } else if (u.jday < 92) {
+ u.month = 3;
+ u.mday = u.jday - 60;
+ } else if (u.jday < 122) {
+ u.month = 4;
+ u.mday = u.jday - 91;
+ } else if (u.jday < 153) {
+ u.month = 5;
+ u.mday = u.jday - 121;
+ } else if (u.jday < 183) {
+ u.month = 6;
+ u.mday = u.jday - 152;
+ } else if (u.jday < 214) {
+ u.month = 7;
+ u.mday = u.jday - 182;
+ } else if (u.jday < 245) {
+ u.month = 8;
+ u.mday = u.jday - 213;
+ } else if (u.jday < 275) {
+ u.month = 9;
+ u.mday = u.jday - 244;
+ } else if (u.jday < 306) {
+ u.month = 10;
+ u.mday = u.jday - 274;
+ } else if (u.jday < 336) {
+ u.month = 11;
+ u.mday = u.jday - 305;
+ } else {
+ u.month = 12;
+ u.mday = u.jday - 335;
+ }
+ }
+
+ u.hour = epoch.s / 3600;
+ epoch.s -= u.hour * 3600;
+ u.minute = epoch.s / 60;
+ epoch.s -= u.minute * 60;
+ u.second = epoch.s;
+
+ u.nanosecond = epoch.ns;
+
+ return u;
+}
+
+
+
+
+EPOCH time_utc_to_epoch (UTC u)
+{
+ unsigned y400;
+ unsigned y100;
+ unsigned y4;
+
+ EPOCH ret;
+
+ static int const mdays[] =
+ { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+ static int const lmdays[] =
+ { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+
+ u.is_leap = is_leap (u.year);
+
+ if (u.year < 100) u.year += 2000;
+
+
+ if (!u.jday) {
+ if (u.is_leap)
+ u.jday = u.mday + lmdays[u.month];
+ else
+ u.jday = u.mday + mdays[u.month];
+ }
+
+ u.year -= 1601;
+ y400 = u.year / 400;
+ u.year -= y400 * 400;
+ y100 = u.year / 100;
+ u.year -= y100 * 100;
+ y4 = u.year / 4;
+ u.year -= y4 * 4;
+
+
+
+ ret.s = u.jday - 1;
+ ret.s += u.year * 365;
+ ret.s += y4 * 1461;
+ ret.s += y100 * 36524;
+ ret.s += y400 * 146097;
+
+ ret.s -= 134774;
+
+ ret.s *= 86400;
+
+ ret.s += u.second;
+ ret.s += u.minute * 60;
+ ret.s += u.hour * 3600;
+
+ ret.ns = u.nanosecond;
+
+ return ret;
+}
+
+void utc_to_str (char *dst, UTC u)
+{
+ const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"};
+ const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+ sprintf (dst, "%s %04d-%s-%02d %02d:%02d:%02d.%09d", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond);
+}
+
+
+void time_print_utc (const char *p, UTC u)
+{
+ const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"};
+ const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+ printf ("%s%s %04d-%s-%02d %02d:%02d:%02d.%09d\r\n", p ? p : "", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond);
+}
+
+void time_print_epoch (const char *p, EPOCH e)
+{
+ UTC u = time_epoch_to_utc (e);
+ time_print_utc (p, u);
+}
+
diff --git a/time_fn.h b/time_fn.h
new file mode 100644
index 0000000..2409eeb
--- /dev/null
+++ b/time_fn.h
@@ -0,0 +1,19 @@
+typedef struct {
+ unsigned year;
+ unsigned is_leap;
+ unsigned jday;
+ unsigned month;
+ unsigned mday;
+ unsigned wday;
+ unsigned hour;
+ unsigned minute;
+ unsigned second;
+ unsigned nanosecond;
+} UTC;
+
+typedef struct {
+ int64_t s;
+ int64_t ns;
+} EPOCH;
+
+
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..8be15a4
--- /dev/null
+++ b/util.c
@@ -0,0 +1,38 @@
+#include "project.h"
+
+int set_parity (uint8_t *d, unsigned s, unsigned e)
+{
+ unsigned i;
+ uint8_t p = 0;
+
+ for (i = s; i <= e; ++i)
+ p ^= d[i];
+
+ return !p;
+}
+
+
+void bcd_set (uint8_t *d, unsigned s, unsigned e, unsigned v)
+{
+ unsigned c, i, w;
+
+
+ w = v % 10;
+
+ for (i = e, c = 1 ; i >= s; --i) {
+
+ d[i] = !! (c & w) ;
+
+ if (c & 0x77777777)
+ c <<= 1;
+ else {
+ c >>= 3;
+ c *= 10;
+ v = v / 10;
+ w = v % 10;
+ }
+ }
+}
+
+
+