43 lines
2.3 KiB
Python
43 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
# Compare per-tick RAM snapshots from the oracle and the port and report
|
|
# the first snapshot where non-scratch game state differs.
|
|
# usage: snapDiff.py oracle.snaps port.snaps every [maxShow] [all] (all = do not stop at the first divergence)
|
|
import sys, re, bisect
|
|
a = open(sys.argv[1], 'rb').read(); b = open(sys.argv[2], 'rb').read()
|
|
every = int(sys.argv[3]); maxShow = int(sys.argv[4]) if len(sys.argv) > 4 else 25
|
|
showAll = len(sys.argv) > 5 and sys.argv[5] == 'all'
|
|
n = min(len(a), len(b)) // 65536
|
|
syms = []
|
|
for line in open('port/include/fs2Symbols.h'):
|
|
m = re.match(r'#define SYM_(\w+)\s+0x([0-9A-F]{4})', line)
|
|
if m: syms.append((int(m.group(2), 16), m.group(1)))
|
|
syms.sort(); addrs = [s[0] for s in syms]
|
|
def name(addr):
|
|
i = bisect.bisect_right(addrs, addr) - 1
|
|
off = addr - syms[i][0]
|
|
return syms[i][1] + (('+%d' % off) if off else '')
|
|
regions = [(0x0000, 0x0100), (0x0140, 0x0400), (0x0800, 0x0AB8), (0x0DB8, 0x1000),
|
|
(0x1E00, 0x1E10), (0x2000, 0x6000), (0xA7E0, 0xB3E0),
|
|
(0xD9E5, 0xD9EA), (0xDFB0, 0xDFBA), (0xE046, 0xE04B), (0xE675, 0xE67F),
|
|
(0xE800, 0xF000), (0xF242, 0xF260), (0xF715, 0xF71C), (0xF8E6, 0xF8E7),
|
|
(0xF9B3, 0xF9B4), (0xFAE9, 0xFAEC), (0xFC00, 0xFD00)]
|
|
scratch = set(list(range(0xA5, 0xB0)) + list(range(0xB0, 0xB4)) + list(range(0xB6, 0xC2)) + list(range(0xC2, 0xCA)) + [0xE5, 0xF1, 0xF2] + list(range(0xF4, 0xFA)) + list(range(0x3C, 0x40)) + list(range(0x98, 0x9C)) + [0x21, 0x22, 0x25, 0x26, 0x27, 0x53, 0x54, 0xAD, 0xAF, 0x1A, 0x1D, 0x20, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3])
|
|
for k in range(n):
|
|
sa = a[k*65536:(k+1)*65536]; sb = b[k*65536:(k+1)*65536]
|
|
diffs = []
|
|
for lo, hi in regions:
|
|
for i in range(lo, hi):
|
|
if sa[i] != sb[i] and i not in scratch:
|
|
diffs.append(i)
|
|
print('tick %3d: %d differing state bytes' % ((k + 1) * every, len(diffs)))
|
|
if diffs:
|
|
shown = 0; i = 0
|
|
while i < len(diffs) and shown < maxShow:
|
|
j = i
|
|
while j + 1 < len(diffs) and diffs[j + 1] == diffs[j] + 1: j += 1
|
|
s0, s1 = diffs[i], diffs[j]
|
|
m = min(8, s1 - s0 + 1)
|
|
print(' $%04X-$%04X (%3d) %-36s oracle=%s port=%s' % (s0, s1, s1 - s0 + 1, name(s0), sa[s0:s0+m].hex(), sb[s0:s0+m].hex()))
|
|
shown += 1; i = j + 1
|
|
if not showAll:
|
|
break
|