Soul Doll Adapter Technical Documentation 0.2
December 18th, 2018
Shonumi aka D.S. Baxter


***************************************************
1. Introduction
*************************************************** 

The Soul Doll Adapter is a GBA accessory for the Legendz franchise, designed to allow data from plastic figurines to transfer over the games. The hardware came bundled with special editions of Legendz: Yomigaeru Shiren no Shima (released July 29th, 2004) and its sequel, Legendz: Sign of Necrom (released February 17th, 2005). The figurines, called "Soul Dollz" contain powerful monsters that players can use in battle. The Soul Dollz are "reborn" in the games, and from there they can level up and transfer that data back to the figurine.


***************************************************
2. General Hardware Information
***************************************************

- Soul Doll Adapter is a small pod that connects to the GBA via a short Link Cable
- The adapter also has a locking mechanism to keep the Soul Doll in place
- Presumably compatible with all Soul Dollz manufactured*
- Each Soul Doll is a small plastic figurine with a built-in IC at the bottom
- Each Soul Doll uses a 24LC08 serial EEPROM controller, stores 1KB of data

* Ones made after Yomigaeru Shiren no Shima was released may not be "recognized" in that game. If the data sent to the adapter is correct but the Soul Doll is not in the game's internal database, it is categorized as "unknown". 

 
***************************************************
3. Communication Protocol - Start Signal
***************************************************

The GBA and the Soul Doll Adapter communicate via the serial port using General Purpose Mode. The protocol is essentially bit-banging. For most of the protocol, the GBA sets both SC and SI high. To begin any communications with the Soul Doll Adapter, the GBA writes to following "device start signal" to RCNT:

Device Start Signal
--------------------
0x8020
0x8025
--------------------

The device start signal basically takes the Soul Doll Adapter out of standby-mode. The Soul Doll Adapter then accepts read or write commands to the EEPROM controller inside the Soul Dollz. When sending any commands or performing write operations, the start signal is always identified with Bit 7 of RCNT set to 0. When receiving data from commands through read operations, the start signal is always identified with Bit 7 of RCNT set to 1. For example, the least significant byte of RCNT may be the following for the start signals:

Start signal when issuing commands or performing writes:
--------------------
0x25 0x27 0x27 0x25
--------------------

Start signal when receiving data through read operations:
--------------------
0xA5 0xA7 0xA7 0xA5
--------------------

These signals determine when one command ends and another begins or when data is read or written.


***************************************************
4. Communication Protocol - Read Operations
***************************************************

The 24LC08 allows for random access at any given address. To do so, the EEPROM controller must receive the following 3 pieces of information:

1) Start Signal + Slave Address + Dummy Write Command
2) Start Signal + Word Address
3) Start Signal + Slave Address + Read Command

The slave address is 1 byte, with the Bits 4-7 being the device identifier (in the case of the 24LC08, this is 0b1010). Bits 1-3 are the device address. They effectively form the two MSBs of the final address (Bit 3 is ignored on the 24LC08, only use Bits 1-2). Bit 0 is the command; 0 = Write and 1 = Read.

The GBA uses 4 transfers per bits, with Bit 3 of RCNT determining whether the value is a "0" or a "1". A typical slave address sent via the GBA might look like this:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bit 7               | Bit 6               | Bit 5               | Bit 4               | Bit 3               | Bit 2               | Bit 1               | Bit 0
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Device ID - 0b1010                                                                    | Ignored             | 2 MSB of final address                    | EEPROM command     
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Data is received MSB first. The 1st and 4th transfers for each bit are probably irrelevant, however, the 2nd and 3rd transfers contain the actual data for the bit. So:

0xAD {0xAF 0xAF} 0xAD = Bit 3 is HIGH = 1
0xA5 {0xA7 0xA7} 0xA5 = Bit 3 is LOW = 0

The first slave address sent is basically ignored, as if the write command. This, however, prompts the 24LC08 to expect a word address next. The word address is the same format; 4 transfers per bit, with the 2nd and 3rd Bit 3 values determining whether it's a "0" or a "1". The word address forms the lower 8 bits of the final address to read from.

After the word address is sent, a final slave address is sent along with Bit 0 being set to 1 to indicate a read command. This final slave address forms the real two MSBs of the final address. Once this slave address and the read command are sent, EEPROM can be read from by sending a start signal followed by 32 transfers. The EEPROM controller doesn't seem to care what is sent during reading, so long as it's not another start signal. Once a full byte has been read, the internal pointer for the EEPROM address is incremented, and another read can be done simply by sending another start signal followed by 32 more transfers. The data format for reading looks something like this:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bit 7               | Bit 6               | Bit 5               | Bit 4               | Bit 3               | Bit 2               | Bit 1               | Bit 0
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25 | 0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25 | 0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25 | 0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Again, 2nd and 3rd transfers use Bit 3 to determine a "0" or a "1". The above example would be 0b10101010 or 0xAA. Once another command is detected, reading stops. One important thing to note, after sending the final slave address, the *very first* start signal still looks something like:

--------------------
0x25 0x27 0x27 0x25
--------------------

But *after* the 1st byte has been read, the start signal shifts to something like:

--------------------
0xA5 0xA7 0xA7 0xA5
--------------------

It isn't until another command is issued that the start signals swap. Generally, both Isle of Trial and Sign of Nekrom tend to read EEPROM in chunks of 128 bytes of 256 bytes. If the internal pointer for the EEPROM address is incremented past 0x3FF, it rolls over to 0x000. Apparently, when this happens, another device start signal must be issued.


***************************************************
5. Communication Protocol - Write Operations
***************************************************

Writing shares many of the same conventions as reading. The EEPROM controller needs 2 pieces of information:

1) Start Signal + Slave Address + Write Command
2) Start Signal + Word Address

It's exactly like reading, except no secondary slave address is issued, therefore what would normally be the dummy write command is actually acknowledged. Additionally, there is no need to shift to a different start signal; only [0x25 0x27 0x27 0x25] is used. Once the slave address, write command, and word address are sent, data is written using a start signal plus 32 transfers for the byte. Once again, the format of the byte looks something like this:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bit 7               | Bit 6               | Bit 5               | Bit 4               | Bit 3               | Bit 2               | Bit 1               | Bit 0
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Again, 2nd and 3rd transfers use Bit 3 to determine a "0" or a "1". The above example would be 0b10101010 or 0xAA. Unlike reads, which can continue on updating the internal EEPROM address, writes are done in 16-byte pages. Up to 16-bytes can be written sequentially; anymore and the writes loop around. E.g. if writing to 0x100 a page write has a range of 0x100 to 0x10F. Attempting to write a 17th byte will overwrite 0x100 instead of 0x110. In order to write 0x110 to 0x11F, another write slave address, write command, and word address need to be sent to the 24LC08.


***************************************************
6. Soul Doll Data Format
***************************************************

Most of the 1KB data contained on the 24LC08 appears to be related to the Talispod or Talisdam accessories, e.g. such data as the Legend's preferred humidity and tempurature, and their stats. For the games, however, only bytes 0x300 - 0x3FF are relevant. This area of memory specifies the nickname, the owner's name, and various other flags related to auto-training mode. Most importantly, these bytes determine what kind of Legend is generated from the Soul Doll. Byte 0x302 acts as this ID:

0x01 = Windragon (A)?
0x03 = Windragon (B)?
0x04 = Mermaid
0x05 = Werewolf
0x06 = Will 'o' Wisp
0x07 = Tornado Kingdragon
0x08 = Blaze Dragon (A)?
0x09 = Goblin
0x0A = Yeti
0x0B = Hell Hound
0x0C = Volcano Kingdragon
0x0D = Windragon Berserker Mode
0x0E = Blazedragon Berserker Mode
0x0F = Fire Giant
0x10 = Undine
0x11 = Peryton
0x12 = Troll
0x13 = Command Windragon
0x14 = Manticore
0x15 = Carbuncle
0x16 = Command Blazedragon
0x17 = Dwarf
0x18 = Skeleton
0x19 = Earthquake Kingdragon
0x1A = Storm Kingdragon
0x1B = Wyvern
0x1E = Ranshiin (A)?
0x1F = Ranshiin (B)?
0x20 = Chibi Shiron
0x21 = Command Windragon Break Armed
0x22 = Command Blazedragon Volk Armed
0x23 = Chimaera
0x24 = Triton
0x25 = Gargoyle
0x26 = Cloud Giant
0x27 = Command Windragon
0x28 = Command Blazedragon
0x2B = Spiritual Windragon
0x2C = Hexadragon
0x2D = Windragon Berserker Mode (Growing)?
0x2E = Blazedradon Berserker Mode (Growing)?
0x31 = Devour Crocodile (Dandy)
0x32 = Harpy
0x33 = Cait Sith
0x34 = Command Blazedragon Volk Armed
0x35 = Devour Crocodile
0x36 = Vampire
0x37 = Spiritual Kingdragon
0x38 = Ogre
0x39 = Spriggan
0x3A = Command Windragon Break Armed
0x3B = Bicorn
0x3C = Centaur
0x3D = Nekrom Kingdragon
0x3E = Golem
0x3F = Ifrit
0x41 = Gorgon
0x42 = Kraken
0x43 = Minotauros
0x44 = Oberon
0x45 = Lich
0x48 = Colonel Windragon Tornado Soul
0x49 = Pheonix
0x4A = Behemoth
0x4B = Jabberwock
0x4C = Leviathan
0x4D = Fenrir
0x4E = Colonel Blazedragon Volcano Soul
0x4F = Sphinx
0x50 = Cyclops
0x54 = Syclla
0x55 = Titan
0x56 = Echidna
0x59 = Ranshiin (B)?
0x5A = Chibi Shiron (Manga Version)?
0x5B = Blazedragon (B)?
0x5C = Windragon (Manga Version)
0x5D = Griffin
0x5E = Bigfoot
0x5F = Tiamat
0x66 = Wyvern
0x67 = Storm Kingdragon
0x68 = Carbuncle
0x6D = Giant Crab
0x71 = Hydra
0x72 = Iron Golem
0x73 = Valkyrie
0x74 = Cerberus

Several IDs appear to be mapped to the same Legend. This may be explained by the fact that some Soul Dollz were released in A, B, and sometimes C variants. The plastic figurine is different, but the GBA games generate the same sprite and default name for the Soul Doll. All of the potential duplicates are marked with "?" in the list above. Although there are 103 Soul Dollz, the list remains incomplete. The gaps between entries do not generate valid Legendz, which suggests other bytes in EEPROM are also responsible for the ID.