Panel Memory Factory Data
Panel Memory Factory Data (Table Data ROM)
The block at 0x99EC00-0x9ABF3F in the Table Data ROM holds the factory contents of the PANEL MEMORY registrations: ten 16-character bank names followed by 80 preset records of 674 bytes – ten banks of eight, one per PANEL MEMORY button. Boot copies all of it into DRAM, where the user’s own registrations later overwrite the working copies.
Two earlier readings of this region are retired by this page:
- “Demo Category Names” – the ten strings at 0x99EC00 are Panel Memory bank names
(“Tour Of The 5000”, “Accordion”, …), not demo-song categories. The eleventh name
older notes listed,
xPiano Atmosphere, is almost certainly a boundary artefact of reading string-shaped runs straight past the end of the name array into the first preset record: the record’s first byte is its0x78name-chunk tag, which is ASCIIx, andPiano Atmosphereis preset 0’s name. - “Tone Generator Configuration Records, 26-byte stride” – there is no 26-byte record stride here. The 26-byte autocorrelation that produced that guess is the 2-byte chunk header plus 24-byte payload of the sound-part chunks inside a 674-byte record. The stride of an actual record is 674.
The block is now assembled from source in table_data/panel_memory_presets.s.
Companion pages: Custom Data Flash for the user Panel Memory storage, Table Data ROM for the region map, Music Stylist Preset Database for the other factory-registration block in this ROM.
Layout
| range | symbol | contents |
|---|---|---|
0x99EC00-0x99EC9F |
PanelMemory_BankNames |
10 x 16-char space-padded bank names |
0x99ECA0-0x9ABF3F |
PanelMemory_Preset_00.._79 |
80 x 674-byte preset records |
Record i is bank i / 8, button (i % 8) + 1. 80 x 674 = 53,920 bytes, ending exactly
at 0x9ABF40, from where the ROM is 0xFF fill to 0x9B3FFF (32,960 bytes, verified).
Factory banks and presets
| bank | name | buttons 1-8 |
|---|---|---|
| 1 | Tour Of The 5000 | Piano Atmosphere, String Orchestra, PianistMode Trio, New Guitars, Fall To The Left, HollywoodRomance, It’s An Illusion, Pomp & Ceremony |
| 2 | Accordion | Le Musette, Jazz Accordion, Steirisches, Soft Latin, Tutti Registers, Pure Tango, Romantic Reeds, Fun Park Reeds |
| 3 | Piano Styles | Ragtime Pianist, Jazz Pianist, Easy Jazz Groove, Lullaby Of Jazz, Bossa Pianist, Deep Rhumba Solo, Blueberry Keys, Sequin Virtuoso |
| 4 | Jazz&Rock Organ | The Cat of Jimmy, Smith strikes B3, Tribute to Joey, DeFrancesco’s C3, The Lord Organ, Hensley’s Livin’, Brian’s Revival, Auger’s Bump |
| 5 | Church & Theatre | Chapel Organ, Sunday Service, Full Pipes, All Stops Out, Funtime Theatre, At The Seaside, Tibia Chorus, Tibias Plus |
| 6 | Light Orchestra | 40’s Dance Band, Late Night Jazz, On The Shore?, Mantostringy!, Latin Muzak, Cello Romance, Pizzicato Magic, Radio Orchestra |
| 7 | Split Sounds | Piano,Bass&Drums, Modern Jazz Trio, Ballad Combo, 60’s Pop Group, Folk Festival, Power Pop Ballad, Hillbilly Band, Brass Band |
| 8 | Layer Production | Behind The Piano, Guitar Dreams, Studio EP, Bright Piano Pad, Guitar Synth, Open Spaces, Super Sweeper, Of The Ether |
| 9 | Special DSP FX | 50’s Echo, Don’t Ring Us!, A Bit Of A Mixup, Phased Guitar, Effective Warmth, Bad Boy Wah, Flanged & Funked, Underwater Echo |
| 10 | World | Sunset in Peru, Party in Greece!, Tango Symphonia, Hungarian Party, Caribbean Style, The French Way!, Eastern Promise, Edinburgh Dance |
Bank names are stored centred with spaces (" Accordion ", " World ");
only bank 0 fills all 16 columns. Preset names are stored likewise and are shown here
trimmed.
Record format: a chunk stream
A record is not a fixed struct. It is a stream of (tag, length, payload[length])
chunks, terminated by a 0xFF tag; a second 0xFF byte pads the record out to 674
bytes. All 80 records carry the same 34-chunk sequence in the same order (verified
across all 80).
| # | tag | payload | role |
|---|---|---|---|
| 1 | 0x78 |
18 | 16-char preset name + 2 spare bytes (00 00 in all 80) |
| 2-5 | 0x00-0x03 |
24 each | sound-part blocks, the four realtime parts |
| 6 | 0x0F |
24 | sound-part block |
| 7-13 | 0x10-0x16 |
24 each | sound-part blocks (accompaniment/rhythm side) |
| 14 | 0x19 |
24 | sound-part block |
| 15-17 | 0x44-0x46 |
10 each | parameter groups (undecoded) |
| 18 | 0x47 |
8 | parameter group (undecoded) |
| 19 | 0x43 |
4 | parameter group (undecoded) |
| 20 | 0x48 |
10 | parameter group (undecoded) |
| 21 | 0x90 |
6 | parameter group (undecoded) |
| 22 | 0x60 |
4 | parameter group (undecoded) |
| 23-27 | 0x61, 0x63-0x66 |
24 each | part-block-sized groups (undecoded) |
| 28 | 0x68 |
10 | undecoded |
| 29 | 0x70 |
8 | undecoded |
| 30 | 0x72 |
14 | undecoded |
| 31 | 0x92 |
14 | undecoded |
| 32 | 0x71 |
2 | undecoded |
| 33 | 0x99 |
30 | undecoded |
| 34 | 0x80 |
14 | undecoded |
| – | 0xFF |
– | terminator, then one 0xFF pad byte |
That adds up: 20 + 13x26 + 78 + 5x26 + 106 + 2 = 674.
Note the chunk order in the stream is not tag order – 0x44 0x45 0x46 0x47 0x43 0x48
is the literal sequence in every record.
The 24-byte sound-part block
Thirteen chunks per record carry a 24-byte sound-part payload (0x00-0x03, 0x0F,
0x10-0x16, 0x19). Five further chunks (0x61, 0x63-0x66) happen to be 24 bytes
long as well but are not part blocks.
Field observations from cross-record diffs, all tentative:
| offset | observation |
|---|---|
| +0 / +1 | sound selection (program number plus a bank/group byte) |
| +3 | volume-like level, range 0x3C-0x7F |
| +8 / +9 | a 0x40-centred pair (pan-like) |
| +13 | part/routing byte – constant per tag across all 80 records |
The +13 byte is the strongest structural signal in the block. Its value per tag, measured over all 80 records:
| tag | +13 | tag | +13 |
|---|---|---|---|
0x00 |
0x00 |
0x13 |
0xC2 |
0x01 |
0x01 |
0x14 |
0xCE |
0x02 |
0x02 |
0x15 |
0xC4 |
0x03 |
0x03 |
0x16 |
0xC0 |
0x0F |
0x0F |
0x19 |
0xCF |
0x10 |
0xC4 |
||
0x11 |
0xC8 |
||
0x12 |
0xC9 |
For the five low tags the byte simply repeats the tag; for the eight high tags it is
0xC0 | m with an m that is not the tag’s low nibble, so the mapping is a lookup, not
an arithmetic rule. There is exactly one exception in the whole block: preset 15
(bank 2 button 8, “Fun Park Reeds”) stores 0xC0 in its 0x19 chunk where the other 79
records store 0xCF.
How the firmware loads it
Three main-CPU routines, cited at their v10 addresses; v7 and v9 carry the same code at shifted addresses. These addresses are still in an unconverted region of the program ROM, so the symbol table only has placeholder names for them.
0xFC81EF – initialise everything.
MEM_COPY(0x1ED350, 0xEDBA1C, 16) ; 16-byte spare name slot: "HK \0" + zeros + c0 03 50
MEM_COPY(0x1ED360, 0x0099EC00, 160) ; the ten bank names
for i in 0..0x4F: call 0xFC7DD8 ; the 80 preset records
The "HK " signature it seeds is the same one the user registration area in the Custom
Data Flash uses (see Custom Data Flash).
0xFC7E82 – copy one bank name. Returns immediately if the index is >= 10, otherwise
MEM_COPY(0x1ED360 + 16*i, 0x99EC00 + 16*i, 16).
0xFC7DD8 – build one RAM record. Bounds-checks the index against 0x50 (= 80),
zero-fills a 960-byte (0x3C0) RAM record at 0x1ED400 + 960*i, then assembles it from
two sources – the 674-byte ROM record at 0x99ECA0 + 674*i, and a fixed default block
in the program ROM:
| RAM range | length | source |
|---|---|---|
+0x000 |
0x07C |
ROM record +0x00 – the name chunk and parts 0x00-0x03 |
+0x07C |
0x11E |
program ROM 0xEDB478 – eleven chunks tagged 0x04-0x0E |
+0x19A |
0x226 |
ROM record +0x7C – everything else, including the FF FF terminator |
The middle piece is the key structural fact: parts 0x04-0x0E are not stored per
preset. The block at main-CPU ROM 0xEDB478 is 286 bytes = eleven chunks in exactly the
same (tag, 24, payload) grammar, tagged 0x04 through 0x0E, and every one of the 80
factory presets gets the identical copy spliced in. The assembled RAM image is therefore a
45-chunk stream of 960 bytes carrying 24 sound parts, with tags 0x17 and 0x18 unused.
Composer factory memory image (0x9B4000-0x9C3FFF)
The 64 KB immediately after the Panel Memory fill is Composer_FactoryMemoryImage: the
factory contents of the COMPOSER (user rhythm-style) memory. It is copied wholesale
into DRAM at boot, with no interior addressing at all:
ld XIY,0x9B4000 / ld XIX,0x94800 / ld BC,0x8000 / ldirw ; 0x8000 words = 64 KB
That code is at main-CPU 0xF6413A in v9 and v10 and 0xF63D36 in v7; the v7 source
tree has it at v7/maincpu/sequencer/accompaniment_engine.s:16703 under the placeholder
label AccWidget_DispatchTable, which does not describe it (a rename is pending). Because
nothing addresses inside the image, the block stays a single labelled .incbin slice.
Structure observed in the image (offsets are image-relative; add 0x9B4000 for ROM):
| image offset | contents |
|---|---|
+0x0000 |
header: memory-configuration words, part lists 01 02 03 04, a 5A 5A 5A ("ZZZ") tag |
+0x0080 |
30 style-slot records, 0x60 bytes each, 16-char name at slot offset +0x20 |
+0x0C00 |
zero fill to +0x12FF |
+0x1300 |
style event pool, to the end of the image |
The 30 slot names are three factory user styles at four variations each –
` Pop Samba 1.. Pop Samba 4, GentleSwing 1..GentleSwing 4,
German 3/4 1..German 3/4 4 -- followed by 18 slots named Clear `.
The “MIDI-like note streams near 0x9C0000”
The old region map described 0x9B4D78-0x9C3FFF as “tone generator parameter data;
MIDI-event-like note streams (90 30 24 ...) from 0x9C0000”. Those streams are real, but
they are the Composer image’s rhythm data, not tone-generator parameters. They use the
same cell grammar the factory rhythms use: a 80 nn 00 FF FF 87 cell header followed by
six-byte note events beginning 0x90. In the dumped image there are 52 such headers,
each landing on a 256-byte boundary, the first at image offset 0xAB00 = ROM
0x9BEB00 – earlier than both the old map’s 0x9C0000 and the “+0xC000” figure quoted
in the module header. The event grammar itself is not decoded on this page; see
Custom Data Flash for the rhythm-cell format in
the factory style database.
Neighbours
0x9999CC-0x9999D2–HelpDB_TrailingResidue, seven stray bytes left after the Indonesian help database:7F D8 7F E2 7F EC 7E, three(0x7F, N)pairs withNstepping by 10, then a lone0x7E. Nothing points at them; they look like the tail of a stride-10 table from an earlier factory build.0x9999D3-0x99EBFF– 0xFF fill (21,037 bytes, verified).0x9C4000-0x9C404F–DemoSongPreset_PointerTable: 19 four-byte LE pointers plus a null terminator, indexed aspart * 4. Every non-null target begins with the ASCII magicSLIDE4K, so these are compressed demo-song presets, not PCM waveform samples as an older note on the Table Data ROM page had it. Entry 18 is the Feature Demo preset at 0x8E0000; the other 18 tile 0x9C4050-0x9F94CA (the last block starts at 0x9F494E), with 0xFF fill following from 0x9F94CB.
Build status
table_data/panel_memory_presets.s is a prerequisite of
rebuilt_ROMs/kn5000_table_data.llvm.o (Makefile:680), so the whole Panel Memory block
assembles from source in the LLVM lane, chunk by chunk, and the demo-preset pointer table
is symbolic. The Composer image is still a labelled raw slice of
table_data/includes/icons_to_strings.bin, and the parallel ASL mirror still takes the
entire 0x944D78-0x9C404F range as one binclude
(archive/asl/table_data/kn5000_table_data.asm:221) so that the blob file stays
byte-identical on disk.
Open items on this block:
- every chunk except the name chunk is undecoded at field level; the sound-part field guesses above have not been checked against the tone-generator command format;
- the meaning of the tags themselves (why
0x43-0x48,0x60-0x66,0x70-0x72,0x80,0x90-0x99) is unknown; - the preset-15
0x19/0xC0outlier is unexplained; - the Composer image’s header words and its 0x1300-0xAB00 span are undescribed;
- the loader routines still carry placeholder
LABEL_*names because that part of the program ROM has not been converted.
Provenance
- Carve + labels:
table_data/panel_memory_presets.sand the Composer / demo-table hunks intable_data/kn5000_table_data.s(commit9510993). - Loader routines: disassembled from
original_ROMs/kn5000_v10_program.romat0xFC81EF,0xFC7E82,0xFC7DD8; the default block at0xEDB478and the"HK "slot at0xEDBA1Cwere read from the same image. - Composer copy:
v7/maincpu/sequencer/accompaniment_engine.s:16703; the immediate0x009B4000occurs exactly once in each of the v7, v9 and v10 program ROMs. - Chunk-signature, +13 census, bank/preset names, fill extents and the Composer image
survey: recomputed from
original_ROMs/kn5000_table_data.romfor this page.