Files
lofi-12xt-firmware/rev-diff.md
T
2026-09-30 22:48:06 +02:00

6.8 KiB
Raw Blame History

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.