Files
samplez/tunie/research/reference-maps/PERMUTATIONS.md
uhryniuk 4aa5da53d2 Commit tune maps and research so tunes are reachable from the phone
Removes the *.hex/maps_cache gitignore rule (explicit user call, reversing
the earlier no-redistribution stance) so the official TuneECU catalogue
maps, derived SAI/O2-delete composites, and the checksum/composition
tooling are actually available to pull up on a phone browser when using
the real TuneECU app. Also folds in tonight's KWP2000 fixes (TesterPresent
keep-alive, connect-failure cleanup, slow-init StartCommunication fix) and
the accumulated research docs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FP2GaxS9HkUdL5sLBnjKje
2026-08-27 01:34:05 -05:00

5.3 KiB

Full mechanical-odo Bonneville permutation grid — cross-diff (Aug 2026)

Downloaded and cross-diffed every official mechanical-odo Bonneville calibration TuneECU ships for the exhaust x fuel grid (up to VIN 739050): stock production/aftermarket, Arrow 2-in-1, Arrow 2-in-2, each at E10 and E25, across both catalog batches (t202/t203). 12 files, all reconstructed to the flat 384 KB ROM with reconstruct_rom.py and diffed byte-for-byte.

IDs used: 20187 20188 20191 20192 (stock), 20262 20263 20264 20265 (t202 Arrow), 20313 20314 20315 20316 (t203 Arrow).

t202 vs t203: same tune, reissued

Every t202/t203 pair with an identical catalogue description (e.g. 20262 vs 20313, both "Arrow 2 in 1, E10") differs by only 10 bytes, in two groups:

  • 8 bytes at 0x4FFFA-B/E-F and 0x5FFFA-B/E-F — right at the 0x50000/ 0x60000 block boundaries, almost certainly per-block ID/checksum metadata (consistent with DEVICES.md/README.md's prior finding that the caXX footer bytes are map-ID metadata, not a calibration checksum).
  • 2 bytes at 0x53626-27 — one real 16-bit calibration value changed. Small, single-cell revision.

Conclusion: t202 and t203 aren't different calibrations, just a catalog-ID reissue with one tiny tweak. Resolves the earlier open question ("which of 20262 vs 20313 is correct for us") — it doesn't matter, use either.

Fuel delta (E10 -> E25) is real, consistent, and localized

Matched pairs (same exhaust, VIN range, everything else equal, only fuel spec differs):

Pair Exhaust Diff
20262 vs 20263 Arrow 2-in-1 4809 bytes (1.22%)
20264 vs 20265 Arrow 2-in-2 4562 bytes (1.16%)
20313 vs 20314 Arrow 2-in-1 (t203) 4809 bytes — identical set to 20262/20263
20315 vs 20316 Arrow 2-in-2 (t203) 4562 bytes — identical set to 20264/20265
20187 vs 20191 stock production only 60 bytes (0.02%)

The E10->E25 delta for Arrow 2-in-1 vs Arrow 2-in-2 overlaps 93% (4455 of 4562-4809 bytes) — same fuel-table region touched regardless of exhaust, which is exactly what you'd expect (ethanol compensation lives in the fuel tables, not the exhaust-specific cells). The stock-production E10->E25 delta being tiny (60 bytes) while the Arrow one is ~80x larger is odd at first glance, but 20187 carries no VIN-range/fuel spec in its description at all — it and 20191 likely aren't a clean matched pair the way the Arrow E10/E25 pairs are (20191 adds a VIN-range qualifier 20187 lacks). Treat 20262/20263 as the trustworthy E10-vs-E25 reference, not 20187/20191.

Exhaust delta and fuel delta are NOT independent/disjoint

Checked whether the "stock -> Arrow 2-in-1" delta and the "E10 -> E25" delta touch separate bytes (which would let us compose them by simple copy/overlay):

  • Exhaust delta (20187 -> 20262): 7548 bytes
  • Fuel delta (20262 -> 20263): 4809 bytes
  • Overlap: 4149 bytes — the large majority of the fuel delta's footprint is inside the exhaust delta's footprint too.

This means naive delta composition (baseline + delta A's changed bytes + delta B's changed bytes) doesn't work cleanly — both mods rewrite overlapping cells in the same VE/fuel tables (expected: richness-for-exhaust and richness-for-ethanol are both corrections to the same underlying fuel surface, so of course they land on the same cells). You can't just XOR two independent byte-level diffs onto a base map; you'd overwrite one mod's change with the other's rather than combining them. Real composition would need table-level math (read both as VE values, apply both corrections arithmetically), not byte-patching — a materially bigger undertaking than toggle_devices.py's simple flag flip.

What this means for "build our own Arrow + SAI/O2-delete tune"

Good news: the exhaust x fuel grid is already solved — TuneECU engineers already shipped the exact validated combination you want (20262/20313, Arrow 2-in-1, E10). No synthesis needed there; picking the catalog entry is strictly better than trying to reconstruct it from deltas.

Bad news, unchanged from COMMUNITY_TUNING.md: none of these 12 files vary the SAI/O2-delete axis — TuneECU never shipped an Arrow-exhaust variant with devices off. The grid we now have doesn't help fill that gap, because the gap isn't on this grid. We're still bottlenecked on the single external 2009AIRBOXBONNY.hex reference (not currently in the repo, needs re-fetching) for that axis, and even that reference conflates "no airbox" with "no SAI/no O2" in one diff (per DEVICES.md), which the exhaust-vs-fuel overlap finding above suggests may be a real problem, not just a theoretical one — table-level effects don't separate cleanly by simple byte diffing when two mods land on the same cells.

Revised recommendation: don't try to hand-synthesize "Arrow 2-in-1 + real SAI/O2 delete" from byte deltas — the overlap finding shows that's not sound with the tooling we have (byte-diff, not semantic table-diff). Either:

  1. Decode the fuel tables to actual VE values (table_map.py/TABLES.md already locate them) and do the composition arithmetically, cell by cell, rather than at the byte level — a real project, not a script tweak.
  2. Or just use a real matched commercial tune (DNK, since TTP's storefront is effectively defunct) rather than DIY-composing one.