Add machinery for building a working `.tap' file.
[zx-fizzbuzz] / tapify
diff --git a/tapify b/tapify
new file mode 100755 (executable)
index 0000000..79adf5b
--- /dev/null
+++ b/tapify
@@ -0,0 +1,33 @@
+#! /usr/bin/perl
+
+use autodie;
+
+sub intify ($) {
+  my ($n) = @_;
+  if ($n =~ /^0/) { $n = oct $n; }
+  return $n;
+}
+
+sub frame ($$) {
+  my ($flag, $d) = @_;
+  my $a = $flag;
+  for (my $i = 0; $i < length $d; $i++) { $a ^= ord substr $d, $i, 1; }
+  return pack("S< C", 2 + length $d, $flag) . $d . chr($a);
+}
+
+@ARGV == 4 or die "usage: $0 TY NAME P1 P2";
+my ($ty, $name, $p1, $p2) = @ARGV;
+
+my $body = "";
+READ: for (;;) {
+  sysread STDIN, my $buf, 4096;
+  last READ unless length $buf;
+  $body .= $buf;
+}
+
+my $tap = "";
+$tap .= frame 0, pack "C A10 S< S< S<",
+  $ty, $name, length $body, intify $p1, intify $p2;
+$tap .= frame 255, $body;
+
+syswrite STDOUT, $tap;