"""Load Power C runtime-helper objects into the 6502 emulator and compare implementations. usage (library): h = Helper(obj, base=0x6000, ext={'C$HIGHMEM': 0xC000, ...}) h.addr('C$105') """ import sys, os, random sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from objfmt import Obj from cpu6502 import CPU class Helper: def __init__(self, obj, base, ext): self.o = obj self.base = base self.code = bytearray(obj.code) for off in obj.reloc: # local absolute operands v = self.code[off + 1] | self.code[off + 2] << 8 v = (v + base) & 0xFFFF self.code[off + 1] = v & 255; self.code[off + 2] = v >> 8 syms = {nm: base + off for nm, k, off in obj.defs} syms.update({k.encode() if isinstance(k, str) else k: v for k, v in ext.items()}) for nm, kind, off in obj.refs: a = syms[bytes(nm)] if kind == 0: self.code[off + 1] = a & 255; self.code[off + 2] = a >> 8 elif kind == 4: a += 1; self.code[off + 1] = a & 255; self.code[off + 2] = a >> 8 elif kind == 2: self.code[off + 1] = a & 255 elif kind == 1: self.code[off + 1] = a >> 8 else: raise ValueError('kind %d' % kind) self.syms = syms def addr(self, name): return self.syms[name.encode() if isinstance(name, str) else name] def install(self, cpu): cpu.m[self.base:self.base + len(self.code)] = self.code def snapshot(cpu, skip=()): m = bytes(cpu.m) return m def diff_mem(a, b, skip): out = [] for i in range(65536): if a[i] != b[i] and not any(lo <= i < hi for lo, hi in skip): out.append((i, a[i], b[i])) if len(out) > 8: break return out