Skip to content

Instantly share code, notes, and snippets.

@decuser
Last active January 20, 2022 18:41
Show Gist options
  • Save decuser/28e009f128463e7956d95f632d7eca6b to your computer and use it in GitHub Desktop.
Save decuser/28e009f128463e7956d95f632d7eca6b to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# Written by Will Senn. Create a bootable SimH tap file to install the system.
# Originally Based on Hellwig Geisse’s mktape.c and inspired by various Perl scripts
# Argument handling borrowed from Allen Garvin's mk-dist-tape.py
#
# created 20171012.1924
# coverted to python 20220120.1019 in prep for a better generalized version
# generalized by adding argument handling
# ./mktape.py -o v7.tap f0:512 f1:512 f2:512 f3:512 f4:512 f5 f6
# equivalent to ./mktape.py -7
# shasum v7.tap
# e6188335c0c9a3e3fbdc9c29615f940233722432 v7.tap
# ./mktape.py -o bsd42.tap stand:512 miniroot rootdump srcsys.tar usr.tar vfont.tar src.tar new.tar ingres.tar
# shasum bsd42.tap
# 8810274832cadf01083eeb228368896048b35a5a bsd42.tap
import sys
import struct
import argparse
EOF = b"\x00\x00\x00\x00"
EOT = b"\xFF\xFF\xFF\xFF"
files = []
blkszs = []
# add arguments for default v7 tape creation, and 4.2bsd
parser = argparse.ArgumentParser(description="Create distribution tapes for simh")
parser.add_argument("--v7", "-7", action='store_true',
help="build v7 tape (requires tape files in dir)")
parser.add_argument("--bsd42", action='store_true',
help="build bsd42 tape (requires tape files in dir)")
parser.add_argument("--blocksize", "-b", type=int,
help="set default block size (default 10240)", default=10240)
parser.add_argument("-output", "-o", metavar="FILE",
help="output to file (if omitted, sends to stdout)")
parser.add_argument("file", nargs="*",
help="files to add in order (append with :bs where bs is block size)")
args = parser.parse_args()
if args.v7:
filelist = ["f0:512", "f1:512", "f2:512", "f3:512", "f4:512", "f5", "f6"]
blocksize = 10240
outfile = "v7.tap"
elif args.bsd42:
filelist = ["stand:512", "miniroot", "rootdump", "srcsys.tar",
"usr.tar", "vfont.tar", "src.tar", "new.tar", "ingres.tar"]
blocksize = 10240
outfile = "bsd42.tap"
else:
blocksize = args.blocksize
if args.output:
outfile = args.output
else:
outfile = "out.tap"
filelist = args.file
for f in filelist:
if ":" in f:
fn = f.split(":")[0]
bs = f.split(":")[1]
if not bs.isdigit():
parser.print_help()
print(f"\nERROR: blocksize {bs} in {f} is not a positive integer")
sys.exit(1)
bs = int(bs)
else:
fn = f
bs = blocksize
files.append(fn)
blkszs.append(bs)
try:
fdout = open(outfile, "wb")
except IOError as e:
print(f"{outfile}: errno {e.errno}: {e.strerror}")
sys.exit(1)
for f in range(0, len(files)):
file = files[f]
blocksize = blkszs[f]
packedlen = struct.pack("<I", blocksize)
try:
fdin = open(file, "rb")
except IOError as e:
print(f"{file}: errno {e.errno}: {e.strerror}")
sys.exit(1)
blockswritten = 0
bytes = fdin.read(blocksize)
while(bytes):
buffer = bytes
if len(bytes) < blocksize:
buffer += b"\x00" * (blocksize - len(bytes))
fdout.write(packedlen)
fdout.write(buffer)
fdout.write(packedlen)
blockswritten += 1
bytes = fdin.read(blocksize)
fdin.close()
fdout.write(EOF)
print(f"file {f}: block size {blocksize}: {blockswritten} records")
print(f"file {f}: eof after {blockswritten} records: {blocksize * blockswritten} bytes")
fdout.write(EOT)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment