KN7000 Display Subsystem
KN7000 Display Subsystem
The KN7000 draws its UI to an LCD through the MILK toolkit’s graphics layer:
palette-indexed bitmaps and text, composited by a family of blit routines and
handed to the LCD controller. This page ties the hardware (the LCD I/O bank
and framebuffer window found by analysing the boot) to the
firmware (the drawing functions recovered by name in the
disassembly). Addresses are decoded from
kn7000_program.rom; work-RAM globals are in the 0x50000000 region.
Panel type: colour vs 2-bit grayscale
The KN7000 was produced with different LCD panels, and the firmware detects
the type into a work-RAM byte at 0x50007578 (accessed by GetColorMode /
SetColorMode). Two predicate functions read it — decoded straight from their
source:
GetColorMode: movhu (0x50007578), d0 ; ret # the panel-type value
CheckColorLcd: return (colormode == 0) # 0x48421D70
Check2BitLcd: return (colormode == 2) # 0x48421D82
So the panel-type enum is 0 = full-colour, 2 = 2-bit (4-level)
grayscale (value 1 is a further mono/other variant). A second byte at
0x5000757A (GetLcdMode / SetLcdMode) holds a related mode flag. The
firmware branches on these throughout the graphics layer — e.g. it provides a
ConvPaletteMono4 routine to fold the colour palette down to 4 grey levels for
the 2-bit panel.
Palette-indexed bitmaps
UI artwork is stored as headerless palette-indexed bitmaps (the same design as the KN5000 — see the Table image format). Pixels are raw palette indices, row-major; the bit depth is 2, 4 or 8 bpp. The blit API has a dedicated fast path per depth, which is how the depths are known:
| Function | CPU addr | Depth |
|---|---|---|
DrawBitmapSPFast4 |
0x484243CD |
2 bpp (4 colours) |
DrawBitmapSPFast16 |
0x484245BC |
4 bpp (16 colours) |
DrawBitmapSPFast256 |
0x48424784 |
8 bpp (256 colours) |
DrawBitmap / DrawBitmapFast |
0x48423B56 / …3C88 |
generic |
DrawBitmapSP / …SP2 |
0x484240A4 / …48DE |
sprite (transparent) |
DrawBitmapFile / …FileEx |
0x48424A9F / …4CC8 |
from a bitmap-file struct |
DrawIcons / DrawJpegFile[R] |
0x48423DCD / …4EBD |
icon sheet / JPEG |
The SP (“sprite”) variants honour a transparent index — index 0xF7,
the KN5000’s transparent colour, which the extracted 8-bpp icons use heavily.
Primitive drawing is provided too: DrawLine/DrawLineEx, DrawBox,
DrawFrame/DrawFrameEx/DrawFrameSP, DrawCircle.
The palette (CLUT)
Indices are resolved through a 256-entry colour look-up table, stored in the
program image at file 0x32573C. Each entry is a 32-bit 0x00BBGGRR
(BGR-order) word — proven by the named colour constants below (CL_Red = index
0xF9 = stored 0x000000FF, i.e. the low byte is red). It is the first data
structure the disassembly project lifted from raw bytes into
typed source. At runtime the palette is manipulated through SetPaletteRGB
(0x4842D9F1), GetPaletteRGB (0x4842DB23) and GetPaletteRGB4
(0x4842DB30); ConvPaletteMono4 (0x4842DC88) derives the 2-bit-panel
greyscale ramp from it.
Named colours
The firmware refers to palette entries by name through a CL_* constant table
(recovered by tools/gen_constants.py). The base is a VGA-16 layout — the
eight dark colours at indices 0x00–0x07 and the eight bright ones at
0xF8–0xFF:
| Index | Name | Index | Name | |
|---|---|---|---|---|
0x00 |
CL_Black |
0xF8 |
CL_Gray |
|
0x01 |
CL_Maroon |
0xF9 |
CL_Red |
|
0x02 |
CL_Green |
0xFA |
CL_Lime |
|
0x03 |
CL_Olive |
0xFB |
CL_Yellow |
|
0x04 |
CL_Navy |
0xFC |
CL_Blue |
|
0x05 |
CL_Purple |
0xFD |
CL_Fuchsia |
|
0x06 |
CL_Teal |
0xFE |
CL_Aqua |
|
0x07 |
CL_Silver |
0xFF |
CL_White |
On top of that sit semantic UI colours — CL_TitleBar, CL_IconBack,
CL_Text, CL_Selected, CL_PageBack, CL_EditSw (0x17–0x1C), the
sound-expansion accents CL_SoundExp1–4, and crucially CL_Transparent =
0xF7, which names the transparent index the SP sprite blitters skip.
Fonts and text
Text metrics come from a font descriptor table whose base pointer lives at
0x50122DB8. Each descriptor is 0x14 (20) bytes, indexed by font id — read
directly from GetCharHeight / GetCharDescent:
GetCharHeight: font = *(0x50122DB8) + id*0x14 ; return *(font + 2) # 0x4842DF60
GetCharDescent: ... return a per-font descent constant # 0x4842DF73
so a descriptor holds the glyph height at +2 (and further metrics beyond).
GetFontCount / GetFontNameTable enumerate the installed fonts, and
ConvertStrings / ConvertStringsEx render/transform strings — the KN7000 draws
English/German/French/Spanish/Indonesian text plus a Japanese developer entry
(see firmware strings).
LCD hardware
Two hardware regions serve the display, both recovered without a schematic:
- LCD controller I/O —
0x34000000bank. The I/O register map found this to be the largest peripheral block (58 registers, dense 16-bit writes at0x34000108…0x34000280plus byte sub-blocks). The boot trace shows it being programmed during initialisation (0x34000280 ← 0xFFFF, …) alongside the0x36008000control/GPIO port. - Framebuffer / video window —
0x90000000(and a second window at0x8C000000). The boot copies data from the top of the program ROM into these device windows; they behave as memory and are almost certainly the LCD V-RAM / video path (the service map names the LCD V-RAM as IC104). The exact pixel route from aDrawBitmap*call to these windows is not yet fully traced.
Relationship to the KN5000
The bitmap storage design, the transparent index 0xF7, the CLUT approach and
the Draw*/…Proc naming are all shared with the KN5000
(Shared Codebase Map); the KN5000
Display subsystem page is the conceptual companion. What
is KN7000-specific: the multiple panel types (colour and 2-bit) with runtime
detection, standard JPEG artwork alongside the indexed bitmaps, and the
0x34000000/0x90000000 hardware addresses.