Reverse Engineering
Reverse Engineering Strategies
Documented approaches for understanding undocumented aspects of the KN5000 system.
HDAE5000 Hard Disk Expansion
The HD-AE5000 is an optional hard disk expansion that provides 1.08GB storage for music files. See the dedicated HDAE5000 page for complete documentation including PPORT commands, entry points, and firmware analysis.
Key Findings Summary
| Property | Value |
|---|---|
| ROM File | hd-ae5000_v2_06i.ic4 (512KB) |
| Base Address | 0x280000 |
| Internal Version | 2.33J (Juli-Oktober 1996, M. Kitajima) |
| PPI Address | 0x160000-0x160006 |
ROM Entry Points
| Address | Target | Description |
|---|---|---|
| 0x280008 | JP 0x28F576 | Boot initialization |
| 0x280010 | JP 0x28F662 | Frame handler (PPORT polling) |
PPI Interface (0x160000)
The main CPU communicates with the HDAE5000 via an 8255 PPI (Programmable Peripheral Interface).
PPI Port Addresses:
| Address | Port | Direction | Function |
|---|---|---|---|
| 0x160000 | Port A | Output | Data output |
| 0x160002 | Port B | Input | Status input |
| 0x160004 | Port C | Output | Control signals |
| 0x160006 | Control | Write | PPI configuration |
PPI Control Register Value: 0x82
- Bit 7 = 1: Mode set active
- Port A: Mode 0, Output
- Port B: Mode 0, Input
- Port C: Output (both nibbles)
Port C Control Signals:
| Bit | Function | Usage |
|---|---|---|
| 0 | Strobe | SET 0 / RES 0 for pulse |
| 1 | Secondary strobe | Secondary handshake |
| 2 | Data direction/select | CHG 2 toggles |
| 3 | Control signal | CHG 3 toggles |
Initialization Sequence (HDAE5000_Parport_Setup at 0xEF4BCC):
1. B5CSL = 0x66 (bus timing for HDAE5000)
2. Control Register = 0x82 (configure PPI)
3. Port A = 0x00 (clear output)
4. Port C = 0x00, then 0x0F (pulse control signals)
5. Delay loop (0xDBBA0 iterations)
6. Port C = 0x00 (clear control)
7. Poll Port B bit 0 until clear (wait for ready)
HDAE5000 Detection (at 0xEF05B0):
BIT 0, (PE) ; Check PE port bit 0
JR NZ, skip_hdae ; If set, HD-AE5000 NOT present
CALR Get_Area_Region_Code
CP L, 4 ; Check region code
CALL NZ, HDAE5000_Parport_Setup ; Init if present
The HD-AE5000 presence is detected via PE port bit 0 (active low).
PPORT Commands (Documented)
15 commands have been identified for PC parallel port communication:
| Code | Command | Description |
|---|---|---|
| 01 | Send Infos About HD | Report HD info to PC |
| 02 | Exit PPORT | End session |
| 03-06 | FSB Operations | Read/Write File System Block |
| 07-11 | Data Transfer | Load/Save between HD, memory, PC |
| 16-18 | HD Management | Delete, Format, Motor off |
| 20 | Send XapFile flash | XAP file transfer |
Windows DLL Callbacks
The firmware contains callback function names used by HD-TechManager5000:
LyricBackColorCheck,LyricForeColorCheck,LyricJumpEditCheckErrMsgTimerCatch,FlsOverWrSwCatch,AttenHDFormatSwCatch
Remaining Tasks
- Disassemble command handlers - Trace PPORT command implementation
- Document FSB structure - File System Block format
- Analyze HD controller protocol - Communication with HD hardware
- Reverse engineer file format - How files are stored on HD
Sub CPU Payload Loading
The main CPU (TMP94C241F) loads a 192KB executable payload to the sub CPU (IC27) at boot time using MicroDMA.
MicroDMA Mechanism
The TMP94C241F has a built-in MicroDMA controller with 4 channels (0-3).
DMA Register Addresses:
| Register | Ch0 | Ch1 | Ch2 | Ch3 | Description |
|---|---|---|---|---|---|
| DMASn | 0x100 | 0x110 | 0x120 | 0x130 | Source Address (24-bit) |
| DMADn | 0x104 | 0x114 | 0x124 | 0x134 | Destination Address (24-bit) |
| DMACn | 0x108 | 0x118 | 0x128 | 0x138 | Transfer Count (16-bit) |
| DMAMn | 0x10C | 0x11C | 0x12C | 0x13C | Mode Register |
DMA Mode Register Bits (DMAMn):
| Bits | Function | Values |
|---|---|---|
| 7-6 | Transfer mode | 00=burst, 01=cycle-steal, 10=single |
| 5-4 | Source addressing | 00=fixed, 01=increment, 10=decrement |
| 3-2 | Dest addressing | 00=fixed, 01=increment, 10=decrement |
| 1-0 | Data size | 00=byte, 01=word, 10=long |
LDC Instruction Encoding for DMA Registers:
DMA registers are accessed via special LDC (Load Control) instructions. ASL doesn’t support these natively, so macros emit raw bytes:
| Instruction | Encoding | Description |
|---|---|---|
LDC DMAS0, XWA |
E8 2E 00 |
Load source ch0 from XWA |
LDC DMAD0, XWA |
E8 2E 20 |
Load dest ch0 from XWA |
LDC DMAC0, WA |
D8 2E 40 |
Load count ch0 from WA |
LDC DMAS2, XDE |
EA 2E 08 |
Load source ch2 from XDE |
LDC DMAD2, XWA |
E8 2E 28 |
Load dest ch2 from XWA |
LDC DMAC2, BC |
D9 2E 48 |
Load count ch2 from BC |
Third Byte Encoding (DMA register selector):
| Value | Register | Description |
|---|---|---|
| 0x00 | DMAS0 | Source, Channel 0 |
| 0x08 | DMAS2 | Source, Channel 2 |
| 0x0C | DMAS3 | Source, Channel 3 |
| 0x20 | DMAD0 | Destination, Channel 0 |
| 0x28 | DMAD2 | Destination, Channel 2 |
| 0x2C | DMAD3 | Destination, Channel 3 |
| 0x40 | DMAM0 | Mode, Channel 0 |
| 0x42 | DMAC0 | Count, Channel 0 |
| 0x48 | DMAM2 | Mode, Channel 2 |
| 0x4A | DMAC2 | Count, Channel 2 |
Sub CPU Boot ROM DMA Usage:
- Channel 0: Latch reads (source=0x120000 fixed, dest=RAM incrementing)
- Channel 2: Payload transfers (configurable source/dest)
- DMA_BURST_CTRL (0x0102) = 0x16: Enables DMA, sets trigger mode
- Trigger: Write 0x0A to 0x0100, or set T01MOD bit 2
DMA Transfer Routines (Sub CPU Boot ROM):
| Routine | Address | Size | Function |
|---|---|---|---|
| SendData_Chunked | 0xFF8604 | 69B | Sends data in 32-byte chunks |
| SendData_Block | 0xFF8649 | 99B | Single block with handshaking |
| SendCmd_E3 | 0xFF86AC | 48B | Payload ready signal |
| SendParams_E2 | 0xFF86DC | 112B | Wait then send E2 command |
| TwoPhase_Transfer | 0xFF874C | 211B | Two-phase transfer with E1 |
Inter-CPU Communication (0x120000)
The main and sub CPUs communicate via a single-byte latch at 0x120000.
Command Encoding:
| Byte Range | Format | Description |
|---|---|---|
| 0x00-0x1F | HHHLLLLL |
Handler (bits 7-5) + data length-1 (bits 4-0) |
| 0xE1 | Fixed | Multi-stage DMA, 6-byte param block at 0x0544 |
| 0xE2 | Fixed | Payload transfer, 10-byte param block at 0x054A |
| 0xE3 | Fixed | Payload ready signal |
Handshaking Register (INTERCPU_STATUS at SFR 0x34):
| Bit | Name | Description |
|---|---|---|
| 0 | SUB_READY | Sub CPU ready to receive |
| 1 | COMPLETION | Transfer complete signal |
| 2 | GATE | Processing gate for InterCPU_RX_Handler |
| 4 | MAIN_READY | Main CPU ready (polled by sub) |
Transfer Sequence (Sub CPU → Main CPU):
1. Poll MAIN_READY (bit 4) until set
2. Clear SUB_READY (bit 0)
3. Write command byte to 0x120000
4. Poll MAIN_READY for acknowledgment
5. Set SUB_READY, initiate DMA
6. Wait for COMPLETION (bit 1) via interrupt
Status Flags (SUBCPU_STATUS_FLAGS at 0x04FE):
- Bit 6: Payload data ready
- Bit 7: Transfer complete
No checksumming observed in protocol - relies on handshaking for reliability.
Boot Sequence
Confirmed flow (from firmware analysis):
- Main CPU initializes after reset (see Reset Vector section)
- Sub CPU boot ROM runs from 0xFF8290 (BOOT_INIT)
- Sub CPU configures DMA for inter-CPU latch at 0x120000
- Sub CPU waits for payload via
InterCPU_RX_Handler(serial receive) - Main CPU sends payload via DMA transfers
- Sub CPU receives E3 command (payload ready signal)
- Sub CPU jumps to payload entry point via trampoline at 0x0400
- Sub CPU signals ready to main CPU via INTERCPU_STATUS
Sub CPU Boot ROM Key Routines:
| Address | Routine | Function |
|---|---|---|
| 0xFF8290 | BOOT_INIT | Hardware initialization entry |
| 0xFF846D | COPY_VECTORS | Copy trampolines to RAM (0x0400) |
| 0xFF85AE | INIT_DMA_SERIAL | Configure DMA for latch |
| 0xFF84A8 | INIT_TONE_GEN | Initialize tone generator at 0x130000 |
| 0xFF881F | InterCPU_RX_Handler | Serial receive interrupt |
| 0xFF88B8 | CMD_Dispatch_Handler | Timer/processing interrupt |
| 0xFF889A | DMA_Complete_Handler | DMA complete interrupt |
Payload Structure
The sub CPU payload (subcpu/kn5000_subprogram_v142.asm) is 192KB.
Key State Variables:
| Address | Symbol | Description |
|---|---|---|
| 0x04FE | PAYLOAD_LOADED_FLAG |
Shared with boot ROM (bit 6: ready, bit 7: complete) |
| 0x10E8 | DMA_XFER_STATE |
DMA transfer state: 0=idle, 1=single, 2=two-phase |
| 0x10EA | CMD_PROCESSING_STATE |
Command processing phase (0-4) |
| 0x10EC | BYTE_FROM_MAINCPU_LATCH |
Last received command byte |
MicroDMA Interrupt Handlers:
| Handler | Address | Description |
|---|---|---|
MICRODMA_CH0_HANDLER |
0x020F1F | Latch reads, command dispatch |
MICRODMA_CH2_HANDLER |
0x020F01 | Payload transfers, state machine |
Command Dispatch Table (CMD_DISPATCH_TABLE):
The command byte received from main CPU uses bits 7-5 to select a handler:
| Bits 7-5 | Range | Handler Address | Purpose |
|---|---|---|---|
| 0 | 0x00-0x1F | 0x034D5F | DSP/audio control |
| 1 | 0x20-0x3F | 0x01FC7C | Audio parameters |
| 2 | 0x40-0x5F | 0x01FC7F | Tone generator |
| 3 | 0x60-0x7F | 0x035893 | Effects |
| 4 | 0x80-0x9F | 0x01F890 | Serial port setup (38400 baud) |
| 5 | 0xA0-0xBF | 0x03CFEE | Voice commands |
| 6-7 | 0xC0-0xFF | 0x020C12 | System commands (shared) |
Bits 4-0 encode the data length minus one (1-32 bytes).
Tone Generator Interface:
The payload accesses the tone generator at two address ranges:
| Address | Register | Description |
|---|---|---|
| 0x110000 | Data | 16-bit voice data (note + velocity) |
| 0x110002 | Status | Status register (bit 0: data ready, bit 1: mode) |
| 0x130000 | Control | Dual DSP control registers |
Port P6 bit 7 controls the A23 address line for tone generator access.
Tone Generator Routines (0x03D0xx):
| Routine | Address | Description |
|---|---|---|
ToneGen_Init |
0x03D016 | Initialize tone gen (mode = 6) |
ToneGen_Process_Notes |
0x03D01E | Process incoming note events |
ToneGen_Read_Voice_Data |
0x03D0C5 | Read voice data with P6.7 control |
ToneGen_Calc_Pitch |
0x03D11F | Calculate pitch from note + tables |
ToneGen_Poll_Init |
0x03D1FB | Clear 8 voice buffers |
ToneGen_Poll_All |
0x03D217 | Poll all 16 channels |
ToneGen_Compare_Voice |
0x03D2AC | Compare 8-byte voice blocks |
Voice State Buffer:
| Address | Size | Description |
|---|---|---|
| 0x4A42 | 1B | DMA command byte |
| 0x4A43 | 1B | Note number |
| 0x4A44 | 1B | Velocity |
| 0x4A48 | 1B | Tone gen mode (0-6) |
| 0x4A4A | 1B | DMA enabled flag |
| 0x4A4C | 16B | Voice slot table (one per channel) |
Serial Port Routines:
| Routine | Address | Description |
|---|---|---|
INTTX1_HANDLER |
0x01F765 | Serial TX interrupt |
READ_BYTE_FROM_RING_BUFFER |
0x01F7B9 | Ring buffer read |
SAVE_BYTE_TO_RING_BUFFER |
0x01F7DD | Ring buffer write |
RING_BUFFER_HAS_OVERRUN |
0x01F7AB | Check buffer empty |
Ring buffer descriptor format (at XWA):
- +0x00: buffer_start pointer
- +0x04: buffer_end pointer
- +0x08: write_pointer
- +0x0C: read_pointer
- +0x14: available_bytes count
Debug Output Routines:
| Routine | Address | Description |
|---|---|---|
Debug_Print_String |
0x038365 | Print string via serial |
Debug_Print_Byte |
0x03836C | Print byte as hex |
Debug_Print_Word |
0x038375 | Print 16-bit word as hex |
These call boot ROM serial routines at 0xFFFEA1 (string) and 0xFFFE86 (byte).
Sub CPU Boot ROM
The 128KB boot ROM (kn5000_subcpu_boot.ic30) initializes the sub CPU hardware and provides a bootstrap environment until the payload is ready.
Memory Map
| Address Range | Size | Description |
|---|---|---|
| 0x0000-0x00FF | 256B | Special Function Registers (SFR) |
| 0x0100-0x01FF | 256B | Extended SFR / Memory Controller |
| 0x0400-0x04E0 | 225B | Interrupt vector trampolines (copied from ROM) |
| 0x04FE | 1B | Payload ready flag |
| 0x0500-0x05A2 | ~160B | RAM / Stack area |
| 0x120000 | - | Inter-CPU Communication Latch |
| 0x130000 | - | Tone Generator Registers |
| 0xFE0000-0xFFFFFF | 128KB | Boot ROM (mostly 0xFF, code at 0xFF8000+) |
ROM Structure
The 128KB boot ROM is mostly erased (0xFF):
| Offset | Address | Size | Content |
|---|---|---|---|
| 0x00000-0x17FFF | 0xFE0000-0xFF7FFF | 96KB | Erased (0xFF) |
| 0x18000-0x1828F | 0xFF8000-0xFF828F | 656B | Data tables (audio lookup?) |
| 0x18290-0x1904D | 0xFF8290-0xFF904D | ~2KB | Boot code and routines |
| 0x1F000-0x1FEFF | 0xFFF000-0xFFFEFF | 4KB | Mostly 0xFF |
| 0x1FEE0 | 0xFFFEE0 | 5B | Reset handler (JP BOOT_INIT) |
| 0x1FF00-0x1FFEF | 0xFFFF00-0xFFFFEF | 240B | Interrupt vector table |
| 0x1FFF0-0x1FFFF | 0xFFFFF0-0xFFFFFF | 16B | Reset vectors |
Boot Sequence (Confirmed)
- Reset (0xFFFEE0):
JP 0xFF8290jumps to boot initialization - Hardware Init (0xFF8290): Configures all SFR registers:
- Port function control (P0FC-PBFC)
- Serial channels (SC0, SC1)
- Timers and watchdog
- DRAM refresh
- DMA for inter-CPU latch
- Stack Setup: Sets XSP to 0x05A2
- Vector Copy (0xFF846D): Copies 225 bytes of interrupt trampolines from ROM (0xFF8F6C) to RAM (0x0400)
- Enable Interrupts:
EI 0 - Initialization Routines:
- Memory test (0xFF8956)
- DMA/Serial setup (0xFF85AE) - configures inter-CPU latch at 0x120000
- Tone generator init (0xFF84A8) - initializes registers at 0x130000
- Main Loop: Waits for payload ready flag at 0x04FE, then calls 0x0400
Interrupt Trampoline System
The boot ROM uses an elegant trampoline system for interrupts:
- ROM Vector Table (0xFFFF00): Contains 4-byte addresses pointing to RAM (0x04xx)
- RAM Trampolines (0x0400): Each is 5 bytes:
JP addr(4B) +RET(1B) - ROM Handlers: Trampolines initially point back to ROM handlers
This allows the payload to replace interrupt handlers by modifying the trampolines in RAM.
Trampoline Layout:
| RAM Address | Handler | Initial Target |
|---|---|---|
| 0x0400 | Handler 0 (Reset) | 0xFFFEE0 (ROM) |
| 0x0405 | Handler 1 | 0xFF8432 (Default RETI) |
| 0x040A | Handler 2 | 0xFF8432 (Default RETI) |
| … | … | … |
| 0x0428 | Handler 9 | 0xFF881F (Specific) |
| … | … | … |
| 0x04AA | Handler 35 | 0xFF88B8 (Specific) |
| 0x04B4 | Handler 37 | 0xFF889A (Specific) |
Key Hardware Addresses Discovered
Inter-CPU Communication Latch (0x120000)
The DMA is configured to use 0x120000 for communication between main CPU and sub CPU. This confirms the latch address documented elsewhere.
Tone Generator (0x130000)
The INIT_TONE_GEN routine writes initialization patterns to registers at 0x130000, confirming this as the tone generator base address.
Disassembly Status
Completed:
- BOOT_INIT (0xFF8290) - Full hardware initialization
- COPY_VECTORS (0xFF846D) - Vector trampoline copy
- RESET_ENTRY (0xFF8433) - Alternative reset handler (uses
jrl Tto BOOT_INIT) - SUB_8437 (0xFF8437) - Tone generator channel initialization loop
- HALT_LOOP (0xFF8490) - Error handler with stub routines
- TONE_GEN_WRITE (0xFF84F1) - Write data to tone generator
- SUB_850E (0xFF850E) - Multi-register push/call wrapper
- SUB_853A (0xFF853A) - Write register pairs to tone generator channel
- COPY_WORDS (0xFF858B) - Word block copy using
ldirw - FILL_WORDS (0xFF8594) - Memory fill with word values
- CHECKSUM_CALC (0xFF859B) - Calculate checksum over memory range
- INIT_DMA_SERIAL (0xFF85AE) - DMA/Serial configuration
- INIT_TONE_GEN (0xFF84A8) - Tone generator setup
- MAIN_LOOP - Payload wait loop
- DEFAULT_HANDLER (0xFF8432) - Simple RETI
- Vector trampolines (0xFF8F6C) - All 45 handlers
- Interrupt vector table (0xFFFF00)
- InterCPU_RX_Handler (0xFF881F) - Serial receive interrupt
- CMD_Dispatch_Handler (0xFF88B8) - Timer/processing interrupt
- DMA_Complete_Handler (0xFF889A) - DMA complete interrupt
- DELAY_ROUTINE (0xFF89A9) - Variable delay routine
- MEM_TEST_ROUTINE (0xFF89FC) - RAM test
- ROM_CHECKSUM (0xFF8AB4) - Boot ROM integrity check
- SERIAL_INIT (0xFF8B07) - Serial communication init
TODO:
- Data tables analysis (0xFF8000)
- DMA transfer and inter-CPU comm routines (0xFF8604-0xFF8955) - ~850 bytes of code
- SUB_8B37, SUB_8B89, SUB_8C80 helper routines
Inter-CPU Protocol (Boot ROM Side)
The sub CPU boot ROM handles commands from the main CPU via the latch at 0x120000. The protocol uses a command byte followed by optional data bytes transferred via DMA.
Command Format
| Command | Action | DMA Buffer | DMA Size |
|---|---|---|---|
E1 |
Set up DMA transfer | CMD_E1_BUFFER (0x0544) |
6 bytes |
E2 |
Set up DMA transfer | CMD_E2_BUFFER (0x054A) |
10 bytes |
E3 |
Signal payload ready | - | - |
00-1F |
Variable-length data | CMD_DATA_BUFFER (0x051E) |
low 5 bits + 1 (1-32 bytes) |
For commands 00-1F, the command byte encodes both the handler index and data length:
- Bits 7-5: Handler index (0-7), selects function from jump table at 0xFF8000
- Bits 4-0: Data length - 1 (0-31 = 1-32 bytes)
Interrupt Handler Details
InterCPU_RX_Handler (0xFF881F) - Serial Receive Interrupt
Triggered when data arrives from the main CPU via the inter-CPU latch.
1. Check if bit 2 of SC0BUF is set (busy flag)
- If set: exit immediately (another transfer in progress)
2. Read command byte from latch (0x120000)
3. Store command in LAST_CMD_BYTE (0x051A)
4. Decode command:
- E1: Set CMD_PROCESSING_STATE=2, DMA 6 bytes to CMD_E1_BUFFER (0x0544)
- E2: Set CMD_PROCESSING_STATE=3, DMA 10 bytes to CMD_E2_BUFFER (0x054A)
- E3: Set bit 6 of SUBCPU_STATUS_FLAGS (0x04FE), skip DMA
- Other: Set CMD_PROCESSING_STATE=1, DMA (cmd & 0x1F)+1 bytes to CMD_DATA_BUFFER (0x051E)
5. Trigger DMA by writing 0x0A to address 0x0100
6. Clear bit 1 of SC0BUF
CMD_Dispatch_Handler (0xFF88B8) - Timer/Processing Interrupt
Main processing interrupt that handles received data after DMA completes.
1. Save all registers (XWA, XBC, XDE, XHL, XIX, XIY, XIZ)
2. Read CMD_PROCESSING_STATE (0x0518):
- State 1: Process received command data
- Push parameters to stack
- Calculate handler index from high 3 bits of LAST_CMD_BYTE
- Call handler from jump table at 0xFF8000 + (index * 4)
- Clean up stack, set CMD_PROCESSING_STATE=0
- State 2: Set up secondary DMA transfer
- Load parameters from CMD_E1_BUFFER (0x0544)
- Trigger DMA, set CMD_PROCESSING_STATE=4
- State 3: Set completion flags
- Write 0xFF to 0x051C
- Set bit 7 of 0x0554
- Set CMD_PROCESSING_STATE=0
- State 4: Finalize transfer
- Clear bit 7 of SUBCPU_STATUS_FLAGS (0x04FE)
- Set CMD_PROCESSING_STATE=0
3. Manage watchdog (toggle bit 2 of WDMOD if set)
4. Restore all registers
DMA_Complete_Handler (0xFF889A) - DMA Complete Interrupt
Handles DMA transfer completion by advancing the state machine.
1. Clear bit 2 of WDMOD (watchdog)
2. Check DMA_STATE (0x0516):
- If 1: Set to 0 (transfer complete)
- If 2: Set to 1 (first phase complete)
3. Return from interrupt
State Machine Diagram
Command Received
│
┌────────────┴────────────┐
│ │
E1/E2 cmd Other cmd (00-1F)
│ │
v v
CMD_PROCESSING_STATE = 2/3 CMD_PROCESSING_STATE = 1
│ │
│ ┌────────────────────┘
│ │
v v
CMD_Dispatch_Handler processes
│
┌─────────┼─────────┬─────────┐
│ │ │ │
State 1 State 2 State 3 State 4
│ │ │ │
v v v v
Call handler DMA Set flags Clear ready
from table transfer flag
│ │ │ │
└─────────┴─────────┴─────────┘
│
v
CMD_PROCESSING_STATE = 0 (Idle)
DMA State Machine - DMA_XFER_STATE (0x0516)
Separate from the command state machine, tracks DMA transfer phases:
| Value | State | Description |
|---|---|---|
| 0 | Idle | No transfer in progress |
| 1 | Single | Single transfer pending, waiting for completion |
| 2 | Two-Phase | E1 mode: phase 1 complete, phase 2 pending |
DMA Register Encoding (LDC Instructions)
The TMP94C241F uses LDC instructions to configure DMA registers. These are not supported by ASL’s TMP96C141 mode, so they require macros emitting raw bytes.
DMA Register Address Encoding (Third Byte of LDC):
| Register | Third Byte | Description |
|---|---|---|
| DMAS0 | 00h |
DMA Source, Channel 0 |
| DMAS2 | 08h |
DMA Source, Channel 2 |
| DMAS3 | 0Ch |
DMA Source, Channel 3 |
| DMAD0 | 20h |
DMA Destination, Channel 0 |
| DMAD2 | 28h |
DMA Destination, Channel 2 |
| DMAD3 | 2Ch |
DMA Destination, Channel 3 |
| DMAM0 | 40h |
DMA Mode, Channel 0 |
| DMAC0 | 42h |
DMA Count, Channel 0 (byte) |
| DMAM2 | 48h |
DMA Mode, Channel 2 |
| DMAC2 | 4Ah |
DMA Count, Channel 2 |
| DMAM3 | 4Ch |
DMA Mode, Channel 3 |
| DMAC3 | 4Eh |
DMA Count, Channel 3 |
LDC Instruction Format:
Byte 1: Register operand encoding (e.g., E8=XWA, E9=XBC, D8=WA, C9=A)
Byte 2: 2Eh (LDC opcode)
Byte 3: DMA register selector (see table above)
Example: LDC DMAD0, XWA = E8 2E 20 (load DMA destination 0 from XWA)
MAME MicroDMA Implementation
The TMP94C241 MicroDMA is implemented in MAME’s tmp94c241.cpp driver. The implementation uses cycle-steal mode where one DMA transfer is performed per CPU instruction boundary.
DMAM Mode Register Format (TMP94C241):
| Bits | Field | Values |
|---|---|---|
| 7-6 | Transfer Mode | 00=Burst, 01=Cycle-steal, 10=Single (currently cycle-steal only) |
| 5-4 | Source Addressing | 00=Fixed, 01=Increment, 10=Decrement |
| 3-2 | Dest Addressing | 00=Fixed, 01=Increment, 10=Decrement |
| 1-0 | Data Size | 00=Byte, 01=Word, 10=Long |
DMA Trigger Mechanism:
- Software writes a start vector to
DMAVnregister (0x100-0x103) - The start vector maps to an interrupt source
- When that interrupt’s flag is set, DMA transfer triggers
- One transfer occurs per
tlcs900_check_hdma()call (cycle-steal) - After transfer, the triggering interrupt flag is cleared
Cycle Costs:
| Transfer Size | Cycles |
|---|---|
| Byte (8-bit) | 8 |
| Word (16-bit) | 8 |
| Long (32-bit) | 12 |
Completion Interrupts:
When DMACn (transfer count) reaches zero:
DMAVnis cleared (disables channel)- Completion interrupt flag is set:
- Channel 0:
INTETC01bit 0x08 - Channel 1:
INTETC01bit 0x80 - Channel 2:
INTETC23bit 0x08 - Channel 3:
INTETC23bit 0x80
- Channel 0:
Key Functions:
tlcs900_check_hdma(): Called each instruction, processes one DMA if pendingtlcs900_process_hdma(channel): Executes single transfer for a channel
Memory Test Routine (0xFF89FC)
At boot, the sub CPU tests RAM integrity using complementary bit patterns. Results are stored in MEMTEST_RESULT (0x0556).
Test Patterns:
- Pattern 1:
0x5A5A5A5A(alternating bits: 01011010…) - Pattern 2:
0xA5A5A5A5(inverted: 10100101…)
Algorithm:
1. For each test region (configured in table at 0xFF8020):
a. Read original value
b. Write pattern 1 (0x5A5A5A5A)
c. Read back and verify both 16-bit halves
d. If mismatch: OR error code from table into MEMTEST_RESULT
e. Restore original, advance to next location
f. Write pattern 2 (0xA5A5A5A5)
g. Read back and verify
h. If mismatch: OR error code into MEMTEST_RESULT
i. Restore original, advance
2. Return error flags in L register (also stored in MEMTEST_RESULT)
The test configuration table at 0xFF8020 contains:
- Start address (4 bytes)
- Size in dwords (4 bytes)
- Error code for low word failure (1 byte)
- Error code for high word failure (1 byte)
ROM Checksum Routine (0xFF8AB4)
Verifies boot ROM integrity by checksumming 0x800 words from 0xFE0000.
Algorithm:
1. Initialize two 16-bit accumulators to 0
2. For each of 0x800 words starting at 0xFE0000:
a. Add word to accumulator (alternating between two)
3. Compare the two checksums
4. If mismatch: Set bit 2 in error flags
5. Return error flags in L register
Delay Routine (0xFF89A9)
Provides variable timing delays based on a bit pattern.
Parameters:
- A register: 3-bit delay selector (bits 0-2 checked)
Algorithm:
1. For each of 3 bits in A (starting from bit 0):
a. Disable timer interrupt (res bit 1 of INTTC01)
b. If current bit set: delay count = 0xC000, else 0x4000
c. Execute nested delay loops (outer: BC count, inner: 32 iterations)
d. Enable timer interrupt (set bit 1 of INTTC01)
e. Execute another nested delay with count 0x4000
f. Shift A right, increment loop counter
g. Repeat until 3 bits processed
This allows 8 different delay combinations based on which bits are set.
Source File
subcpu_boot/kn5000_subcpu_boot.asm - 1098 lines of disassembled code
Embedded Images
The ROMs contain icons, UI elements, and splash screens for the LCD display.
Image Locations
Main CPU ROM:
- 1-bit status bitmaps (Please Wait, Completed, etc.)
- UI elements (drawbar sliders, icons)
- Various graphics referenced by display routines
- Palette data at
0xEB37DE(256 colors × 4 bytes RGBA)
Table Data ROM:
- Feature demo BMP images (FTBMP01-06)
- Additional UI assets
HDAE5000 ROM:
- Product logo, promotional images, UI panels (320×240, 8-bit indexed)
- Hard disk icon (28×28, 8-bit indexed)
- Main palette at
0x65dce(256 colors × 4 bytes RGBA) - Icon palette at
0x6158e(Windows halftone-style)
Image Format
The LCD controller is IC206 (MN89304) with 4Mbit Video RAM (IC207).
Format characteristics to document:
- Pixel depth (1bpp, 4bpp, 8bpp, or RGB)
- Dimension encoding
- Palette format (if indexed color)
- Compression (if any)
- Header structure
Extraction Workflow
- Scan ROMs for image signatures (BMP headers:
0x42 0x4D) - Trace display code to find image address references
- Extract to binary files in
maincpu/images/,table_data/images/, orhdae5000/images/ - Name descriptively based on apparent purpose
- Update assembly sources with
incbindirectives - Verify byte-match after rebuild
Palette Discovery Technique
For indexed color images without obvious palette data, trace the boot/initialization code:
- Search for VGA DAC writes - Look for code writing to
0x3C8(palette index) and0x3C9(RGB data) - Find the palette load routine - Often a loop loading 256 entries
- Trace back to find palette address - The
LDAinstruction before the call reveals the palette location
Example (HDAE5000): Boot code at 0x28f585 executes:
lda XWA, 0x2e5dce ; Palette address (ROM offset 0x65dce)
calr 0x28f8e0 ; Palette load routine
The load routine at 0x28f8e0 shifts each RGB component right by 4 bits before writing to the 6-bit VGA DAC.
Current Progress
Already extracted:
maincpu/images/- 42 files (1-bit bitmaps, UI elements, logos)table_data/images/- 6 BMP files (feature demo screens)hdae5000/images/- 4 images + 2 palettes (product images, icon)
Tools:
extract_include_binaries.py- Extraction scriptconvert_images.py- Converts raw.binto PNG with correct palettes
Conversion for Documentation
For website documentation, images can be converted to PNG format for viewing. This helps identify what each image represents and aids in understanding the UI.
Boot Sequence
Understanding the complete boot sequence is essential for MAME emulation and debugging.
Reset Vector and Early Init
Reset Vector: 0xFFFF00 points to RESET_HANDLER at 0xEF03C6
The main CPU executes the following initialization sequence:
| Step | Address | Action | Register Values |
|---|---|---|---|
| 1 | 0xEF03C6 | Disable Watchdog | WDMOD=0x00, WDCR=0xB1 |
| 2 | 0xEF03CC | Clock Config | CLKMOD=0x04 |
| 3 | 0xEF03D0 | Port Setup | See table below |
| 4 | 0xEF0420 | Timer Init | T01MOD=0x1D, T23MOD=0x1D |
| 5 | 0xEF0450 | Memory Controller | MSAR0-5, MAMR0-5 |
| 6 | 0xEF04A1 | DRAM Init | DRAM1REF, DRAM1CRL/H |
| 7 | 0xEF04C0 | Bus Chip Select | B0CSL-B5CSL, B0CSH-B5CSH |
| 8 | 0xEF0510 | Serial & DAC | SC0MOD=0x29, DAREG0/1=0xFF |
| 9 | 0xEF0526 | Stack Pointer | XSP=0x00000C00 |
Port Configuration (Step 3):
| Port | Data | Function Control | Control Register |
|---|---|---|---|
| PF | 0x00 | 0x73 (panel on, MIDI off) | 0x15 |
| P2/P3 | - | 0xFF | - |
| P7 | 0xFF | 0x1F | 0x00 |
| PA | 0xFE | 0x08 | - |
| PB | 0xFF | 0x1F | - |
| PC | 0x03 | 0x00 | 0x02 |
| PD | 0x00 | 0x06 | 0x11 |
| PE | 0x00 | 0x42 | 0x20 |
| PH | 0x00 | 0x1E | 0x09 |
| PZ | 0xFF | - | 0x03 |
Timer Initialization (Step 4):
8-bit Timers:
T01MOD = 0x1D, T23MOD = 0x1D
T02FFCR = 0x00
TREG0 = 0x0A, TREG1 = 0x10
T8RUN bit 1 set
16-bit Timer 4:
T4MOD = 0x05, T4FFCR = 0x00, T16CR = 0x00
TREG4L = 0x0001, TREG5L = 0x3D09
T16RUN bits 7 and 0 set
Post-Init Sequence (after 0xEF0526):
Seems_to_copy_some_data_buffers- Data initializationMainCPU_self_test_routines- RAM testGet_Firmware_Version- Read version from ROM- If boot ROM (version 0xFF): Display “Please Wait !!” bitmap
- Initialize system timestamp to 0
- Call peripheral init routines
- Set interrupt priorities (INTET01, INTET45)
- Detect area/region code
- Check for HD-AE5000 (PE bit 0)
- Read control panel buttons for update mode
- Optional:
FLASH_MEM_UPDATEif holding button combo
Memory Initialization
Hardware:
- DRAM: IC9/IC10 (M5M44260AJ7S, 4Mbit each)
- SRAM: IC21 (1Mbit, battery-backed)
Memory Segment Configuration (MSAR/MAMR):
| Segment | MSAR | MAMR | Start Address | Size |
|---|---|---|---|---|
| 0 | 0x1E | 0x0F | 0x1E0000 | 64KB |
| 1 | 0x10 | 0x3F | 0x100000 | 256KB |
| 2 | 0xC0 | 0x7F | 0xC00000 | 512KB |
| 3 | 0x00 | 0x1F | 0x000000 | 128KB |
| 4 | 0x80 | 0xFF | 0x800000 | 1MB (Table Data) |
| 5 | 0x00 | 0xFF | 0x000000 | 1MB |
DRAM Initialization Sequence (0xEF04A1-0xEF04BC):
1. Short delay loop (BC = 0x400 iterations)
2. DRAM1REF = 0x81 (initial refresh)
3. Longer delay loop (BC = 0x2000 iterations)
4. DRAM1REF = 0x71 (final refresh)
5. DRAM1CRL = 0x8B (DRAM control low)
6. DRAM1CRH = 0x58 (DRAM control high)
7. PMEMCR bit 4 cleared
Bus Chip Select Configuration:
| Register | Low | High | Description |
|---|---|---|---|
| B0CS | 0x11 | 0x80 | Bus segment 0 |
| B1CS | 0x33 | 0x81 | Bus segment 1 |
| B2CS | 0x11 | 0xC2 | Bus segment 2 |
| B3CS | 0x22 | 0x8A | Bus segment 3 |
| B4CS | 0x11 | 0x82 | Bus segment 4 |
| B5CS | 0x22 | 0x81 | Bus segment 5 |
Memory Test:
MainCPU_self_test_routinesperforms RAM test- Uses complementary patterns: 0x5A5A5A5A and 0xA5A5A5A5
Peripheral Initialization Order
The confirmed initialization order (from RESET_HANDLER analysis):
| Order | Peripheral | Registers | Values |
|---|---|---|---|
| 1 | Watchdog | WDMOD, WDCR | 0x00, 0xB1 (disable) |
| 2 | Clock | CLKMOD | 0x04 |
| 3 | GPIO Ports | Px, PxFC, PxCR | See port table above |
| 4 | 8-bit Timers | T01MOD, T23MOD, TREGx | See timer table |
| 5 | 16-bit Timers | T4MOD, T16RUN, TREGxL | See timer table |
| 6 | Memory Controller | MSARx, MAMRx | See memory table |
| 7 | DRAM | DRAM1REF, DRAM1CRL/H | See DRAM sequence |
| 8 | Bus Chip Select | BxCSL, BxCSH | See bus table |
| 9 | Serial Channel 0 | SC0MOD, SC0CR | 0x29, 0x00 |
| 10 | DAC | DAREG0, DAREG1, DADRV | 0xFF, 0xFF, 0x03 |
| 11 | Stack Pointer | XSP | 0x00000C00 |
Sub CPU Initialization (after main init):
| Order | Peripheral | Registers | Values |
|---|---|---|---|
| 1 | Watchdog | WDMOD_REAL, WDCR_REAL | 0x00, 0xB1 |
| 2 | Interrupt | INT_CTRL (0x10A) | 0x04 |
| 3 | Port Functions | P0FC-PBFC | 0xFF (most ports) |
| 4 | Interrupt/Status | INTTC01 (0x30) | 0x03 |
| 5 | 8-bit Timers | T01MOD, T23MOD | 0x1D, 0x0A |
| 6 | 16-bit Timer 4 | T4MOD, T4FFCR | 0x05, 0x00 |
| 7 | Serial Channels | SER0_MOD, SER1_MOD | 0x01, 0x29 |
Sub CPU Startup
Sequence:
- Main CPU releases sub CPU from reset
- MicroDMA transfers 192KB payload
- Latch communication at
0x120000 - Sub CPU signals ready
See Sub CPU Payload Loading for details.
Control Panel Initialization
Tasks:
- Document when serial channel to CPL/CPR MCUs is configured
- Trace initial command sequence sent to panels
- Document LED initialization pattern
- Identify panel ready confirmation
LCD Splash Screen
Tasks:
- Document LCD controller register setup
- Trace Video RAM initialization
- Document Technics/KN5000 logo display timing
- Identify boot progress indicators
Optional Hardware Detection
HDAE5000:
- Probe PPI at
0x160000 - Check for ROM at
0x280000 - Initialize if present, skip gracefully if absent
Audio Subsystem
Tasks:
- Document tone generator initialization via sub CPU
- Trace DAC setup (IC310)
- Document DSP initialization (IC311)
- Identify audio ready state
Boot Timeline Goal
Create comprehensive timeline showing:
- Time from power-on for each stage
- Dependencies between init stages
- Total boot time to user-ready state
Video Hardware
The KN5000 has a 320x240 QVGA LCD display for user interface.
Hardware Components
| IC | Part Number | Function |
|---|---|---|
| IC206 | MN89304 | LCD Controller |
| IC207 | M5M44265CJ8S | 4Mbit Video RAM |
LCD Controller (MN89304)
The MN89304 is a Panasonic LCD controller providing VGA-compatible register interface.
I/O Port Addresses (memory-mapped):
| Port | Register | Function |
|---|---|---|
| 0x3C0 | Attribute Controller | Address/Data |
| 0x3C2 | Misc Output | Timing config (write) |
| 0x3C3 | VGA Enable | Global enable |
| 0x3C4/3C5 | Sequencer | Address/Data |
| 0x3C6 | DAC Mask | Palette mask |
| 0x3C8 | DAC Write Addr | Palette index |
| 0x3C9 | DAC Data | Palette RGB (6-bit each) |
| 0x3CE/3CF | Graphics Ctrl | Address/Data |
| 0x3D4/3D5 | CRTC | Address/Data |
| 0x3DA | Input Status 1 | Vertical retrace |
Display Configuration:
| Parameter | Value | Description |
|---|---|---|
| Resolution | 320x240 | QVGA |
| Color Depth | 8bpp | 256 indexed colors |
| Dot Clock | 25 MHz | From Misc Output = 0xE3 |
| Refresh | ~60 Hz | Standard VGA timing |
Initialization Sequence (Some_VGA_setup at 0xEF55A7):
| Step | Port | Value | Action |
|---|---|---|---|
| 1 | 0x3C3 | 0x01 | Global enable |
| 2 | 0x3C2 | 0xE3 | 25MHz clock, 60Hz |
| 3 | Seq 00 | 0x00 | Reset sequencer |
| 4 | Seq 01 | 0x21 | Screen off, 8-dot clock |
| 5 | Seq 00 | 0x03 | Release reset |
| 6 | Seq 02 | 0x0F | All planes writable |
| 7 | Seq 04 | 0x06 | Sequential, extended mem |
| 8 | GC 05 | 0x00 | Write mode 0, read mode 0 |
| 9 | GC 08 | 0xFF | Bit mask all bits |
CRTC Timing Registers:
| Register | Value | Description |
|---|---|---|
| Horiz Total | 0x65 | 101 characters |
| Horiz Display End | 0x27 | 39 chars = 320 pixels |
| Start H Retrace | 0x28 | Horizontal sync start |
| End H Retrace | 0x29 | Horizontal sync end |
| Vert Total | 0xF3 | 243 scanlines total |
| Vert Display End | 0xEF | 239 = 240 visible lines |
| Start V Retrace | 0xF2 | Vertical sync start |
| End V Retrace | 0x03 | Vertical sync end |
Helper Functions:
Write_VGA_Register(0xEF5141): Writes BC to port WARead_VGA_Register(0xEF5157): Reads from port WA
Video RAM Organization
IC207: Mitsubishi M5M44265CJ8S (4Mbit VRAM)
| Parameter | Value |
|---|---|
| Capacity | 512KB (4Mbit) |
| Type | Dual-ported VRAM |
| Base Address | 0x1A0000 |
Confirmed Configuration:
| Setting | Value |
|---|---|
| Color Depth | 8bpp (256 colors) |
| Frame Size | 320 × 240 × 1 = 76,800 bytes |
| Available Frames | 512KB / 75KB ≈ 6.8 frames |
Memory Layout:
| Address Range | Size | Content |
|---|---|---|
| 0x1A0000-0x1A12BFF | 76,800B | Frame buffer 0 |
| 0x1A12C00-0x1A257FF | 76,800B | Frame buffer 1 (if double-buffered) |
| 0x1A25800-0x1A7FFFF | ~360KB | Additional buffers / sprites |
Access Patterns:
- CPU writes to 0x1A0000 base
- VGA controller reads via serializer
- CRTC Start Address (0x0C/0x0D) selects active buffer
- Current config: Start Address = 0x0000 (buffer 0)
Display Timing:
- Pixel clock: 25 MHz
- Horizontal: 320 visible + blanking ≈ 400 total
- Vertical: 240 visible + blanking ≈ 262 total
- Frame rate: 25MHz / (400 × 262) ≈ 60 Hz
Pixel Format and Palette
Confirmed: 8-bit indexed color
| Property | Value |
|---|---|
| Bits per pixel | 8 |
| Color count | 256 |
| Palette format | 6-bit R, 6-bit G, 6-bit B |
| Total palette colors | 18-bit (262,144 possible) |
Palette Loading:
- Write palette index to 0x3C8
- Write R, G, B values (6-bit each) to 0x3C9
- Index auto-increments
EGA Compatibility:
- Attribute Controller (0x3C0) provides 16-color EGA palette at indices 0-15
- Standard EGA palette loaded during initialization
Drawing Primitives
Firmware contains graphics routines for:
Tasks:
- Find pixel plotting routine
- Document line drawing algorithm
- Trace rectangle fill
- Analyze bitmap blitting (BLT)
- Identify any hardware acceleration
Font System
Tasks:
- Locate font data in ROM
- Document font format (bitmap vs vector)
- Identify character encoding
- Document available font sizes
- Trace text rendering routines
- Check internationalization support
UI Widget Rendering
The UI includes various interactive elements:
- Buttons and menus
- Sliders (drawbar controls)
- Piano keyboard display
- Waveform displays
- Level meters
Tasks:
- Document widget drawing routines
- Identify any sprite system
- Trace interactive element updates
Screen Layout
Tasks:
- Map screen regions (header, content, status bar)
- Document how different modes use display
- Create annotated screenshots
Animation and Effects
Transition effects found in extracted images:
BitmapFadeInPicture.bin/BitmapFadeOutPicture.binBitmapFadeInText.bin/BitmapFadeOutText.bin
Tasks:
- Analyze fade effect implementation
- Document screen transition timing
- Identify scrolling implementation
- Check for hardware effect support
Font Extraction
Goal: Extract fonts as usable assets.
Tasks:
- Extract font bitmaps from ROM
- Convert to standard format (BDF, PNG atlas)
- Document character coverage
- Add samples to Image Gallery
Feature Demo Extraction
The Feature Demo is an interactive presentation showcasing keyboard features. Extracting its data structures enables documentation, modification, and source code simplification.
Components
- Slides - Background images with overlaid UI widgets
- Widgets - Text, images, shapes, interactive elements
- MIDI files - Demo music embedded in ROM
- Timing data - Slide duration and transitions
Known Demo Images
Already extracted to table_data/images/:
| File | Size | Description |
|---|---|---|
| FTBMP01.BMP | 320x240 | Demo screen 1 |
| FTBMP02.BMP | 320x130 | Demo screen 2 |
| FTBMP03.BMP | 320x120 | Demo screen 3 |
| FTBMP04.BMP | corrupted | Demo screen 4 |
| FTBMP05.BMP | 320x125 | Demo screen 5 |
| FTBMP06.BMP | 320x240 | Demo screen 6 |
See Image Gallery for viewable versions.
Slide Data Structure
Tasks:
- Locate slide table/index in ROM
- Document per-slide record format:
- Slide type/ID
- Duration/timing
- Background image reference
- Widget list pointer
- MIDI file pointer
- Transition effects
UI Widget Types
Expected widget types based on typical presentation systems:
| Widget | Parameters |
|---|---|
| TEXT | x, y, font_id, color, string |
| IMAGE | x, y, image_id |
| RECT | x, y, width, height, fill_color, border_color |
| LINE | x1, y1, x2, y2, color |
| ICON | x, y, icon_id |
| BUTTON | x, y, width, height, label, action |
| PIANO | x, y, width, height, highlighted_keys |
| METER | x, y, width, height, value, max |
Tasks:
- Trace slide rendering code
- Identify all widget types
- Document parameter format for each
- Create widget type reference
ASL Macro Design
Goal: Replace raw data bytes with human-readable macros.
Slide macros:
SLIDE_BEGIN id, background_image, duration_ms, midi_ptr
; widgets defined here
SLIDE_END
Widget macros:
TEXT x, y, font, color, "string"
IMAGE x, y, image_id
RECT x, y, w, h, fill_color, border_color
LINE x1, y1, x2, y2, color
Example slide definition:
SLIDE_BEGIN 1, FTBMP01, 5000, DemoMidi1
TEXT 10, 20, FONT_LARGE, COLOR_WHITE, "Welcome to KN5000"
IMAGE 100, 80, ICON_KEYBOARD
RECT 50, 150, 200, 30, COLOR_BLUE, COLOR_WHITE
SLIDE_END
Tasks:
- Design macro syntax for each structure
- Implement macros in ASL format
- Ensure macros emit correct binary
- Add to
feature_demo.inc
Embedded MIDI Extraction
MIDI files are embedded for demo music playback.
Detection:
- Search for MIDI header:
4D 54 68 64(“MThd”) - Track chunks start with:
4D 54 72 6B(“MTrk”)
Tasks:
- Scan ROMs for MIDI headers
- Parse MIDI structure to find boundaries
- Extract as standalone
.midfiles - Verify playback in standard MIDI player
- Document each file’s purpose
Output directory:
maincpu/midi/
├── demo_song_1.mid
├── demo_song_2.mid
└── ...
Source Code Refactoring
After macros are defined:
- Identify raw data sections for slides
- Replace
db/dwsequences with macros - Rebuild ROM:
make all - Verify byte-match:
python compare_roms.py - Measure source line reduction
Goal: Significantly reduce assembly source length while improving readability.
Slide Viewer Tool
Optional Python tool for visualizing extracted slides:
Features:
- Parse slide data structures
- Render widgets using PIL/Pillow
- Export as PNG or HTML
- Enable slide editing for custom demos
Sound Hardware
The KN5000 has a sophisticated sound generation system with dedicated processors for synthesis and effects.
Architecture Overview
Main CPU (TMP94C241F)
│
│ Commands via 0x120000 latches
v
Sub CPU (IC27) ──────> Waveform ROM (IC306-307)
│ │
│ Audio data │ Samples
v v
DSP (IC311) <──────────────┘
│
│ Processed audio
v
DAC (IC310)
│
│ Analog audio
v
Output Jacks (Line, Headphones, Speakers)
Hardware Components
| IC | Function | Description |
|---|---|---|
| IC27 | Sub CPU | Tone generator control, synthesis engine |
| IC306-307 | Waveform ROM | PCM sample storage for all instruments |
| IC311 | DSP | Digital effects (reverb, chorus, EQ) |
| IC310 | DAC | Digital-to-analog conversion for audio output |
Sub CPU (IC27)
The Sub CPU handles all real-time sound generation, receiving commands from the main CPU.
Tasks:
- Identify exact chip type from service manual schematics
- Find datasheet and document architecture
- Document clock speed and memory map
- Analyze I/O capabilities and interfaces
DSP (IC311)
Digital Signal Processor for audio effects.
Tasks:
- Identify chip type and find datasheet
- Determine if programmable or fixed-function
- Document effects capabilities (reverb types, chorus, EQ)
- Trace interface to main/sub CPU
- Document audio data format and routing
DAC (IC310)
Converts digital audio to analog output.
Tasks:
- Identify chip type and specifications
- Document resolution (bits) and sample rate
- Identify number of output channels
- Document interface protocol (I2S, parallel, etc.)
- Trace analog output path
Waveform ROM (IC306-307)
Contains all PCM samples for instrument sounds.
Tasks:
- Document total ROM size
- Analyze sample encoding (PCM bit depth, compression)
- Document sample indexing scheme
- Map samples to instrument patches
- Identify loop points and root notes
Main CPU ↔ Sub CPU Protocol
Communication via latches at 0x120000.
Expected command types:
- Note On/Off (key number, velocity, channel)
- Program Change (instrument selection)
- Control Change (volume, pan, expression, sustain)
- Pitch Bend
- Effects parameters (reverb depth, chorus rate, etc.)
Tasks:
- Trace all accesses to
0x120000in main CPU firmware - Document command byte format
- Create complete command reference
- Identify response/status mechanism
Synthesis Architecture
Questions to answer (ANSWERED — see Tone Generator):
- Polyphony count: 64 voices, register-indirect at 0x100000/0x100002
- Synthesis method: PCM sample playback from 16MB waveform ROM (4 chips)
- Envelope generators: Hardware-internal ADSR — firmware sends pitch/volume/pan, chip handles envelopes
- LFO capabilities: Firmware computes LFO modulation (Voice_PanReg_WriteDispatch, 6+ modes)
- Filter types: Unknown — group 4/5/6 registers may control filtering
Tasks:
- Analyze sub CPU firmware for synthesis routines
- Document oscillator/voice architecture
- Trace envelope generator implementation
- Identify filter algorithms
Effects Processing
Known effects (from panel labels):
- Reverb (multiple types: Hall, Room, Plate, etc.)
- Chorus/Flanger
- EQ (bass, treble, presence)
Tasks:
- Determine which chip handles each effect
- Document effects parameter ranges
- Trace effects routing (insert vs send)
- Catalog effects presets
Audio Output Path
From DAC to physical jacks.
Outputs:
- Line Out (L/R)
- Headphone jack
- Internal speakers (if present)
Tasks:
- Trace analog signal path from DAC
- Document amplifier stages
- Identify any analog mixing or effects
- Document output levels and impedances
MIDI Implementation
Full MIDI capability for external control and sequencing.
Tasks:
- Document MIDI IN/OUT/THRU signal handling
- Identify channel assignments (parts to channels)
- Document supported Control Change (CC) messages
- Analyze SysEx command format
- Check GM/GS/XG compatibility level
- Document MIDI clock sync behavior
Rhythm/Accompaniment Engine
Auto-accompaniment system for backing tracks.
Components:
- Rhythm patterns (drums, percussion)
- Bass patterns
- Chord patterns
- Style variations (Intro, Main A/B, Fill, Ending)
Tasks:
- Analyze rhythm pattern data format in ROM
- Document chord detection algorithm
- Trace bass/chord part generation
- Document style structure and switching
Sample/Patch Extraction
Goals:
- Extract all instrument patch definitions
- Document patch parameters (samples, envelopes, filters)
- Create patch list matching front panel sound groups
- Extract raw waveforms as WAV files for analysis
- Document sample rates, loop points, root notes
System Update Procedures
The KN5000 supports firmware updates via floppy disk. Understanding this system enables custom firmware development.
Update File Formats
Official updates distributed as executable files on floppy disk.
Known files (from archive.org):
| File | Version | Date |
|---|---|---|
| KN5KPV5.EXE | v5 | 1997-11-12 |
| KN5KPV6.EXE | v6 | 1998-01-16 |
| KN5KPV7.EXE | v7 | 1998-06-26 |
| KN5KPV8.EXE | v8 | 1998-11-13 |
| KN5KPV9.EXE | v9 | 1999-01-26 |
| KN5KPV10.EXE | v10 | 1999-08-02 |
File Type Identifiers (38-byte header at 0xE00038):
| ID | Header String | Description |
|---|---|---|
| 1 | Technics KN5000 Program DATA FILE 1/2 |
Main CPU ROM disk 1 |
| 2 | Technics KN5000 Program DATA FILE 2/2 |
Main CPU ROM disk 2 |
| 3 | Technics KN5000 Table DATA FILE 1/2 |
Table data disk 1 |
| 4 | Technics KN5000 Table DATA FILE 2/2 |
Table data disk 2 |
| 5 | Technics KN5000 CMPCUSTOMDATA FILE |
Custom data (compressed?) |
| 6 | Technics KN5000 HD-AEPRG DATA FILE |
HDAE5000 ROM |
| 7 | Technics KN5000 Program DATA FILE PCK |
Main CPU ROM (packed) |
| 8 | Technics KN5000 Table DATA FILE PCK |
Table data (packed) |
File Structure:
- 38-byte identification header string
- Null terminator (0x00)
- 0xFF marker byte
- Payload data
Handler Dispatch: Table at 0xE00178 routes each file type to its handler. Types 2 and 4 show “ILLEGAL DISK” if loaded before 1 and 3 respectively.
Update Mode Entry
Entry Conditions (all must be true at RESET_HANDLER 0xEF05C5):
| Condition | Check | Description |
|---|---|---|
| 1 | Firmware version = 0xFF | Running from boot ROM, not flash |
| 2 | Floppy disk inserted | Check_for_Floppy_Disk_Change ≠ 0 |
| 3 | Button code = 0x04 | Specific button held at power-on |
Detection Code:
CALL Read_control_panel_buttons ; Read buttons at power-on
LD (0402h), L ; Store button state
CALL Get_Firmware_Version
CP L, 0ffh ; Check if boot ROM
JR NZ, skip_update
CALL Check_for_Floppy_Disk_Change
CP HL, 0 ; Check disk present
JR Z, skip_update
CP (0402h), 004h ; Button code 0x04?
JR NZ, skip_update
CALL FLASH_MEM_UPDATE ; Enter update mode
Notes:
- Update mode only accessible from boot ROM (virgin/corrupted flash)
- “Please Wait !!” bitmap displayed at 0xEF0536 when in boot ROM mode
- System halts after update (infinite loop at Boot_MainSequence_Trampoline)
File Types and Target Components
| File ID | Header | Target | Address | Size |
|---|---|---|---|---|
| 1 | Program 1/2 | Main CPU ROM (first half) | 0xE00000+ | 1MB |
| 2 | Program 2/2 | Main CPU ROM (second half) | 0xF00000+ | 1MB |
| 3 | Table 1/2 | Table Data (first half) | 0x800000+ | 1MB |
| 4 | Table 2/2 | Table Data (second half) | 0x900000+ | 1MB |
| 5 | CMPCUSTOMDATA | Custom Data Flash | 0x300000 | 1MB |
| 6 | HD-AEPRG | HDAE5000 ROM | 0x280000 | 512KB |
| 7 | Program PCK | Main CPU ROM (packed) | 0xE00000 | 2MB |
| 8 | Table PCK | Table Data (packed) | 0x800000 | 2MB |
Component Sizes:
| Component | Size | Distribution |
|---|---|---|
| Main CPU ROM | 2MB | 2 disks (1/2, 2/2) or 1 packed |
| Table Data | 2MB | 2 disks (1/2, 2/2) or 1 packed |
| Custom Data | 1MB | 1 disk (compressed?) |
| HDAE5000 ROM | 512KB | 1 disk |
Note: Sub CPU payload (192KB) is embedded within main CPU ROM, not a separate update file.
Flash ROM Chips
Chip Identification: QV1GFKN5KAX1
| Location | Chip | Capacity | Address |
|---|---|---|---|
| IC4/IC6 | Program Flash | 2MB total | 0xE00000 |
| - | Custom Data Flash | 1MB | 0x300000 |
Flash Erase Algorithm
Flash memory must be erased before programming.
Typical sequence:
- Write unlock sequence to chip
- Issue sector erase or chip erase command
- Poll for completion
- Verify erasure (all 0xFF)
Tasks:
- Trace erase routine in firmware
- Document unlock sequence
- Identify sector vs chip erase usage
- Document timeout handling
Flash Program Algorithm
Writing data to Flash ROM.
Typical sequence:
- Write unlock sequence
- Issue program command
- Write data byte/word
- Poll for completion
- Verify written data
Tasks:
- Trace program routine in firmware
- Identify byte-program vs page-buffer mode
- Document write verification
- Trace error handling
FDC Interaction
Floppy Disk Controller at 0x110000 (IC208: D72068GF-3B9).
Tasks:
- Document disk detection sequence
- Trace file reading routines
- Analyze sector layout expectations
- Document multi-disk handling (“Change FD 2 of 2”)
Update Progress Display
LCD messages during update (extracted as 1-bit bitmaps):
| Bitmap | Message | Stage |
|---|---|---|
Bitmap_1bit_Flash_Memory_Update.bin |
Flash Memory Update | Start |
Bitmap_1bit_Please_Wait.bin |
Please Wait | Processing |
Bitmap_1bit_Now_Erasing.bin |
Now Erasing | Erase phase |
Bitmap_1bit_FD_to_Flash_Memory.bin |
FD to Flash Memory | Write phase |
Bitmap_1bit_Completed.bin |
Completed | Success |
Bitmap_1bit_Turn_On_AGAIN.bin |
Turn On AGAIN | Restart needed |
Bitmap_1bit_Illegal_Disk.bin |
Illegal Disk | Error |
Bitmap_1bit_Change_FD_2_of_2.bin |
Change FD 2 of 2 | Multi-disk |
Tasks:
- Correlate bitmaps with update state machine
- Document state transitions
- Identify error conditions
Validation and Error Handling
Tasks:
- Document file header validation
- Trace checksum verification
- Identify version checking logic
- Document ROM verification after write
- Analyze “Illegal Disk” trigger conditions
HDAE5000 Update
Separate update procedure for HD-AE5000 expansion.
Versions:
- v1.10i (1998-07-06)
- v1.15i (1998-10-13)
- v2.0i (1999-01-15) - Added lyrics display
Tasks:
- Document separate update disk format
- Trace communication via PPI (0x160000)
- Identify Flash chips on expansion board
- Document version compatibility
Homebrew Development
Understanding the update system enables:
- Custom firmware creation
- Feature modifications
- Bug fixes for aging hardware
- Preservation of update capability
Tools needed:
- Update file parser (extract/create update files)
- Checksum calculator
- Flash programmer emulation for testing
Jump Tables
The firmware uses jump tables extensively for event dispatching, state machines, and handler selection. Documenting these tables is essential for understanding program flow.
Jump Table Patterns
Direct address tables (32-bit entries):
; Table of absolute addresses
JUMP_TABLE:
dd HANDLER_0
dd HANDLER_1
dd HANDLER_2
; Usage: index in register, multiply by 4, load address, jump
SLL 2, A ; index * 4
LDA XHL, JUMP_TABLE
LD XHL, (XHL + A) ; load address
JP T, XHL ; jump to handler
Offset tables (16-bit entries):
; Table of offsets from base address
OFFSET_TABLE:
dw (HANDLER_0 - BASE_ADDR)
dw (HANDLER_1 - BASE_ADDR)
; Usage: load offset, add to base, jump
LDA XIX, OFFSET_TABLE
LD WA, (XIX + WA) ; load offset
LDA XIX, BASE_ADDR
JP T, XIX + WA ; jump to base+offset
Indirect Jump Instructions
| Pattern | Description |
|---|---|
CALL T, XHL |
Call through XHL register |
CALL T, XIX |
Call through XIX register |
JP T, XHL |
Jump through XHL register |
JP T, XIX + WA |
Indexed jump (base + WA offset) |
JP T, XIX + BC |
Indexed jump (base + BC offset) |
JP T, XIX + DE |
Indexed jump (base + DE offset) |
Jump Table Statistics
Analysis of indirect jump patterns in the main CPU ROM:
| Pattern | Count | Status |
|---|---|---|
JP T, XIX + WA |
118 | 9 documented, 109 need naming |
JP T, XIX + BC |
54 | 4% documented |
JP T, XIX + DE |
56 | 4% documented |
CALL T, XHL |
103 | 5 labeled, 6 raw addresses |
LDA XIX/XHL, 0E/0F*h |
441 | Raw address loads |
High-use indirect call tables (analyzed):
- 0xE9F11C (13 uses) - EVENT_HANDLER_DISPATCH_TABLE (11 handlers + 2 padding)
- 0xEA0A16 (12 uses) - SingleLoadDstHandlerTable (data transfer subsystem)
FDC Memory Map
FDC handler routines access these RAM locations:
| Address | Purpose |
|---|---|
| 0x8A20 | FDC status/mode flag (0xFF = active) |
| 0x8A24 | Error indicator (0x00 = success) |
| 0x8A26 | Cached FDC status |
| 0x8A2E | FDC timing parameter |
| 0x8A34 | FDC control value |
| 0x8A36 | FDC address register |
| 0x8A40 | FDC command code (0-11) |
| 0x8A44 | FDC output control flag |
| 0x8A48-4A | Sector/track/head |
| 0x8A6A | FDC output enable flag |
| 0x8A6C | FDC drive/mode selector |
| 0x8B04 | FDC control register |
FDC Handler Routines
The FDC subsystem uses a handler dispatch table at 0xF97D8D with 12 handlers. Full disassembly is documented in docs/fdc_disassembly.md in the roms-disasm repository.
| Address | Name | Description |
|---|---|---|
| 0xF96BBF | FDC_INIT | Basic FDC initialization |
| 0xF96BD0 | FDC_CONFIG_VERIFY | Configuration/status verification |
| 0xF96D95 | FDC_CMD_DISPATCH_SUB | Command handler subroutine |
| 0xF97696 | FDC_STATUS_HANDLER | Status/interrupt handler |
| 0xF976E4 | FDC_CMD_EXEC | Command execution handler |
| 0xF97835 | FDC_SECTOR_XFER | Sector/data transfer handler |
| 0xF97984 | FDC_MODE_CONFIG | Mode configuration (modes 0-5) |
| 0xF97C21 | FDC_CMD_ENABLE | Command enable (sets bit 3 @ 0x28) |
| 0xF97C4B | FDC_CMD_DISABLE | Command disable |
| 0xF97C54 | FDC_STATUS_COPY | Copy cached status |
| 0xF97C5B | FDC_OUTPUT_CTRL | Output control |
| 0xF97C7C | FDC_INTERRUPT_HANDLER | Main interrupt handler |
Handler dispatch works by reading an index from 0x8A40 (0-11) and calling the corresponding routine through the dispatch table.
FDC Helper Routines (Fully Analyzed)
These helper routines support the main FDC handlers:
| Address | Name | Size | Description |
|---|---|---|---|
| 0xF97544 | FDC_DRIVE_DETECT | 78 bytes | 6-check drive detection (returns HL=0xFFFF if found) |
| 0xF97592 | FDC_DRIVE_STATUS | 26 bytes | Quick 2-check status validation |
| 0xF972F9 | FDC_SEND_COMMAND | 231 bytes | NEC uPD765 command protocol |
| 0xF975DC | FDC_SET_TIMEOUT | 6 bytes | Set wait flag for timeout protection |
| 0xF975E2 | FDC_WAIT_TIMEOUT | 48 bytes | Wait with 500ms timeout (error 0x09) |
| 0xF97612 | SOME_DELAY | 32 bytes | Millisecond delay (WA/2 ms) |
FDC_DRIVE_DETECT (0xF97544) validates 6 conditions:
- (8A46h) == 0 - Status register 3 clear
- (8A44h) == 0 - Status register 2 clear
- (8A40h) == 3 - Command = Sense Drive Status
- (8A4Ah) == 1 - Result count = 1
- (8A10h) == 0xFFFF - Detection mode active
- (8A48h) == 2 or 0xFF - Valid drive response
FDC_SEND_COMMAND (0xF972F9) implements the NEC uPD765 protocol:
- Command byte structure: MT(7), MF(6), SK(5), Command(4-0)
- Accesses FDC hardware at 0x110008 (status) and 0x11000A (data)
- Handles: Seek, Recalibrate, Read/Write Data, Format Track, Sense Interrupt
SOME_DELAY timing: Uses SYSTEM_TIMESTAMP at 0x0409, incremented by Timer 1 at ~1ms intervals. Delay = WA/2 milliseconds.
Known Jump Tables
| Table | Address | Type | Entries | Purpose |
|---|---|---|---|---|
HANDLE_UPDATE_OFFSETS |
0xE00178 | 16-bit offsets | 8 | Update file type dispatch |
UI_STATE_MACHINE_TABLE |
0xEF0D64 | 32-bit addresses | 3 | UI state machine (3 states) |
UI_SUBSTATE_TABLE |
0xEF0DA5 | 32-bit addresses | 16 | UI sub-state handler dispatch |
SOUND_DATA_SECTION_PTRS |
0xE023B0 | 32-bit addresses | 16 | Sound category data pointers |
FDC_HANDLER_OFFSETS |
0xEA98CA | 16-bit offsets | 12 | FDC command handler dispatch |
FDC_HANDLER_DISPATCH_BASE |
0xF97D8D | (base address) | 12 | FDC handler routines |
SQTR_DISPATCH_TABLE_1 |
0xF20D37 | Inline code | 6 | Sequencer track handler (SqTrAsTtlFunc) |
SQTR_DISPATCH_TABLE_2 |
0xF20D8E | Inline code | 6 | Sequencer track handler (SqTrAsTtlFunc) |
APP_EVENT_HANDLER_TABLE |
0xF44169 | Inline code | 32 | Application event delivery system |
NOTE_EVENT_DISPATCH_1 |
0xF17155 | Inline code | 7 | Note event handler (BC index) |
NOTE_EVENT_DISPATCH_2 |
0xF171C4 | Inline code | 7 | Note event handler (WA index) |
UI_COMPONENT_DISPATCH |
0xF1A7CB | Inline code | 8 | UI grid/focus component handler |
RESOURCE_INFO_HANDLERS |
0xF1EA4C | Inline code | 10 | Resource info retrieval (GetResouceInfo) |
FDC_COMMAND_DISPATCHER |
0xF96DB1 | Inline code | 12 | FDC command dispatcher |
FDC_CMD_HANDLER_BASE |
0xF96DD6 | (base address) | 12 | FDC command handler base |
Handler Dispatch Example
The update file handler uses offset-based dispatch:
Erase_and_Burn____when_disk_is_valid:
LD A, (0F23Ch) ; Get file type ID
EXTZ WA ; Zero-extend to 16-bit
SLL 1, WA ; Multiply by 2 (word offset)
LDA XIX, HANDLE_UPDATE_OFFSETS
LD WA, (XIX + WA) ; Load offset from table
LDA XIX, HANDLE_UPDATE_FILE_TYPE_ID_001h ; Base address
JP T, XIX + WA ; Jump to handler
State Machine Pattern
Multi-level dispatch using nested jump tables:
; First level: 3 main states
LDA XHL, 0EF0D64h ; Main state table
LD XHL, (XHL + A)
JP T, XHL
UI_STATE_MACHINE_TABLE:
dd UI_STATE_0_IDLE ; State 0
dd UI_STATE_1_PROCESS ; State 1
dd UI_STATE_2_SUBSTATE ; State 2
; State 2 has 16 sub-states
UI_STATE_2_SUBSTATE:
LDA XHL, 0EF0DA5h ; Sub-state table
LD XHL, (XHL + A)
JP T, XHL
UI_SUBSTATE_TABLE:
dd UI_SUBSTATE_CLEAR_FLAGS ; Sub-state 0
dd UI_SUBSTATE_PROCESS_A ; Sub-state 1
... (16 total entries)
Undocumented Jump Table Targets
The FDC handler dispatch table (FDC_HANDLER_OFFSETS at 0xEA98CA) calls helper routines that are still raw bytes in the source. These routines handle floppy disk operations:
| Routine | Address | Status | Called By |
|---|---|---|---|
FDC_STATUS_HANDLER |
0xF97696 | Raw bytes | FDC_HANDLER_02 |
FDC_CMD_EXEC |
0xF976E4 | Raw bytes | FDC_HANDLER_03 |
FDC_SECTOR_XFER |
0xF97835 | Raw bytes | FDC_HANDLER_04 |
FDC_CMD_ENABLE |
0xF97C21 | Raw bytes | Multiple handlers |
FDC_INTERRUPT_HANDLER |
0xF97C7C | Raw bytes | FDC_HANDLER_11 |
FDC_INIT |
0xF96BBF | Raw bytes | FDC_InitSequence_Full |
FDC_CONFIG_VERIFY |
0xF96BD0 | Raw bytes | FDC_InitSequence_Full |
FDC_MODE_CONFIG |
0xF97984 | Raw bytes | FDC_HANDLER_05 |
FDC_CMD_DISABLE |
0xF97C4B | Raw bytes | FDC_HANDLER_07 |
FDC_STATUS_COPY |
0xF97C54 | Raw bytes | FDC_HANDLER_08 |
FDC_OUTPUT_CTRL |
0xF97C5B | Raw bytes | FDC_HANDLER_09 |
FDC_CMD_DISPATCH_SUB |
0xF96D95 | Raw bytes | FDC_HANDLER_10 |
These routines are in FDC_SeekRecalibrate raw byte block (lines 336862-336929).
Finding Jump Tables
To find undocumented jump tables:
- Search for indirect jumps:
grep -E "JP T, X|CALL T, X" - Look for raw address loads before jumps:
LDA XIX, 0E*horLDA XHL, 0F*h - Trace back to find table definitions (
dd LABEL_*ordw offset) - Verify all table targets are disassembled
Jump Table Analysis Statistics
Analysis of indirect jump patterns in the main CPU ROM reveals the scale of dispatch mechanisms used:
| Pattern | Count | Status |
|---|---|---|
JP T, XIX + WA |
118 | 9 documented, 109 need naming |
JP T, XIX + BC |
54 | 4% documented |
JP T, XIX + DE |
56 | 4% documented |
CALL T, XHL |
103 | 5 labeled, 6 raw addresses |
LDA XIX/XHL, 0E/0F*h |
441 | Raw address loads for tables |
High-Use Indirect Call Tables (Analyzed):
| Address | Uses | Purpose |
|---|---|---|
| 0xE9F11C | 13 | EVENT_HANDLER_DISPATCH_TABLE (11 handlers + 2 padding) |
| 0xEA0A16 | 12 | SingleLoadDstHandlerTable (data transfer subsystem) |
| 0xEA0212 | 1 | Resource loader dispatch |
UI and Event System
The firmware implements a sophisticated event-driven UI system with multiple dispatch layers.
Event Handler Dispatch
The main event loop uses a multi-level dispatch system:
APP_EVENT_HANDLER_TABLE (0xF44169):
- 32 inline code handlers for application events
- Used for LED control, button handling, and UI updates
UI_COMPONENT_DISPATCH (0xF1A7CB):
- 8 inline code handlers for UI grid/focus components
- Handles keyboard grid navigation and focus management
NOTE_EVENT_DISPATCH (0xF17155 / 0xF171C4):
- Two 7-entry tables for note event handling
- Uses BC index (table 1) or WA index (table 2)
Sequencer System
The sequencer track system uses dedicated dispatch tables:
| Table | Address | Entries | Purpose |
|---|---|---|---|
| SQTR_DISPATCH_TABLE_1 | 0xF20D37 | 6 | SqTrAsTtlFunc handlers |
| SQTR_DISPATCH_TABLE_2 | 0xF20D8E | 6 | SqTrAsTtlFunc handlers |
Resource System
GetResouceInfo (0xF1EA4C):
- 10-entry dispatch table for resource information retrieval
- Handles font metrics, character widths, and string dimensions
Known lookup tables:
| Address | Register | Purpose |
|---|---|---|
| 0xE0CB1A | XHL | Character lookup table |
| 0xE46312 | XHL | Character/font metrics |
| 0xE161E4-0xE16244 | XHL | String width tables |
UI State Machine
The main UI uses a two-level state machine:
Level 1 (0xEF0D64): 3 main states
├── State 0: UI_STATE_0_IDLE
├── State 1: UI_STATE_1_PROCESS
└── State 2: UI_STATE_2_SUBSTATE → Level 2
Level 2 (0xEF0DA5): 16 sub-states for detailed UI handling
Undocumented Data Structures
Large binary includes that need analysis:
| Address Range | Size | File | Status |
|---|---|---|---|
| 0xE0176C-0xE01F7F | 2.1 KB | e0176c_e01f7f.bin |
Unknown structure |
| 0xE02510-0xE06BAF | 18 KB | e02510_e06baf.bin |
Unknown structure |
| 0xE06F30-0xE0ADCF | 16 KB | e06f30_e0adcf.bin |
Unknown structure |
| 0xE0B250-0xE0BA60 | 2.1 KB | e0b250_e0ba60.bin |
Unknown structure |
| 0xE0BB90-0xE0E974 | 12 KB | e0bb90_e0e974.bin |
Unknown structure |
Total undocumented binary data: ~50 KB requiring structural analysis.
Semantic Label Naming
A comprehensive analysis identified 200+ labels across 14 assembly files that need semantic names. The full recommendations are in docs/label_rename_recommendations.md in the disassembly repository.
Completed Renames
150+ labels renamed across 22 files using sed scripts in scripts/rename_labels/:
| File | Renames | Examples |
|---|---|---|
| demo_routines.asm | 23 | DemoStyle_InputHandler, DemoRhythm_DispatchTable |
| sysex_routines.asm | 15 | ExcSendFunc_InvalidParam_Exit, ExcDotFunc_HandlerJumpTable |
| midi_serial_routines.asm | 15 | MIDI_RX_BYTE_DISPATCHER, MIDI_CHANNEL_HANDLER_JUMP_TABLE |
| cpanel_routines.asm | 16 | CPanel_InterruptPoll_MainLoop, CPanel_PanelDetection |
| fdc_routines.asm | 15 | FDC_Setup_DMA_Write_Mode, FDC_Exception_Status_Decoder |
| subcpu_boot.asm | 15 | TONE_GEN_CHANNEL_INIT, DEBUG_OUTPUT_BYTE_HEX |
| subcpu_payload.asm | 20 | Audio_DMA_RingBuffer_To_Maincpu, Voice_EnvelopeRate_Lookup |
| hdae5000.asm | 22 | HDAE5000_Calculate_Row_Address, HDAE5000_PPORT_Cmd_LoadHDtoMemory |
| file_io/*.asm | 20 | SelectPasswordMode, DisplaySmfFileList |
Naming Conventions
| Category | Pattern | Examples |
|---|---|---|
| Routines | VerbNoun | FDC_Validate_Drive_Head, MIDI_RX_BYTE_DISPATCHER |
| Dispatch Tables | *_DispatchTable | DemoStyle_DispatchTable, MIDI_CHANNEL_HANDLER_JUMP_TABLE |
| Exit Points | *_Exit, *_Return | ExcDotFunc_InvalidIndex_Exit |
| Error Handlers | *_Error, *_Invalid | FDC_WaitReady_TimeoutCheck |
| Data Tables | *_Table | Voice_PolyphonyLimits_Table |
High-Priority Renames (Pending)
| File | Count | Key Labels |
|---|---|---|
| maincpu main | 30 | InitSystemRAM_ReleaseMemoryLock, FormatString_PrintfLike |
| subcpu payload | 20 | Audio_DMA_RingBuffer_To_Maincpu, Voice_EnvelopeRate_Lookup |
| midi_serial_routines | 15 | MIDI_RX_BYTE_DISPATCHER, MIDI_QUEUE_EVENT_TO_SEQUENCER |
| fdc_routines | 15 | FDC_Setup_DMA_Write_Mode, FDC_Exception_Status_Decoder |
| cpanel_routines | 15 | CPanel_InterruptPoll_MainLoop, CPanel_PanelDetection |
References
- Service Manual PDF
- System Update Disks Archive
- HDAE5000 Technical Info
- Image Gallery - Extracted graphics from firmware