--- /dev/null
+#!/usr/bin/env nickle
+
+typedef struct {
+ int addr;
+ int[8] data;
+} dumpline_t;
+
+dumpline_t
+read_dumpline(file f)
+{
+ dumpline_t d;
+ string l;
+
+ l = fgets(f);
+ if (File::sscanf(l, "%x %x %x %x %x %x %x %x %x",
+ &d.addr,
+ &d.data[0],
+ &d.data[1],
+ &d.data[2],
+ &d.data[3],
+ &d.data[4],
+ &d.data[5],
+ &d.data[6],
+ &d.data[7]) != 9)
+ d.addr = -1;
+ return d;
+}
+
+dumpline_t[...]
+read_dumplines(file f)
+{
+ dumpline_t[...] lines;
+
+ setdim(lines, 0);
+ while (!File::end(f)) {
+ dumpline_t line;
+
+ line = read_dumpline(f);
+ if (line.addr == -1)
+ continue;
+ lines[dim(lines)] = line;
+ }
+ return lines;
+}
+
+int
+read_byte(file f)
+{
+ static int off = 8;
+ static dumpline_t d;
+
+
+ if (off == 8) {
+ if (File::end(f))
+ return -1;
+ d = read_dumpline(f);
+ off = 0;
+ }
+ return d.data[off++];
+}
+
+int[...]
+read_bytes(file f, int len)
+{
+ int i;
+ int[len] a;
+ for (i = 0; i < len; i++) {
+ int b = read_byte(f);
+ if (b < 0)
+ return (int[0]) {};
+ a[i] = b;
+ }
+ return a;
+}
+
+void
+dump_line(file f, int len)
+{
+ int[...] line = read_bytes(f, len);
+
+ if (dim(line) == 0)
+ return;
+
+ bool valid_block() {
+ int sum = 0x5a;
+ static string packet_types = "FATDSGNWHV";
+
+ if (line[0] == 0)
+ return false;
+ if (String::index(packet_types, String::new(line[0])) < 0)
+ return false;
+ for (int i = 0; i < len; i++)
+ sum += line[i];
+ return (sum & 0xff) == 0;
+ }
+
+ int one_byte(int i) = line[i];
+
+ int two_bytes(int i) = line[i] + (line[i+1] << 8);
+
+ if (valid_block()) {
+ printf("%c %04x %04x %04x\n",
+ one_byte(0),
+ two_bytes(2),
+ two_bytes(4),
+ two_bytes(6));
+ }
+}
+
+void
+dump_file(file f, int len)
+{
+ while (!File::end(f))
+ dump_line(f, len);
+}
+
+void
+doit (string name)
+{
+ twixt (file f = File::open(name, "r"); File::close(f))
+ dump_file(f, 8);
+}
+
+void
+main()
+{
+ if (dim(argv) > 1) {
+ for (int i = 1; i < dim(argv); i++)
+ doit(argv[i]);
+ } else {
+ dump_file(stdin, 8);
+ }
+}
+
+main();