Add machinery for building a working `.tap' file.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 14 Nov 2021 13:53:38 +0000 (13:53 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 14 Nov 2021 13:59:32 +0000 (13:59 +0000)
I maintain the ZX BASIC loader program using FUSE, so, alas, the
`spectrum-loader.tap' file is the `preferred' form for modification.
I'd like something less awful.

.gitignore
Makefile
spectrum-loader.tap [new file with mode: 0644]
tapify [new file with mode: 0755]

index a89285e..6477f1c 100644 (file)
@@ -1 +1,2 @@
 *.img
+/spectrum-fizzbuzz.tap
index eeaf9d2..9bef433 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,10 +6,16 @@ clean::
 TARGETS                         =
 CLEANFILES              = $(TARGETS)
 
-TARGETS                += spectrum-fb.img
+CLEANFILES             += spectrum-fb.img
 spectrum-fb.img: fizzbuzz.s
        z80asm -o $@ $^
 
+TARGETS                        += spectrum-fizzbuzz.tap
+spectrum-fizzbuzz.tap: tapify spectrum-loader.tap spectrum-fb.img
+       { cat spectrum-loader.tap; \
+         ./tapify 3 fb 0x7000 0x8000 <spectrum-fb.img; } \
+               >$@.new && mv $@.new $@
+
 all: $(TARGETS)
 
 clean::; rm -f $(CLEANFILES)
diff --git a/spectrum-loader.tap b/spectrum-loader.tap
new file mode 100644 (file)
index 0000000..3ea384f
Binary files /dev/null and b/spectrum-loader.tap differ
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;