This commit is contained in:
Dejvino
2026-09-30 22:48:06 +02:00
commit 8913cb4314
37 changed files with 3190 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
# Lofi-12 XT firmware — cross-version diff (v1.1.156 → v1.2.179 → v1.5.205)
Per-version structural notes: `docs/firmware/notes-v{1.1.156,1.2.179,1.5.205}.md`
(Sep-26 snapshots; update-entry + checksum notes there are superseded — see
`docs/firmware-update.md` and `tools/README.md`).
This file only documents what *changed* between builds.
Method: `cmtd/mmtd/sect` headers parsed per build (all verified to tile EOF
exactly); string sets compared as `sort -u` of `strings` output with length ≥ 6.
(Raw set lists were scratch files, not shipped.)
Code sects are rebased between builds (different DDR load addresses), so no
byte-level code diff was attempted — deltas below are sizes + string/symbol
evidence.
## TL;DR
- v1.1.156 → v1.2.179: small delta (+10,592 B file, +10,080 B code). Only two
user-visible string additions: `TRACK MUTE`, `AppPad::handleKeyPadOnSliceMode`.
- v1.2.179 → v1.5.205: big delta (+100,852 B file, +90,912 B code). New subsystems
with fresh class families: **audio export**, **MIDI Note Map**, new master FX
(`MIsolator`, `MRackComp`, `SlipRoll`, `HoldDelay`), sample tag search,
precount/sequencer-transport rework, `REVERSE` sample mode, step-LED updates.
- Callback ABI shift in v1.5: many `std::function` symbols change `Fv` (void) →
`Fvi`/`Fvii`/`Fviii` signatures; `FileUtil` gains `removeResourceFork` + `Rb`
params; old `RenderBufferIhLi128ELi128E` display path symbols disappear.
## Image headers
| Field | v1.1.156 | v1.2.179 | v1.5.205 |
|---|---|---|---|
| filesize | 1,595,605 (`0x1858D5`) | 1,606,197 (`0x188235`) | 1,707,049 (`0x1A0C29`) |
| sha256 | `617c3efe…1908ac5` | `30ea9eeb…b616a212` | `a8bffa65…4198026` |
| cmtd cksum | `0xF58AF539` | `0xDFF0D8C2` | `0xB17C0857` |
| mmtd flags | `6e 25 13 20` | `4e b6 e4 04` | `e8 bc f8 4f` |
| version triple | (1, 1, 156) | (1, 2, 179) | (1, 5, 205) |
| entry point | `0xC26C4820` | `0xC26CA4C0` | `0xC2CD1AA0` |
| nsect | 7 | **6** (8 B zero slot absent) | 7 (slot back) |
All three entries disassemble (C64x LE) to the same reset prelude
(`ZERO b0; mvc b0,ier; mvc b0,csr; mvk/mvklh b15/b14; and -8,…`) — only the
stack immediates differ. Container version field stays `(1, 3)` in all builds.
Checksum is solved: CRC32-IEEE init 0 over the image with bytes `[8:12]`
replaced by `0xC27C6282` (proven 3/3; `tools/` computes it). `mmtd` flags
semantics unknown, covered as-is, no handling needed.
## Section map evolution
| Role | v1.1.156 (addr / len) | v1.2.179 (addr / len) | v1.5.205 (addr / len) |
|---|---|---|---|
| asset/blob | C27753B8 / 85,912 | C277B320 / 83,496 | C2DA7600 / 86,168 |
| float table | C2774C6C / 656 | C277AB18 / 660 | C2DA6DD4 / 688 |
| record table | C2775000 / 512 | C277B000 / 512 | C2DA7400 / 512 |
| **code (.text)** | C2589800 / 1,389,120 | C258D800 / 1,399,200 | C2B80C00 / 1,490,112 |
| 8 B zero slot | C2589508 / 8 | — absent — | C2B809E8 / 8 |
| **strings (.rodata)** | C2755488 / 115,561 | C275A7A0 / 117,825 | C2D84DE0 / 125,081 |
| float ramp tail | C27737F8 / 3,668 | C27793E8 / 4,348 | C2DA5680 / 4,312 |
Notes:
- Whole image rebased upward each release (code base `C2589800 → C258D800 → C2B80C00`);
relative layout (code → data → assets) is unchanged.
- Code delta v1.1→v1.2 is +10,080 B; v1.2→v1.5 is +90,912 B.
- Strings-sect cross-refs grow monotonically: code-ptrs 5,854 → 5,909 → 6,362;
self-ptrs 2,932 → 2,967 → 3,141.
- Big-sect entropy constant (6.890 / 6.887 / ~6.89, ~12.6% zeros) — same
code+data mix, no new packing/encryption introduced.
- The 8 B zero sect comes and goes (present, absent, present) — looks like
alignment/patch-slot churn in Sonicware's image generator, not a payload.
## v1.1.156 → v1.2.179: +369 / −318 unique strings (≥6)
Essentially a feature-point release; only two user-visible additions:
- `TRACK MUTE` (+ `PTN MUTE` behavior per changelog)
- `AppPad::handleKeyPadOnSliceMode` (+ lambda variant) — slice-mode pad handling
(matches v1.2 changelog: EVEN slice mode, PAD hold/ROLL, per-track swing, new
LSF/HSF filters — the rest is parameter/data churn, no new class families)
## v1.2.179 → v1.5.205: +551 / −427 unique strings (≥6)
### Added — new subsystems (each a whole class family, not one-offs)
- Audio export: `18AppAudioExportMenu`, `21AppAudioExportMixdown`,
`25AppAudioExportMenuPattern`, `31AppAudioExportIndividualPattern`,
`22AppSongAudioExportMenu`, `25AppSongAudioExportMixdown`,
`28AppSongAudioExportIndividual` (+ `…::execute` lambdas),
`20DialogAudioExporting`, UI strings `AUDIO EXPORT`, `PATTERN/SONG MIXDOWN`,
`MIXDOWN FILE NAME:`, `INDIVIDUAL TRACKS`, `CANNOT EXPORT`, `TO EXPORT.`
- MIDI Note Map: `14AppMIDINoteMap`, `MIDI NOTE MAP`, `NOTE MAP`
- New master FX (match v1.5 changelog): `SoundEffect::MIsolator`,
`MRackComp`, `SlipRoll`, `HoldDelay`
- Sequencer transport rework: `…AppSequencerTransport…::startPrecount` (new
`EibiEUliE`/`EibiEUlvE` overloads; old `EbiEUliE`/`EbiEUlvE` removed)
- `REVERSE` (sample reverse mode), `18AppAudioFileSelect::playPreview`,
`18AppSampleTagSearch::action`, `22StepEditPageController::updateAppLED`,
`MixDown~`
### Added — API/ABI evolution
- `FileUtil::removeResourceFork` (4 refs, previously 0) + `Rb` (bool) params on
`convFsRecursive`/`searchFileRecursive` etc. — matches the v1.5 "1,024 files per
folder / FILE DATABASE" rework. Old `(…S1_jjPjS2_…)` / `(…_PA256_c…Fv…)`
overloads removed (6 `convFsRecursive` old-sig symbols gone).
- Broad `Fv` (void-callback) → `Fvi`/`Fvii`/`Fviii` signature migration across
`TrackAndModuleController::checkStepLock*`, `MainDelegate::loadProjectData…`,
graphics `RenderBuffer` functors, etc.
### Removed (meaningful, 35 strings ≥12 chars; rest is relocated code-sect noise)
- Old `FileUtil` overloads (see above), old `startPrecount` overloads,
`TrackAndModuleController::checkStepLock{ForUpdateParams,ForSendingMidiCc}`
old shapes, `MainDelegate::loadProjectDataWithProgressBar` old shape.
- Display pipeline: all `RenderBufferIhLi128ELi128ELi1327E` symbols gone —
matches the "enhanced GUI / visual feedback" rework.
- `CONVERTABLE FILES:` and `?REPITCH TO TEMPO` strings gone.
### Continuity (present in all three)
Crash dumper (`Legacy NMI Exception`, `A0–A31/B0–B31`, `NTSR/ITSR/…`),
`N3HAL*Driver` family, `14AppSongBrowser`, `Lofi-12XT` branding,
`TRACK MUTE` (added in v1.2, retained in v1.5).
`AppPad::handleKeyPadOnSliceMode` (added in v1.2) is *superseded* in v1.5
(symbol absent — slice engine reworked for 16 slices / multi-slice edit).
## Open questions (updated 2026-09-30)
- ~~Checksum unknown~~ — solved (see above + `tools/lofi_image.compute_checksum`).
- C64x byte-level code diff: now feasible — Ghidra 12.1.3 + ghidra-c6000 lab is
set up (`ghidra/headless/`, PyGhidra path) and `analysis/gen_funcmap.py` maps
vtable-anchored functions; rebase-aware function-hash diffing still to be run.