Display driver (DRV_UI.DRV)
Layout
A driver file has a resident part and code banks like a program, but in three groups. The header names the groups at 0x30; a bank’s address is 0x13NN0000 (first group, 0x400 apart in the file), 0x0bNN0400 (second, 0x800 apart) or 0x03NN0c00 (third, 0x400 apart), with NN = twice its place in the group. The function table (its address at 0x3c of the header, 0x1190d4 in memory) holds such addresses directly, next to addresses in the resident part.
firmware_analysis/tools/drv_dis.py disassembles a driver, this one and DRV_LCD.DRV included.
Programs call it through svc 6 with the function number in r3: ui(a, b, c, function).
Functions
The table has 40 entries. Numbers 0 to 34 are the SDK’s (ui_op_e in display.h of the US212A SDK, names below);
35 to 39 exist only in this firmware. Addresses are the table’s (Thumb bit included).
No. |
Address |
SDK name |
What it does here |
|---|---|---|---|
0 |
0x13080063 |
|
open a resource file |
1 |
0x13080125 |
|
close it |
2 |
0x117701 |
|
picture box |
3 |
0x0b1a04bb |
|
text box: background (plain picture draw), then the text; a text that does not fit prepares scrolling from the background’s sideways copy (0x13220000) |
4 |
0x0b180401 |
|
time box |
5 |
0x0b100777 |
|
number box: picture form (0x0b10064a, digits through 0x0b100400) or text form (0x13120001) |
6 |
0x0b160401 |
|
progress bar |
7 |
0x13060001 |
|
|
8 |
0x131a0123 |
|
list box |
9 |
0x0b2007c5 |
|
dialog |
10 |
0x13180001 |
|
|
11 |
0x131e0001 |
|
slider (volume, brightness, equaliser) |
12 |
0x13040001 |
|
a text box’s area (the cover area is text box 1 of |
13 |
0x130e0001 |
|
|
14 |
0x130c0001 |
|
list style attributes (lines per page) |
15 |
0x0b0c06b5 |
|
the rotating title line |
16 |
0x03020c01 |
|
|
17 |
0x118011 |
|
read the current colours (to restore them) |
18 |
0x03080c01 |
|
|
19 |
0x11801f |
|
text colour |
20 |
0x118027 |
|
background colour |
21 |
0x0b080679 |
|
draw a string in a region |
22 |
0x03060c01 |
|
|
23 |
0x1186fb |
|
|
24 |
0x0b0604ab |
|
measure how much text fits a line; mode bit 1: do not end a line inside a word (a word is a run of A to Z, a to z and the straight apostrophe) |
25 |
0x03080c4b |
|
|
26 |
0x03040d8b |
|
|
27 |
0x03040c99 |
|
|
28 |
0x118047 |
|
|
29 |
0x03040c01 |
|
|
30 |
0x03080c21 |
|
turn the screen: 1 = landscape (160 x 128); every later drawing call works in those coordinates |
31 |
0x1187d1 |
|
draw a picture at x, y |
32 |
0x03080c9d |
|
|
33 |
0x03080c0f |
|
|
34 |
0x03080c97 |
|
|
35 |
0x130c0057 |
prepare a list style (the list code calls it before drawing) |
|
36 |
0x0b06069d |
||
37 |
0x117c7f |
draw a picture over a background picture; black pixels of the picture are replaced by the background’s |
|
38 |
0x118a7b |
keyed draw: restore the background piece, then draw only pixels whose 16-bit value is above a key |
|
39 |
0x118fc1 |
a row of pictures through the keyed draw (the status bar clock) |
A style is passed as {id, type} (4 bytes; type 1 = COMMON.STY). Strings are passed as the SDK’s string_desc_t
(12 bytes): data pointer (or a text id in the low half), type byte (0x7e text id, 0x7d UTF-16 data with FF FE first,
0x7c UTF-8, otherwise a language id for one-byte text), a reserved byte, buffer size, an argument and a result
halfword.
String drawing modes (16 bits): bits 0-1 fill mode (0 read the background back from the panel and draw over it, 1 opaque with the background colour, 2 from a column-wise background picture, 3 nothing: see below), bits 2-3 alignment (left, centre, right), bits 4-7 long-text handling (clip, drop incomplete characters, several rows, ellipsis, scroll), bits 10-11 font size (0 normal, 1 large, 2 small), bit 12 divide words.
A string is drawn into a buffer strip as wide as the text (at the place its alignment gives it in the region) and as high as the font (16 rows), in pieces of at most 160 columns, and each piece is written to the panel whole. Before the letters go in, the strip is prepared by the fill mode (0x11825e, then 0x117e32): mode 1 fills it with the background colour (DC +4, the colour function 18 fills with), mode 0 reads the panel back into it, mode 2 copies the background picture, and mode 3 does nothing, so the strip holds what the previous string left there. Mode 3 is not “transparent”: around the letters the panel gets stale pixels (stage 25 as first flashed).
Keyed draws
Function 38 compares each pixel as an unsigned 16-bit value with the key in its argument block and draws it only if
it is greater. The screensaver clock passes 0xb5b6 (red at least about 184 of 255), so in the stock firmware soft
edges, dim and non-red colours vanished there; stage 15 sets that key to 0. The status bar clock (function 39) uses
0x7bcf: a theme’s text2 colour must stay above it.
List boxes
The list box function reads the style’s 28-byte record (Resources, menus and fonts) and draws, by the record’s byte 24:
on a full redraw (mode 3) the background picture of the record (stock 185 at (0, 0), the whole screen);
bit 1: the title (0x131a0088), only on a full redraw, over what is on the screen;
bit 2: the scroll bar (0x131a0000);
bit 3: the counter (0x0b0e0400), on every draw;
the rows (0x131c0000 per row): each row’s background is the slice of picture 263 behind it, the icon is the row’s icon number plus the style’s icon base, the text is clipped or scrolled; rows beyond the list’s end are drawn empty.
Draw modes: 1 the active row, 2 the rows, 3 everything, 5 continue scrolling the active row. The list data is the
SDK’s listbox_private_t (100 bytes): title descriptor at +0, six item descriptors at +12 (12 bytes each; the item’s
argv holds its icon and mark), icon ids at +84 and +86, rows filled +88, active row +90, previous row +92, total
+94, position +96 (rows counted from 0).
The counter formats “position + 1” and “total”. With attribute bit 0 clear (stock) it builds “pos/total” and draws it as text in the interface font in the counter’s text box, with the background picture (bit 5) first. With bit 0 set it hands the digits to the number-box picture routine 0x0b100400: the background picture is drawn at the counter’s x and y when the number of digits changes, then each changed digit is drawn as picture “first + digit” over it with black transparent, the separator after the position’s digits. That routine keeps the last digits in a buffer shared with the number boxes and starts afresh on a full list redraw.
The LCD driver and rotation
Function 30 sets a flag and the drawing window (160 x 128 or 128 x 160). Every drawing routine sets its window
through one hook (0x117ebe), which tells the LCD driver the orientation. DRV_LCD.DRV function 2 (0x119d9c) writes
the panel’s orientation register: mode 0 = 0xc8 (upright), 1 = 0xa8 (landscape), 2 = 0x48, 3 and 4 = 0xe8,
5 = 0x88, 6 = 0xa8. Modes 4 and 5 are the column-by-column modes behind the sideways picture copies. In landscape a
point (x, y) is the upright point (127 − y, x): the upright top edge is the landscape left edge. The shared code has a
wrapper around function 30 that remembers the direction (MUSIC.AP 0x18da1d34, read back by 0x18da1d28), which the
screensaver uses.