DSP Name Tables (Main CPU)
The DSP Effect and Parameter Name Tables
Everything the KN5000 shows you on the effect-editor page — the effect’s name, the eight parameter labels down the left, the unit suffix next to each value — comes from four tables in the Main CPU ROM. The algorithms those names label live on the other side of the inter-CPU link, in the Sub-CPU payload (DSP Effect Data Zone).
The tables’ ROM addresses have been known for a long time (see
Sound Parameter Protocol). What was
missing until commit 8c9b66d (2026-08-08) was their presence in the reconstruction’s
source: they sat inside a C-compiled blob as several hundred anonymous uint16_t
members, so nothing in the repository said what they were.
What this page is not. Naming a table is not the same as decoding it. The four tables below are exact and their consumers are traced, but they are the labelling layer only — they carry no DSP semantics. The surrounding 146 KB of widget-descriptor material in the same blob is still largely anonymous, and the repository’s build gate proves byte-identity of the rebuild, nothing about any interpretation on this page.
1. Where they live
The whole zone is inside one binary include. v10/maincpu/ui_widgets/widget_descriptors.s
contains a single directive:
NakaData_WidgetDescriptors:
.incbin "includes/generated/naka_widget_descriptors.bin"
That 150,888-byte file (ROM 0xE30E60-0xE55BC7) is a build product, not a dump slice:
the Makefile compiles v10/maincpu/ui_widgets/naka_widget_descriptors.c with
clang -target tlcs900, links it with naka_widget_descriptors_link.ld and extracts
.text with llvm-objcopy. The C file is one large packed struct auto-generated by
scripts/naka_struct_decode.py, hand-annotated where a region has been identified.
The DSP naming zone occupies blob offsets +0x15B8 through +0x2719 —
ROM 0xE32418-0xE33579, 4,450 bytes:
| Symbol | ROM address | v10 ROM file offset | Blob offset | Shape |
|---|---|---|---|---|
DspParamUnit_Table |
0xE32418 |
0x032418 |
+0x15B8 |
86 × 2 bytes |
DspParamName_Table |
0xE324C4 |
0x0324C4 |
+0x1664 |
86 × 17 bytes |
DspEffectName_PtrTable |
0xE32A7A |
0x032A7A |
+0x1C1A |
128 × u32 |
DspEffectName_Strings |
0xE32C7A |
0x032C7A |
+0x1E1A |
128 × 18 bytes |
172 + 1462 + 512 + 2304 = 4450 — the four tables tile the zone exactly, with no padding
between them. (The Main CPU program ROM maps at 0xE00000, so the file offsets above are
simply the ROM address minus 0xE00000.)
In assembly the four names are .equ aliases relative to NakaData_WidgetDescriptors;
in the C source they are struct members of the same name. The 128 effect-name strings keep
their pre-existing assembler labels NakaInst_<EFFECT> (e.g. NakaInst_NO_OPERATION,
NakaInst_CHORUS); the EffectName_EffNNN_<NAME> spellings are C struct members inside
naka_widget_descriptors.c and are not linker symbols.
2. Why a grep never found them
The effect-name strings were already in the C source as ALIGNED_STRING(...) members —
but they were called str_0 … str_127, with no indication that str_0 is effect 127
and str_127 is effect 0. Their index array was ptrs_0[128].
The parameter name and unit tables were worse: 817 contiguous anonymous uint16_t
members, field_15b8 through field_1c18, initialised with hex word constants. Because
the name records are 17 bytes long, every other name starts at an odd offset and each
16-bit member holds a byte-swapped fragment of two different characters. “VOLUME” in
slot 1 was stored as:
.field_1674 = 0x5620, /* ' ' 'V' */
.field_1676 = 0x4C4F, /* 'O' 'L' */
.field_1678 = 0x4D55, /* 'U' 'M' */
No grep of the checked-in text sources could turn up a parameter name in this table —
naka_widget_descriptors.c contains no readable copy of one. That is why the disassembly
plan carried “carve the maincpu effect/name tables” as an open item long after outside
tooling had already read the same bytes straight out of the ROM dump.
The 817 members split 86 + 731: 86 words for the unit table (86 × 2 = 172 B) and
731 words for the name table (86 × 17 = 1,462 B). Both counts, and the fact that the
removed members form one unbroken 2-byte-stride run from +0x15B8 to +0x1C18, are
mechanically checkable in the commit diff.
3. Parameter names and units
One index — the parameter-id byte — selects a row of both tables, so slot i of the name table and slot i of the unit table always describe the same UI control.
- Name record: 17 bytes = 16 display characters + a
:separator. It is not NUL-terminated; the firmware copies exactly 17 bytes withStrncpy. - Unit record: 2 characters, no terminator. Only four values occur in the whole
table: two spaces (55 slots),
Hz(13),ms(11) andsfollowed by a space (7). - Slots 0 and 85 are blank spares: 17 spaces, no colon. Slots 1 and 2 are both
VOLUME, so the 86 slots hold 84 distinct records.
Four records — slots 15, 16, 17 and 73, marked † below — begin with seven leading
spaces: SLOW, WIND UP, WIND DOWN and FAST. They read as indented continuation
rows under the label above them on screen; which label each one hangs from has not been
confirmed against a screenshot.
| # | Name | Unit | # | Name | Unit |
|---|---|---|---|---|---|
| 0 | (blank spare) | — | 43 | RELEASE SENS. |
s |
| 1 | VOLUME |
— | 44 | ATTACK RATE |
s |
| 2 | VOLUME |
— | 45 | RELEASE RATE |
s |
| 3 | REV SEND |
— | 46 | GATE TIME |
ms |
| 4 | DRIVE |
— | 47 | MASK TIME |
ms |
| 5 | ADJUST |
— | 48 | HARS TIME |
— |
| 6 | EMPHASIS GAIN |
— | 49 | LFO WAVEFORM |
— |
| 7 | DEPTH |
— | 50 | OSC WAVEFORM |
— |
| 8 | LFO SPEED |
Hz |
51 | BAND EMPHASIS FC |
Hz |
| 9 | SLOW LFO SPEED |
Hz |
52 | BAND EMPHASIS Q |
— |
| 10 | FAST LFO BALANCE |
— | 53 | BAND EMPHASIS G |
— |
| 11 | RESONANCE |
— | 54 | LOW MIX |
— |
| 12 | MANUAL |
— | 55 | HIGH MIX |
— |
| 13 | SLOW/FAST |
— | 56 | PHASE |
— |
| 14 | TREBLE FAST |
Hz |
57 | FEEDBACK |
— |
| 15 | SLOW † |
Hz |
58 | SWEEP RANGE |
— |
| 16 | WIND UP † |
s |
59 | WAH CENTER FC |
— |
| 17 | WIND DOWN † |
s |
60 | HARS TIME L |
ms |
| 18 | BASS FAST |
Hz |
61 | HARS TIME R |
ms |
| 19 | BASS SLOW |
Hz |
62 | BALANCE L |
— |
| 20 | VOLUME ADJUST |
— | 63 | BALANCE R |
— |
| 21 | OSC SPEED |
Hz |
64 | FAST LFO SPEED L |
Hz |
| 22 | DELAY L |
ms |
65 | FAST LFO SPEED R |
Hz |
| 23 | DELAY R |
ms |
66 | MODULATION DEPTH |
— |
| 24 | FEEDBACK L |
— | 67 | DELAY1 DRY/WET |
— |
| 25 | FEEDBACK R |
— | 68 | DELAY2 DRY/WET |
— |
| 26 | DELAY DRY/WET |
— | 69 | VIBRATO DRY/WET |
— |
| 27 | CHORUS DRY/WET |
— | 70 | WAH DRY/WET |
— |
| 28 | FLANGER DRY/WET |
— | 71 | FAST LFO SPEED |
Hz |
| 29 | PHASER DRY/WET |
— | 72 | TREBLE DEPTH |
— |
| 30 | LOW EMPHASIS FC |
— | 73 | FAST † |
Hz |
| 31 | LOW EMPHASIS G |
— | 74 | BASS DEPTH |
— |
| 32 | HIGH EMPHASIS FC |
Hz |
75 | DELAY 1 |
ms |
| 33 | HIGH EMPHASIS G |
— | 76 | DELAY 2 |
ms |
| 34 | REVERB TIME |
s |
77 | DELAY 3 |
ms |
| 35 | PRE DELAY |
ms |
78 | DELAY 4 |
ms |
| 36 | HIGH DAMP GAIN |
— | 79 | PAN 1 |
— |
| 37 | ER.LEVEL |
— | 80 | PAN 2 |
— |
| 38 | PITCH L |
— | 81 | PAN 3 |
— |
| 39 | PITCH R |
— | 82 | PAN 4 |
— |
| 40 | THRESHOLD |
— | 83 | INTENSITY |
— |
| 41 | RATIO |
— | 84 | EXCITE |
— |
| 42 | ATTACK SENS. |
s |
85 | (blank spare) | — |
Trailing spaces are stripped in this table for readability; every record is exactly 16 characters wide in the ROM.
4. The effect-name table runs backwards
DspEffectName_PtrTable is a plain 128-entry u32 array indexed by effect number
0-127. Its entries are not in address order:
DspEffectName_PtrTable[n] == 0xE33568 - 18 * n
That formula holds for all 128 entries — effect 0’s name sits at the highest address
(0xE33568) and effect 127’s at the lowest (0xE32C7A). The string block is therefore
laid out in descending effect order, which is why the pre-existing NakaInst_* label
run in widget_descriptors.s starts with the reserved slots and ends with
NakaInst_NO_OPERATION. The source states the inverse mapping explicitly: for any label
in that run, the effect number is (0x02708 - blob_offset) / 18.
Each record is 18 bytes: 16 display characters, 0x00, then 0xFF filler. Effect numbers
stop at 99 — all 28 slots from 100 to 127 hold the placeholder ---------- centred in its
16-character field, as do 29 of the slots below 100, leaving 71 named effects.
5. Who reads them
All four consumers are in sequencer/sequencer_ui.s. Addresses are from the linked v10
ELF:
| Routine | Address | Reads | Mechanism |
|---|---|---|---|
DspItem0_DisplayEffectName |
0xF355F3 |
DspEffectName_PtrTable |
effect no. from RAM word 0x2976, sll xwa,2, index, Strcpy |
DspItem0_DisplayParamNames |
0xF3561F |
DspParamName_Table |
param id × 0x11, Strncpy 17 bytes, 8 rows per page |
DspItem0_DisplayParamValues |
0xF3566C |
DspParamUnit_Table |
same param id × 2, Strncpy 2 bytes |
EntertainerGridCheck |
0xF30326 |
DspEffectName_PtrTable |
takes the table address into a stack slot |
Both parameter routines get their id the same way: the per-effect ordered id list is a
byte array whose base address is taken with lda_d16 xbc, (0x29ac), and the row index of
the first line on the current page is the byte at 0x021098. The loop paints eight rows
(cpw (xsp + 18), 0x8), so a screen is a sliding window into that id list.
6. Cross-reference to the Sub-CPU algorithms
Every effect-name member in naka_widget_descriptors.c now carries a comment naming the
DSP_EffNN_* / DSP2_EffNN_* blocks it labels in v142/subcpu/subcpu_data_tables.s.
Counting those comments over the 128 slots:
| Class | Count |
|---|---|
| Own at least one Sub-CPU block | 60 |
Marked STUB — nothing of their own |
40 |
| Effect numbers 100-127, no Sub-CPU slot at all | 28 |
That reconciles with the figure already on the
DSP Effect Data Zone page — 42 effect
numbers point all three of algorithm / coefficient / descriptor at the shared NO OPERATION
trio. The 42 are the 40 stubs plus two special cases: effect 0 itself, which owns the
trio, and effect 37 SLOW ATTACKER, which owns a parameter-value table (0x0173F2) but
runs the pass-through program. Nine of the 60 owners are DSP2_* (IC310 / MN19413)
programs.
The zone bytes are identical in the v7, v9 and v10 program dumps — none of the 348
bytes that differ between the v7 blob and the v9/v10 blob falls inside
+0x15B8-+0x2719; the differences are relocated code pointers elsewhere in the
descriptor material.
7. Caveats and open items
- The blob is still one
.incbin. Only the naming zone has been identified; most of the 150,888-byte struct is stillfield_XXXX/ptr_XXXXmembers with no meaning attached. Naming 4,450 bytes does not make the widget-descriptor format understood. - The rename landed in v9 and v10 only.
v7/maincpu/sequencer/sequencer_ui.sstill loads the table through the positional aliasNakaData_WidgetDescriptors_0x1C1A. The three aliases remain defined inshared/positional_labels.sin all three trees. - v7 does not compile this blob from its C source. The v7 program build runs a second
pass (
scripts/build/extract_v7_bins.py) that re-extracts generated.binfiles from the original v7 ROM whenever the compiled v9 version matches ≥50 % at the same address, andnaka_widget_descriptors.binis one of them — the committedv7/.../naka_widget_descriptors_link.ldis a copy of v9’s and carries v9 symbol addresses. The disassembly plan tracks this as its largest open item (v7-cdata, ~703 KB across 23 shared-named bins) and flags the 50 % heuristic as a silent-corruption risk. The v7 tree’s 100 % byte-match for this region is therefore not evidence that the C source reproduces v7. - The UI parameter order is not in these tables. Which ids an effect shows, and in
what order, comes from the Sub-CPU side; the ordered lists quoted in the per-effect
banners of
subcpu_data_tables.swere captured live in emulation, not read from a table.
Provenance
- Carve + labels: commit
8c9b66din kn5000-roms-disasm —v10/maincpu/ui_widgets/widget_descriptors.s,v10/maincpu/ui_widgets/naka_widget_descriptors.c(and the v7/v9 copies),v9,v10/maincpu/sequencer/sequencer_ui.s. - Table contents, shapes, blank slots, unit distribution and the
0xE33568 - 18npointer formula: read directly out oforiginal_ROMs/kn5000_v10_program.rom. - Routine addresses:
llvm-nmonrebuilt_ROMs/kn5000_v10_program.llvm.elf. - Stub/owner counts: the 100-entry pointer arrays at Sub-CPU
0x01ED7C/0x01EF0C/0x01F09C/0x01F22Cinoriginal_ROMs/kn5000_subprogram_v142.rom. - Open v7 item:
analysis/binclude-audit-2026-08-07/PLAN.md, packagev7-cdata.