#!/usr/bin/env python # Read in an LGP-30 program and disassemble it. # Adam Sampson # # This emulates the "P10.4" loader, documented here: # ftp://ftp.informatik.uni-stuttgart.de/pub/cm/lgp30/papertapes/P104/ import sys def die(*s): print >>sys.stderr, "".join(map(str, s)) sys.exit(1) hexdigits = "0l23456789fgjkqw" def dehex(s): n = 0 for c in s: i = hexdigits.find(c) if i == -1: die("Expected hex digit, got ", c) n = (n << 4) | i return n orders = "zbyridnmpeuthcas" order_names = { "b": "bring", "h": "hold-store", "c": "clear-store", "y": "store-addr", "u": "transfer", "r": "return-addr", "t": "test", "z": "stop", "p": "print", "i": "input", "a": "add", "s": "subtract", "m": "multiply-hi", "n": "multiply-lo", "d": "divide", "e": "extract", } # Memory is 4096 31-bit words, arranged in 64 tracks of 64 sectors. # Location numbers are of the form decimal (or hex) TTSS. memory = [0] * 4096 def main(): tape = sys.stdin.read() pos = 0 while pos < len(tape): c = tape[pos] pos += 1 if c == "v": # Vnnnmmmm = load nnn hex words at address mmmm count = dehex(tape[pos:pos + 3]) track = dehex(tape[pos + 3:pos + 5]) sector = dehex(tape[pos + 5:pos + 7]) pos += 7 assert tape[pos] == "'" pos += 1 while tape[pos] in " \n": pos += 1 print >>sys.stderr, "(%d) Loading %d words at %02d%02d" % (pos, count, track, sector) assert track < 64 and sector < 64 while count > 0: hex = "" while tape[pos] != "'": if not tape[pos] in hexdigits: die("Expected hex digit at ", pos) hex += tape[pos] pos += 1 pos += 1 while tape[pos] in " \n": pos += 1 memory[(track * 64) + sector] = dehex(hex) sector += 1 if sector == 64: track += 1 assert track < 64 sector = 0 count -= 1 # Skip checksum. while tape[pos] != "'": pos += 1 pos += 1 elif c in " \n": continue else: die("Unknown loader instruction ", c, " at ", pos) print >>sys.stderr, "Loading complete" for i in range(4096): if memory[i] == 0: continue track = i / 64 sector = i % 64 v = memory[i] order = orders[(v >> 16) & 0xf] atrack = (v >> 8) & 0x3f asector = (v >> 2) & 0x3f print "%02d%02d %10d %08x %s %15s %02d%02d" % (track, sector, v, v, order, order_names[order], atrack, asector) if __name__ == "__main__": main()