4.3 KiB
Historical snapshot (2026-09-26 working notes). Two claims are superseded: update entry is hold-PAD-while-powering-on (see ../firmware-update.md), and the cmtd checksum is solved (see ../../tools/README.md).
Lofi-12 XT.bin — Reverse Engineering Notes (v1.1.156)
- File:
Lofi-12 XT.bin(firmware v1.1.156) - Size: 1,595,605 bytes (
0x1858D5) - SHA256:
617c3efea92399b0e3ed40890dd67a75013b0132059fa713076cae68a1908ac5 - Folder also contains
.DS_Store; no sample folders (unlike v1.5.205) - Same SD-root
SYSTEM UPDATEflow as v1.5.205
Hardware context
Same platform as v1.5.205 (see ../Lofi-12XT_v1.5.205/Lofi-12XT_v1.5.205/reversed.md):
TI TMS320C6748 (ARM9 + C674x DSP), DDR2 base 0xC0000000. All sect
load addresses are 0xC2xxxxxx (DDR2 snapshot loaded by the SPI-flash bootloader).
Container format (same Sonicware custom format as v1.5.205)
[cmtd 48B][mmtd 36B][sect x7 -> EOF, exact fit]
cmtd (0x00–0x2F)
| Off | Value | Meaning |
|---|---|---|
| 0x00 | cmtd |
magic |
| 0x04 | 1595605 | u32 LE filesize (matches) |
| 0x08 | 0xF58AF539 |
u32 checksum (?) — differs per version, algorithm TBD |
| 0x10–0x2F | (12, 1, 3, 1, 1, 156, 48, 1595557) |
container (?, 1, 3), fw (1, 1, 156), hdr len 48, remaining |
mmtd (0x30–0x53)
| Off | Value | Meaning |
|---|---|---|
| 0x30 | mmtd |
magic |
| 0x34 | 1595557 | remaining size |
| 0x38 | 6e 25 13 20 ff ff ff ff |
timestamp/flags? (build-specific) |
| 0x40 | (1, 1, 156) |
fw version |
| 0x4C | 0xC26C4820 |
entry point (inside big code sect, verified below) |
| 0x50 | 7 | sect count |
sects
| # | File off | Load addr | Len | End addr | Role |
|---|---|---|---|---|---|
| 0 | 0x000054 | C27753B8 | 85912 (0x14F98) |
C278A350 | asset/blob |
| 1 | 0x014FF8 | C2774C6C | 656 (0x290) |
C2774EFC | float table |
| 2 | 0x015294 | C2775000 | 512 (0x200) |
C2775200 | record table |
| 3 | 0x0154A0 | C2589800 | 1389120 (0x153240) |
C26DCA40 | main code (.text), C6000 DSP |
| 4 | 0x1686EC | C2589508 | 8 | C2589510 | zeros (gap/patch slot, same as v1.5.205) |
| 5 | 0x168700 | C2755488 | 115561 (0x1C369) |
C27718F1 | .rodata/.data (all readable strings) |
| 6 | 0x184A75 | C27737F8 | 3668 (0xE54) |
C277464C | float ramp tail |
Chain verified: next_off = off + 12 + len, ends exactly at EOF (0x1858D5).
Memory tiling: code C25895xx–C26DCA40, data C2755488–C277464C (same
code→data→assets split as v1.5.205, just at lower DDR addresses).
Code identification
- Entry
0xC26C4820→ file off0x1504CC. C64x-LE disassembly:ZERO b0; mvc b0,ier; mvc b0,csr; mvk 0x37f4,b15; mvklh -0x3d89,b15; and -8,…— identical reset prelude shape as v1.2.179/v1.5.205, only the stack immediates differ. Confirms C6000 DSP code. - Big sect entropy 6.890, zeros 175,494 (12.6%) — same code+data mix as v1.5.205.
- String sect cross-refs: 5,854 words into code range + 2,932 self-pointers (vs 6,362 + 3,141 in v1.5.205 — table growth with features).
- Total
strings>=4: 10,902 (vs 11,110 in v1.2.179; v1.5.205 higher).
Data sect contents (file 0x168700–0x184A75)
- Same C674x crash dumper (
Legacy NMI Exception,IERR=,A0=…A31=,B0=…B31=,NTSR/ITSR/IRP/SSR/AMR,14AppSongBrowser,N3HAL…Driver, libc++NSt3__). - Older
FileUtilAPI shape: signatures use(…S1_S1_PA256_c…Fv…)/(…S1_jjPjS2_…); noremoveResourceForksymbols at all (present in v1.5.205), and noRb(bool) params — file-DB / resource-fork handling postdates this build. - v1.5-only feature strings absent:
Snip Loop0 hits,PATTERN MIXDOWN0,AUDIO EXPORT0. (Isolator1 hit,Reverse1,Compressor2 — isolated pre-existing occurrences, not the v1.5 master-FX set.)
Differences vs newer builds
| v1.1.156 | v1.2.179 | v1.5.205 | |
|---|---|---|---|
| size | 1,595,605 | 1,606,197 | 1,707,049 |
| nsect | 7 (with 8 B patch slot) | 6 (slot absent) | 7 (slot back) |
| code len | 1,389,120 | 1,399,200 | 1,490,112 |
| strings len | 115,561 | 117,825 | 125,081 |
| code base | C2589800 | C258D800 | C2B80C00 |
| entry | C26C4820 | C26CA4C0 | C2CD1AA0 |
v1.1→v1.2 is a small delta (+10 kB code); v1.2→v1.5 is the big jump (+91 kB code, +7 kB strings: audio export, 4 new master FX, 16 slices, MIDI Note Map, …).