|
- """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
|