#!/usr/bin/env python3 """setup.py - prepare the Power C improvement toolchain (the original disk is only read). python tools/setup.py extract the runtime library objects into lib/ and build optlib/ python tools/setup.py --disk also write POWERc-opt.d81 (original + improved runtime objects) optlib/ gets drop-in replacements (same file names as on POWERc.d81): cmulti.obj faster 16x16 multiply c0047.obj faster divide / remainder (same results, fewer shift steps) c0077.obj the unsigned >= helper with its broken branch opcode ($80 -> $90) fixed """ import os, sys, subprocess, shutil, hashlib HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.normpath(os.path.join(HERE, '..')) sys.path.insert(0, HERE) from objfmt import Obj from pcasm import assemble sys.path.insert(0, os.path.join(ROOT, 'src')) import div_patch C1541 = r'C:\Program Files\GTK3VICE-3.10-win64\bin\c1541.exe' ORIG = os.path.normpath(os.path.join(ROOT, '..', 'POWERc.d81')) def run(*a): return subprocess.run([C1541] + list(a), capture_output=True, text=True) def extract(): os.makedirs(os.path.join(ROOT, 'lib'), exist_ok=True) out = run(ORIG, '-list').stdout names = [] for ln in out.splitlines(): if '"' in ln and ln.rstrip().endswith('seq'): nm = ln.split('"')[1] if nm.endswith(('.obj', '.o', '.l')): names.append(nm) args = [] for nm in sorted(set(names)): args += ['-read', nm + ',s', os.path.join(ROOT, 'lib', nm)] run(ORIG, *args) print('extracted %d files into lib/' % len(set(names))) def build(): os.makedirs(os.path.join(ROOT, 'optlib'), exist_ok=True) cm, _ = assemble(open(os.path.join(ROOT, 'src', 'cmulti.s')).read()) open(os.path.join(ROOT, 'optlib', 'cmulti.obj'), 'wb').write(cm.build()) o = Obj.parse(open(os.path.join(ROOT, 'lib', 'c0047.obj'), 'rb').read()) open(os.path.join(ROOT, 'optlib', 'c0047.obj'), 'wb').write(div_patch.patch(o).build()) o = Obj.parse(open(os.path.join(ROOT, 'lib', 'c0077.obj'), 'rb').read()) assert o.code[0x1d] == 0x80, 'c0077.obj is not the expected original' o.code[0x1d] = 0x90 open(os.path.join(ROOT, 'optlib', 'c0077.obj'), 'wb').write(o.build()) print('built optlib/cmulti.obj c0047.obj c0077.obj') def disk(): dst = os.path.join(ROOT, 'POWERc-opt.d81') shutil.copyfile(ORIG, dst) for nm in ('cmulti.obj', 'c0047.obj', 'c0077.obj'): run(dst, '-delete', nm) run(dst, '-write', os.path.join(ROOT, 'optlib', nm), nm + ',s') print('wrote', dst) if __name__ == '__main__': h = hashlib.sha256(open(ORIG, 'rb').read()).hexdigest() exp = open(os.path.join(ROOT, 'POWERc.d81.sha256')).read().split()[0] if h != exp: print('WARNING: reference/POWERc.d81 differs from the recorded original hash') extract() build() if '--disk' in sys.argv: disk()