Firmware Architecture Flowchart
Firmware Architecture Flowchart
This page documents the complete execution flow of the KN5000 firmware, from power-on through steady-state operation. The firmware runs on a TMP94C241F (TLCS-900/H2) CPU at 16 MHz with a cooperative multitasking scheduler.
Power-On Boot Sequence
flowchart TD
RESET["RESET Vector
(0xE00000)"] --> HW_INIT["Hardware Init
IO ports, stack, RAM clear"]
HW_INIT --> SELF_TEST["Self Test
ROM checksum, RAM test"]
SELF_TEST --> FW_VER{"Firmware
version?"}
FW_VER -->|"v0xFF (boot ROM)"| SHOW_WAIT["Display
'Please Wait !!'"]
FW_VER -->|"Normal"| POST_TEST["Post Self Test"]
SHOW_WAIT --> POST_TEST
POST_TEST --> TASK_INIT["TaskSched_Init
Initialize cooperative scheduler"]
TASK_INIT --> PERIPH["Init Peripherals
GPIO, region code"]
PERIPH --> FLASH["Flash_InitAllBanks
Initialize flash memory"]
FLASH --> HDAE{"HD-AE5000
present?"}
HDAE -->|Yes| PPI_INIT["HDAE5000 PPI Init
Parallel port interface"]
HDAE -->|No| SEQ_INIT
PPI_INIT --> SEQ_INIT["Seq_FullInit
Sequencer initialization"]
SEQ_INIT --> CPANEL["CPanel_ScanButtons
Read power-on key combo"]
CPANEL --> FLASH_UPD{"Key combo =
flash update?"}
FLASH_UPD -->|Yes| FW_UPDATE["FLASH_MEM_UPDATE
Firmware update from floppy"]
FLASH_UPD -->|No| MAIN_BOOT
FW_UPDATE --> HALT["Boot_MainSequence_Trampoline
(infinite loop — reboot required)"]
subgraph MAIN_BOOT ["Main Boot Path"]
FACTORY{"Factory reset
requested?"}
FACTORY -->|Yes| RESET_DRAM["Clear all DRAM + SRAM"]
FACTORY -->|No| SUBCPU_INIT
RESET_DRAM --> SUBCPU_INIT["SubCPU_Init_DMA_Channels"]
SUBCPU_INIT --> PAYLOAD["SubCPU_Send_Payload
Transfer 192KB firmware"]
PAYLOAD --> VERIFY["SubCPU_Payload_Verify
Checksum validation"]
VERIFY --> SCREEN0["ScreenGroup_Dispatch(0)
Initial boot screen"]
SCREEN0 --> CHECK_ERR{"Payload
transfer OK?"}
CHECK_ERR -->|Error| ERR_SCREEN["ScreenGroup_Dispatch(2)
'ERROR in CPU data'"]
CHECK_ERR -->|OK| BOOT_SCREEN["Boot_DisplayScreen
ScreenGroup_Dispatch(1)"]
end
BOOT_SCREEN --> MAIN_LOOP
Main Event Loop
After boot, the firmware enters a cooperative multitasking loop driven by a task scheduler and event dispatch system.
flowchart TD
BOOT["Boot_DisplayScreen"] --> INIT_SUBSYS["Initialize All Subsystems"]
subgraph INIT_SUBSYS ["Subsystem Initialization"]
INIT_NAKA["InitializeNaka
Register 478 UI widget objects"]
INIT_HAMA["InitializeHama
Register file I/O titles"]
INIT_AUDIO["AudioInit
Tone gen, DSP, voice allocation"]
INIT_MIDI["MIDI Init
Serial port, routing tables"]
INIT_SEQ["Sequencer Init
Ring buffers, part state"]
end
INIT_SUBSYS --> MAIN_LOOP
subgraph MAIN_LOOP ["Main Event Loop (cooperative multitasking)"]
SCHED["TaskSched_Dispatch
Run next ready task"]
SCHED --> EVT_CHECK{"Events
pending?"}
EVT_CHECK -->|Yes| EVT_DISPATCH["Event Dispatch
Route to registered handler"]
EVT_CHECK -->|No| TIMER_CHECK{"Timer
expired?"}
EVT_DISPATCH --> SCHED
TIMER_CHECK -->|Yes| TIMER_HANDLER["Timer Handler
Sequencer tick, UI refresh"]
TIMER_CHECK -->|No| SCHED
TIMER_HANDLER --> SCHED
end
Interrupt Service Routines
The firmware uses hardware interrupts for real-time operations. ISRs feed data into ring buffers consumed by the main loop.
flowchart LR
subgraph ISR ["Hardware Interrupts"]
DMA_ISR["E1 DMA ISR
Inter-CPU data transfer"]
TIMER_ISR["Timer ISR
System tick (1ms)"]
SERIAL_ISR["Serial ISR
MIDI RX/TX, Control Panel"]
end
subgraph BUFFERS ["Ring Buffers"]
NOTE_BUF["NoteEvent Buffer
(0x0203D5)"]
SOUND_BUF["SoundEdit Buffer"]
VOICE_BUF["VoiceMap Buffer
(0x0201C1)"]
DSP_BUF["DspSysEx Buffer
(0x01FCA3)"]
MIDI_BUF["MIDI Out Buffer
(0x01F785)"]
end
DMA_ISR --> NOTE_BUF
DMA_ISR --> SOUND_BUF
DMA_ISR --> VOICE_BUF
DMA_ISR --> DSP_BUF
SERIAL_ISR --> MIDI_BUF
Subsystem Architecture
flowchart TD
subgraph UI_LAYER ["UI Layer"]
NAKA["NAKA Widget Framework
478 widget objects, 9 type codes"]
SCREEN["Screen Manager
Screen groups, mode dispatch"]
DRAW["Drawing Primitives
Lines, boxes, text, bitmaps"]
VGA["VGA Controller
320x240 8bpp LCD"]
end
subgraph AUDIO_LAYER ["Audio Layer"]
TONEGEN["Tone Generator (IC303)
64 voices, PCM wavetable"]
DSP["DSP Effects
IC310 (serial) + IC311 (parallel)"]
VOICE["Voice Allocator
Note-on/off, velocity, pan"]
SNDPARAM["Sound Parameters
Preset lookup, category maps"]
end
subgraph SEQ_LAYER ["Sequencer Layer"]
SEQ["Sequencer Engine
16-track, ring buffer playback"]
ACCOMP["Accompaniment Engine
Rhythm, bass, chord patterns"]
SMF["SMF Player
Standard MIDI File playback"]
STYLE["Style System
SSF data, variation select"]
end
subgraph IO_LAYER ["I/O Layer"]
CPANEL["Control Panel
Serial protocol, 150 buttons, 119 LEDs"]
MIDI["MIDI
31250 baud UART, SysEx, CC routing"]
FDC["Floppy Disk
UPD72067 controller"]
IDE["IDE/ATA
HD-AE5000 hard disk"]
FLASH["Flash Memory
User settings, custom data"]
end
subgraph CPU_LAYER ["Inter-CPU Communication"]
MAIN["Main CPU
TMP94C241F @ 16MHz"]
SUB["Sub CPU
TMP94C241F (audio engine)"]
LATCH["Latch @ 0x140000
Command/response protocol"]
end
UI_LAYER --> AUDIO_LAYER
UI_LAYER --> SEQ_LAYER
SEQ_LAYER --> AUDIO_LAYER
AUDIO_LAYER --> CPU_LAYER
IO_LAYER --> UI_LAYER
IO_LAYER --> SEQ_LAYER
MAIN <-->|"E1/E2/E3 commands"| LATCH
LATCH <-->|"DMA bulk transfer"| SUB
SUB --> TONEGEN
SUB --> DSP
NAKA Widget Event Flow
The UI framework uses a hierarchical event dispatch system. Events flow from hardware through the control panel to NAKA widget handlers.
flowchart TD
BUTTON["Physical Button Press"] --> CPANEL_ISR["Control Panel ISR
Serial packet decode"]
CPANEL_ISR --> EVT_GEN["Generate Event ID
(e.g., 0x01C00008 = DISK MENU)"]
EVT_GEN --> VIEWABLE["ViewableProc
(0xFA5995)"]
VIEWABLE --> TYPE_CLASS["SeMenu_SetObjectFlags
Classify by widget type"]
TYPE_CLASS --> HANDLER_TABLE["handler_table lookup
(DRAM dispatch table)"]
HANDLER_TABLE --> INHERITED["InheritedProc
Walk parent chain"]
subgraph WIDGETS ["Widget Handlers"]
CONTAINER["Container Handler
Screen root, layout"]
MENU_ITEM["Menu Item Handler
Selection, navigation"]
SLIDER["Slider Handler
Value adjustment"]
DISPATCH["Dispatch Handler
Proc function call"]
end
INHERITED --> CONTAINER
INHERITED --> MENU_ITEM
INHERITED --> SLIDER
INHERITED --> DISPATCH
DISPATCH --> PROC["Proc Function
(e.g., IvDrawbarProc)"]
PROC --> ACTION["UI Action
Sound change, screen transition"]
Memory Map Overview
flowchart LR
subgraph ADDR_SPACE ["24-bit Address Space"]
INT_RAM["0x000000-0x000FFF
Internal RAM (4KB)
CPU registers, stack"]
IO["0x001000-0x0FFFFF
I/O & Peripherals
Timers, serial, DMA"]
TONE["0x100000-0x15FFFF
Tone Gen Hardware
64 voices × 32 regs"]
VRAM["0x1A0000-0x1DFFFF
VRAM (256KB)
320×240 8bpp LCD"]
DRAM["0x200000-0x27FFFF
Extension DRAM (512KB)
Sequencer, NAKA state"]
HDAE["0x280000-0x2FFFFF
HDAE5000 ROM (512KB)
Hard disk expansion"]
CUSTOM["0x300000-0x3FFFFF
Custom Data Flash
User settings"]
TABLE["0x800000-0x9FFFFF
Table Data ROM (2MB)
Styles, rhythms, demos"]
PROG["0xE00000-0xFFFFFF
Program ROM (2MB)
Main firmware"]
end
Source File Organization
flowchart TD
MAIN["kn5000_v10_program.s
(3,400 lines — entry point)"]
subgraph BOOT_FILES ["Boot & System"]
BOOT_HW["shared/boot_hw_init.s"]
SYS_HAND["boot/system_handlers.s"]
FACTORY["factory_test/test_*.s"]
end
subgraph UI_FILES ["UI Framework (19 .s + 27 .c)"]
WIDGET_DEFS["ui/ui_widget_defs.s (19K)"]
DRAW_PRIM["ui/drawing_primitives.s"]
CPANEL_RT["ui/cpanel_routines.s"]
NAKA_C["ui_widgets/*.c (26 files)
Typed C struct widget data"]
end
subgraph AUDIO_FILES ["Audio (31 files)"]
ACE["audio/audio_control_engine.s (8K)"]
NVM["audio/note_voice_mapping.s (26K)"]
SEMENU["audio/semenu_routines.s"]
DSP_CFG["audio/dsp_config_sysex.s"]
SND_DATA["audio/sound_data_*.s (7 files)"]
end
subgraph SEQ_FILES ["Sequencer (15 files)"]
ACC_ENG["sequencer/accompaniment_engine.s (33K)"]
SEQ_ENG["sequencer/sequencer_engine.s (32K)"]
SMF_PLAY["sequencer/smf_playback.s"]
end
subgraph MIDI_FILES ["MIDI (9 files)"]
MIDI_SER["midi/midi_serial_routines.s"]
MIDI_DISP["midi/midi_dispatch_handlers.s"]
SYSEX["midi/sysex_routines.s"]
end
subgraph STORAGE_FILES ["Storage (2 files)"]
FDC_RT["storage/fdc_routines.s"]
FLASH_RT["storage/flash_floppy_handlers.s"]
end
MAIN --> BOOT_FILES
MAIN --> UI_FILES
MAIN --> AUDIO_FILES
MAIN --> SEQ_FILES
MAIN --> MIDI_FILES
MAIN --> STORAGE_FILES
Disassembly Statistics
| Metric | Value |
|---|---|
| Total native instructions | 279,441 (0 code .byte remaining) |
| Assembly source files | 154 (.s) + 70 (.c) |
| ROM byte match | 100% on all 6 ROMs |
| Labeled symbols | 37,276 (0 opaque LABEL_XXXXXX) |
| NAKA widget C structs | 26 files with typed fields |
Auto-generated from KN5000 ROM disassembly analysis. Last updated: March 2026.