Initial commit. Basic version of bin2load for converting binary blobs into paper...
authorAaron Taylor <ataylor@subgeniuskitty.com>
Wed, 11 Nov 2020 12:11:12 +0000 (04:11 -0800)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Wed, 11 Nov 2020 12:11:12 +0000 (04:11 -0800)
LICENSE.txt [new file with mode: 0644]
Makefile [new file with mode: 0644]
README.md [new file with mode: 0644]
bin2load.c [new file with mode: 0644]

diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..7c29737
--- /dev/null
@@ -0,0 +1,21 @@
+MIT/X Consortium License
+
+© 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..407f515
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,24 @@
+# © 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
+# See LICENSE.txt file for copyright and license details.
+
+PREFIX = $(HOME)
+BINPREFIX = $(PREFIX)/bin
+
+CC = cc
+CC_FLAGS = -std=c99
+
+all: bin2load
+
+bin2load:
+       @$(CC) $(CC_FLAGS) -o $@ bin2load.c
+
+install: bin2load
+       @mkdir -p $(BINPREFIX)
+       @cp ./bin2load $(BINPREFIX)/bin2load
+       @chmod +x $(BINPREFIX)/bin2load
+
+uninstall:
+       @rm $(BINPREFIX)/bin2load
+
+clean:
+       @rm -f bin2load bin2load.core
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..c433f67
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# Overview #
+
+This is a simple program that converts raw binary data into a paper-tape image
+compatible with SIMH.
+
+For example, I commonly use it when transfering compiled PDP-11 code into SIMH
+with the output of:
+
+    pdp11-aout-objcopy --only-section=.text --output-target binary program.out program.bin
+
+It does not generate correct checksums, but this generates only a warning in
+SIMH, not an error.
+
+
+# Status #
+
+Tested and working on Linux and FreeBSD.
+
+
+# Instructions #
+
+The `Makefile` provides targets for `all`, `install`, `uninstall`, and `clean`.
+Edit the `Makefile` to set `$PREFIX` for alternate installation paths. By
+default it installs to `$HOME/bin`.
+
+Once compiled and added to your `$PATH`, simply provide a raw binary blob as
+`input` and receive a SIMH compatible paper tape image at `output`.
+
+If provided via the `-a` flag, the paper tape will load at the provided address
+in memory. If not provided, this defaults to `01000` (`1000` octal).
+
+    bin2load -i /path/to/input -o /path/to/output -a 01000
+
diff --git a/bin2load.c b/bin2load.c
new file mode 100644 (file)
index 0000000..5764c9f
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * © 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
+ * See LICENSE.txt file for copyright and license details.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#define VERSION 1
+
+void
+print_usage( char ** argv )
+{
+    printf( "bin2load v%d (www.subgeniuskitty.com)\n"
+            "Usage: %s i <file> -o <file> [-a <address>]\n"
+            "  -i <file>    Binary file to be written to tape.\n"
+            "               For example, binary executable from 'pdp11-aout-objdump'.\n"
+            "  -o <file>    New paper tape image for use with SIMH.\n"
+            "  -a <address> Address on PDP-11 at which to load paper tape contents.\n"
+            , VERSION, argv[0]
+    );
+}
+
+
+int
+main( int argc, char ** argv)
+{
+    int c;
+    FILE * src = NULL;
+    FILE * dst = NULL;
+    uint16_t address = 01000; /* Default address to load tape contents. */
+
+    while ((c = getopt(argc, argv, "i:o:a:h")) != -1) {
+        switch (c) {
+            case 'i':
+                if ((src = fopen(optarg, "r")) == NULL ) {
+                    fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
+                }
+                break;
+            case 'o':
+                if ((dst = fopen(optarg, "w+")) == NULL ) {
+                    fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
+                }
+                break;
+            case 'a':
+                address = (uint16_t) strtol(optarg, NULL, 0);
+                break;
+            case 'h':
+                print_usage(argv);
+                exit(EXIT_FAILURE);
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (src == NULL || dst == NULL) {
+        print_usage(argv);
+        exit(EXIT_FAILURE);
+    }
+    printf("Paper tape will load at address 0%o.\n", address);
+
+    /*
+     * Paper tape format(bytes, not words):
+     *   01
+     *   00
+     *   Low byte of packet length (binary length + 6 for header)
+     *   High byte of packet length
+     *   Low byte of address to load binary data at
+     *   High byte of address
+     *   DataBegin
+     *    |
+     *    |
+     *   DataEnd
+     *   Checksum
+     *
+     * I am unsure of the checksum format and need to check the SIMH source.
+     * In the meantime a zero checksum still functions, albeit with a warning.
+     */
+
+    uint16_t size = 6;
+
+    uint16_t header[] = {1,0,01000};
+    fwrite(header,6,1,dst);
+
+    uint8_t byte;
+    int read;
+    do {
+        read = fread(&byte,1,1,src);
+        if(read == 1) fwrite(&byte,1,1,dst);
+        size += read;
+    } while (read == 1);
+
+    uint16_t footer[] = {0,1,6,01000,0};
+    fwrite(footer,10,1,dst);
+
+    fseek(dst,2,SEEK_SET);
+    fwrite(&size,2,1,dst);
+
+    fclose(src);
+    fclose(dst);
+}