summaryrefslogtreecommitdiffstats
path: root/v17tcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'v17tcm.c')
-rw-r--r--v17tcm.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/v17tcm.c b/v17tcm.c
new file mode 100644
index 0000000..0edaefe
--- /dev/null
+++ b/v17tcm.c
@@ -0,0 +1,109 @@
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "v17tcm.h"
+
+static const uint8_t v17tcm_table[] = {
+ 0, 1, 2, 3,
+ 1, 2, 3, 0,
+ 2, 3, 0, 1,
+ 3, 0, 1, 2
+};
+
+static const uint8_t v17tcm_table_reverse[] = {
+ 0, 1, 2, 3,
+ 3, 0, 1, 2,
+ 2, 3, 0, 1,
+ 1, 2, 3, 0
+};
+
+void v17tcm_init(struct v17tcm_state *s) {
+ assert(s);
+ memset(s, 0, sizeof(*s));
+}
+
+static uint8_t conv_encode(struct v17tcm_state* s, uint8_t y) {
+ uint8_t x, a, b, c, d, e;
+
+ /*
+ fprintf(stderr, "conv_encode(..., %u)\n", y);
+ */
+ a = (y&1) ^ (y>>1);
+ b = (a ^ s->c1);
+ d = s->c2 ^ (s->c2 ^ (y>>1));
+ c = b ^ (s->c3 & d);
+ e = d ^ ((y&1) & s->c3);
+
+ x = s->c3;
+
+ s->c1 = s->c3;
+ s->c2 = c;
+ s->c3 = e;
+
+ return x;
+}
+
+uint8_t v17tcm_encode(struct v17tcm_state* s, uint8_t input) {
+ uint8_t y, c;
+
+ y = s->y = v17tcm_table[((input & 3) << 2) | (s->y & 3)];
+
+ /*fprintf(stderr, "tcm = %u\n", y);*/
+
+ c = conv_encode(s, y);
+
+ /*fprintf(stderr, "c:%u von %u\n", c, y);*/
+
+ return c | ((y | (input & ~3)) << 1);
+}
+
+uint8_t v17tcm_decode(struct v17tcm_state *s, uint8_t input) {
+ uint8_t y, py;
+
+ if (conv_encode(s, (input >> 1) & 3) != (input & 1))
+ fprintf(stderr, "Invalid TCM code, ignoring\n");
+
+ y = v17tcm_table_reverse[((s->y&3) << 2) | (py = ((input >> 1) & 3))];
+
+ s->y = py;
+
+ return (input >> 3 << 2) | y;
+}
+
+#ifdef TEST1
+int main() {
+ uint8_t c;
+
+ for (c = 0; c <= 0xF; c++) {
+ if (v17tcm_table_reverse[v17tcm_table[c] | ((c&3) << 2)] != (c >> 2))
+ fprintf(stderr, "%u: FEHLER\n", c);
+ else
+ fprintf(stderr, "%u: OK\n", c);
+ }
+ return 0;
+}
+#endif
+
+#ifdef TEST2
+int main() {
+ struct v17tcm_state s1, s2;
+ int c, n;
+
+ v17tcm_init(&s1);
+ v17tcm_init(&s2);
+
+ n = 0;
+ while ((c = getchar()) >= 0) {
+ uint8_t b = ((uint8_t) c) & 63;
+ uint8_t u = v17tcm_encode(&s1, b);
+ uint8_t e = v17tcm_decode(&s2, u);
+
+ fprintf(stderr, "%i) %u %s %u (encoded: %u)\n", n++, b, b == e ? "==" : "!=", e, u);
+ }
+
+ return 0;
+}
+
+#endif