Files
Yaya48 c230971f07 IOS LLE: checkpoint NAND conformance and diagnostic tooling
Preserve formatted NAND boot and Wii Remote pairing, add DMA/SRAM conformance tests and a Wii comparison probe. Keep P1 profiling tools and native update A/B evidence; reject the unhelpful targeted SRAM shortcut.
2026-09-23 13:30:17 +02:00

80 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""Compare two runs of the identical Wii conformance DOL."""
import argparse
import csv
import sys
from pathlib import Path
METADATA = ("schema", "rounds", "observations", "ios_version", "ios_revision")
HEADER = ["seq", "test", "round", "value", "extra"]
def read_capture(path: Path):
with path.open(newline="", encoding="utf-8") as stream:
rows = csv.reader(stream)
metadata = {}
for key in METADATA:
row = next(rows, None)
if row is None or len(row) != 2 or row[0] != key:
raise ValueError(f"{path}: expected metadata row {key!r}")
metadata[key] = int(row[1])
if next(rows, None) != HEADER:
raise ValueError(f"{path}: invalid observation header")
observations = []
for line, row in enumerate(rows, start=7):
if len(row) != 5:
raise ValueError(f"{path}:{line}: expected 5 columns")
seq, test, round_number, value, extra = row
if int(seq) != len(observations):
raise ValueError(f"{path}:{line}: sequence is not contiguous")
observations.append((test, int(round_number), int(value), int(extra)))
if len(observations) != metadata["observations"]:
raise ValueError(
f"{path}: expected {metadata['observations']} observations, "
f"found {len(observations)}"
)
return metadata, observations
def compare(reference, candidate, limit=20):
reference_meta, reference_rows = reference
candidate_meta, candidate_rows = candidate
for key in METADATA:
if reference_meta[key] != candidate_meta[key]:
print(f"Incomparable runs: {key}: Wii={reference_meta[key]}, Dolphin={candidate_meta[key]}")
return 2
differences = 0
for index in range(max(len(reference_rows), len(candidate_rows))):
expected = reference_rows[index] if index < len(reference_rows) else None
actual = candidate_rows[index] if index < len(candidate_rows) else None
if expected == actual:
continue
differences += 1
if differences <= limit:
print(f"#{index} Wii={expected} Dolphin={actual}")
if differences:
print(f"{differences} differences across {max(len(reference_rows), len(candidate_rows))} observations")
return 1
print(f"Identical: {len(reference_rows)} observations")
return 0
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("wii", type=Path, help="CSV from the real Wii")
parser.add_argument("dolphin", type=Path, help="CSV from Dolphin")
args = parser.parse_args()
try:
return compare(read_capture(args.wii), read_capture(args.dolphin))
except (OSError, ValueError) as error:
print(error, file=sys.stderr)
return 2
if __name__ == "__main__":
raise SystemExit(main())