Files
samplez/tunie/research/reference-maps/TABLES.md
uhryniuk 173f6fa0c4 Locate Keihin tables + render real fuel maps in the viewer
Reversed the inner map format from l.java (Nc/Lb) and validated it against the
stock reference maps:

- reconstruct_rom.py: decoded map -> unpack directory -> 384KB flat ROM. In the
  flat ROM, production (20187) vs aftermarket (20188) differ only 1.4% (vs 96%
  packed), i.e. real fuel enrichment.
- table_map.py + TABLES.md: fe = c.a[Qd*48]; base = (fe[0]&0x2F0)<<12 = 0x50000;
  table = base + fe[k]. Located 9 tables (main/low-throttle fuel per cylinder,
  base/idle fuel, ignition by gear x4), 32 RPM rows x 20 throttle cols, with real
  axes (RPM fe[8], throttle fe[27]) and the AFR curve (fe[2], 128=lambda 1.00).
  Validated: main-fuel delta is uniformly richer in the aftermarket map.

Viewer now has a "Triumph tables" tab: drop a real .hex (or pick two) and it
decodes, unpacks, and renders the fuel/ignition tables as heatmaps with real
axes, plus an A->B difference view. build_viewer.py embeds the c.a/s.a directory
so any map resolves in-browser.

Catalogue dropdown: download_maps.py fetches map .hex files into maps_cache/;
serve.py serves the viewer over http so the dropdown can fetch them (drag-and-drop
still works on file://).

Proprietary map binaries (*.hex, *.dec.bin, maps_cache/) are gitignored — code and
docs only.
2026-08-11 07:00:19 -05:00

62 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Keihin SH7054 (Triumph 865 twin, mechanical odo) — table map
Reversed from `Nc()`/`Lb()` in `l.java` and validated against the stock reference
maps. All offsets are in the reconstructed **flat ROM** (0x60000). Compute per map:
```
fe = c.a[Qd*48] # Qd from the s.a directory lookup on the map signature
base = (fe[0] & 0x2F0) << 12 # = 0x50000 for the 865 twin family
offset(table) = base + fe[<field>]
```
Main tables are **32 rows (RPM) × 20 cols (throttle), 16-bit big-endian**.
## Axes
| Axis | fe field | Entries | Values (20187) | Meaning |
|---|---|---|---|---|
| RPM (rows) | `fe[8]` | 32 | 0, 500, 900, 1000 … 10000 | engine speed, direct RPM |
| Throttle (cols) | `fe[27]` | 20 | 0, 10, 20 … 780, 1000 | throttle %, ÷10 (0–100.0%) |
## Tables (validated by production 20187 vs aftermarket 20188 diff)
| Table | fe | Offset (20187) | Value range | Notes |
|---|---|---|---|---|
| Main fuel — cyl 1 | 11 | 0x56990 | 951–10480 | **strong**: 75% diff, smooth VE, aftermarket richer |
| Main fuel — cyl 2 | 12 | 0x56E90 | 951–10680 | **strong**: 67% diff |
| Low-throttle fuel — cyl 1 | 15 | 0x55590 | 0–10760 | 70% diff; starts at 0 (closed throttle) |
| Low-throttle fuel — cyl 2 | 16 | 0x55A90 | 0–10810 | 68% diff; cyl-1 pair |
| Fuel — base/idle | 9 | 0x55500 | 0–10760 | 61% diff; lower values |
| Ignition advance — gear 1 | 19 | 0x587D0 | 13–600 | 4 evenly-spaced (0x500) 20×32 tables |
| Ignition advance — gears 2–5 | 20 | 0x58CD0 | 13–600 | main operating map |
| Ignition advance — gear 6 | 21 | 0x591D0 | 13–600 | overdrive |
| Ignition advance — neutral | 22 | 0x596D0 | 60–600 | idle/free-rev |
## AFR / target lambda
`fe[2]` @ 0x52260 is an interleaved (value, breakpoint) curve where **128 = λ1.00
(stoich, 14.7 AFR)** — e.g. `… 128, 500, 128, 400, 128, 300 …`. The `128` cells are
the closed-loop lambda targets; disabling closed loop (O2 delete) lets you set
these richer. Exact dimensions still being confirmed.
## Scaling (confidence varies)
- **Fuel** values are VE/fuel-mass in the ECU's internal units (≈ 0–10800). Real
units (injector µs / VE %) need the ECU's fuel constant; relative changes are
exact, absolute scaling TBD.
- **Ignition** 13–600 is advance in an internal unit (candidate: value ÷ 10 = °BTDC,
giving ~1.3–60°; the low-RPM row 90→14→20 fits a retard-then-advance curve). TBD.
- **AFR** 128 = λ1.00 is solid (standard Keihin convention).
## SAI / O2 / lambda flags
Now findable via the localised flat-ROM diff (20187 vs 20188), which isolates small
single-byte changes (e.g. 0x50C13, 0x534AD, 0x59759) as prime toggle candidates.
Confirming which is SAI vs O2 needs either bench testing or the finer `Nc` device
logic — a follow-up.
## Status
Fuel and ignition table **locations** are validated end-to-end. Remaining: exact
scaling constants, AFR dimensions, and confirming the individual device flags.