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.