dev builds
themes manual
device status forums
mailing lists
IRC bugs
dev guide

Search | Go
Wiki > Main > MPIOHD200Port > DissasemblyMPIOHD200 (r58)

Page heading


upgrade files mappings in flash

unicode.sys contains fonts bitmaps (bytes are swapped) - low byte goes to page, high byte goes to page-1. On coldstart this file is loaded to 0x30E00000

HD200TBL?.sys - not present in upgrade files archives but there are routines to write content of this file to 0x00105000 - 0x00144FFF in flash

HD200ICON?.sys contains icons (small one and fullscreen frames). This file is copied to flash 0x00145000 - 0x001F4FFF.

HD200_UPG.SYS is the main firmware file. During upgrade it is written to flash 0x00000000 - 0x000FFFFF

Looking at flash write routines there is "memory hole" in flash 0x100000 - 0x104A00 - there is no routine writing to this location. However string printing routines reads fonts bitmaps for wchar less than 0x24F there so this must be programmed in factory and never touched.

Last two sectors of flash are used to save some config settings (and resume data)

Start sequence

I have started the dissasembly of firmware upgrade files. The file HD200_UPG.SYS (1.30.05) looks promising. After short initialization routines the code from flash is copied to dram and sram according to the table below. Then program jumps to the entry point located in dram.

source destination length (words)
0xb0a-0xf09 0x10000000-0x100003FF 0x200
0xf0a-0x16a1 0x10000400-0x10000b97 0x3cc
0x16a2-0x1b6b 0x10000ba0-0x10001069 0x265
0x1b6c-0x1fcf 0x100010f0-0x10001553 0x232
0x1fd0-0x6b9b 0x100066e0-0x1000b2ab 0x25e6
0x6b9c-0xa6d3 0x1000b2ac-0x1000ede3 0x1d9c
0xa6d4-0xc3eb 0x30BE3C20-0x30BE5937 0xe8c
0xC3EC-0x4b1f7 0x30BE5938-0x30c24743 0x1f706
0x4B1F8-0x6c6e3 0x30C24744-0x30C45c2f 0x10a76
0x6C6E4-0x6d503 0x30C45C30-0x30C46a4f 0x710
0x6D504-0x6f01b 0x30C46A50-0x30c48567 0xd8c
0x6f01c-0x72561 0x30c48a70-0x30c4bfb5 0x1aa3
0x72562-0x7a0dc 0x30c4e361-0x30c55eda 0x3dbd + 1byte
0x7a0dd-0x7af14 0x30c55ee0-0x30c56d17 0x71c
0x7af15-0x7bc78 0x30c56d20-0x30c57a83 0x6b2
0x7bc79-0x7e78a 0x30c57a90-0x30c5a5a1 0x1589
0x7e78b-0x807e2 0x30c5a5b0-0x30c5c607 0x102c
0x807e3-0x81bfa 0x30c5c610-0x30c5da27 0xa0c
0x81bfb-0x82d3e 0x30c5da30-0x30c5eb73 0x8a2
0x82d3f-0x86c3e 0x30c5eb80-0x30c62a7f 0x1f80
0x86c3f-0x93ace 0x30c62a80-0x30c6e40f 0x6748
0x92e33-0xb1d20 0x30c6e410-0x30c70afd 0xf777
0x95921-0x963f4 0x30c70b00-0x30c715d3 0x56a
0x95ff5-0x9a002 0x100066e0-0x1000a6ed 0x2007
0x9a003-0x9b0da 0x1000f60c-0x100106e3 0x86c
0x980db-0xaf016 0x30c75b80-0x30c8cabb 0xb79e
0xb2017-0xb25e2 0x30c8cac0-0x30c8d08b 0x2e6

Memory map

address range length (bytes) description
0x00000000-0x001FFFFF 0x200000 chip select 0 (2MB Flash)
0x10000000-0x1000FFFF 0x10000 sram1 64k
0x10010000-0x10017FFF 0x8000 sram0 32k
0x30000000-0x30FFFFFF 0x1000000 sdram 16M
0x40000000   mbar
0x50000000   chip select 3 (LCD)
0x60000000   chip select 2 (IDE)
0x80000000   mbar2

exception vector table is located in sram 0x10000000-0x100003FF

LCD initialization

The LCD initialization routine (0x30BF81A0) looks consistent with datasheet: First we have setting GPO34 low, delay, setting GPO34 high which I think is hardware reset sequence. Than we write to CS3
opcode description
0xE2 reset
0x48 0x80 duty ratio 1/128
0xA0 select ADC normal
0xC0 select SHL normal
0x44 0x00 set COM0 = 0x00
0xAB osc. on
0x67 DC-DC boost 6x
0x27 select regulator resistor 7.2
0x81 0x1B select volume 0x1B
0x56 select LCD bias 1/11
0x96 select 3 FRC, 12 PWM
0x34 0x00 ???
0x1A ???
0x88 0x00 set gray 0
0x89 0x00 set gray 1
0x8A 0x0C set gray 2
0x8B 0x00 set gray 3
0x8C 0xC4 set gray 4
0x8D 0x00 set gray 5
0x8E 0xCC set gray 6
0x8F 0x00 set gray 7
0x2F power on all circuits
0xAF display on

display is flipped i.e page 0x0f column 0 is left upper corner


Port pin I/O/F E Description Port pin I/O/F E Description
0 F 0 DDATA0 32 (0) F 0 Unassigned
1 F 0 DDATA1 33 (1) F* 0 TIN0/TOUT0
2 F 0 DDATA2 34 (2) O 1 LCD Reset line (goes low on line in jack insert?) T
3 F 0 SCL1 (second I2C? clock) 35 (3) F 0 TOUT1/ADOUT
4 F 0 DDATA3 36 (4) I/O* 1 in: main hold (active high) out: reset of the GL811E? usb bridge (low = reset state)
5 I/O 0   37 (5) I/O* 0 ATA_BSY line???
6 F 0   38 (6) F* 0 ADC input0 (remote keys) (goes low on headphone insert) T
7 F 0 SDRAMCS2 39 (7) F* 0 in: ADC input1 (internal keys) out: MCLK1
8 F 0 A[25] 40 (8) F 0 /OE
9 I 0 Battery fault (low) (TLC1733 /FAULT) 41 (9) F* 0 in: remote key PLAY out: Audio Serial Data
10 F 0 SCLK (SDRAM clock output) 42 (10) F* 0 in: USB connect (active low) T out: MCLK2 (delivered to WM8750)
11 F 0 CS3 43 (11) F 0 Unassigned
12 F 0 /SWE 44 (12) F 0 Audio Word Clock
13 F 0 IDE-DIOR 45 (13) F 0 LRCK3
14 F 0 IDE-DIOW 46 (14) I 0 Wall Charger connect (active low) (LTC1733 /ACPR) T
15 O 1 configures charging current limit (low = 100 mA, high = ?) 47 (15) F 0 Unassigned
16 F 0 IDE-IORDY 48 (16) F 0 Audio Serial Bit Clock
17 F 0 BUFENB2 49 (17) O 1 FM power (low=ON)
18 F 0 CFLAG 50 (18) O 1 IDE power (low = ON) When on power consumption is increased by more than 100mA!
9 O 1 ATA Reset line 51 (19) F 0 RCK (subcode clock)
20 F 0 TA 52 (20) F 0 SFSY
21 F 0 QSPICS2 53 (21) O 1 set high on startup, set low on shutdown
22 O 1

USB related - 0 - enter usb-bridge 1 - leave usb-bridge

this is connected through buffer with GL811E? DGND pin ***

54 (22) I 0 goes low on Wall Charger connect T
23 O 0/1 Connected to LTC1733 PROG pin. Pulling this up and then tristate restarts charging cycle 55 (23) F 0 SDA1 second I2C? serial data line
24 F 0 QSPICS1 56 (24) I 0 internal key PLAY (active high) T
25 F 0 SDATAO1 audio data serial out 57 (25) F/O 1 headphone out enable (active high)
26 I 0 ? 58 (26) F 0 /CS1
27 F* 0 TXD0 + RXD0 59 (27) F 0 PST0
28 I/O* 1 in: ADC input2 (battery level) out: backlight** 60 (28) F 0 PST1
29 O 1 ? 61 (29) F 0 PST2
30 I/O* 1

in: Battery charging (high)/Battery full (low) (LTC1733 /CHRG) out: USB related?

out pin is driving transistor which connects GL811E? DVCC to power rail ***

62 (30) F 0 PST3
31 I/O* 1 in: ADC input3 (this pin flips irregulary) T out: low is needed to ATA work properly (set once at startup) 63 (31) F 0 PSTCLK

T means it was tested with simple code injected into test mode (assignment of F/I/O and E comes mostly from this readings also)

"*" indicates that this GPIO or function is actually implemented by two pins on the physical package -- one dedicated input pin and one dedicated output. This means that this logical bit can serve two functions simultaneously. There's only one bit that decides function vs. GPIO, so the composite pin must either both be function pins or a GPI and GPO pin.

Notes: pulling GPO53 low when on battery turns off device immediately (Like hardware reset button).

"**" - Pulling GPO28 low turns off backlight. To turn it on again it is necessary to produce some waveform. Basically it is GPO28 low, delay, n times (GPO28 high, GPO28 low), GPO28 high. I am unable to reproduce this correctly. If I use calls to OF functions toggling GPIO bits it works. Mybe this is some timing issue? The brightness of backlight is related to how many high to low transtions of GPO28 was made. OF firmware uses 20 transitions.Edit: running the same procedure in rockbox bootloader works.

"***" - checked after desoldering MCU and LD245A? buffer from defective HD300 mainboard. Dissasembly reveals that both players share the same code for USB handling

Battery charging

Charging is done by LTC1733 chip. It charges with 100mA current (15k Ohm PROG resistor) and with 6 hours timeout (0.2 uF TIME capacitor). GPIO23 is connected to the LTC1733 PROG pin and is high by default (which puts chip into shutdown mode). Charging cycle starts when GPIO23 is tristated. GPIO15 set charging current limit - low = 100mA, high = (The biggest reading I saw on multimeter was 180mA). End of charging condition is signaled by pulling high GPIO30. Error condition is signaled on GPIO9 pin.

Key reading

5249 ADC is used. Input1 is for internal buttons, and Input0 probably for remote. Below are values taken from dissasembly and crosschecked with "Test mode". The bitflag describes return value of the "read_keys()" subroutine in OF. One can see that flags for internal keys are in low word and for remote are in high word.

ADC1 values internal key bitflag
200-500 REC 0x00000020
550-850 VOL- 0x00000010
900-1200 VOL+ 0x00000008
1250-1550 NEXT 0x00000002
1600-1900 PREV 0x00000004
1950-2250 SELECT 0x00002000

ADC0 values remote key bitflag
230-370 VOL- 0x00100000
480-620 VOL+ 0x00080000
830-970 NEXT 0x00020000
1230-1370 PREV 0x00040000
1930-2070 SELECT 0x80000000
44 HOLD ?

In the same routine GPIO56 high produces flag 0x00000001 and GPIO41 produces flag 0x00010000 which is PLAY signal (main and remote respectively).

battery level reading

ADC2 is related to battery level. In firmware there are some flags assigned based on reading from ADC. ADC is read 20 times, than we take mean value of 10 biggest readings and based on this battery level is determined. In other battery related subroutine moving average filter with 20 readings window and ramping is used. Voltages ware measured by hooking external power supply to the connector instead of the battery. Current draw is 70-80 mA for idle and 120-160 mA when playing music. Backlight contribution is about 20mA.

ADC2 values flag voltage [V]
<2250 low battery <3.70
2250-2280 6 3.70 - 3.75
2280-2330 5 3.75 - 3.85
2330-2450 4 3.85 - 4.05
>2450 3 >4.05
Charger connected 1 -

USB sequence

This GPIO toggling sequence is present in a few subroutines in OF related to USB handling:

Enable USB brdge Disable USB bridge
GPO 50 high GPO22 high
GPO30 low GPO30 high
GPO36 low GPO36 low
delay 10ms GPO22 high
GPO36 high GPO50 high
GPO50 low  
GPO19 high  
GPO22 low  

running code

Today (13.11.2009) i fired up my first few lines of code on this device. This was simple 'Hello world'. I injected assembled code into TEST mode subroutines. I poked around and found out unfortunately that unicode.sys which is loaded on coldstart to 0x30E00000 is not preserved there or is not there yet (at least when entering TEST mode). This leaves only few kB of safe code space in TEST mode subroutines to inject my own code.

Debug port

There is unpopulated ZIF/FPC 20-pin connector between battery connector and headphones connector. It is probably BDM port. Here I will try to document my attempt to find proper wiring:
Pins Function Notes
3,8,17 GND mulitmeter
6, 19 VCCIO multimeter
4 /RESET multimeter - hardware reset switch pulls this line down
12,11,10,9 PST[0:3] osciloscope
16,15,14,13 DDATA[0:3] run program which generate square wave on this pins and look with scope
18 PSTCLK osciloscope
1 /BKPT tested
2 DSCLK tested
5 DSI tested
7 DSO tested
20 TA last one left smile

By trials I mean put CPU in HALT mode and than setup transmission for GO command and change lines until processor leaves HALT mode. In theory this should work.

edit: 13.01.2010 This works :-). I am able to HALT cpu and resume it. This is BIG step forward because this makes messing with bootloader quite safe.

edit: 19.02.2010 I finaly got PCB for tblcf pod. Thanks to the I was able to combine BDM and gdb together. Now I have to gain some more practice with gdb.


  • hd200icon is small and dirty utility to examine HD200ICON?.sys file. It displays graphics stored insied the file (using SDL), prints offset to the stdout and optionaly can save 'screenshot' of hd200 graphic. Fullscreen frames extracted with this utility are collected in
  • binpatch small utility to insert binary inside another binary at specified offset. Now obsoleted by mkmpioboot which automates patching firmware file
  • flash2dram is utility which prints mappings flash<->dram/iram. It is handy in dissasembly to see where particular function from flash is loaded into ram.
I Attachment Action Size Date Who Comment binpatch.c manage 3.6 K 10 Nov 2009 - 23:27 MarcinBukat simple program to insert binary into another binary
dump0.pngpng dump0.png manage 826.3 K 16 Oct 2009 - 09:57 MarcinBukat first 0x7fff fonts rendered from unicode.sys WARRNING this file seems to crash firefox (but renders correctly in GIMP)
dump1.pngpng dump1.png manage 812.0 K 16 Oct 2009 - 09:58 MarcinBukat last 7fff fonts rendered from unicode.sys WARRNING this file seems to crash firefox (but renders correctly in GIMP) flash2dram.c manage 2.2 K 10 Nov 2009 - 23:28 MarcinBukat simple program that prints mapping between flash address and dram address
hd200_icons.zipzip manage 82.3 K 20 Oct 2009 - 14:01 MarcinBukat fullscreen frames found in HD200ICON? hd200icon.c manage 6.3 K 31 Mar 2010 - 07:27 MarcinBukat utility to examine HD200ICON?.sys file
r58 - 10 Nov 2010 - 23:01:50 - MarcinBukat

Copyright by the contributing authors.