<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.3dbrew.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=D0k3</id>
	<title>3dbrew - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.3dbrew.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=D0k3"/>
	<link rel="alternate" type="text/html" href="https://www.3dbrew.org/wiki/Special:Contributions/D0k3"/>
	<updated>2026-04-03T18:59:03Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Serials&amp;diff=20623</id>
		<title>Serials</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Serials&amp;diff=20623"/>
		<updated>2018-02-28T14:27:49Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* Physical Serial */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page talks about the 3DS products&#039; serial number and model number structures (the console, manual, accessories, games, etc...).&lt;br /&gt;
&lt;br /&gt;
== Console Serial Numbers ==&lt;br /&gt;
&lt;br /&gt;
A 3DS console serial number is composed of at least two letters followed by nine decimal digits.  The ninth digit is a &amp;quot;check digit&amp;quot;, meaning that it is derived from the other digits.&lt;br /&gt;
&lt;br /&gt;
The check digit is an industry-standard algorithm, the one used for UPC codes.  To calculate the check digit of a 3DS console, separate the non-check digits into &amp;quot;odd&amp;quot; and &amp;quot;even&amp;quot; groups, where the &amp;quot;odd&amp;quot; group is digits in odd-numbered positions, and the &amp;quot;even&amp;quot; group is digits in even-numbered positions.  (The first digit is &amp;quot;odd&amp;quot;, with &amp;quot;first&amp;quot; representing &amp;quot;1&amp;quot;.)&lt;br /&gt;
&lt;br /&gt;
After separating the digits, add the digits in each group together.  Multiply the sum of the even digits by 3, then add the sum of the odd digits. To calculate the check digit, take this value modulo 10, and if not 0, subtract from 10.&lt;br /&gt;
&lt;br /&gt;
Example: CW404567772&lt;br /&gt;
&lt;br /&gt;
The non-check digits are 40456777.  Separating into odd and even groups, we get the following:&lt;br /&gt;
&lt;br /&gt;
Odds: 4 + 4 + 6 + 7 = 21&lt;br /&gt;
Evens: 0 + 5 + 7 + 7 = 19&lt;br /&gt;
&lt;br /&gt;
Applying the algorithm, we get ((3 * 19) + 21) % 10 = 8, which is not 0, thus 10 - 8 = 2, matching the example&#039;s check digit.&lt;br /&gt;
&lt;br /&gt;
The letter prefixes are a letter specifying the device, followed by one letter specifying the region in which it was sold.  In some regions, a third letter is present; a current guess is that this letter distinguishes among factories for a given sales region.  Note that several different sales regions&#039; console may be considered to be the same region for region-locking purposes, such as Europe and Australia.&lt;br /&gt;
&lt;br /&gt;
The current serial number scheme began with the DSi, hence its listing in the tables below.  Among standalone consoles, the Wii U belongs to this scheme as well; the Switch started a new scheme.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Model !! Device Prefix (Retail) !! Device Prefix (Dev/Test)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi&#039;&#039; || T || V&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi XL/LL&#039;&#039; || W || &#039;&#039;unknown&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Wii U&#039;&#039; || F || &#039;&#039;unknown&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 3DS || C || E&lt;br /&gt;
|-&lt;br /&gt;
| 3DS XL/LL || S || R&lt;br /&gt;
|-&lt;br /&gt;
| 2DS || A || P&lt;br /&gt;
|-&lt;br /&gt;
| New 3DS || Y || Y&lt;br /&gt;
|-&lt;br /&gt;
| New 3DS XL/LL || Q || Q&lt;br /&gt;
|-&lt;br /&gt;
| New 2DS XL/LL || N || N&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Test (&amp;quot;Panda&amp;quot;) units with the same prefix as retail can be distinguished by test units having 00 or 01 as the first two digits of the serial number portion.  00 was used with the New 3DS and New 3DS XL for test units; 01 was used with the New 2DS XL test unit.  Preview versions of the N2DS XL given out to the press had 01; these appear to have been test units with the development titles deleted.&lt;br /&gt;
&lt;br /&gt;
Old 3DS development systems (Partner-CTR, IS-CTR-BOX, IS-SPR-BOX) use the &amp;quot;E&amp;quot; and &amp;quot;R&amp;quot; prefixes like test systems, but have 90 (Partner-CTR) or 91 (IS-CTR-BOX, IS-SPR-BOX) as their first two digits.  Similarly, the main New 3DS development unit, IS-SNAKE-BOX, uses the Y prefix (same as retail) with 91.  It is currently unknown what is the serial number format of the rare New 3DS XL development system (IS-CLOSER-BOX).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sales Region !! Region Lock !! Region Suffix&lt;br /&gt;
|-&lt;br /&gt;
| Japan || Japan || JF, JH, JM&lt;br /&gt;
|-&lt;br /&gt;
| North America || North America || W&lt;br /&gt;
|-&lt;br /&gt;
| Middle East / Southeast Asia || North America || S&lt;br /&gt;
|-&lt;br /&gt;
| Europe || Europe || EF, EH, EM&lt;br /&gt;
|-&lt;br /&gt;
| Australia || Europe || AH, AG&lt;br /&gt;
|-&lt;br /&gt;
| South Korea || Korea || KF, KH, KM&lt;br /&gt;
|-&lt;br /&gt;
| China (iQue) || China || CF, CH, CM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Console Models ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Device !! Product Code&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DS&#039;&#039; || NTR&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DS lite&#039;&#039; || USG&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi&#039;&#039; || TWL&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi XL/LL&#039;&#039; || UTL&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Wii U&#039;&#039; || WUP&lt;br /&gt;
|-&lt;br /&gt;
| 3DS || CTR&lt;br /&gt;
|-&lt;br /&gt;
| 3DS XL/LL || SPR&lt;br /&gt;
|-&lt;br /&gt;
| 2DS || FTR&lt;br /&gt;
|-&lt;br /&gt;
| [[New 3DS]] || KTR&lt;br /&gt;
|-&lt;br /&gt;
| [[New 3DS]] XL/LL || RED&lt;br /&gt;
|-&lt;br /&gt;
| New 2DS XL/LL || JAN&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DS had the product code NTR (short for Nitro), so we see the TR is recurring.&lt;br /&gt;
&lt;br /&gt;
== Title ID and Unique ID ==&lt;br /&gt;
&#039;&#039;see [[Titles]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== NCCH Product Code ==&lt;br /&gt;
&lt;br /&gt;
This serial is similiar to the &amp;quot;physical serial&amp;quot; described later in this page; it is the canonical identifier for a specific title in the field of business formalities with Nintendo, but this is not reflected in the 3DS&#039;s software architecture (where it is vastly unused in favor of the Title ID: it is therefore considered the successor of the &amp;quot;internal name&amp;quot; contained in ROMs of previous handhelds), is not guaranteed to be unique.&lt;br /&gt;
&lt;br /&gt;
The product code is located in a [[NCCH]]&#039;s header (not its ExHeader).&lt;br /&gt;
&lt;br /&gt;
The product code &amp;quot;CTR-P-CTAP&amp;quot; is the default generic product code for NCCH files. Most [[NCSD|NCCHs apart from the first one]] in a title are generally CTR-P-CTAP.&lt;br /&gt;
Referring to &amp;quot;the product code of a title&amp;quot; is therefore a simplification for &amp;quot;the product code of the NCCH in its first partition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
So, for example, a Japanese copy of Ridge Racer 3D would have a product code of &amp;quot;CTR-P-ARRJ&amp;quot; and a serial of &amp;quot;LNA-CTR-ARRJ-JPN&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A Nintendo-assigned product code follows this format, however, there is no requirement for a product code to match or resemble this structure as long as it&#039;s within the length limit:&lt;br /&gt;
&lt;br /&gt;
[CTR/KTR]-[Category letter]-[Type][Identifier][Region]-[Sub ID]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Category letter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| P || Cartridge software, or downloadable versions of them.&lt;br /&gt;
|-&lt;br /&gt;
| N || Digital-only releases, including [[Title list|system applications and applets]].&lt;br /&gt;
|-&lt;br /&gt;
| M || [[DLC]]&lt;br /&gt;
|-&lt;br /&gt;
| T || [[eShop Demos]], excluding so-called &amp;quot;special demos&amp;quot; which are category N.&lt;br /&gt;
|-&lt;br /&gt;
| U || [[Title list#0004000E - Add-on Content (Updates)|Patches]] for category P titles.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;sub ID&amp;quot; only applies to DLC, demos, and local copies of Download Play titles. It&#039;s a 2-digit number associated with the [[Title list|Title ID Variation]].&lt;br /&gt;
&lt;br /&gt;
See the next chapter for explanation of the other components of the Product Code.&lt;br /&gt;
&lt;br /&gt;
== Physical Serial ==&lt;br /&gt;
&lt;br /&gt;
[Product][Retail/Demo]-CTR-[Type][Identifier][Region]-[Label Region]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Length !! Description !! colspan=2 | Values&lt;br /&gt;
|-&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Product&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | 2&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Product type&lt;br /&gt;
|-&lt;br /&gt;
| LN || Cartridge&lt;br /&gt;
|-&lt;br /&gt;
| MA || Instruction manual&lt;br /&gt;
|-&lt;br /&gt;
| TS || Game box&lt;br /&gt;
|-&lt;br /&gt;
| FA || Leaflet&lt;br /&gt;
|-&lt;br /&gt;
| MK || Quick-start Guide&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Retail/Demo&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | 1 &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| A || Retail&lt;br /&gt;
|-&lt;br /&gt;
| Z || Demo&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | CTR/KTR&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | 3&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Platform&lt;br /&gt;
|-&lt;br /&gt;
| CTR || 3DS&lt;br /&gt;
|-&lt;br /&gt;
| KTR || New 3DS&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;11&amp;quot; | Type&lt;br /&gt;
| rowspan=&amp;quot;11&amp;quot; | 1&lt;br /&gt;
| rowspan=&amp;quot;11&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| A || retail&lt;br /&gt;
|-&lt;br /&gt;
| B || retail&lt;br /&gt;
|-&lt;br /&gt;
| C || used for N3DS exclusive retail and default &#039;CTAP&#039;&lt;br /&gt;
|-&lt;br /&gt;
| E || used for card 2 type retail cartridges&lt;br /&gt;
|-&lt;br /&gt;
| H || used for built in applications like [[Mii Maker]]&lt;br /&gt;
|-&lt;br /&gt;
| J || normal eShop Title&lt;br /&gt;
|-&lt;br /&gt;
| K || unknown, seen in Mighty Gunvolt&lt;br /&gt;
|-&lt;br /&gt;
| S || usually a 3D Classics eShop title&lt;br /&gt;
|-&lt;br /&gt;
| P || used with GBA eShop titles&lt;br /&gt;
|-&lt;br /&gt;
| T || used with NES eShop titles&lt;br /&gt;
|-align=center&lt;br /&gt;
| Identifier&lt;br /&gt;
| 2&lt;br /&gt;
| colspan=3 |Game name (two alphanumeric characters)&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Region&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | 1&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| E || English (US)&lt;br /&gt;
|-&lt;br /&gt;
| P || PAL (Europe/Australia)&lt;br /&gt;
|-&lt;br /&gt;
| J || Japanese (Japan)&lt;br /&gt;
|-&lt;br /&gt;
| K || Korean (Korea)&lt;br /&gt;
|-&lt;br /&gt;
| C || Chinese (China/Taiwan)&lt;br /&gt;
|-&lt;br /&gt;
| Y || Multiple regions&lt;br /&gt;
|-&lt;br /&gt;
| W || Tai&#039;&#039;&#039;w&#039;&#039;&#039;an(?) (Taiwan/Hong Kong)&lt;br /&gt;
|-&lt;br /&gt;
| Z || Multiple regions&lt;br /&gt;
|-&lt;br /&gt;
| A || All (region-free)&lt;br /&gt;
|-&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Label Region&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | 3&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| USA || United States&lt;br /&gt;
|-&lt;br /&gt;
| EUR || Europe&lt;br /&gt;
|-&lt;br /&gt;
| CAN || Canada&lt;br /&gt;
|-&lt;br /&gt;
| AUS || Australia&lt;br /&gt;
|-&lt;br /&gt;
| JPN || Japan&lt;br /&gt;
|-&lt;br /&gt;
| KOR || Korea&lt;br /&gt;
|-&lt;br /&gt;
| TWN || Taiwan/Hong Kong&lt;br /&gt;
|-&lt;br /&gt;
| CHT || Taiwan/Hong Kong (&amp;quot;Chinese-Traditional&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| CHN || China&lt;br /&gt;
|-&lt;br /&gt;
| UKV || United Kingdom (&amp;quot;United Kingdom version&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| MDE || Saudi Arabia/U.A.E./Malaysia/Singapore (&amp;quot;Middle East&amp;quot;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Electronic Manuals ===&lt;br /&gt;
&lt;br /&gt;
Some eShop titles have [[NCCH#CFA|Electronic Manuals]] which store the product code at the end of the &#039;Health &amp;amp; Safety&#039; section of the manual. However,   product codes can differ from the above format as shown below:&lt;br /&gt;
&lt;br /&gt;
CTR-[P/N/T/U]-[Type][Identifier][Region]-[Region]-[Digit]&lt;br /&gt;
&lt;br /&gt;
CTR-[Type][Identifier][Region]-[Region]-[Digit]&lt;br /&gt;
&lt;br /&gt;
* P/N/T/U - Same as in product code structure&lt;br /&gt;
* [Type][Identifier][Region] - Same as in serial structure&lt;br /&gt;
* [Region] - A three character representation of the title region, i.e. &#039;EUR&#039; (not always present)&lt;br /&gt;
* [Digit] - A single digit usually &#039;1&#039; or &#039;0&#039; (not always present). Possibly revision or manual revision.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These alternate versions of the product code, potentially found in [[NCCH#CFA|Electronic Manuals]] don&#039;t represent the actual product code, as found in the game&#039;s CXI. They are only found in the game&#039;s Home Menu manual, and on the game&#039;s packaging and external labeling.&lt;br /&gt;
&lt;br /&gt;
==Back of Card Serial==&lt;br /&gt;
AREPY10111 (example)&lt;br /&gt;
&lt;br /&gt;
AAAABCDEEE (presumably)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;A&#039;&#039;&#039; - Identifier (last 4 digits of product code)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;B&#039;&#039;&#039; - Production Month (X,Y,Z -&amp;gt; Oct,Nov,Dec)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;C&#039;&#039;&#039; - Production Year (2010 + C)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;D&#039;&#039;&#039; - Revision&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;E&#039;&#039;&#039; - Production Run? (000-999)&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Serials&amp;diff=20622</id>
		<title>Serials</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Serials&amp;diff=20622"/>
		<updated>2018-02-28T14:24:19Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* Physical Serial */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page talks about the 3DS products&#039; serial number and model number structures (the console, manual, accessories, games, etc...).&lt;br /&gt;
&lt;br /&gt;
== Console Serial Numbers ==&lt;br /&gt;
&lt;br /&gt;
A 3DS console serial number is composed of at least two letters followed by nine decimal digits.  The ninth digit is a &amp;quot;check digit&amp;quot;, meaning that it is derived from the other digits.&lt;br /&gt;
&lt;br /&gt;
The check digit is an industry-standard algorithm, the one used for UPC codes.  To calculate the check digit of a 3DS console, separate the non-check digits into &amp;quot;odd&amp;quot; and &amp;quot;even&amp;quot; groups, where the &amp;quot;odd&amp;quot; group is digits in odd-numbered positions, and the &amp;quot;even&amp;quot; group is digits in even-numbered positions.  (The first digit is &amp;quot;odd&amp;quot;, with &amp;quot;first&amp;quot; representing &amp;quot;1&amp;quot;.)&lt;br /&gt;
&lt;br /&gt;
After separating the digits, add the digits in each group together.  Multiply the sum of the even digits by 3, then add the sum of the odd digits. To calculate the check digit, take this value modulo 10, and if not 0, subtract from 10.&lt;br /&gt;
&lt;br /&gt;
Example: CW404567772&lt;br /&gt;
&lt;br /&gt;
The non-check digits are 40456777.  Separating into odd and even groups, we get the following:&lt;br /&gt;
&lt;br /&gt;
Odds: 4 + 4 + 6 + 7 = 21&lt;br /&gt;
Evens: 0 + 5 + 7 + 7 = 19&lt;br /&gt;
&lt;br /&gt;
Applying the algorithm, we get ((3 * 19) + 21) % 10 = 8, which is not 0, thus 10 - 8 = 2, matching the example&#039;s check digit.&lt;br /&gt;
&lt;br /&gt;
The letter prefixes are a letter specifying the device, followed by one letter specifying the region in which it was sold.  In some regions, a third letter is present; a current guess is that this letter distinguishes among factories for a given sales region.  Note that several different sales regions&#039; console may be considered to be the same region for region-locking purposes, such as Europe and Australia.&lt;br /&gt;
&lt;br /&gt;
The current serial number scheme began with the DSi, hence its listing in the tables below.  Among standalone consoles, the Wii U belongs to this scheme as well; the Switch started a new scheme.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Model !! Device Prefix (Retail) !! Device Prefix (Dev/Test)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi&#039;&#039; || T || V&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi XL/LL&#039;&#039; || W || &#039;&#039;unknown&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Wii U&#039;&#039; || F || &#039;&#039;unknown&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 3DS || C || E&lt;br /&gt;
|-&lt;br /&gt;
| 3DS XL/LL || S || R&lt;br /&gt;
|-&lt;br /&gt;
| 2DS || A || P&lt;br /&gt;
|-&lt;br /&gt;
| New 3DS || Y || Y&lt;br /&gt;
|-&lt;br /&gt;
| New 3DS XL/LL || Q || Q&lt;br /&gt;
|-&lt;br /&gt;
| New 2DS XL/LL || N || N&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Test (&amp;quot;Panda&amp;quot;) units with the same prefix as retail can be distinguished by test units having 00 or 01 as the first two digits of the serial number portion.  00 was used with the New 3DS and New 3DS XL for test units; 01 was used with the New 2DS XL test unit.  Preview versions of the N2DS XL given out to the press had 01; these appear to have been test units with the development titles deleted.&lt;br /&gt;
&lt;br /&gt;
Old 3DS development systems (Partner-CTR, IS-CTR-BOX, IS-SPR-BOX) use the &amp;quot;E&amp;quot; and &amp;quot;R&amp;quot; prefixes like test systems, but have 90 (Partner-CTR) or 91 (IS-CTR-BOX, IS-SPR-BOX) as their first two digits.  Similarly, the main New 3DS development unit, IS-SNAKE-BOX, uses the Y prefix (same as retail) with 91.  It is currently unknown what is the serial number format of the rare New 3DS XL development system (IS-CLOSER-BOX).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sales Region !! Region Lock !! Region Suffix&lt;br /&gt;
|-&lt;br /&gt;
| Japan || Japan || JF, JH, JM&lt;br /&gt;
|-&lt;br /&gt;
| North America || North America || W&lt;br /&gt;
|-&lt;br /&gt;
| Middle East / Southeast Asia || North America || S&lt;br /&gt;
|-&lt;br /&gt;
| Europe || Europe || EF, EH, EM&lt;br /&gt;
|-&lt;br /&gt;
| Australia || Europe || AH, AG&lt;br /&gt;
|-&lt;br /&gt;
| South Korea || Korea || KF, KH, KM&lt;br /&gt;
|-&lt;br /&gt;
| China (iQue) || China || CF, CH, CM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Console Models ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Device !! Product Code&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DS&#039;&#039; || NTR&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DS lite&#039;&#039; || USG&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi&#039;&#039; || TWL&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;DSi XL/LL&#039;&#039; || UTL&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;Wii U&#039;&#039; || WUP&lt;br /&gt;
|-&lt;br /&gt;
| 3DS || CTR&lt;br /&gt;
|-&lt;br /&gt;
| 3DS XL/LL || SPR&lt;br /&gt;
|-&lt;br /&gt;
| 2DS || FTR&lt;br /&gt;
|-&lt;br /&gt;
| [[New 3DS]] || KTR&lt;br /&gt;
|-&lt;br /&gt;
| [[New 3DS]] XL/LL || RED&lt;br /&gt;
|-&lt;br /&gt;
| New 2DS XL/LL || JAN&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DS had the product code NTR (short for Nitro), so we see the TR is recurring.&lt;br /&gt;
&lt;br /&gt;
== Title ID and Unique ID ==&lt;br /&gt;
&#039;&#039;see [[Titles]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== NCCH Product Code ==&lt;br /&gt;
&lt;br /&gt;
This serial is similiar to the &amp;quot;physical serial&amp;quot; described later in this page; it is the canonical identifier for a specific title in the field of business formalities with Nintendo, but this is not reflected in the 3DS&#039;s software architecture (where it is vastly unused in favor of the Title ID: it is therefore considered the successor of the &amp;quot;internal name&amp;quot; contained in ROMs of previous handhelds), is not guaranteed to be unique.&lt;br /&gt;
&lt;br /&gt;
The product code is located in a [[NCCH]]&#039;s header (not its ExHeader).&lt;br /&gt;
&lt;br /&gt;
The product code &amp;quot;CTR-P-CTAP&amp;quot; is the default generic product code for NCCH files. Most [[NCSD|NCCHs apart from the first one]] in a title are generally CTR-P-CTAP.&lt;br /&gt;
Referring to &amp;quot;the product code of a title&amp;quot; is therefore a simplification for &amp;quot;the product code of the NCCH in its first partition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
So, for example, a Japanese copy of Ridge Racer 3D would have a product code of &amp;quot;CTR-P-ARRJ&amp;quot; and a serial of &amp;quot;LNA-CTR-ARRJ-JPN&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A Nintendo-assigned product code follows this format, however, there is no requirement for a product code to match or resemble this structure as long as it&#039;s within the length limit:&lt;br /&gt;
&lt;br /&gt;
[CTR/KTR]-[Category letter]-[Type][Identifier][Region]-[Sub ID]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Category letter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| P || Cartridge software, or downloadable versions of them.&lt;br /&gt;
|-&lt;br /&gt;
| N || Digital-only releases, including [[Title list|system applications and applets]].&lt;br /&gt;
|-&lt;br /&gt;
| M || [[DLC]]&lt;br /&gt;
|-&lt;br /&gt;
| T || [[eShop Demos]], excluding so-called &amp;quot;special demos&amp;quot; which are category N.&lt;br /&gt;
|-&lt;br /&gt;
| U || [[Title list#0004000E - Add-on Content (Updates)|Patches]] for category P titles.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;sub ID&amp;quot; only applies to DLC, demos, and local copies of Download Play titles. It&#039;s a 2-digit number associated with the [[Title list|Title ID Variation]].&lt;br /&gt;
&lt;br /&gt;
See the next chapter for explanation of the other components of the Product Code.&lt;br /&gt;
&lt;br /&gt;
== Physical Serial ==&lt;br /&gt;
&lt;br /&gt;
[Product][Retail/Demo]-CTR-[Type][Identifier][Region]-[Label Region]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Length !! Description !! colspan=2 | Values&lt;br /&gt;
|-&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Product&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | 2&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Product type&lt;br /&gt;
|-&lt;br /&gt;
| LN || Cartridge&lt;br /&gt;
|-&lt;br /&gt;
| MA || Instruction manual&lt;br /&gt;
|-&lt;br /&gt;
| TS || Game box&lt;br /&gt;
|-&lt;br /&gt;
| FA || Leaflet&lt;br /&gt;
|-&lt;br /&gt;
| MK || Quick-start Guide&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Retail/Demo&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | 1 &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| A || Retail&lt;br /&gt;
|-&lt;br /&gt;
| Z || Demo&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | CTR/KTR&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | 3&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Platform&lt;br /&gt;
|-&lt;br /&gt;
| CTR || 3DS&lt;br /&gt;
|-&lt;br /&gt;
| KTR || New 3DS&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;11&amp;quot; | Type&lt;br /&gt;
| rowspan=&amp;quot;11&amp;quot; | 1&lt;br /&gt;
| rowspan=&amp;quot;11&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| A || retail&lt;br /&gt;
|-&lt;br /&gt;
| B || retail&lt;br /&gt;
|-&lt;br /&gt;
| C || part of the default serial &#039;CTAP&#039;, also used for N3DS exclusive retail&lt;br /&gt;
|-&lt;br /&gt;
| E || typically used for card 2 type retail cartridges&lt;br /&gt;
|-&lt;br /&gt;
| H || used for built in applications like [[Mii Maker]]&lt;br /&gt;
|-&lt;br /&gt;
| J || normal eShop Title&lt;br /&gt;
|-&lt;br /&gt;
| K || unknown, seen in Mighty Gunvolt&lt;br /&gt;
|-&lt;br /&gt;
| S || usually a 3D Classics eShop title&lt;br /&gt;
|-&lt;br /&gt;
| P || used with GBA eShop titles&lt;br /&gt;
|-&lt;br /&gt;
| T || used with NES eShop titles&lt;br /&gt;
|-align=center&lt;br /&gt;
| Identifier&lt;br /&gt;
| 2&lt;br /&gt;
| colspan=3 |Game name (two alphanumeric characters)&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Region&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | 1&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| E || English (US)&lt;br /&gt;
|-&lt;br /&gt;
| P || PAL (Europe/Australia)&lt;br /&gt;
|-&lt;br /&gt;
| J || Japanese (Japan)&lt;br /&gt;
|-&lt;br /&gt;
| K || Korean (Korea)&lt;br /&gt;
|-&lt;br /&gt;
| C || Chinese (China/Taiwan)&lt;br /&gt;
|-&lt;br /&gt;
| Y || Multiple regions&lt;br /&gt;
|-&lt;br /&gt;
| W || Tai&#039;&#039;&#039;w&#039;&#039;&#039;an(?) (Taiwan/Hong Kong)&lt;br /&gt;
|-&lt;br /&gt;
| Z || Multiple regions&lt;br /&gt;
|-&lt;br /&gt;
| A || All (region-free)&lt;br /&gt;
|-&lt;br /&gt;
|-align=center&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | Label Region&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | 3&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| USA || United States&lt;br /&gt;
|-&lt;br /&gt;
| EUR || Europe&lt;br /&gt;
|-&lt;br /&gt;
| CAN || Canada&lt;br /&gt;
|-&lt;br /&gt;
| AUS || Australia&lt;br /&gt;
|-&lt;br /&gt;
| JPN || Japan&lt;br /&gt;
|-&lt;br /&gt;
| KOR || Korea&lt;br /&gt;
|-&lt;br /&gt;
| TWN || Taiwan/Hong Kong&lt;br /&gt;
|-&lt;br /&gt;
| CHT || Taiwan/Hong Kong (&amp;quot;Chinese-Traditional&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| CHN || China&lt;br /&gt;
|-&lt;br /&gt;
| UKV || United Kingdom (&amp;quot;United Kingdom version&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| MDE || Saudi Arabia/U.A.E./Malaysia/Singapore (&amp;quot;Middle East&amp;quot;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Electronic Manuals ===&lt;br /&gt;
&lt;br /&gt;
Some eShop titles have [[NCCH#CFA|Electronic Manuals]] which store the product code at the end of the &#039;Health &amp;amp; Safety&#039; section of the manual. However,   product codes can differ from the above format as shown below:&lt;br /&gt;
&lt;br /&gt;
CTR-[P/N/T/U]-[Type][Identifier][Region]-[Region]-[Digit]&lt;br /&gt;
&lt;br /&gt;
CTR-[Type][Identifier][Region]-[Region]-[Digit]&lt;br /&gt;
&lt;br /&gt;
* P/N/T/U - Same as in product code structure&lt;br /&gt;
* [Type][Identifier][Region] - Same as in serial structure&lt;br /&gt;
* [Region] - A three character representation of the title region, i.e. &#039;EUR&#039; (not always present)&lt;br /&gt;
* [Digit] - A single digit usually &#039;1&#039; or &#039;0&#039; (not always present). Possibly revision or manual revision.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These alternate versions of the product code, potentially found in [[NCCH#CFA|Electronic Manuals]] don&#039;t represent the actual product code, as found in the game&#039;s CXI. They are only found in the game&#039;s Home Menu manual, and on the game&#039;s packaging and external labeling.&lt;br /&gt;
&lt;br /&gt;
==Back of Card Serial==&lt;br /&gt;
AREPY10111 (example)&lt;br /&gt;
&lt;br /&gt;
AAAABCDEEE (presumably)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;A&#039;&#039;&#039; - Identifier (last 4 digits of product code)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;B&#039;&#039;&#039; - Production Month (X,Y,Z -&amp;gt; Oct,Nov,Dec)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;C&#039;&#039;&#039; - Production Year (2010 + C)&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;D&#039;&#039;&#039; - Revision&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;E&#039;&#039;&#039; - Production Run? (000-999)&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Bootloader&amp;diff=20568</id>
		<title>Bootloader</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Bootloader&amp;diff=20568"/>
		<updated>2018-01-16T00:10:53Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* Boot11 image data memory layout */ Fixed a typo again&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The bootloader is the binary code stored in the ARM9 and ARM11 boot ROMs and hence is ran when the 3DS is powered on. It&#039;s purpose is initializing hardware and loading the [[FIRM|system firmware]] from the internal [[Flash_Filesystem|NAND memory]]..&lt;br /&gt;
&lt;br /&gt;
Besides NATIVE_FIRM, the bootloader is also capable of booting other firmwares (such as TWL_FIRM and AGB_FIRM). However, this will result either in a japanese error-screen or a system shutdown, directly after FIRM-Launching.&lt;br /&gt;
&lt;br /&gt;
== Boot ROM ==&lt;br /&gt;
Upon boot, parts of the ARM9 and ARM11 boot ROMs are protected by writing to [[CONFIG#CFG_SYSPROT9|CFG_SYSPROT9]] and [[CONFIG#CFG_SYSPROT11|CFG_SYSPROT11]], respectively. The ARM9 and ARM11 boot ROMs are identical for all 3DS consoles (3DS, 3DS XL, 2DS, New 3DS, New 3DS XL, New 2DS XL)&lt;br /&gt;
&lt;br /&gt;
== NAND FIRM boot ==&lt;br /&gt;
Boot9 is not hard-coded to only handle 2 FIRM partitions: it parses all 8 NCSD partitions for this. Boot9 will attempt to use every partition listed in the NCSD which is an actual FIRM partition, in the same order listed in the NCSD, until booting one of them succeeds. Among the not-yet-processed partitions, the FIRM which has the highest value at u32 firmhdr+4 will have a FIRM-boot attempted first. Since that value is normally 0x0, the order of FIRM-partition processing is normally identical to the order of the NCSD partitions.&lt;br /&gt;
&lt;br /&gt;
Boot9 is hard-coded for using [[AES_Registers|AES]] keyslot 0x6 for NAND crypto.&lt;br /&gt;
&lt;br /&gt;
== Non-NAND FIRM boot ==&lt;br /&gt;
Boot9 can also boot from non-NAND. For this a different set of RSA pubks are used(separate pubks for retail/devunit like NAND). The spiflash FIRM image for this is also encrypted with AES-CBC using a normalkey stored in prot_boot9(separate for retail/devunit). This encryption is basically used instead of what is used for NAND-firm-partitions. This encryption is only used for the FIRM sections, the FIRM header is used raw. The AES keyslot for this is only overwritten afterwards when booting from non-NAND fails. AES keyslot 0x3F is used for this.&lt;br /&gt;
&lt;br /&gt;
  CTR_word[0] = firmimageoffset;//FIRM section offset from FIRM header&lt;br /&gt;
  CTR_word[1] = outbufaddr;//FIRM section load addr&lt;br /&gt;
  CTR_word[2] = readsize;//FIRM section size&lt;br /&gt;
  CTR_word[3] = readsize;//FIRM section size&lt;br /&gt;
&lt;br /&gt;
When booting from NAND fails, boot9 will then attempt to boot from Wifi SPI-flash(this only triggers when the wifi module hw is properly accessible/connected, which is normally the case). The base offset for spiflash FIRM is 0x400. Note that this region(all data prior to offset 0x1F300) is write-protected by the spiflash(not writable from 3DS-mode / DS-mode).&lt;br /&gt;
&lt;br /&gt;
Additionally, if the shell is closed and a special key combination (Start + Select + X) is held, boot9 will attempt to boot from an inserted NTR cartridge before booting from NAND. Note: While normally on O3DS/2DS the console will not turn on if the shell is closed (or this is faked by holding a magnet to the console), when this special key combination is held holding down the power button will cause boot to occur anyway.&lt;br /&gt;
&lt;br /&gt;
For non-NAND booting, NCSD / FIRM-backup is not used.&lt;br /&gt;
&lt;br /&gt;
== SDMMC ==&lt;br /&gt;
&lt;br /&gt;
Boot9 has code implemented for using SD(HC) cards, but the input deviceids used by boot9 for those functions are hard-coded for NAND. However, it is possible to use an SD(HC) card in place of the NAND if the NAND chip is first disconnected, and a SD card connected to the bus. Due to the CID being different, partitions will need to be re-encrypted and TWL mode will not work, due to the MBR being in the NCSD header. Using sighax, it may be possible to replace the NCSD header.&lt;br /&gt;
&lt;br /&gt;
== Boot9 RSA keyslots ==&lt;br /&gt;
&lt;br /&gt;
The following are initialized during main() startup, by initialize_rsakeyslots_pubk(). Each of these, for the ones which are actually set, have different keydata for retail/devunit.&lt;br /&gt;
* 0: Not set.&lt;br /&gt;
* 1: Used for the NAND FIRM signature.&lt;br /&gt;
* 2: Used for the non-NAND-FIRM signature.&lt;br /&gt;
* 3: Used for the NAND-NCSD FIRM signature.&lt;br /&gt;
&lt;br /&gt;
When FIRM loading is successful, initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk() is called, right before calling the final function in main(). Besides ITCM writing, this overwrites all 4 RSA keyslots with modulus + private-exponents loaded from boot9 data.&lt;br /&gt;
&lt;br /&gt;
initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk():&lt;br /&gt;
This initializes the 4 0x100-byte/0x200-byte chunks at 0x07ffb800+0x500(0x07ffbd00)/0x07ffb800+0x900(0x07ffc100). End address of the first section is 0x07ffc100(start addr of the second section), end address of the second section is 0x07ffc900. Hence, the first section total size is 0x400-bytes, while the second section total size is 0x800-bytes.&lt;br /&gt;
&lt;br /&gt;
These are initialized using via the boot9 data image, with ptrs from DTCM. Seperate keydata is used for retail/devunit.&lt;br /&gt;
&lt;br /&gt;
When initializing the first ITCM area: rsa_setkeyslot_privk() is called for all 4 RSA keyslots. The modulo for each one is also copied to (index*0x100) + 0x07ffb800 + 0x500. The private exponent is not copied into ITCM.&lt;br /&gt;
&lt;br /&gt;
The second ITCM area is initialized by copying 4 0x200-byte entries in a loop. These are RSA pubks+privks, which Boot9 doesn&#039;t use itself at all besides this copy loop.&lt;br /&gt;
&lt;br /&gt;
== Boot9 image data memory layout ==&lt;br /&gt;
0xffffb088 is the beginning of the boot9 image data section.&lt;br /&gt;
&lt;br /&gt;
* 0xffffb088 size 0x38-bytes: This is the array used during FIRM-section-loading for the memory-range blacklist for FIRM sections.&lt;br /&gt;
* 0xffffb0c0(end-addr of the above area) size 0x20-bytes: Unknown.&lt;br /&gt;
* 0xffffb0e0(end-addr of the above area) size 0x2f80-bytes: This is *all* of the keys stored in the image.&lt;br /&gt;
* 0xffffe060(end addr of the above key-area) size 0x230-bytes: This is the initial DTCM image @ 0xFFF00000, see below.&lt;br /&gt;
* 0xffffe290(DTCM_image_end) - {boot9 image end}: All-zero.&lt;br /&gt;
&lt;br /&gt;
Layout of the 0x2f80-byte key-area at 0xffffb0e0:&lt;br /&gt;
* 0xffffb0e0 size 0x2600-bytes: This is the RSA key-data, see below.&lt;br /&gt;
* 0xffffd6e0(end-addr of the above area) size 0x40-bytes: This is the keydata used for crypting the entire OTP with keyslot 0x3f, used by main(). The first 0x20-bytes is for retail, the remaining 0x20-bytes starting at 0xffffd700 is for devunit. Chunk+0(retail=0xffffd6e0 devunit=0xffffd700) is the normalkey, chunk+0x10(retail=0xffffd6f0 devunit=0xffffd710) is the AES-IV.&lt;br /&gt;
* ...&lt;br /&gt;
* 0xffffd760: size 0x100-bytes: First 0x80-bytes is for retail, the remaining 0x80-bytes at 0xffffd7e0 is for devunit. This 0x80-byte block is copied to 0x07ffcd00 by a Boot9 function, however that code actually does the copy in two 0x40-bytes chunks.&lt;br /&gt;
* 0xffffd860(end-addr of the above area) size 0x400-bytes: This is the bootrom_dataptr passed to the aes-keyinit function for retail. See the below Tools section for how this is processed.&lt;br /&gt;
* 0xffffdc60(end-addr of the above area) size 0x400-bytes: This is the devunit version of the above the 0x400-byte chunk. This is very last chunk of data in the boot9 data-section key-area: end addr for this area is 0xffffe060.&lt;br /&gt;
&lt;br /&gt;
Layout of the 0x2600-byte RSA key-data at 0xffffb0e0:  &lt;br /&gt;
First 0x1300-bytes is for retail, the remaining 0x1300-bytes starting at 0xffffc3e0 is for devunit.&lt;br /&gt;
* +0x0 retail=0xffffb0e0 devunit=0xffffc3e0: RSA modulo for keyslot3, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x100 retail=0xffffb1e0 devunit=0xffffc4e0: RSA modulo for keyslot1, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x200 retail=0xffffb2e0 devunit=0xffffc5e0: RSA modulo for keyslot2, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x300 size 0x200, retail=0xffffb3e0 devunit=0xffffc6e0: First 0x100-bytes is the RSA modulo, then the following 0x100-bytes is the RSA privk(private-exponent). This is for RSA-engine keyslot0 with initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk(), which also copies this modulo to the array starting at 0x07ffbd00.&lt;br /&gt;
* +0x500 size 0x200, retail=0xffffb5e0 devunit=0xffffc8e0: Used the same as the above block except for slot1.&lt;br /&gt;
* +0x700 size 0x200, retail=0xffffb7e0 devunit=0xffffcae0: Used the same as the above block except for slot2.&lt;br /&gt;
* +0x900 size 0x200, retail=0xffffb9e0 devunit=0xffffcce0: Used the same as the above block except for slot3.&lt;br /&gt;
* +0xb00 size 0x200, retail=0xffffbbe0 devunit=0xffffcee0: First 0x100-bytes is the RSA modulo, then the following 0x100-bytes is the RSA privk(private-exponent). The 0x200-bytes here is copied to slot0 in the array at 0x07ffc100 by initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk().&lt;br /&gt;
* +0xd00 size 0x200, retail=0xffffbde0 devunit=0xffffd0e0: Used the same as the above block except for slot1.&lt;br /&gt;
* +0xf00 size 0x200, retail=0xffffbfe0 devunit=0xffffd2e0: Used the same as the above block except for slot2.&lt;br /&gt;
* +0x1100 size 0x200, retail=0xffffc1e0 devunit=0xffffd4e0: Used the same as the above block except for slot3.&lt;br /&gt;
&lt;br /&gt;
== Boot9 DTCM layout ==&lt;br /&gt;
Most of this is just ptrs / other unknown data, not actual keys. However, there is an unknown 0x10-byte block @ +0x124(there&#039;s a ptr initialized for this block elsewhere).&lt;br /&gt;
&lt;br /&gt;
== Boot11 image data memory layout ==&lt;br /&gt;
* 0x0001817c..0x000181f4 size 0x78-bytes: This is the bootrom error screen font gfx data. This begins at the exact end-address of the crt0 code, the rest of the protected boot11 code begins at this end-address(0x000181f4). To extract the font gfx data from there, the 30 dwords at this address need to be converted to big endian. The correct resolution (when displayed as raw) is 32x30x1. The bootrom font looks very similar to [https://robey.lag.net/2010/01/23/tiny-monospace-font.html this font].&lt;br /&gt;
* 0x00019400 is the beginning of the boot11 data area, the first 8-bytes here are unknown.&lt;br /&gt;
* 0x00019408..0x0001b498 size 0x2090-bytes: This is the blowfish keydata which gets copied to arm9itcm_twlkeydata+0x3e0 later.&lt;br /&gt;
* 0x0001c498..0x0001c4f8 size 0x60-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x380.&lt;br /&gt;
* 0x0001c4f8..0x0001c538 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x340.&lt;br /&gt;
* 0x0001c538..0x0001c578 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x300.&lt;br /&gt;
* 0x0001c578..0x0001c5f8 size 0x80-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x280.&lt;br /&gt;
* 0x0001c5f8..0x0001c678 size 0x80-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x0.&lt;br /&gt;
* 0x0001c678..0x0001c878 size 0x200-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x80.&lt;br /&gt;
* 0x0001c878..0x0001d078 size 0x800-bytes: These are the 3DS RSA-2048 modulus which are eventually copied to arm9_itcm+0x4900: on retail the first 4 are copied there by boot9, on devunit the last 4 are copied to itcm.&lt;br /&gt;
* 0x0001d078 size 0x120-bytes is the initial data for the .data section @ 0x1ffe8000, this is the very end of the protected arm11-bootrom.&lt;br /&gt;
&lt;br /&gt;
== AES keys ==&lt;br /&gt;
See the Tools section for how Boot9 initializes the keyslots.&lt;br /&gt;
&lt;br /&gt;
See also [[AES_Registers|here]].&lt;br /&gt;
&lt;br /&gt;
For an issue with console-unique key-init, see [[OTP_Registers|here]].&lt;br /&gt;
&lt;br /&gt;
== BootROM Errors ==&lt;br /&gt;
Sample error-screen(where firm0+firm1 RSA signatures were corrupted):&lt;br /&gt;
&lt;br /&gt;
  BOOTROM 8046&lt;br /&gt;
  ERRCODE: 00F800FF&lt;br /&gt;
  DEDEFFFF FFFFFFFF&lt;br /&gt;
  00000000 00000000&lt;br /&gt;
&lt;br /&gt;
* 1st line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;BOOTROM %X&amp;quot;, 0x8046);//This last param comes from the .pool.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 2nd line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;ERRCODE:    %08X&amp;quot;, *((unsigned int*)(0x1FFFE000+0xC)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 3rd line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;%08X %08X&amp;quot;, *((unsigned int*)(0x1FFFE000+0x10))`, `*((unsigned int*)(0x1fffe000+0x14)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 4th line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;%08X %08X&amp;quot;,*((unsigned int*)(0x1FFFE000+0x18))`, `*((unsigned int*)(0x1fffe000+0x1C)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 0x1FFFE000 memory ==&lt;br /&gt;
This memory is used by boot9 mainly for sending info to the arm11 for the error-screen. The data in this region is still stored in memory by the time the ARM9+ARM11 jumps to FIRM.&lt;br /&gt;
&lt;br /&gt;
Among boot9/boot11, the 3 words at 0x1FFFE000 seem to be &#039;&#039;only&#039;&#039; accessed by the boot11 function initializing those words.&lt;br /&gt;
&lt;br /&gt;
* u32 0x1FFFE000+0: ARM11 MPCore &amp;quot;Cycle Counter Register (CCNT)&amp;quot;.&lt;br /&gt;
* u32 0x1FFFE000+4: ARM11 MPCore &amp;quot;Count Register 0 (PMN0)&amp;quot;.&lt;br /&gt;
* u32 0x1FFFE000+8: ARM11 MPCore &amp;quot;Count Register 1 (PMN0)&amp;quot;.&lt;br /&gt;
* 8bit-entry-array 0x1FFFE000+0xC: 8bit status-codes initialized by boot9 main(), for the FIRM-boot devices. +0 is NAND, +1 is NTRCARD and +2 is wifi-spiflash.&lt;br /&gt;
* ...&lt;br /&gt;
* 8bit-entry-array 0x1FFFE000+0x10: Status-codes originally from nand_findfirmpartition_loadfirm(), for each of the 8 NCSD partitions.&lt;br /&gt;
&lt;br /&gt;
== BootROM Status Codes ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Value&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| Success&lt;br /&gt;
|-&lt;br /&gt;
| 0xEE(~17)&lt;br /&gt;
| NCSD header validation function failed: NCSD magicnum is invalid or RSA verification failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0xDE(~33)&lt;br /&gt;
| FIRM header validation function failed: FIRM magicnum is invalid or RSA verification failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0xDF(~32)&lt;br /&gt;
| Failed to read sector data from the device.&lt;br /&gt;
|-&lt;br /&gt;
| 0xCF(~48)&lt;br /&gt;
| FIRM section validation function failed: FIRM section is invalid.&lt;br /&gt;
|-&lt;br /&gt;
| 0xF7(~8)&lt;br /&gt;
| A NAND FIRM from another partition was already found with a priority(firmhdr+4) &amp;gt;= to the value for the current partition&#039;s FIRM priority.&lt;br /&gt;
|-&lt;br /&gt;
| 0xF8(~7)&lt;br /&gt;
| The FIRM magicnum(firmhdr+0) is invalid.&lt;br /&gt;
|-&lt;br /&gt;
| 0xFF(~0)&lt;br /&gt;
| Initial value for each entry in the 8-entry array of status-codes for the NAND NCSD partitions. Indicates that the partition is not a FIRM partition(partition fs type isn&#039;t 0x3 or partition fs crypt-type isn&#039;t 0x2).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Boot9 startup ==&lt;br /&gt;
&lt;br /&gt;
0xffff0000 jumps to 0xffff8000. 0xffff8000 is crt0:&lt;br /&gt;
* Very first thing this does is clear u8 register 0x10000002 ([[CONFIG_Registers#CFG_RST11|CFG_RST11]]) bit 0 to zero.&lt;br /&gt;
* Then sp is initialized for each cpumode, IRQs/FIQs are disabled during the first mode-switch.&lt;br /&gt;
* Order of mode-switches + sp initialization: svc-mode = 0xfff04000, irq-mode = 0xfff03f00, system-mode = 0xfff03b00. Hence, the rest of the code following this runs in system-mode.&lt;br /&gt;
* Then L_ffff80cc/mpu_init() is called.&lt;br /&gt;
* Then L_ffff0038() is called, which initializes the exception-handler addresses @ 0x08000000.&lt;br /&gt;
* Then L_ffff81b8() is called(r4 + lr are saved on the DTCM stack), which after calling a memclear function which doesn&#039;t do anything, it then clears 0x08000030 size 0x10. Here the DTCM at 0xfff00000 size 0x4000 is cleared.&lt;br /&gt;
* Then L_ffff81b4() is called, which branches to DTCM_init(). This copies the initial DTCM data from the Boot9 data image into boot9, then it clears 0xFFF00230 - 0xFFF01AC0.&lt;br /&gt;
* Then LT_ffff8228/main is jumped to, with LR set to the address of an infinite-branch-loop instruction.&lt;br /&gt;
&lt;br /&gt;
mpu_init():&lt;br /&gt;
* Bitmask 0x000f9005 is cleared in the cp15 control register. MCR instructions which do then following are then executed: flush entire instruction cache, flush entire data cache, and drain write buffer.&lt;br /&gt;
* Then the 8 [[Memory_layout|MPU]] memregions are initialized.&lt;br /&gt;
* ITCM memregion reg = 0x24: baseaddr=0x0, size = 128MB(0x08000000).&lt;br /&gt;
* DTCM memregion reg = 0xfff0000a: baseaddr=0xfff00000, size=16KB(0x00004000).&lt;br /&gt;
* Then instruction cachable and data cachable/bufferable bits for the MPU regions are setup.&lt;br /&gt;
* Then the instruction/data access permissions for the MPU regions are setup.&lt;br /&gt;
* Lastly bitmask 0x0005707d is orred in the cp15 control register.&lt;br /&gt;
&lt;br /&gt;
== Boot9 main() ==&lt;br /&gt;
&lt;br /&gt;
  The following functions are called: LT_ffff2024(), LT_ffff1ff8(), pxi_init(), rsa_init(), initialize_rsakeyslots_pubk(), crypto_initialize(), and aesengine_reset().&lt;br /&gt;
  Then AES keyslot 0x3F is setup: aesengine_setnormalkey(0x3f, 5, ptr) is called. ptr on retail(CFG_UNITINFO check) is 0xffffd6e0, 0xffffd700 for devunit. Then essentially, aesengine_setctr(5, ptr+0x10) is executed.&lt;br /&gt;
  Then AES keyslot 0x3f is selected.&lt;br /&gt;
  When calling the following functions, if any of them return zero, it will immediately jump to setting ptr to 0x10012000(otp), otherwise when all of them return non-zero ptr = sp+0x94. otp_decrypt(sp+4), otp_verify(sp+4), initialize_consoleunique_itcm(sp+4, 0x07ffb800).&lt;br /&gt;
  Then the following is executed: initialize_aeskeys_wrap(ptr, 0x70);&lt;br /&gt;
  Then sp+4 size 0x100 is cleared to zero.&lt;br /&gt;
  &lt;br /&gt;
  ...&lt;br /&gt;
  &lt;br /&gt;
  NAND firm-boot code-block, is described below. Note that boot9 is basically hard-coded to use deviceid NAND, not SD.&lt;br /&gt;
  {&lt;br /&gt;
  	timer_updatestoredstate() is called, then the AES keyslot for NAND-FIRM is selected(0x6).&lt;br /&gt;
  	Then LT_ffff56c8() is called, if that returns non-zero the statuscode variable is set to ~2 then it jumps to NAND_BOOTEND.&lt;br /&gt;
  	Then LT_ffff5774(0x201) is called, if that returns non-zero the statuscode variable is set to ~1 then it jumps to NAND_BOOTEND.&lt;br /&gt;
  	Then fsdriver_setup_mmc() is called. Then nand_findfirmpartition_loadfirm(0) is called, with the statuscode variable set to the retval.&lt;br /&gt;
  	Executes a loop which runs 8 times: write the output from get_errorcode_arrayentry_xfff005e8(loopindex) to u8 0x1fffe000+0x10+loopindex(copy the array of 32bit error-codes for all 8 NCSD partitions initialized by nand_findfirmpartition_loadfirm() to the array of 8bit entries at 0x1fffe000+0x10).&lt;br /&gt;
  &lt;br /&gt;
  	NAND_BOOTEND:&lt;br /&gt;
  	Then the statuscode variable is written to u8 0x1fffe000+0xc.&lt;br /&gt;
  	Then LT_ffff5690(0x201, 0x1fffe018, 0x1fffe01c) is called.&lt;br /&gt;
  	Then LT_ffff5644() is called.&lt;br /&gt;
  	Then timer_updatestoredstate() is called.&lt;br /&gt;
  	When statuscode==0 for success, it jumps to FIRMLOAD_END. Otherwise, it continues to the next code-block.&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Wifi spi-flash firm-boot code-block, executed when no FIRM was loaded successfully so far.&lt;br /&gt;
  {&lt;br /&gt;
  	timer_updatestoredstate() is called.&lt;br /&gt;
  &lt;br /&gt;
  	Then spi_wififlash_cmdgetstatusreg(sp+0x100) is executed. When bit0 of the output u8 at sp+0x100 is clear, it will continue this code-block, otherwise it will set the statuscode variable to ~1 then jump to SPIFLASH_BOOTEND.&lt;br /&gt;
  	Then fsdriver_setup_wififlash() is called.&lt;br /&gt;
  	Here read_firmhdr_validate_loadfirm(0, 2) is called, with the statuscode variable set to the retval.&lt;br /&gt;
  &lt;br /&gt;
  	SPIFLASH_BOOTEND:&lt;br /&gt;
  	Then the statuscode variable is written to u8 0x1fffe000+0xe.&lt;br /&gt;
  	Then timer_updatestoredstate() is called.&lt;br /&gt;
  	When statuscode==0 for success, it jumps to FIRMLOAD_END. Otherwise, it executes writenormalkey_keyslot3f(), then jumps to FIRMLOAD_FAILURE.&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_END:&lt;br /&gt;
  Here it calls firmhdr_getarm11_entrypoint() and firmhdr_getarm9_entrypoint(). Immediately after calling each function it checks if the retval is 0, if so it then jumps to FIRMLOAD_FAILURE.&lt;br /&gt;
  After calling initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk(), it jumps to FIRMLOAD_EXIT.&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_FAILURE:&lt;br /&gt;
  Here it clears 0x07ffb800 size 0x3c70 to zero, endaddr = 0x07fff470.&lt;br /&gt;
  Then it continues to FIRMLOAD_EXIT.&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_EXIT:&lt;br /&gt;
  Here firmboot() is called, which should never return. The instruction after this bl is a call for panic().&lt;br /&gt;
&lt;br /&gt;
== Boot11 ==&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
main():&lt;br /&gt;
  LT_1263c();&lt;br /&gt;
  ...&lt;br /&gt;
  LT_13944()&lt;br /&gt;
  ...&lt;br /&gt;
  pxi_init();&lt;br /&gt;
  initializefuncptr_firmboot_start(firmbootbegin_funcptr);&lt;br /&gt;
  firmboot();&lt;br /&gt;
  return;&lt;br /&gt;
&lt;br /&gt;
LT_12220/initializefuncptr_firmboot_start&lt;br /&gt;
  inr0=funcptr&lt;br /&gt;
  This writes inr0 to address 0x1ffe8028, then returns.&lt;br /&gt;
  This initializes the funcptr which firmboot() can call after the very first func-call.&lt;br /&gt;
&lt;br /&gt;
LT_13944&lt;br /&gt;
  if([[I2C_Registers|i2cmcu_readregf]](sp+0)==0)&lt;br /&gt;
  {&lt;br /&gt;
  	return (*((u8*)0x10147000) &amp;gt;&amp;gt; 4) &amp;amp; 1;//Reads [[GPIO_Registers|GPIO]] when reading I2C fails.&lt;br /&gt;
  }&lt;br /&gt;
  Here it basically does &amp;quot;return &amp;lt;byte loaded from sp+0&amp;gt; ^ 0x2&amp;quot;. Hence in this case, it will return 0x2 when the system shell is closed(sleep-mode), otherwise 0x0 is returned.&lt;br /&gt;
&lt;br /&gt;
LT_12454/firmboot&lt;br /&gt;
  This is the arm11 version of the boot9 firmboot() function, like boot9 this is the final function called from main(). The functionality for these two functions are identical, minus addresses.&lt;br /&gt;
  ptr = firmboot_loadentrypoint11();&lt;br /&gt;
  funcptr = *(0x1ffe8028);&lt;br /&gt;
  if(funcptr)funcptr(ptr);&lt;br /&gt;
  LT_11ffc(ptr);&lt;br /&gt;
  return;&lt;br /&gt;
&lt;br /&gt;
== Boot Procedure ==&lt;br /&gt;
&lt;br /&gt;
* 0 seconds - unit is powered on. The ARM9 and ARM11 [[Memory_layout|bootroms]] begin execution.&lt;br /&gt;
* &amp;lt;= ~1 second - BootROMs fully run, load FIRM, etc. The loaded FIRM begins running.&lt;br /&gt;
**The ARM11 sysmodules included with FIRM are launched by ARM11-kernel, etc.&lt;br /&gt;
**The [[Process_Manager_Services|PM]] module launches [[NS]].&lt;br /&gt;
**If [[Home_Menu#Auto-Boot_Function|auto-booting]] is needed, NS will [[NS#Auto-boot|auto-boot]] titles.&lt;br /&gt;
**Otherwise, NS will instead launch [[ErrDisp]] and the [[Configuration Memory#ACTIVEMENUTID|current active menu]] via the PM module. For retail units, this menu is usually the [[Home Menu]]. Note that the PM module first launches the module dependencies when launching a process, prior to actually launching the process.&lt;br /&gt;
**The further Home Menu startup process is described [[Home_Menu#Home_Menu_startup|here]]. This includes Home Menu manually launching various sysmodules.&lt;br /&gt;
&lt;br /&gt;
* 4 seconds - the LCD screens are initialized.&lt;br /&gt;
&lt;br /&gt;
* 7 seconds - [[Home Menu]] is fully initialized/loaded.&lt;br /&gt;
&lt;br /&gt;
== NAND Reads during Boot ==&lt;br /&gt;
During a successful boot on 6.x, the bootloader (and firm) reads the following sectors from NAND (in this order):&lt;br /&gt;
 00000000 (NCSD Partition Table)&lt;br /&gt;
 &lt;br /&gt;
 Only verify &#039;FIRM&#039; magic? (A second Header-read will be attempted even if everything except the magic is 0xFF...)&lt;br /&gt;
 0B130000 (FIRM Partition)&lt;br /&gt;
 0B530000 (Secondary FIRM Partition)&lt;br /&gt;
 &lt;br /&gt;
 Verify RSA signature and parse Header:&lt;br /&gt;
 0B130000 (FIRM: Header)&lt;br /&gt;
 0B130200 (FIRM: Section 1)&lt;br /&gt;
 0B163E00 (FIRM: Section 2)&lt;br /&gt;
 0B193E00 (FIRM: Section 3)&lt;br /&gt;
 &lt;br /&gt;
 00013000 .. Below is probably NATIVE_FIRM booting ..&lt;br /&gt;
 00014000&lt;br /&gt;
 00015000&lt;br /&gt;
 00016000&lt;br /&gt;
 00017000&lt;br /&gt;
 &lt;br /&gt;
 09011A00&lt;br /&gt;
 09011C00&lt;br /&gt;
 09012000&lt;br /&gt;
 09012400&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Error Codes ==&lt;br /&gt;
When the 3DS does not find the NAND chip, the following error is displayed:&lt;br /&gt;
&lt;br /&gt;
[[Image:CTR_Bootrom_Error.jpg|240px]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Error&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE 00000000 00000000 00000200 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Error when having SD-card reader connected to NAND during boot.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE 00000000 00000000 00000400 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND not found error (?)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000080 00800000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT1 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000005 00800000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT2 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000005 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT3 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FF F8F8FFFF FFFFFFFF 00000000 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Both the firm0 and firm1 partitions are corrupt (failed signature checks).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800EE FFFFFFFF FFFFFFFF 00000000 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| [[NCSD]] header in sector 0 is corrupt (failed signature check).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [https://github.com/yellows8/boot9_tools boot9_tools]&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Bootloader&amp;diff=20567</id>
		<title>Bootloader</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Bootloader&amp;diff=20567"/>
		<updated>2018-01-16T00:10:15Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* Boot11 image data memory layout */ fixed wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The bootloader is the binary code stored in the ARM9 and ARM11 boot ROMs and hence is ran when the 3DS is powered on. It&#039;s purpose is initializing hardware and loading the [[FIRM|system firmware]] from the internal [[Flash_Filesystem|NAND memory]]..&lt;br /&gt;
&lt;br /&gt;
Besides NATIVE_FIRM, the bootloader is also capable of booting other firmwares (such as TWL_FIRM and AGB_FIRM). However, this will result either in a japanese error-screen or a system shutdown, directly after FIRM-Launching.&lt;br /&gt;
&lt;br /&gt;
== Boot ROM ==&lt;br /&gt;
Upon boot, parts of the ARM9 and ARM11 boot ROMs are protected by writing to [[CONFIG#CFG_SYSPROT9|CFG_SYSPROT9]] and [[CONFIG#CFG_SYSPROT11|CFG_SYSPROT11]], respectively. The ARM9 and ARM11 boot ROMs are identical for all 3DS consoles (3DS, 3DS XL, 2DS, New 3DS, New 3DS XL, New 2DS XL)&lt;br /&gt;
&lt;br /&gt;
== NAND FIRM boot ==&lt;br /&gt;
Boot9 is not hard-coded to only handle 2 FIRM partitions: it parses all 8 NCSD partitions for this. Boot9 will attempt to use every partition listed in the NCSD which is an actual FIRM partition, in the same order listed in the NCSD, until booting one of them succeeds. Among the not-yet-processed partitions, the FIRM which has the highest value at u32 firmhdr+4 will have a FIRM-boot attempted first. Since that value is normally 0x0, the order of FIRM-partition processing is normally identical to the order of the NCSD partitions.&lt;br /&gt;
&lt;br /&gt;
Boot9 is hard-coded for using [[AES_Registers|AES]] keyslot 0x6 for NAND crypto.&lt;br /&gt;
&lt;br /&gt;
== Non-NAND FIRM boot ==&lt;br /&gt;
Boot9 can also boot from non-NAND. For this a different set of RSA pubks are used(separate pubks for retail/devunit like NAND). The spiflash FIRM image for this is also encrypted with AES-CBC using a normalkey stored in prot_boot9(separate for retail/devunit). This encryption is basically used instead of what is used for NAND-firm-partitions. This encryption is only used for the FIRM sections, the FIRM header is used raw. The AES keyslot for this is only overwritten afterwards when booting from non-NAND fails. AES keyslot 0x3F is used for this.&lt;br /&gt;
&lt;br /&gt;
  CTR_word[0] = firmimageoffset;//FIRM section offset from FIRM header&lt;br /&gt;
  CTR_word[1] = outbufaddr;//FIRM section load addr&lt;br /&gt;
  CTR_word[2] = readsize;//FIRM section size&lt;br /&gt;
  CTR_word[3] = readsize;//FIRM section size&lt;br /&gt;
&lt;br /&gt;
When booting from NAND fails, boot9 will then attempt to boot from Wifi SPI-flash(this only triggers when the wifi module hw is properly accessible/connected, which is normally the case). The base offset for spiflash FIRM is 0x400. Note that this region(all data prior to offset 0x1F300) is write-protected by the spiflash(not writable from 3DS-mode / DS-mode).&lt;br /&gt;
&lt;br /&gt;
Additionally, if the shell is closed and a special key combination (Start + Select + X) is held, boot9 will attempt to boot from an inserted NTR cartridge before booting from NAND. Note: While normally on O3DS/2DS the console will not turn on if the shell is closed (or this is faked by holding a magnet to the console), when this special key combination is held holding down the power button will cause boot to occur anyway.&lt;br /&gt;
&lt;br /&gt;
For non-NAND booting, NCSD / FIRM-backup is not used.&lt;br /&gt;
&lt;br /&gt;
== SDMMC ==&lt;br /&gt;
&lt;br /&gt;
Boot9 has code implemented for using SD(HC) cards, but the input deviceids used by boot9 for those functions are hard-coded for NAND. However, it is possible to use an SD(HC) card in place of the NAND if the NAND chip is first disconnected, and a SD card connected to the bus. Due to the CID being different, partitions will need to be re-encrypted and TWL mode will not work, due to the MBR being in the NCSD header. Using sighax, it may be possible to replace the NCSD header.&lt;br /&gt;
&lt;br /&gt;
== Boot9 RSA keyslots ==&lt;br /&gt;
&lt;br /&gt;
The following are initialized during main() startup, by initialize_rsakeyslots_pubk(). Each of these, for the ones which are actually set, have different keydata for retail/devunit.&lt;br /&gt;
* 0: Not set.&lt;br /&gt;
* 1: Used for the NAND FIRM signature.&lt;br /&gt;
* 2: Used for the non-NAND-FIRM signature.&lt;br /&gt;
* 3: Used for the NAND-NCSD FIRM signature.&lt;br /&gt;
&lt;br /&gt;
When FIRM loading is successful, initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk() is called, right before calling the final function in main(). Besides ITCM writing, this overwrites all 4 RSA keyslots with modulus + private-exponents loaded from boot9 data.&lt;br /&gt;
&lt;br /&gt;
initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk():&lt;br /&gt;
This initializes the 4 0x100-byte/0x200-byte chunks at 0x07ffb800+0x500(0x07ffbd00)/0x07ffb800+0x900(0x07ffc100). End address of the first section is 0x07ffc100(start addr of the second section), end address of the second section is 0x07ffc900. Hence, the first section total size is 0x400-bytes, while the second section total size is 0x800-bytes.&lt;br /&gt;
&lt;br /&gt;
These are initialized using via the boot9 data image, with ptrs from DTCM. Seperate keydata is used for retail/devunit.&lt;br /&gt;
&lt;br /&gt;
When initializing the first ITCM area: rsa_setkeyslot_privk() is called for all 4 RSA keyslots. The modulo for each one is also copied to (index*0x100) + 0x07ffb800 + 0x500. The private exponent is not copied into ITCM.&lt;br /&gt;
&lt;br /&gt;
The second ITCM area is initialized by copying 4 0x200-byte entries in a loop. These are RSA pubks+privks, which Boot9 doesn&#039;t use itself at all besides this copy loop.&lt;br /&gt;
&lt;br /&gt;
== Boot9 image data memory layout ==&lt;br /&gt;
0xffffb088 is the beginning of the boot9 image data section.&lt;br /&gt;
&lt;br /&gt;
* 0xffffb088 size 0x38-bytes: This is the array used during FIRM-section-loading for the memory-range blacklist for FIRM sections.&lt;br /&gt;
* 0xffffb0c0(end-addr of the above area) size 0x20-bytes: Unknown.&lt;br /&gt;
* 0xffffb0e0(end-addr of the above area) size 0x2f80-bytes: This is *all* of the keys stored in the image.&lt;br /&gt;
* 0xffffe060(end addr of the above key-area) size 0x230-bytes: This is the initial DTCM image @ 0xFFF00000, see below.&lt;br /&gt;
* 0xffffe290(DTCM_image_end) - {boot9 image end}: All-zero.&lt;br /&gt;
&lt;br /&gt;
Layout of the 0x2f80-byte key-area at 0xffffb0e0:&lt;br /&gt;
* 0xffffb0e0 size 0x2600-bytes: This is the RSA key-data, see below.&lt;br /&gt;
* 0xffffd6e0(end-addr of the above area) size 0x40-bytes: This is the keydata used for crypting the entire OTP with keyslot 0x3f, used by main(). The first 0x20-bytes is for retail, the remaining 0x20-bytes starting at 0xffffd700 is for devunit. Chunk+0(retail=0xffffd6e0 devunit=0xffffd700) is the normalkey, chunk+0x10(retail=0xffffd6f0 devunit=0xffffd710) is the AES-IV.&lt;br /&gt;
* ...&lt;br /&gt;
* 0xffffd760: size 0x100-bytes: First 0x80-bytes is for retail, the remaining 0x80-bytes at 0xffffd7e0 is for devunit. This 0x80-byte block is copied to 0x07ffcd00 by a Boot9 function, however that code actually does the copy in two 0x40-bytes chunks.&lt;br /&gt;
* 0xffffd860(end-addr of the above area) size 0x400-bytes: This is the bootrom_dataptr passed to the aes-keyinit function for retail. See the below Tools section for how this is processed.&lt;br /&gt;
* 0xffffdc60(end-addr of the above area) size 0x400-bytes: This is the devunit version of the above the 0x400-byte chunk. This is very last chunk of data in the boot9 data-section key-area: end addr for this area is 0xffffe060.&lt;br /&gt;
&lt;br /&gt;
Layout of the 0x2600-byte RSA key-data at 0xffffb0e0:  &lt;br /&gt;
First 0x1300-bytes is for retail, the remaining 0x1300-bytes starting at 0xffffc3e0 is for devunit.&lt;br /&gt;
* +0x0 retail=0xffffb0e0 devunit=0xffffc3e0: RSA modulo for keyslot3, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x100 retail=0xffffb1e0 devunit=0xffffc4e0: RSA modulo for keyslot1, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x200 retail=0xffffb2e0 devunit=0xffffc5e0: RSA modulo for keyslot2, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x300 size 0x200, retail=0xffffb3e0 devunit=0xffffc6e0: First 0x100-bytes is the RSA modulo, then the following 0x100-bytes is the RSA privk(private-exponent). This is for RSA-engine keyslot0 with initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk(), which also copies this modulo to the array starting at 0x07ffbd00.&lt;br /&gt;
* +0x500 size 0x200, retail=0xffffb5e0 devunit=0xffffc8e0: Used the same as the above block except for slot1.&lt;br /&gt;
* +0x700 size 0x200, retail=0xffffb7e0 devunit=0xffffcae0: Used the same as the above block except for slot2.&lt;br /&gt;
* +0x900 size 0x200, retail=0xffffb9e0 devunit=0xffffcce0: Used the same as the above block except for slot3.&lt;br /&gt;
* +0xb00 size 0x200, retail=0xffffbbe0 devunit=0xffffcee0: First 0x100-bytes is the RSA modulo, then the following 0x100-bytes is the RSA privk(private-exponent). The 0x200-bytes here is copied to slot0 in the array at 0x07ffc100 by initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk().&lt;br /&gt;
* +0xd00 size 0x200, retail=0xffffbde0 devunit=0xffffd0e0: Used the same as the above block except for slot1.&lt;br /&gt;
* +0xf00 size 0x200, retail=0xffffbfe0 devunit=0xffffd2e0: Used the same as the above block except for slot2.&lt;br /&gt;
* +0x1100 size 0x200, retail=0xffffc1e0 devunit=0xffffd4e0: Used the same as the above block except for slot3.&lt;br /&gt;
&lt;br /&gt;
== Boot9 DTCM layout ==&lt;br /&gt;
Most of this is just ptrs / other unknown data, not actual keys. However, there is an unknown 0x10-byte block @ +0x124(there&#039;s a ptr initialized for this block elsewhere).&lt;br /&gt;
&lt;br /&gt;
== Boot11 image data memory layout ==&lt;br /&gt;
* 0x0001817c..0x000181f4 size 0x78-bytes: This is to be the bootrom error screen font gfx data. This begins at the exact end-address of the crt0 code, the rest of the protected boot11 code begins at this end-address(0x000181f4). To extract the font gfx data from there, the 30 dwords at this address need to be converted to big endian. The correct resolution (when displayed as raw) is 32x30x1. The bootrom font looks very similar to [https://robey.lag.net/2010/01/23/tiny-monospace-font.html this font].&lt;br /&gt;
* 0x00019400 is the beginning of the boot11 data area, the first 8-bytes here are unknown.&lt;br /&gt;
* 0x00019408..0x0001b498 size 0x2090-bytes: This is the blowfish keydata which gets copied to arm9itcm_twlkeydata+0x3e0 later.&lt;br /&gt;
* 0x0001c498..0x0001c4f8 size 0x60-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x380.&lt;br /&gt;
* 0x0001c4f8..0x0001c538 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x340.&lt;br /&gt;
* 0x0001c538..0x0001c578 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x300.&lt;br /&gt;
* 0x0001c578..0x0001c5f8 size 0x80-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x280.&lt;br /&gt;
* 0x0001c5f8..0x0001c678 size 0x80-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x0.&lt;br /&gt;
* 0x0001c678..0x0001c878 size 0x200-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x80.&lt;br /&gt;
* 0x0001c878..0x0001d078 size 0x800-bytes: These are the 3DS RSA-2048 modulus which are eventually copied to arm9_itcm+0x4900: on retail the first 4 are copied there by boot9, on devunit the last 4 are copied to itcm.&lt;br /&gt;
* 0x0001d078 size 0x120-bytes is the initial data for the .data section @ 0x1ffe8000, this is the very end of the protected arm11-bootrom.&lt;br /&gt;
&lt;br /&gt;
== AES keys ==&lt;br /&gt;
See the Tools section for how Boot9 initializes the keyslots.&lt;br /&gt;
&lt;br /&gt;
See also [[AES_Registers|here]].&lt;br /&gt;
&lt;br /&gt;
For an issue with console-unique key-init, see [[OTP_Registers|here]].&lt;br /&gt;
&lt;br /&gt;
== BootROM Errors ==&lt;br /&gt;
Sample error-screen(where firm0+firm1 RSA signatures were corrupted):&lt;br /&gt;
&lt;br /&gt;
  BOOTROM 8046&lt;br /&gt;
  ERRCODE: 00F800FF&lt;br /&gt;
  DEDEFFFF FFFFFFFF&lt;br /&gt;
  00000000 00000000&lt;br /&gt;
&lt;br /&gt;
* 1st line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;BOOTROM %X&amp;quot;, 0x8046);//This last param comes from the .pool.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 2nd line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;ERRCODE:    %08X&amp;quot;, *((unsigned int*)(0x1FFFE000+0xC)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 3rd line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;%08X %08X&amp;quot;, *((unsigned int*)(0x1FFFE000+0x10))`, `*((unsigned int*)(0x1fffe000+0x14)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 4th line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;%08X %08X&amp;quot;,*((unsigned int*)(0x1FFFE000+0x18))`, `*((unsigned int*)(0x1fffe000+0x1C)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 0x1FFFE000 memory ==&lt;br /&gt;
This memory is used by boot9 mainly for sending info to the arm11 for the error-screen. The data in this region is still stored in memory by the time the ARM9+ARM11 jumps to FIRM.&lt;br /&gt;
&lt;br /&gt;
Among boot9/boot11, the 3 words at 0x1FFFE000 seem to be &#039;&#039;only&#039;&#039; accessed by the boot11 function initializing those words.&lt;br /&gt;
&lt;br /&gt;
* u32 0x1FFFE000+0: ARM11 MPCore &amp;quot;Cycle Counter Register (CCNT)&amp;quot;.&lt;br /&gt;
* u32 0x1FFFE000+4: ARM11 MPCore &amp;quot;Count Register 0 (PMN0)&amp;quot;.&lt;br /&gt;
* u32 0x1FFFE000+8: ARM11 MPCore &amp;quot;Count Register 1 (PMN0)&amp;quot;.&lt;br /&gt;
* 8bit-entry-array 0x1FFFE000+0xC: 8bit status-codes initialized by boot9 main(), for the FIRM-boot devices. +0 is NAND, +1 is NTRCARD and +2 is wifi-spiflash.&lt;br /&gt;
* ...&lt;br /&gt;
* 8bit-entry-array 0x1FFFE000+0x10: Status-codes originally from nand_findfirmpartition_loadfirm(), for each of the 8 NCSD partitions.&lt;br /&gt;
&lt;br /&gt;
== BootROM Status Codes ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Value&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| Success&lt;br /&gt;
|-&lt;br /&gt;
| 0xEE(~17)&lt;br /&gt;
| NCSD header validation function failed: NCSD magicnum is invalid or RSA verification failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0xDE(~33)&lt;br /&gt;
| FIRM header validation function failed: FIRM magicnum is invalid or RSA verification failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0xDF(~32)&lt;br /&gt;
| Failed to read sector data from the device.&lt;br /&gt;
|-&lt;br /&gt;
| 0xCF(~48)&lt;br /&gt;
| FIRM section validation function failed: FIRM section is invalid.&lt;br /&gt;
|-&lt;br /&gt;
| 0xF7(~8)&lt;br /&gt;
| A NAND FIRM from another partition was already found with a priority(firmhdr+4) &amp;gt;= to the value for the current partition&#039;s FIRM priority.&lt;br /&gt;
|-&lt;br /&gt;
| 0xF8(~7)&lt;br /&gt;
| The FIRM magicnum(firmhdr+0) is invalid.&lt;br /&gt;
|-&lt;br /&gt;
| 0xFF(~0)&lt;br /&gt;
| Initial value for each entry in the 8-entry array of status-codes for the NAND NCSD partitions. Indicates that the partition is not a FIRM partition(partition fs type isn&#039;t 0x3 or partition fs crypt-type isn&#039;t 0x2).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Boot9 startup ==&lt;br /&gt;
&lt;br /&gt;
0xffff0000 jumps to 0xffff8000. 0xffff8000 is crt0:&lt;br /&gt;
* Very first thing this does is clear u8 register 0x10000002 ([[CONFIG_Registers#CFG_RST11|CFG_RST11]]) bit 0 to zero.&lt;br /&gt;
* Then sp is initialized for each cpumode, IRQs/FIQs are disabled during the first mode-switch.&lt;br /&gt;
* Order of mode-switches + sp initialization: svc-mode = 0xfff04000, irq-mode = 0xfff03f00, system-mode = 0xfff03b00. Hence, the rest of the code following this runs in system-mode.&lt;br /&gt;
* Then L_ffff80cc/mpu_init() is called.&lt;br /&gt;
* Then L_ffff0038() is called, which initializes the exception-handler addresses @ 0x08000000.&lt;br /&gt;
* Then L_ffff81b8() is called(r4 + lr are saved on the DTCM stack), which after calling a memclear function which doesn&#039;t do anything, it then clears 0x08000030 size 0x10. Here the DTCM at 0xfff00000 size 0x4000 is cleared.&lt;br /&gt;
* Then L_ffff81b4() is called, which branches to DTCM_init(). This copies the initial DTCM data from the Boot9 data image into boot9, then it clears 0xFFF00230 - 0xFFF01AC0.&lt;br /&gt;
* Then LT_ffff8228/main is jumped to, with LR set to the address of an infinite-branch-loop instruction.&lt;br /&gt;
&lt;br /&gt;
mpu_init():&lt;br /&gt;
* Bitmask 0x000f9005 is cleared in the cp15 control register. MCR instructions which do then following are then executed: flush entire instruction cache, flush entire data cache, and drain write buffer.&lt;br /&gt;
* Then the 8 [[Memory_layout|MPU]] memregions are initialized.&lt;br /&gt;
* ITCM memregion reg = 0x24: baseaddr=0x0, size = 128MB(0x08000000).&lt;br /&gt;
* DTCM memregion reg = 0xfff0000a: baseaddr=0xfff00000, size=16KB(0x00004000).&lt;br /&gt;
* Then instruction cachable and data cachable/bufferable bits for the MPU regions are setup.&lt;br /&gt;
* Then the instruction/data access permissions for the MPU regions are setup.&lt;br /&gt;
* Lastly bitmask 0x0005707d is orred in the cp15 control register.&lt;br /&gt;
&lt;br /&gt;
== Boot9 main() ==&lt;br /&gt;
&lt;br /&gt;
  The following functions are called: LT_ffff2024(), LT_ffff1ff8(), pxi_init(), rsa_init(), initialize_rsakeyslots_pubk(), crypto_initialize(), and aesengine_reset().&lt;br /&gt;
  Then AES keyslot 0x3F is setup: aesengine_setnormalkey(0x3f, 5, ptr) is called. ptr on retail(CFG_UNITINFO check) is 0xffffd6e0, 0xffffd700 for devunit. Then essentially, aesengine_setctr(5, ptr+0x10) is executed.&lt;br /&gt;
  Then AES keyslot 0x3f is selected.&lt;br /&gt;
  When calling the following functions, if any of them return zero, it will immediately jump to setting ptr to 0x10012000(otp), otherwise when all of them return non-zero ptr = sp+0x94. otp_decrypt(sp+4), otp_verify(sp+4), initialize_consoleunique_itcm(sp+4, 0x07ffb800).&lt;br /&gt;
  Then the following is executed: initialize_aeskeys_wrap(ptr, 0x70);&lt;br /&gt;
  Then sp+4 size 0x100 is cleared to zero.&lt;br /&gt;
  &lt;br /&gt;
  ...&lt;br /&gt;
  &lt;br /&gt;
  NAND firm-boot code-block, is described below. Note that boot9 is basically hard-coded to use deviceid NAND, not SD.&lt;br /&gt;
  {&lt;br /&gt;
  	timer_updatestoredstate() is called, then the AES keyslot for NAND-FIRM is selected(0x6).&lt;br /&gt;
  	Then LT_ffff56c8() is called, if that returns non-zero the statuscode variable is set to ~2 then it jumps to NAND_BOOTEND.&lt;br /&gt;
  	Then LT_ffff5774(0x201) is called, if that returns non-zero the statuscode variable is set to ~1 then it jumps to NAND_BOOTEND.&lt;br /&gt;
  	Then fsdriver_setup_mmc() is called. Then nand_findfirmpartition_loadfirm(0) is called, with the statuscode variable set to the retval.&lt;br /&gt;
  	Executes a loop which runs 8 times: write the output from get_errorcode_arrayentry_xfff005e8(loopindex) to u8 0x1fffe000+0x10+loopindex(copy the array of 32bit error-codes for all 8 NCSD partitions initialized by nand_findfirmpartition_loadfirm() to the array of 8bit entries at 0x1fffe000+0x10).&lt;br /&gt;
  &lt;br /&gt;
  	NAND_BOOTEND:&lt;br /&gt;
  	Then the statuscode variable is written to u8 0x1fffe000+0xc.&lt;br /&gt;
  	Then LT_ffff5690(0x201, 0x1fffe018, 0x1fffe01c) is called.&lt;br /&gt;
  	Then LT_ffff5644() is called.&lt;br /&gt;
  	Then timer_updatestoredstate() is called.&lt;br /&gt;
  	When statuscode==0 for success, it jumps to FIRMLOAD_END. Otherwise, it continues to the next code-block.&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Wifi spi-flash firm-boot code-block, executed when no FIRM was loaded successfully so far.&lt;br /&gt;
  {&lt;br /&gt;
  	timer_updatestoredstate() is called.&lt;br /&gt;
  &lt;br /&gt;
  	Then spi_wififlash_cmdgetstatusreg(sp+0x100) is executed. When bit0 of the output u8 at sp+0x100 is clear, it will continue this code-block, otherwise it will set the statuscode variable to ~1 then jump to SPIFLASH_BOOTEND.&lt;br /&gt;
  	Then fsdriver_setup_wififlash() is called.&lt;br /&gt;
  	Here read_firmhdr_validate_loadfirm(0, 2) is called, with the statuscode variable set to the retval.&lt;br /&gt;
  &lt;br /&gt;
  	SPIFLASH_BOOTEND:&lt;br /&gt;
  	Then the statuscode variable is written to u8 0x1fffe000+0xe.&lt;br /&gt;
  	Then timer_updatestoredstate() is called.&lt;br /&gt;
  	When statuscode==0 for success, it jumps to FIRMLOAD_END. Otherwise, it executes writenormalkey_keyslot3f(), then jumps to FIRMLOAD_FAILURE.&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_END:&lt;br /&gt;
  Here it calls firmhdr_getarm11_entrypoint() and firmhdr_getarm9_entrypoint(). Immediately after calling each function it checks if the retval is 0, if so it then jumps to FIRMLOAD_FAILURE.&lt;br /&gt;
  After calling initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk(), it jumps to FIRMLOAD_EXIT.&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_FAILURE:&lt;br /&gt;
  Here it clears 0x07ffb800 size 0x3c70 to zero, endaddr = 0x07fff470.&lt;br /&gt;
  Then it continues to FIRMLOAD_EXIT.&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_EXIT:&lt;br /&gt;
  Here firmboot() is called, which should never return. The instruction after this bl is a call for panic().&lt;br /&gt;
&lt;br /&gt;
== Boot11 ==&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
main():&lt;br /&gt;
  LT_1263c();&lt;br /&gt;
  ...&lt;br /&gt;
  LT_13944()&lt;br /&gt;
  ...&lt;br /&gt;
  pxi_init();&lt;br /&gt;
  initializefuncptr_firmboot_start(firmbootbegin_funcptr);&lt;br /&gt;
  firmboot();&lt;br /&gt;
  return;&lt;br /&gt;
&lt;br /&gt;
LT_12220/initializefuncptr_firmboot_start&lt;br /&gt;
  inr0=funcptr&lt;br /&gt;
  This writes inr0 to address 0x1ffe8028, then returns.&lt;br /&gt;
  This initializes the funcptr which firmboot() can call after the very first func-call.&lt;br /&gt;
&lt;br /&gt;
LT_13944&lt;br /&gt;
  if([[I2C_Registers|i2cmcu_readregf]](sp+0)==0)&lt;br /&gt;
  {&lt;br /&gt;
  	return (*((u8*)0x10147000) &amp;gt;&amp;gt; 4) &amp;amp; 1;//Reads [[GPIO_Registers|GPIO]] when reading I2C fails.&lt;br /&gt;
  }&lt;br /&gt;
  Here it basically does &amp;quot;return &amp;lt;byte loaded from sp+0&amp;gt; ^ 0x2&amp;quot;. Hence in this case, it will return 0x2 when the system shell is closed(sleep-mode), otherwise 0x0 is returned.&lt;br /&gt;
&lt;br /&gt;
LT_12454/firmboot&lt;br /&gt;
  This is the arm11 version of the boot9 firmboot() function, like boot9 this is the final function called from main(). The functionality for these two functions are identical, minus addresses.&lt;br /&gt;
  ptr = firmboot_loadentrypoint11();&lt;br /&gt;
  funcptr = *(0x1ffe8028);&lt;br /&gt;
  if(funcptr)funcptr(ptr);&lt;br /&gt;
  LT_11ffc(ptr);&lt;br /&gt;
  return;&lt;br /&gt;
&lt;br /&gt;
== Boot Procedure ==&lt;br /&gt;
&lt;br /&gt;
* 0 seconds - unit is powered on. The ARM9 and ARM11 [[Memory_layout|bootroms]] begin execution.&lt;br /&gt;
* &amp;lt;= ~1 second - BootROMs fully run, load FIRM, etc. The loaded FIRM begins running.&lt;br /&gt;
**The ARM11 sysmodules included with FIRM are launched by ARM11-kernel, etc.&lt;br /&gt;
**The [[Process_Manager_Services|PM]] module launches [[NS]].&lt;br /&gt;
**If [[Home_Menu#Auto-Boot_Function|auto-booting]] is needed, NS will [[NS#Auto-boot|auto-boot]] titles.&lt;br /&gt;
**Otherwise, NS will instead launch [[ErrDisp]] and the [[Configuration Memory#ACTIVEMENUTID|current active menu]] via the PM module. For retail units, this menu is usually the [[Home Menu]]. Note that the PM module first launches the module dependencies when launching a process, prior to actually launching the process.&lt;br /&gt;
**The further Home Menu startup process is described [[Home_Menu#Home_Menu_startup|here]]. This includes Home Menu manually launching various sysmodules.&lt;br /&gt;
&lt;br /&gt;
* 4 seconds - the LCD screens are initialized.&lt;br /&gt;
&lt;br /&gt;
* 7 seconds - [[Home Menu]] is fully initialized/loaded.&lt;br /&gt;
&lt;br /&gt;
== NAND Reads during Boot ==&lt;br /&gt;
During a successful boot on 6.x, the bootloader (and firm) reads the following sectors from NAND (in this order):&lt;br /&gt;
 00000000 (NCSD Partition Table)&lt;br /&gt;
 &lt;br /&gt;
 Only verify &#039;FIRM&#039; magic? (A second Header-read will be attempted even if everything except the magic is 0xFF...)&lt;br /&gt;
 0B130000 (FIRM Partition)&lt;br /&gt;
 0B530000 (Secondary FIRM Partition)&lt;br /&gt;
 &lt;br /&gt;
 Verify RSA signature and parse Header:&lt;br /&gt;
 0B130000 (FIRM: Header)&lt;br /&gt;
 0B130200 (FIRM: Section 1)&lt;br /&gt;
 0B163E00 (FIRM: Section 2)&lt;br /&gt;
 0B193E00 (FIRM: Section 3)&lt;br /&gt;
 &lt;br /&gt;
 00013000 .. Below is probably NATIVE_FIRM booting ..&lt;br /&gt;
 00014000&lt;br /&gt;
 00015000&lt;br /&gt;
 00016000&lt;br /&gt;
 00017000&lt;br /&gt;
 &lt;br /&gt;
 09011A00&lt;br /&gt;
 09011C00&lt;br /&gt;
 09012000&lt;br /&gt;
 09012400&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Error Codes ==&lt;br /&gt;
When the 3DS does not find the NAND chip, the following error is displayed:&lt;br /&gt;
&lt;br /&gt;
[[Image:CTR_Bootrom_Error.jpg|240px]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Error&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE 00000000 00000000 00000200 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Error when having SD-card reader connected to NAND during boot.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE 00000000 00000000 00000400 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND not found error (?)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000080 00800000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT1 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000005 00800000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT2 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000005 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT3 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FF F8F8FFFF FFFFFFFF 00000000 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Both the firm0 and firm1 partitions are corrupt (failed signature checks).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800EE FFFFFFFF FFFFFFFF 00000000 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| [[NCSD]] header in sector 0 is corrupt (failed signature check).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [https://github.com/yellows8/boot9_tools boot9_tools]&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Bootloader&amp;diff=20566</id>
		<title>Bootloader</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Bootloader&amp;diff=20566"/>
		<updated>2018-01-16T00:09:33Z</updated>

		<summary type="html">&lt;p&gt;D0k3: Fixed formatting, added info about the stored font gfx format.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The bootloader is the binary code stored in the ARM9 and ARM11 boot ROMs and hence is ran when the 3DS is powered on. It&#039;s purpose is initializing hardware and loading the [[FIRM|system firmware]] from the internal [[Flash_Filesystem|NAND memory]]..&lt;br /&gt;
&lt;br /&gt;
Besides NATIVE_FIRM, the bootloader is also capable of booting other firmwares (such as TWL_FIRM and AGB_FIRM). However, this will result either in a japanese error-screen or a system shutdown, directly after FIRM-Launching.&lt;br /&gt;
&lt;br /&gt;
== Boot ROM ==&lt;br /&gt;
Upon boot, parts of the ARM9 and ARM11 boot ROMs are protected by writing to [[CONFIG#CFG_SYSPROT9|CFG_SYSPROT9]] and [[CONFIG#CFG_SYSPROT11|CFG_SYSPROT11]], respectively. The ARM9 and ARM11 boot ROMs are identical for all 3DS consoles (3DS, 3DS XL, 2DS, New 3DS, New 3DS XL, New 2DS XL)&lt;br /&gt;
&lt;br /&gt;
== NAND FIRM boot ==&lt;br /&gt;
Boot9 is not hard-coded to only handle 2 FIRM partitions: it parses all 8 NCSD partitions for this. Boot9 will attempt to use every partition listed in the NCSD which is an actual FIRM partition, in the same order listed in the NCSD, until booting one of them succeeds. Among the not-yet-processed partitions, the FIRM which has the highest value at u32 firmhdr+4 will have a FIRM-boot attempted first. Since that value is normally 0x0, the order of FIRM-partition processing is normally identical to the order of the NCSD partitions.&lt;br /&gt;
&lt;br /&gt;
Boot9 is hard-coded for using [[AES_Registers|AES]] keyslot 0x6 for NAND crypto.&lt;br /&gt;
&lt;br /&gt;
== Non-NAND FIRM boot ==&lt;br /&gt;
Boot9 can also boot from non-NAND. For this a different set of RSA pubks are used(separate pubks for retail/devunit like NAND). The spiflash FIRM image for this is also encrypted with AES-CBC using a normalkey stored in prot_boot9(separate for retail/devunit). This encryption is basically used instead of what is used for NAND-firm-partitions. This encryption is only used for the FIRM sections, the FIRM header is used raw. The AES keyslot for this is only overwritten afterwards when booting from non-NAND fails. AES keyslot 0x3F is used for this.&lt;br /&gt;
&lt;br /&gt;
  CTR_word[0] = firmimageoffset;//FIRM section offset from FIRM header&lt;br /&gt;
  CTR_word[1] = outbufaddr;//FIRM section load addr&lt;br /&gt;
  CTR_word[2] = readsize;//FIRM section size&lt;br /&gt;
  CTR_word[3] = readsize;//FIRM section size&lt;br /&gt;
&lt;br /&gt;
When booting from NAND fails, boot9 will then attempt to boot from Wifi SPI-flash(this only triggers when the wifi module hw is properly accessible/connected, which is normally the case). The base offset for spiflash FIRM is 0x400. Note that this region(all data prior to offset 0x1F300) is write-protected by the spiflash(not writable from 3DS-mode / DS-mode).&lt;br /&gt;
&lt;br /&gt;
Additionally, if the shell is closed and a special key combination (Start + Select + X) is held, boot9 will attempt to boot from an inserted NTR cartridge before booting from NAND. Note: While normally on O3DS/2DS the console will not turn on if the shell is closed (or this is faked by holding a magnet to the console), when this special key combination is held holding down the power button will cause boot to occur anyway.&lt;br /&gt;
&lt;br /&gt;
For non-NAND booting, NCSD / FIRM-backup is not used.&lt;br /&gt;
&lt;br /&gt;
== SDMMC ==&lt;br /&gt;
&lt;br /&gt;
Boot9 has code implemented for using SD(HC) cards, but the input deviceids used by boot9 for those functions are hard-coded for NAND. However, it is possible to use an SD(HC) card in place of the NAND if the NAND chip is first disconnected, and a SD card connected to the bus. Due to the CID being different, partitions will need to be re-encrypted and TWL mode will not work, due to the MBR being in the NCSD header. Using sighax, it may be possible to replace the NCSD header.&lt;br /&gt;
&lt;br /&gt;
== Boot9 RSA keyslots ==&lt;br /&gt;
&lt;br /&gt;
The following are initialized during main() startup, by initialize_rsakeyslots_pubk(). Each of these, for the ones which are actually set, have different keydata for retail/devunit.&lt;br /&gt;
* 0: Not set.&lt;br /&gt;
* 1: Used for the NAND FIRM signature.&lt;br /&gt;
* 2: Used for the non-NAND-FIRM signature.&lt;br /&gt;
* 3: Used for the NAND-NCSD FIRM signature.&lt;br /&gt;
&lt;br /&gt;
When FIRM loading is successful, initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk() is called, right before calling the final function in main(). Besides ITCM writing, this overwrites all 4 RSA keyslots with modulus + private-exponents loaded from boot9 data.&lt;br /&gt;
&lt;br /&gt;
initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk():&lt;br /&gt;
This initializes the 4 0x100-byte/0x200-byte chunks at 0x07ffb800+0x500(0x07ffbd00)/0x07ffb800+0x900(0x07ffc100). End address of the first section is 0x07ffc100(start addr of the second section), end address of the second section is 0x07ffc900. Hence, the first section total size is 0x400-bytes, while the second section total size is 0x800-bytes.&lt;br /&gt;
&lt;br /&gt;
These are initialized using via the boot9 data image, with ptrs from DTCM. Seperate keydata is used for retail/devunit.&lt;br /&gt;
&lt;br /&gt;
When initializing the first ITCM area: rsa_setkeyslot_privk() is called for all 4 RSA keyslots. The modulo for each one is also copied to (index*0x100) + 0x07ffb800 + 0x500. The private exponent is not copied into ITCM.&lt;br /&gt;
&lt;br /&gt;
The second ITCM area is initialized by copying 4 0x200-byte entries in a loop. These are RSA pubks+privks, which Boot9 doesn&#039;t use itself at all besides this copy loop.&lt;br /&gt;
&lt;br /&gt;
== Boot9 image data memory layout ==&lt;br /&gt;
0xffffb088 is the beginning of the boot9 image data section.&lt;br /&gt;
&lt;br /&gt;
* 0xffffb088 size 0x38-bytes: This is the array used during FIRM-section-loading for the memory-range blacklist for FIRM sections.&lt;br /&gt;
* 0xffffb0c0(end-addr of the above area) size 0x20-bytes: Unknown.&lt;br /&gt;
* 0xffffb0e0(end-addr of the above area) size 0x2f80-bytes: This is *all* of the keys stored in the image.&lt;br /&gt;
* 0xffffe060(end addr of the above key-area) size 0x230-bytes: This is the initial DTCM image @ 0xFFF00000, see below.&lt;br /&gt;
* 0xffffe290(DTCM_image_end) - {boot9 image end}: All-zero.&lt;br /&gt;
&lt;br /&gt;
Layout of the 0x2f80-byte key-area at 0xffffb0e0:&lt;br /&gt;
* 0xffffb0e0 size 0x2600-bytes: This is the RSA key-data, see below.&lt;br /&gt;
* 0xffffd6e0(end-addr of the above area) size 0x40-bytes: This is the keydata used for crypting the entire OTP with keyslot 0x3f, used by main(). The first 0x20-bytes is for retail, the remaining 0x20-bytes starting at 0xffffd700 is for devunit. Chunk+0(retail=0xffffd6e0 devunit=0xffffd700) is the normalkey, chunk+0x10(retail=0xffffd6f0 devunit=0xffffd710) is the AES-IV.&lt;br /&gt;
* ...&lt;br /&gt;
* 0xffffd760: size 0x100-bytes: First 0x80-bytes is for retail, the remaining 0x80-bytes at 0xffffd7e0 is for devunit. This 0x80-byte block is copied to 0x07ffcd00 by a Boot9 function, however that code actually does the copy in two 0x40-bytes chunks.&lt;br /&gt;
* 0xffffd860(end-addr of the above area) size 0x400-bytes: This is the bootrom_dataptr passed to the aes-keyinit function for retail. See the below Tools section for how this is processed.&lt;br /&gt;
* 0xffffdc60(end-addr of the above area) size 0x400-bytes: This is the devunit version of the above the 0x400-byte chunk. This is very last chunk of data in the boot9 data-section key-area: end addr for this area is 0xffffe060.&lt;br /&gt;
&lt;br /&gt;
Layout of the 0x2600-byte RSA key-data at 0xffffb0e0:  &lt;br /&gt;
First 0x1300-bytes is for retail, the remaining 0x1300-bytes starting at 0xffffc3e0 is for devunit.&lt;br /&gt;
* +0x0 retail=0xffffb0e0 devunit=0xffffc3e0: RSA modulo for keyslot3, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x100 retail=0xffffb1e0 devunit=0xffffc4e0: RSA modulo for keyslot1, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x200 retail=0xffffb2e0 devunit=0xffffc5e0: RSA modulo for keyslot2, initialized by initialize_rsakeyslots_pubk().&lt;br /&gt;
* +0x300 size 0x200, retail=0xffffb3e0 devunit=0xffffc6e0: First 0x100-bytes is the RSA modulo, then the following 0x100-bytes is the RSA privk(private-exponent). This is for RSA-engine keyslot0 with initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk(), which also copies this modulo to the array starting at 0x07ffbd00.&lt;br /&gt;
* +0x500 size 0x200, retail=0xffffb5e0 devunit=0xffffc8e0: Used the same as the above block except for slot1.&lt;br /&gt;
* +0x700 size 0x200, retail=0xffffb7e0 devunit=0xffffcae0: Used the same as the above block except for slot2.&lt;br /&gt;
* +0x900 size 0x200, retail=0xffffb9e0 devunit=0xffffcce0: Used the same as the above block except for slot3.&lt;br /&gt;
* +0xb00 size 0x200, retail=0xffffbbe0 devunit=0xffffcee0: First 0x100-bytes is the RSA modulo, then the following 0x100-bytes is the RSA privk(private-exponent). The 0x200-bytes here is copied to slot0 in the array at 0x07ffc100 by initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk().&lt;br /&gt;
* +0xd00 size 0x200, retail=0xffffbde0 devunit=0xffffd0e0: Used the same as the above block except for slot1.&lt;br /&gt;
* +0xf00 size 0x200, retail=0xffffbfe0 devunit=0xffffd2e0: Used the same as the above block except for slot2.&lt;br /&gt;
* +0x1100 size 0x200, retail=0xffffc1e0 devunit=0xffffd4e0: Used the same as the above block except for slot3.&lt;br /&gt;
&lt;br /&gt;
== Boot9 DTCM layout ==&lt;br /&gt;
Most of this is just ptrs / other unknown data, not actual keys. However, there is an unknown 0x10-byte block @ +0x124(there&#039;s a ptr initialized for this block elsewhere).&lt;br /&gt;
&lt;br /&gt;
== Boot11 image data memory layout ==&lt;br /&gt;
* 0x0001817c..0x000181f4 size 0x78-bytes: This seems to be the bootrom error screen font gfx data. This begins at the exact end-address of the crt0 code, the rest of the protected boot11 code begins at this end-address(0x000181f4). To extract the font gfx data from there, the 30 dwords at this address need to be converted to big endian. The correct resolution (when displayed as raw) is 32x30x1. The bootrom font looks very similar to [https://robey.lag.net/2010/01/23/tiny-monospace-font.html this font].&lt;br /&gt;
* 0x00019400 is the beginning of the boot11 data area, the first 8-bytes here are unknown.&lt;br /&gt;
* 0x00019408..0x0001b498 size 0x2090-bytes: This is the blowfish keydata which gets copied to arm9itcm_twlkeydata+0x3e0 later.&lt;br /&gt;
* 0x0001c498..0x0001c4f8 size 0x60-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x380.&lt;br /&gt;
* 0x0001c4f8..0x0001c538 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x340.&lt;br /&gt;
* 0x0001c538..0x0001c578 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x300.&lt;br /&gt;
* 0x0001c578..0x0001c5f8 size 0x80-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x280.&lt;br /&gt;
* 0x0001c5f8..0x0001c678 size 0x80-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x0.&lt;br /&gt;
* 0x0001c678..0x0001c878 size 0x200-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x80.&lt;br /&gt;
* 0x0001c878..0x0001d078 size 0x800-bytes: These are the 3DS RSA-2048 modulus which are eventually copied to arm9_itcm+0x4900: on retail the first 4 are copied there by boot9, on devunit the last 4 are copied to itcm.&lt;br /&gt;
* 0x0001d078 size 0x120-bytes is the initial data for the .data section @ 0x1ffe8000, this is the very end of the protected arm11-bootrom.&lt;br /&gt;
&lt;br /&gt;
== AES keys ==&lt;br /&gt;
See the Tools section for how Boot9 initializes the keyslots.&lt;br /&gt;
&lt;br /&gt;
See also [[AES_Registers|here]].&lt;br /&gt;
&lt;br /&gt;
For an issue with console-unique key-init, see [[OTP_Registers|here]].&lt;br /&gt;
&lt;br /&gt;
== BootROM Errors ==&lt;br /&gt;
Sample error-screen(where firm0+firm1 RSA signatures were corrupted):&lt;br /&gt;
&lt;br /&gt;
  BOOTROM 8046&lt;br /&gt;
  ERRCODE: 00F800FF&lt;br /&gt;
  DEDEFFFF FFFFFFFF&lt;br /&gt;
  00000000 00000000&lt;br /&gt;
&lt;br /&gt;
* 1st line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;BOOTROM %X&amp;quot;, 0x8046);//This last param comes from the .pool.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 2nd line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;ERRCODE:    %08X&amp;quot;, *((unsigned int*)(0x1FFFE000+0xC)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 3rd line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;%08X %08X&amp;quot;, *((unsigned int*)(0x1FFFE000+0x10))`, `*((unsigned int*)(0x1fffe000+0x14)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
* 4th line is: &amp;lt;code&amp;gt;print_string(..., &amp;quot;%08X %08X&amp;quot;,*((unsigned int*)(0x1FFFE000+0x18))`, `*((unsigned int*)(0x1fffe000+0x1C)));//See below memory notes.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 0x1FFFE000 memory ==&lt;br /&gt;
This memory is used by boot9 mainly for sending info to the arm11 for the error-screen. The data in this region is still stored in memory by the time the ARM9+ARM11 jumps to FIRM.&lt;br /&gt;
&lt;br /&gt;
Among boot9/boot11, the 3 words at 0x1FFFE000 seem to be &#039;&#039;only&#039;&#039; accessed by the boot11 function initializing those words.&lt;br /&gt;
&lt;br /&gt;
* u32 0x1FFFE000+0: ARM11 MPCore &amp;quot;Cycle Counter Register (CCNT)&amp;quot;.&lt;br /&gt;
* u32 0x1FFFE000+4: ARM11 MPCore &amp;quot;Count Register 0 (PMN0)&amp;quot;.&lt;br /&gt;
* u32 0x1FFFE000+8: ARM11 MPCore &amp;quot;Count Register 1 (PMN0)&amp;quot;.&lt;br /&gt;
* 8bit-entry-array 0x1FFFE000+0xC: 8bit status-codes initialized by boot9 main(), for the FIRM-boot devices. +0 is NAND, +1 is NTRCARD and +2 is wifi-spiflash.&lt;br /&gt;
* ...&lt;br /&gt;
* 8bit-entry-array 0x1FFFE000+0x10: Status-codes originally from nand_findfirmpartition_loadfirm(), for each of the 8 NCSD partitions.&lt;br /&gt;
&lt;br /&gt;
== BootROM Status Codes ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Value&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| Success&lt;br /&gt;
|-&lt;br /&gt;
| 0xEE(~17)&lt;br /&gt;
| NCSD header validation function failed: NCSD magicnum is invalid or RSA verification failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0xDE(~33)&lt;br /&gt;
| FIRM header validation function failed: FIRM magicnum is invalid or RSA verification failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0xDF(~32)&lt;br /&gt;
| Failed to read sector data from the device.&lt;br /&gt;
|-&lt;br /&gt;
| 0xCF(~48)&lt;br /&gt;
| FIRM section validation function failed: FIRM section is invalid.&lt;br /&gt;
|-&lt;br /&gt;
| 0xF7(~8)&lt;br /&gt;
| A NAND FIRM from another partition was already found with a priority(firmhdr+4) &amp;gt;= to the value for the current partition&#039;s FIRM priority.&lt;br /&gt;
|-&lt;br /&gt;
| 0xF8(~7)&lt;br /&gt;
| The FIRM magicnum(firmhdr+0) is invalid.&lt;br /&gt;
|-&lt;br /&gt;
| 0xFF(~0)&lt;br /&gt;
| Initial value for each entry in the 8-entry array of status-codes for the NAND NCSD partitions. Indicates that the partition is not a FIRM partition(partition fs type isn&#039;t 0x3 or partition fs crypt-type isn&#039;t 0x2).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Boot9 startup ==&lt;br /&gt;
&lt;br /&gt;
0xffff0000 jumps to 0xffff8000. 0xffff8000 is crt0:&lt;br /&gt;
* Very first thing this does is clear u8 register 0x10000002 ([[CONFIG_Registers#CFG_RST11|CFG_RST11]]) bit 0 to zero.&lt;br /&gt;
* Then sp is initialized for each cpumode, IRQs/FIQs are disabled during the first mode-switch.&lt;br /&gt;
* Order of mode-switches + sp initialization: svc-mode = 0xfff04000, irq-mode = 0xfff03f00, system-mode = 0xfff03b00. Hence, the rest of the code following this runs in system-mode.&lt;br /&gt;
* Then L_ffff80cc/mpu_init() is called.&lt;br /&gt;
* Then L_ffff0038() is called, which initializes the exception-handler addresses @ 0x08000000.&lt;br /&gt;
* Then L_ffff81b8() is called(r4 + lr are saved on the DTCM stack), which after calling a memclear function which doesn&#039;t do anything, it then clears 0x08000030 size 0x10. Here the DTCM at 0xfff00000 size 0x4000 is cleared.&lt;br /&gt;
* Then L_ffff81b4() is called, which branches to DTCM_init(). This copies the initial DTCM data from the Boot9 data image into boot9, then it clears 0xFFF00230 - 0xFFF01AC0.&lt;br /&gt;
* Then LT_ffff8228/main is jumped to, with LR set to the address of an infinite-branch-loop instruction.&lt;br /&gt;
&lt;br /&gt;
mpu_init():&lt;br /&gt;
* Bitmask 0x000f9005 is cleared in the cp15 control register. MCR instructions which do then following are then executed: flush entire instruction cache, flush entire data cache, and drain write buffer.&lt;br /&gt;
* Then the 8 [[Memory_layout|MPU]] memregions are initialized.&lt;br /&gt;
* ITCM memregion reg = 0x24: baseaddr=0x0, size = 128MB(0x08000000).&lt;br /&gt;
* DTCM memregion reg = 0xfff0000a: baseaddr=0xfff00000, size=16KB(0x00004000).&lt;br /&gt;
* Then instruction cachable and data cachable/bufferable bits for the MPU regions are setup.&lt;br /&gt;
* Then the instruction/data access permissions for the MPU regions are setup.&lt;br /&gt;
* Lastly bitmask 0x0005707d is orred in the cp15 control register.&lt;br /&gt;
&lt;br /&gt;
== Boot9 main() ==&lt;br /&gt;
&lt;br /&gt;
  The following functions are called: LT_ffff2024(), LT_ffff1ff8(), pxi_init(), rsa_init(), initialize_rsakeyslots_pubk(), crypto_initialize(), and aesengine_reset().&lt;br /&gt;
  Then AES keyslot 0x3F is setup: aesengine_setnormalkey(0x3f, 5, ptr) is called. ptr on retail(CFG_UNITINFO check) is 0xffffd6e0, 0xffffd700 for devunit. Then essentially, aesengine_setctr(5, ptr+0x10) is executed.&lt;br /&gt;
  Then AES keyslot 0x3f is selected.&lt;br /&gt;
  When calling the following functions, if any of them return zero, it will immediately jump to setting ptr to 0x10012000(otp), otherwise when all of them return non-zero ptr = sp+0x94. otp_decrypt(sp+4), otp_verify(sp+4), initialize_consoleunique_itcm(sp+4, 0x07ffb800).&lt;br /&gt;
  Then the following is executed: initialize_aeskeys_wrap(ptr, 0x70);&lt;br /&gt;
  Then sp+4 size 0x100 is cleared to zero.&lt;br /&gt;
  &lt;br /&gt;
  ...&lt;br /&gt;
  &lt;br /&gt;
  NAND firm-boot code-block, is described below. Note that boot9 is basically hard-coded to use deviceid NAND, not SD.&lt;br /&gt;
  {&lt;br /&gt;
  	timer_updatestoredstate() is called, then the AES keyslot for NAND-FIRM is selected(0x6).&lt;br /&gt;
  	Then LT_ffff56c8() is called, if that returns non-zero the statuscode variable is set to ~2 then it jumps to NAND_BOOTEND.&lt;br /&gt;
  	Then LT_ffff5774(0x201) is called, if that returns non-zero the statuscode variable is set to ~1 then it jumps to NAND_BOOTEND.&lt;br /&gt;
  	Then fsdriver_setup_mmc() is called. Then nand_findfirmpartition_loadfirm(0) is called, with the statuscode variable set to the retval.&lt;br /&gt;
  	Executes a loop which runs 8 times: write the output from get_errorcode_arrayentry_xfff005e8(loopindex) to u8 0x1fffe000+0x10+loopindex(copy the array of 32bit error-codes for all 8 NCSD partitions initialized by nand_findfirmpartition_loadfirm() to the array of 8bit entries at 0x1fffe000+0x10).&lt;br /&gt;
  &lt;br /&gt;
  	NAND_BOOTEND:&lt;br /&gt;
  	Then the statuscode variable is written to u8 0x1fffe000+0xc.&lt;br /&gt;
  	Then LT_ffff5690(0x201, 0x1fffe018, 0x1fffe01c) is called.&lt;br /&gt;
  	Then LT_ffff5644() is called.&lt;br /&gt;
  	Then timer_updatestoredstate() is called.&lt;br /&gt;
  	When statuscode==0 for success, it jumps to FIRMLOAD_END. Otherwise, it continues to the next code-block.&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Wifi spi-flash firm-boot code-block, executed when no FIRM was loaded successfully so far.&lt;br /&gt;
  {&lt;br /&gt;
  	timer_updatestoredstate() is called.&lt;br /&gt;
  &lt;br /&gt;
  	Then spi_wififlash_cmdgetstatusreg(sp+0x100) is executed. When bit0 of the output u8 at sp+0x100 is clear, it will continue this code-block, otherwise it will set the statuscode variable to ~1 then jump to SPIFLASH_BOOTEND.&lt;br /&gt;
  	Then fsdriver_setup_wififlash() is called.&lt;br /&gt;
  	Here read_firmhdr_validate_loadfirm(0, 2) is called, with the statuscode variable set to the retval.&lt;br /&gt;
  &lt;br /&gt;
  	SPIFLASH_BOOTEND:&lt;br /&gt;
  	Then the statuscode variable is written to u8 0x1fffe000+0xe.&lt;br /&gt;
  	Then timer_updatestoredstate() is called.&lt;br /&gt;
  	When statuscode==0 for success, it jumps to FIRMLOAD_END. Otherwise, it executes writenormalkey_keyslot3f(), then jumps to FIRMLOAD_FAILURE.&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_END:&lt;br /&gt;
  Here it calls firmhdr_getarm11_entrypoint() and firmhdr_getarm9_entrypoint(). Immediately after calling each function it checks if the retval is 0, if so it then jumps to FIRMLOAD_FAILURE.&lt;br /&gt;
  After calling initialize_x07ffbd00_x07ffc100_rsakeyslotsprivk(), it jumps to FIRMLOAD_EXIT.&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_FAILURE:&lt;br /&gt;
  Here it clears 0x07ffb800 size 0x3c70 to zero, endaddr = 0x07fff470.&lt;br /&gt;
  Then it continues to FIRMLOAD_EXIT.&lt;br /&gt;
  &lt;br /&gt;
  FIRMLOAD_EXIT:&lt;br /&gt;
  Here firmboot() is called, which should never return. The instruction after this bl is a call for panic().&lt;br /&gt;
&lt;br /&gt;
== Boot11 ==&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
main():&lt;br /&gt;
  LT_1263c();&lt;br /&gt;
  ...&lt;br /&gt;
  LT_13944()&lt;br /&gt;
  ...&lt;br /&gt;
  pxi_init();&lt;br /&gt;
  initializefuncptr_firmboot_start(firmbootbegin_funcptr);&lt;br /&gt;
  firmboot();&lt;br /&gt;
  return;&lt;br /&gt;
&lt;br /&gt;
LT_12220/initializefuncptr_firmboot_start&lt;br /&gt;
  inr0=funcptr&lt;br /&gt;
  This writes inr0 to address 0x1ffe8028, then returns.&lt;br /&gt;
  This initializes the funcptr which firmboot() can call after the very first func-call.&lt;br /&gt;
&lt;br /&gt;
LT_13944&lt;br /&gt;
  if([[I2C_Registers|i2cmcu_readregf]](sp+0)==0)&lt;br /&gt;
  {&lt;br /&gt;
  	return (*((u8*)0x10147000) &amp;gt;&amp;gt; 4) &amp;amp; 1;//Reads [[GPIO_Registers|GPIO]] when reading I2C fails.&lt;br /&gt;
  }&lt;br /&gt;
  Here it basically does &amp;quot;return &amp;lt;byte loaded from sp+0&amp;gt; ^ 0x2&amp;quot;. Hence in this case, it will return 0x2 when the system shell is closed(sleep-mode), otherwise 0x0 is returned.&lt;br /&gt;
&lt;br /&gt;
LT_12454/firmboot&lt;br /&gt;
  This is the arm11 version of the boot9 firmboot() function, like boot9 this is the final function called from main(). The functionality for these two functions are identical, minus addresses.&lt;br /&gt;
  ptr = firmboot_loadentrypoint11();&lt;br /&gt;
  funcptr = *(0x1ffe8028);&lt;br /&gt;
  if(funcptr)funcptr(ptr);&lt;br /&gt;
  LT_11ffc(ptr);&lt;br /&gt;
  return;&lt;br /&gt;
&lt;br /&gt;
== Boot Procedure ==&lt;br /&gt;
&lt;br /&gt;
* 0 seconds - unit is powered on. The ARM9 and ARM11 [[Memory_layout|bootroms]] begin execution.&lt;br /&gt;
* &amp;lt;= ~1 second - BootROMs fully run, load FIRM, etc. The loaded FIRM begins running.&lt;br /&gt;
**The ARM11 sysmodules included with FIRM are launched by ARM11-kernel, etc.&lt;br /&gt;
**The [[Process_Manager_Services|PM]] module launches [[NS]].&lt;br /&gt;
**If [[Home_Menu#Auto-Boot_Function|auto-booting]] is needed, NS will [[NS#Auto-boot|auto-boot]] titles.&lt;br /&gt;
**Otherwise, NS will instead launch [[ErrDisp]] and the [[Configuration Memory#ACTIVEMENUTID|current active menu]] via the PM module. For retail units, this menu is usually the [[Home Menu]]. Note that the PM module first launches the module dependencies when launching a process, prior to actually launching the process.&lt;br /&gt;
**The further Home Menu startup process is described [[Home_Menu#Home_Menu_startup|here]]. This includes Home Menu manually launching various sysmodules.&lt;br /&gt;
&lt;br /&gt;
* 4 seconds - the LCD screens are initialized.&lt;br /&gt;
&lt;br /&gt;
* 7 seconds - [[Home Menu]] is fully initialized/loaded.&lt;br /&gt;
&lt;br /&gt;
== NAND Reads during Boot ==&lt;br /&gt;
During a successful boot on 6.x, the bootloader (and firm) reads the following sectors from NAND (in this order):&lt;br /&gt;
 00000000 (NCSD Partition Table)&lt;br /&gt;
 &lt;br /&gt;
 Only verify &#039;FIRM&#039; magic? (A second Header-read will be attempted even if everything except the magic is 0xFF...)&lt;br /&gt;
 0B130000 (FIRM Partition)&lt;br /&gt;
 0B530000 (Secondary FIRM Partition)&lt;br /&gt;
 &lt;br /&gt;
 Verify RSA signature and parse Header:&lt;br /&gt;
 0B130000 (FIRM: Header)&lt;br /&gt;
 0B130200 (FIRM: Section 1)&lt;br /&gt;
 0B163E00 (FIRM: Section 2)&lt;br /&gt;
 0B193E00 (FIRM: Section 3)&lt;br /&gt;
 &lt;br /&gt;
 00013000 .. Below is probably NATIVE_FIRM booting ..&lt;br /&gt;
 00014000&lt;br /&gt;
 00015000&lt;br /&gt;
 00016000&lt;br /&gt;
 00017000&lt;br /&gt;
 &lt;br /&gt;
 09011A00&lt;br /&gt;
 09011C00&lt;br /&gt;
 09012000&lt;br /&gt;
 09012400&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Error Codes ==&lt;br /&gt;
When the 3DS does not find the NAND chip, the following error is displayed:&lt;br /&gt;
&lt;br /&gt;
[[Image:CTR_Bootrom_Error.jpg|240px]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Error&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE 00000000 00000000 00000200 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Error when having SD-card reader connected to NAND during boot.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE 00000000 00000000 00000400 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND not found error (?)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000080 00800000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT1 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000005 00800000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT2 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FE FFFFFFFF FFFFFFFF 00000005 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| NAND error when DAT3 was used as DAT0.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800FF F8F8FFFF FFFFFFFF 00000000 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| Both the firm0 and firm1 partitions are corrupt (failed signature checks).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;00F800EE FFFFFFFF FFFFFFFF 00000000 00000000&amp;lt;/tt&amp;gt;&lt;br /&gt;
| [[NCSD]] header in sector 0 is corrupt (failed signature check).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [https://github.com/yellows8/boot9_tools boot9_tools]&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=I2C_Registers&amp;diff=20478</id>
		<title>I2C Registers</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=I2C_Registers&amp;diff=20478"/>
		<updated>2017-11-22T01:24:07Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* Device 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Registers =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Old3DS&lt;br /&gt;
!  Name&lt;br /&gt;
!  Address&lt;br /&gt;
!  Width&lt;br /&gt;
!  Used by&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C1_DATA&lt;br /&gt;
| 0x10161000&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| [[#I2C_CNT|I2C1_CNT]]&lt;br /&gt;
| 0x10161001&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C1_CNTEX&lt;br /&gt;
| 0x10161002&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C1_SCL&lt;br /&gt;
| 0x10161004&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C2_DATA&lt;br /&gt;
| 0x10144000&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| [[#I2C_CNT|I2C2_CNT]]&lt;br /&gt;
| 0x10144001&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C2_CNTEX&lt;br /&gt;
| 0x10144002&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C2_SCL&lt;br /&gt;
| 0x10144004&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C3_DATA&lt;br /&gt;
| 0x10148000&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| [[#I2C_CNT|I2C3_CNT]]&lt;br /&gt;
| 0x10148001&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C3_CNTEX&lt;br /&gt;
| 0x10148002&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| 0x10148004&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C_CNT ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  BIT&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Stop (0=No, 1=Stop/last byte)&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Start (0=No, 1=Start/first byte)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Pause (0=Transfer Data, 1=Pause after Error, used with/after Stop)&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Ack Flag         (0=Error, 1=Okay)  (For DataRead: W, for DataWrite: R)&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Data Direction   (0=Write, 1=Read)&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Interrupt Enable (0=Disable, 1=Enable)&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Start/busy       (0=Ready, 1=Start/busy)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= I2C Devices =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!   [[I2C_Registers|Device id]]&lt;br /&gt;
!   Device bus id&lt;br /&gt;
!   Device Write Address&lt;br /&gt;
!   Accessible via I2C [[I2C_Services|service]]&lt;br /&gt;
!   Device description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0x4a&lt;br /&gt;
| &amp;quot;i2c::MCU&amp;quot;&lt;br /&gt;
| Power management?(same device addr as the DSi power-management)&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0x7a&lt;br /&gt;
| &amp;quot;i2c::CAM&amp;quot;&lt;br /&gt;
| Camera0?(same dev-addr as DSi cam0)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 1&lt;br /&gt;
| 0x78&lt;br /&gt;
| &amp;quot;i2c::CAM&amp;quot;&lt;br /&gt;
| Camera1?(same dev-addr as DSi cam1)&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| 2&lt;br /&gt;
| 0x4a&lt;br /&gt;
| &amp;quot;i2c::MCU&amp;quot;&lt;br /&gt;
| MCU&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| 2&lt;br /&gt;
| 0x78&lt;br /&gt;
| &amp;quot;i2c::CAM&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| 2&lt;br /&gt;
| 0x2c&lt;br /&gt;
| &amp;quot;i2c::LCD&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| 2&lt;br /&gt;
| 0x2e&lt;br /&gt;
| &amp;quot;i2c::LCD&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| 2&lt;br /&gt;
| 0x40&lt;br /&gt;
| &amp;quot;i2c::DEB&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| 2&lt;br /&gt;
| 0x44&lt;br /&gt;
| &amp;quot;i2c::DEB&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| 3&lt;br /&gt;
| 0xa6&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| Unknown. The device table in I2C-module had the device address changed from 0xA6 to 0xD6 with [[8.0.0-18]].&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| 3&lt;br /&gt;
| 0xd0&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| Gyroscope&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| 3&lt;br /&gt;
| 0xd2&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| 3&lt;br /&gt;
| 0xa4&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| DebugPad&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| 3&lt;br /&gt;
| 0x9a&lt;br /&gt;
| &amp;quot;i2c::IR&amp;quot;&lt;br /&gt;
| IR&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| 3&lt;br /&gt;
| 0xa0&lt;br /&gt;
| &amp;quot;i2c::EEP&amp;quot;&lt;br /&gt;
| eeprom?&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| 2&lt;br /&gt;
| 0xee&lt;br /&gt;
| &amp;quot;i2c::NFC&amp;quot;&lt;br /&gt;
| New3DS-only [[NFC_Services|NFC]]&lt;br /&gt;
|-&lt;br /&gt;
| 16&lt;br /&gt;
| 1&lt;br /&gt;
| 0x40&lt;br /&gt;
| &amp;quot;i2c::QTM&amp;quot;&lt;br /&gt;
| New3DS-only [[QTM_Services|QTM]]&lt;br /&gt;
|-&lt;br /&gt;
| 17&lt;br /&gt;
| 3&lt;br /&gt;
| 0x54&lt;br /&gt;
| &amp;quot;i2c::IR&amp;quot;&lt;br /&gt;
| Used by IR-module starting with [[8.0.0-18]], for New3DS-only HID via &amp;quot;ir:rst&amp;quot;. This deviceid doesn&#039;t seem to be supported by i2c module on [[8.0.0-18]](actual support was later added in New3DS i2c module).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notice&#039;&#039;&#039;: These device addresses are used for writing to the respective device, for reading bit0 must be set (see I2C protocol). Thus, the actual device address is &amp;gt;&amp;gt; 1.&lt;br /&gt;
&lt;br /&gt;
== Device 3 ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  REGISTER&lt;br /&gt;
!  WIDTH&lt;br /&gt;
!  INFO&lt;br /&gt;
!  DESCRIPTION &lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Version high&lt;br /&gt;
|-&lt;br /&gt;
| 0x01&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Version low&lt;br /&gt;
|-&lt;br /&gt;
| 0x02&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x03&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Top screen flicker&lt;br /&gt;
|-&lt;br /&gt;
| 0x04&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Bottom screen flicker&lt;br /&gt;
|-&lt;br /&gt;
| 0x05&lt;br /&gt;
- 0x07&lt;br /&gt;
| s(3)&lt;br /&gt;
| rw&lt;br /&gt;
| Danger zone - [[MCU_Services#MCU_firmware_versions|MCU unlock sequence]] is written here&lt;br /&gt;
|-&lt;br /&gt;
| 0x08&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Raw 3D slider position&lt;br /&gt;
|-&lt;br /&gt;
| 0x09&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Volume slider state (0x00 - 0x3F)&lt;br /&gt;
This is the same value returned by [[MCUHWC:GetSoundVolume|MCUHWC:GetSoundVolume]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x0A&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ? (seems to be power management related?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x0B&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Battery percentage&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ? (changes to 0 for a second when the charger is plugged in then it resets to its previous value)&lt;br /&gt;
|-&lt;br /&gt;
| 0x0D&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| System voltage&lt;br /&gt;
|-&lt;br /&gt;
| 0x0E&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x0F&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Flags: bit7-5 are read via [[MCU_Services|mcu::GPU]]. The rest of these are read via [[MCU_Services|mcu::RTC]]: bit4 = BatteryChargeState. bit3 = AdapterState. bit1 = ShellState.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
- 0x13&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Received interrupt bitmask, see register 0x18 for possible values  &lt;br /&gt;
If no interrupt was received this register is 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
- 0x1B&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Interrupt mask for register 0x10 (0=enabled,1=disabled)&lt;br /&gt;
  bit00: Power button press&lt;br /&gt;
  bit01: Power button held (the 3DS turns off regardless after a fixed time)&lt;br /&gt;
  bit02: HOME button press&lt;br /&gt;
  bit03: HOME button release&lt;br /&gt;
  bit04: WiFi switch button&lt;br /&gt;
  bit05: Shell close&lt;br /&gt;
  bit06: Shell open&lt;br /&gt;
  bit07: Fatal hardware condition([[Services#Notifications|?]])&lt;br /&gt;
  bit08: Charger removed&lt;br /&gt;
  bit09: Charger plugged in&lt;br /&gt;
  bit10: ??? (Power Management related?)&lt;br /&gt;
  bit11: ??? (HID related)&lt;br /&gt;
  bit12: HID update&lt;br /&gt;
  bit13: Battery dead(?)&lt;br /&gt;
  bit14: ??? (Power Management related?)&lt;br /&gt;
  bit15: ??? (Power Management related?)&lt;br /&gt;
  bit22: Volume slider position change&lt;br /&gt;
  bit24: ??? (???)&lt;br /&gt;
  bit25: ??? (???)&lt;br /&gt;
  bit26: ??? (???)&lt;br /&gt;
  bit27: ??? (???)&lt;br /&gt;
  bit28: ??? (???)&lt;br /&gt;
  bit29: ??? (???)&lt;br /&gt;
  bit30: forced off my mcu sysmodule&lt;br /&gt;
  bit31: forced off my mcu sysmodule&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ? (survives reboot and power off)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ? (survives reboot and power off)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ? (survives reboot and power off)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ? (survives reboot and power off)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| s&lt;br /&gt;
| wo&lt;br /&gt;
| System power control:&lt;br /&gt;
  bit0: power off&lt;br /&gt;
  bit1: reboot (unused?)&lt;br /&gt;
  bit2: reboot (used by mcu sysmodule and LgyBg)&lt;br /&gt;
  bit3: used by LgyBg to power off, causes hangs in 3DS-mode&lt;br /&gt;
  bit4: doesn&#039;t seem to do anything, but an mcu::RTC command uses this&lt;br /&gt;
Other bits are unused, and seem to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| s&lt;br /&gt;
| wo&lt;br /&gt;
| Used to set LCD states&lt;br /&gt;
  bit0: don&#039;t push to LCDs&lt;br /&gt;
  bit1: push to LCDs&lt;br /&gt;
  bit2: bottom screen backlight off&lt;br /&gt;
  bit3: bottom screen backlight on&lt;br /&gt;
  bit4: top screen backlight off (does nothing on 2DS as the backlight is bottom only)&lt;br /&gt;
  bit5: top screen backlight on (see above)&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| s&lt;br /&gt;
| ??&lt;br /&gt;
| Watchdog timer. This must be set *before* the timer is triggered, otherwise the old value is used. Value zero disables the watchdog.&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x26&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x27&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Raw volume slider state&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Brightness of the WiFi/Power LED&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| ds(0x64)&lt;br /&gt;
| ro / rw&lt;br /&gt;
| Empty battery pattern holder, repeats all written bytes&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| WiFi LED state, non-0 value turns on the WiFi LED, capped at 0x0F&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Camera LED state, 0, 3, 6-0xF = off, 1 = slowly blinking, 2 = constantly on, 4 = flash once, 5 = delay before changing to 2&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| 3D LED state, capped at 0x0F&lt;br /&gt;
|-&lt;br /&gt;
| 0x2D&lt;br /&gt;
| 0x64&lt;br /&gt;
| wo&lt;br /&gt;
| This is used for [[MCURTC:SetInfoLEDPattern|controlling]] the notification LED (see [[MCURTC:SetInfoLEDPatternHeader]] as well), when this register is written. It&#039;s possible to write data here with size less than 0x64, and only that portion of the pattern data will get overwritten. Reading from this register only returns zeroes, so it&#039;s considered write-only. Writing past the size of this register seems to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| 0x2E&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| This [[MCURTC:GetInfoLEDStatus|returns]] the notification LED status when read (1 means new cycle started)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2F&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
- 0x37&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| RTC time (system clock). 7 bytes are read from this. The upper nibble of each byte encodes 10s (BCD), so each byte is post-processed with (byte &amp;amp; 0xF) + (10 * (byte &amp;gt;&amp;gt; 4)).&lt;br /&gt;
  byte 0: seconds&lt;br /&gt;
  byte 1: minutes&lt;br /&gt;
  byte 2: hours&lt;br /&gt;
  byte 3: current day of the week (unused)&lt;br /&gt;
  byte 4: days&lt;br /&gt;
  byte 5: months&lt;br /&gt;
  byte 6: years&lt;br /&gt;
  byte 7: leap year counter (unused)&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
- 0x3C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| RTC alarm registers&lt;br /&gt;
Register 0x3B could be used to upload [[MCU_Services#MCU_firmware_versions|MCU firmware]] if some conditions are met.&lt;br /&gt;
|-&lt;br /&gt;
| 0x3D&lt;br /&gt;
0x3E&lt;br /&gt;
| s (2)&lt;br /&gt;
| ro&lt;br /&gt;
| RTC tick counter (resets to 0 when the seconds increase)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3F&lt;br /&gt;
| s&lt;br /&gt;
| wo&lt;br /&gt;
| Peripheral power related? bit0 seems to depower everything, pressing the power key afterwards instantly turns the whole 3DS off&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Pedometer state (?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Index selector for register 0x44&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???, accelometer related&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???, accelometer related&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Gyro Y(?) axis rotation (0x00 = flat, 0x40 = 3DS standing on right side, 0xBE = 3DS standing on left side)&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Gyro Z(?) axis rotation (0x00 = flat, 0x40 = 3DS standing horizontally, 0xBE = 3DS base is horizontally upside-down)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Gyro X(?) axis rotation (0x00 = 3DS base facing upwards, 0x40 = face-down flat, 0xBE = standing(?) flat)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| PedometerStepCount (for the current day)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x4F&lt;br /&gt;
| 0x156&lt;br /&gt;
| ro&lt;br /&gt;
| ???&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???&lt;br /&gt;
|-&lt;br /&gt;
| 0x51&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???&lt;br /&gt;
|-&lt;br /&gt;
| 0x52&lt;br /&gt;
- 0x57&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| DSP volume slider 0% volume offset (setting this to 0xFF will esentially mute the DSP as it&#039;s the volume slider&#039;s maximum raw value)&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| DSP volume slider 100% volume offset (setting both this and the above to 0 will disable the volume slider with 100% volume, setting this to a lower value than the above will make the volume slider have only 2 states; on and off)&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x5B&lt;br /&gt;
- 0x5F&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ? (these seem to be invalid regsiters)&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ds(1)&lt;br /&gt;
| ro&lt;br /&gt;
first byte is wo&lt;br /&gt;
| Looping queue register&lt;br /&gt;
Writing to first byte resets the queue position to the nth element&lt;br /&gt;
Reading from this register causes the values to shift up by `readsize-1`(needs confirmation) bytes after returning `readsize-1` bytes from the top of the stack (first byte is read-only, so is always zero)&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| ds(0x100)&lt;br /&gt;
| rw&lt;br /&gt;
| Writing to this register pushes values on top of register 0x60&#039;s stack. Reading from this register doesn&#039;t advance the stack.&lt;br /&gt;
The first byte is used to store flags for managing FIRM/NS state - bit0 = &amp;quot;WirelessDisabled&amp;quot;, bit1 = &amp;quot;SoftwareClosed&amp;quot;, bit2 = &amp;quot;PowerOffInitiated&amp;quot;, bit4 = &amp;quot;LegacyJumpProhibited&amp;quot;. This register survives power-off, but does not seem to be saved to non-volatile storage (does not survive battery pulls). This register doesn&#039;t seem to actually control MCU behaviour by itself, it just seems to be used for storing arbitrary data.&lt;br /&gt;
|-&lt;br /&gt;
| 0x62 - 0x7E&lt;br /&gt;
| s&lt;br /&gt;
| invalid (ro)&lt;br /&gt;
| These registers don&#039;t exist at all, thus reading them will yield 0xFF&lt;br /&gt;
|-&lt;br /&gt;
| 0x7F&lt;br /&gt;
| 19(?)&lt;br /&gt;
| ro&lt;br /&gt;
| Various system state information.&lt;br /&gt;
  byte 06: battery related? (seems to decrease while charging and increase while discharging)&lt;br /&gt;
  byte 09: system model (see [[Cfg:GetSystemModel#System_Model_Values|Cfg:GetSystemModel]] for values)&lt;br /&gt;
  byte 10: power LED related? 0 is off, 1 is red&lt;br /&gt;
  byte 13: RGB LED red intensity&lt;br /&gt;
  byte 14: RGB LED green intensity&lt;br /&gt;
  byte 15: RGB LED blue intensity&lt;br /&gt;
  byte 17: WiFi LED brightness&lt;br /&gt;
  byte 18: raw button states?&lt;br /&gt;
    bit0: unset while power button is held&lt;br /&gt;
    bit1: unset while home button is held&lt;br /&gt;
    bit2: unset while Wifi slider is held&lt;br /&gt;
    bit5: unset while the charging LED is active&lt;br /&gt;
    bit6: unset while charger is plugged in&lt;br /&gt;
    &lt;br /&gt;
    this byte is reset to 0 before an svcBreak takes effect&lt;br /&gt;
|-&lt;br /&gt;
| 0x80&lt;br /&gt;
- 0xFF&lt;br /&gt;
| s&lt;br /&gt;
| invalid (ro)&lt;br /&gt;
| These registers don&#039;t exist at all, thus reading them will yield 0xFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: the letter &amp;quot;s&amp;quot; in the size field means that the given register is in a &amp;quot;shared register pool&amp;quot;, meaning if you read/write with size more than 1 you can read the next `readamount-1` of shared registers. It&#039;s possible to corrupt the shared value of a &amp;quot;non-shared&amp;quot; register by writing into a shared register with a size bigger than one. Writing more than 0x100 bytes into a shared register will corrupt all writable registers, including the shared portion of &amp;quot;non-shared&amp;quot; registers.&lt;br /&gt;
&lt;br /&gt;
Non-shared register: it&#039;s a register separate from the shared register pool. Messing with these registers will not affect the shared register pool at all.&lt;br /&gt;
&lt;br /&gt;
== Device 5 &amp;amp; 6 ==&lt;br /&gt;
LCD controllers for main/sub displays, most likely.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Register&lt;br /&gt;
!  Width&lt;br /&gt;
!  Name&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 8&lt;br /&gt;
| CMD_IN/CMD_RESULT1&lt;br /&gt;
| Write to trigger a command? Seen commands: 0xFF=Reset?, 0x62=IsFinished?. Result is stored in CMD_RESULT1:CMD_RESULT0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| 8&lt;br /&gt;
| CMD_RESULT0&lt;br /&gt;
| Read result &lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0xFE&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Device 10 ==&lt;br /&gt;
See the datasheet linked to on the [[Hardware]] page for reference.&lt;br /&gt;
&lt;br /&gt;
== Device 12 ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  REGISTER&lt;br /&gt;
!  WIDTH&lt;br /&gt;
!  DESCRIPTION &lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 21&lt;br /&gt;
| DebugPad state.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the DebugPad device, see [[HID_Shared_Memory|here]].&lt;br /&gt;
&lt;br /&gt;
== Device 13 ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Raw I2C register address&lt;br /&gt;
!  Internal register address&lt;br /&gt;
!  Width&lt;br /&gt;
!  Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x40&lt;br /&gt;
| RHR / THR (data receive/send FIFO)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x1&lt;br /&gt;
| 0x1&lt;br /&gt;
| IER&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0x1&lt;br /&gt;
| FCR/IIR&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 0x3&lt;br /&gt;
| 0x1&lt;br /&gt;
| LCR&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x1&lt;br /&gt;
| MCR&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| 0x5&lt;br /&gt;
| 0x1&lt;br /&gt;
| LSR&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x6&lt;br /&gt;
| 0x1&lt;br /&gt;
| MSR/TCR&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x7&lt;br /&gt;
| 0x1&lt;br /&gt;
| SPR/TLR&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x1&lt;br /&gt;
| TXLVL&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| 0x9&lt;br /&gt;
| 0x1&lt;br /&gt;
| RXLVL&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0xA&lt;br /&gt;
| 0x1&lt;br /&gt;
| IODir&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0xB&lt;br /&gt;
| 0x1&lt;br /&gt;
| IOState&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 0xC&lt;br /&gt;
| 0x1&lt;br /&gt;
| IoIntEna&lt;br /&gt;
|-&lt;br /&gt;
| 0x68&lt;br /&gt;
| 0xD&lt;br /&gt;
| 0x1&lt;br /&gt;
| reserved&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| 0xE&lt;br /&gt;
| 0x1&lt;br /&gt;
| IOControl&lt;br /&gt;
|-&lt;br /&gt;
| 0x78&lt;br /&gt;
| 0xF&lt;br /&gt;
| 0x1&lt;br /&gt;
| EFCR&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See the [http://www.alldatasheet.net/datasheet-pdf/pdf/347838/NXP/SC16IS750IBS.html datasheet] linked to on the [[Hardware]] page for reference. From that datasheet, for the structure of the I2C register address u8: &amp;quot;Bit 0 is not used, bits 2:1 select the channel, bits 6:3 select one of the UART internal registers. Bit 7 is not used with the I2C-bus interface, but it is used by the SPI interface to indicate a read or a write operation.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Device 14 ==&lt;br /&gt;
&lt;br /&gt;
Used by [[Config_Services|Cfg]]-sysmodule via the i2c::EEP service. This is presumably EEPROM going by the service name.&lt;br /&gt;
&lt;br /&gt;
The Cfg-module code which loads the [[Flash_Filesystem|CCAL]](nandro:/sys/{HWCAL0.dat/HWCAL1.dat}) file from NAND will load it from I2C instead, if a certain state flag is non-zero. Likewise for the function which writes CCAL to NAND. HMAC/hash verification after loading is skipped when the CCAL was loaded from I2C.&lt;br /&gt;
&lt;br /&gt;
== Device 15 ==&lt;br /&gt;
This the New3DS [[NFC_Services|NFC]] controller &amp;quot;I2C&amp;quot; interface. This device is accessed via the WriteDeviceRaw/ReadDeviceRaw I2C service [[I2C_Services|commands]].&lt;br /&gt;
&lt;br /&gt;
Since the *Raw commands are used with this, this device has no I2C registers. Instead, raw data is transfered after the I2C device is selected. Hence, WriteDeviceRaw is used for sending commands to the controller, while ReadDeviceRaw is for receiving responses from the controller. Certain commands may return multiple command responses.&lt;br /&gt;
&lt;br /&gt;
Command request / response structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x1&lt;br /&gt;
| Normally 0x10?&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 0x1&lt;br /&gt;
| Command source / destination.&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0x1&lt;br /&gt;
| CmdID&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 0x1&lt;br /&gt;
| Payload size.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following the above header is the payload data(when payload size is non-zero), with the size specified in the header. The command response payload is usually at least 1-byte, where that byte appears to be normally 0x0. For command requests the payload data is the command parameters.&lt;br /&gt;
&lt;br /&gt;
For command requests sent to the NFC tag itself, Cmd[1]=0x0 and CmdID=0x0. The command request payload data here is the actual command request data for the NFC tag, starting with the CmdID u8 at payload+0.&lt;br /&gt;
&lt;br /&gt;
During NFC module startup, a certain command is sent to the controller which eventually(after various cmd-reply headers etc) returns the following the payload after the first byte in the payload:&lt;br /&gt;
 000000: 44 65 63 20 32 32 20 32 30 31 32 31 34 3a 35 33  Dec 22 201214:53 &lt;br /&gt;
 000010: 3a 35 30 01 05 0d 46 05 1b 79 20 07 32 30 37 39  :50...F..y .2079&lt;br /&gt;
 000020: 31 42 35                                         1B5&lt;br /&gt;
&lt;br /&gt;
Or that is: &amp;quot;Dec 22 201214:53:50&amp;lt;binary&amp;gt;20791B5&amp;quot;. Therefore, this appears to return the part-number of the NFC controller(other command request(s) / response(s) use this part-number value too).&lt;br /&gt;
&lt;br /&gt;
=== NFC controller commands  ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  CmdRequest[1]&lt;br /&gt;
!  CmdID&lt;br /&gt;
!  Payload data for parameters&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x2E&lt;br /&gt;
| 0x2F&lt;br /&gt;
| Firmware image for this chunk, size varies.&lt;br /&gt;
| This is used during NFC module startup to upload the firmware image to the NFC controller. This is used repeatedly to upload multiple chunks of the image.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=I2C_Registers&amp;diff=20427</id>
		<title>I2C Registers</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=I2C_Registers&amp;diff=20427"/>
		<updated>2017-10-26T20:26:30Z</updated>

		<summary type="html">&lt;p&gt;D0k3: Fixed typo for RTC offsets in MCU&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Registers =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Old3DS&lt;br /&gt;
!  Name&lt;br /&gt;
!  Address&lt;br /&gt;
!  Width&lt;br /&gt;
!  Used by&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C1_DATA&lt;br /&gt;
| 0x10161000&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| [[#I2C_CNT|I2C1_CNT]]&lt;br /&gt;
| 0x10161001&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C1_CNTEX&lt;br /&gt;
| 0x10161002&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C1_SCL&lt;br /&gt;
| 0x10161004&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 1 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C2_DATA&lt;br /&gt;
| 0x10144000&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| [[#I2C_CNT|I2C2_CNT]]&lt;br /&gt;
| 0x10144001&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C2_CNTEX&lt;br /&gt;
| 0x10144002&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C2_SCL&lt;br /&gt;
| 0x10144004&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 2 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C3_DATA&lt;br /&gt;
| 0x10148000&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| [[#I2C_CNT|I2C3_CNT]]&lt;br /&gt;
| 0x10148001&lt;br /&gt;
| 1&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C3_CNTEX&lt;br /&gt;
| 0x10148002&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background: green&amp;quot; | Yes&lt;br /&gt;
| I2C3_SCL&lt;br /&gt;
| 0x10148004&lt;br /&gt;
| 2&lt;br /&gt;
| I2C bus 3 devices&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== I2C_CNT ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  BIT&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Stop (0=No, 1=Stop/last byte)&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Start (0=No, 1=Start/first byte)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Pause (0=Transfer Data, 1=Pause after Error, used with/after Stop)&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Ack Flag         (0=Error, 1=Okay)  (For DataRead: W, for DataWrite: R)&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Data Direction   (0=Write, 1=Read)&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Interrupt Enable (0=Disable, 1=Enable)&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Start/busy       (0=Ready, 1=Start/busy)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= I2C Devices =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!   [[I2C_Registers|Device id]]&lt;br /&gt;
!   Device bus id&lt;br /&gt;
!   Device Write Address&lt;br /&gt;
!   Accessible via I2C [[I2C_Services|service]]&lt;br /&gt;
!   Device description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0x4a&lt;br /&gt;
| &amp;quot;i2c::MCU&amp;quot;&lt;br /&gt;
| Power management?(same device addr as the DSi power-management)&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0x7a&lt;br /&gt;
| &amp;quot;i2c::CAM&amp;quot;&lt;br /&gt;
| Camera0?(same dev-addr as DSi cam0)&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 1&lt;br /&gt;
| 0x78&lt;br /&gt;
| &amp;quot;i2c::CAM&amp;quot;&lt;br /&gt;
| Camera1?(same dev-addr as DSi cam1)&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| 2&lt;br /&gt;
| 0x4a&lt;br /&gt;
| &amp;quot;i2c::MCU&amp;quot;&lt;br /&gt;
| MCU&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| 2&lt;br /&gt;
| 0x78&lt;br /&gt;
| &amp;quot;i2c::CAM&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| 2&lt;br /&gt;
| 0x2c&lt;br /&gt;
| &amp;quot;i2c::LCD&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| 2&lt;br /&gt;
| 0x2e&lt;br /&gt;
| &amp;quot;i2c::LCD&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| 2&lt;br /&gt;
| 0x40&lt;br /&gt;
| &amp;quot;i2c::DEB&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| 2&lt;br /&gt;
| 0x44&lt;br /&gt;
| &amp;quot;i2c::DEB&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| 3&lt;br /&gt;
| 0xa6&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| Unknown. The device table in I2C-module had the device address changed from 0xA6 to 0xD6 with [[8.0.0-18]].&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| 3&lt;br /&gt;
| 0xd0&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| Gyroscope&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| 3&lt;br /&gt;
| 0xd2&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| 3&lt;br /&gt;
| 0xa4&lt;br /&gt;
| &amp;quot;i2c::HID&amp;quot;&lt;br /&gt;
| DebugPad&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| 3&lt;br /&gt;
| 0x9a&lt;br /&gt;
| &amp;quot;i2c::IR&amp;quot;&lt;br /&gt;
| IR&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| 3&lt;br /&gt;
| 0xa0&lt;br /&gt;
| &amp;quot;i2c::EEP&amp;quot;&lt;br /&gt;
| eeprom?&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| 2&lt;br /&gt;
| 0xee&lt;br /&gt;
| &amp;quot;i2c::NFC&amp;quot;&lt;br /&gt;
| New3DS-only [[NFC_Services|NFC]]&lt;br /&gt;
|-&lt;br /&gt;
| 16&lt;br /&gt;
| 1&lt;br /&gt;
| 0x40&lt;br /&gt;
| &amp;quot;i2c::QTM&amp;quot;&lt;br /&gt;
| New3DS-only [[QTM_Services|QTM]]&lt;br /&gt;
|-&lt;br /&gt;
| 17&lt;br /&gt;
| 3&lt;br /&gt;
| 0x54&lt;br /&gt;
| &amp;quot;i2c::IR&amp;quot;&lt;br /&gt;
| Used by IR-module starting with [[8.0.0-18]], for New3DS-only HID via &amp;quot;ir:rst&amp;quot;. This deviceid doesn&#039;t seem to be supported by i2c module on [[8.0.0-18]](actual support was later added in New3DS i2c module).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notice&#039;&#039;&#039;: These device addresses are used for writing to the respective device, for reading bit0 must be set (see I2C protocol). Thus, the actual device address is &amp;gt;&amp;gt; 1.&lt;br /&gt;
&lt;br /&gt;
== Device 3 ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  REGISTER&lt;br /&gt;
!  WIDTH&lt;br /&gt;
!  INFO&lt;br /&gt;
!  DESCRIPTION &lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Version high&lt;br /&gt;
|-&lt;br /&gt;
| 0x01&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Version low&lt;br /&gt;
|-&lt;br /&gt;
| 0x02&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x03&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Top screen flicker&lt;br /&gt;
|-&lt;br /&gt;
| 0x04&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Bottom screen flicker&lt;br /&gt;
|-&lt;br /&gt;
| 0x05&lt;br /&gt;
- 0x07&lt;br /&gt;
| s(3)&lt;br /&gt;
| rw&lt;br /&gt;
| Danger zone - [[MCU_Services#MCU_firmware_versions|MCU unlock sequence]] is written here&lt;br /&gt;
|-&lt;br /&gt;
| 0x08&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Raw 3D slider position&lt;br /&gt;
|-&lt;br /&gt;
| 0x09&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Volume slider state (0x00 - 0x3F)&lt;br /&gt;
This is the same value returned by [[MCUHWC:GetSoundVolume|MCUHWC:GetSoundVolume]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x0A&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ? (seems to be power management related?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x0B&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Battery percentage&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ? (changes to 0 for a second when the charger is plugged in then it resets to its previous value)&lt;br /&gt;
|-&lt;br /&gt;
| 0x0D&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| System voltage&lt;br /&gt;
|-&lt;br /&gt;
| 0x0E&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x0F&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Flags: bit7-5 are read via [[MCU_Services|mcu::GPU]]. The rest of these are read via [[MCU_Services|mcu::RTC]]: bit4 = BatteryChargeState. bit3 = AdapterState. bit1 = ShellState.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
- 0x13&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Received interrupt bitmask, see register 0x18 for possible values  &lt;br /&gt;
If no interrupt was received this register is 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
- 0x1B&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Interrupt mask for register 0x10 (0=enabled,1=disabled)&lt;br /&gt;
  bit00: Power button press&lt;br /&gt;
  bit01: Power button held (the 3DS turns off regardless after a fixed time)&lt;br /&gt;
  bit02: HOME button press&lt;br /&gt;
  bit03: HOME button release&lt;br /&gt;
  bit04: WiFi switch button&lt;br /&gt;
  bit05: Shell close&lt;br /&gt;
  bit06: Shell open&lt;br /&gt;
  bit07: Fatal hardware condition([[Services#Notifications|?]])&lt;br /&gt;
  bit08: Charger removed&lt;br /&gt;
  bit09: Charger plugged in&lt;br /&gt;
  bit10: ??? (Power Management related?)&lt;br /&gt;
  bit11: ??? (HID related)&lt;br /&gt;
  bit12: HID update&lt;br /&gt;
  bit13: Battery dead(?)&lt;br /&gt;
  bit14: ??? (Power Management related?)&lt;br /&gt;
  bit15: ??? (Power Management related?)&lt;br /&gt;
  bit22: Volume slider position change&lt;br /&gt;
  bit24: ??? (???)&lt;br /&gt;
  bit25: ??? (???)&lt;br /&gt;
  bit26: ??? (???)&lt;br /&gt;
  bit27: ??? (???)&lt;br /&gt;
  bit28: ??? (???)&lt;br /&gt;
  bit29: ??? (???)&lt;br /&gt;
  bit30: forced off my mcu sysmodule&lt;br /&gt;
  bit31: forced off my mcu sysmodule&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| s&lt;br /&gt;
| wo&lt;br /&gt;
| System power control:&lt;br /&gt;
  bit0: power off&lt;br /&gt;
  bit1: reboot (unused?)&lt;br /&gt;
  bit2: reboot (used by mcu sysmodule and LgyBg)&lt;br /&gt;
  bit3: used by LgyBg to power off, causes hangs in 3DS-mode&lt;br /&gt;
  bit4: doesn&#039;t seem to do anything, but an mcu::RTC command uses this&lt;br /&gt;
Other bits are unused, and seem to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| s&lt;br /&gt;
| wo&lt;br /&gt;
| Used to set LCD states&lt;br /&gt;
  bit0: don&#039;t push to LCDs&lt;br /&gt;
  bit1: push to LCDs&lt;br /&gt;
  bit2: bottom screen backlight off&lt;br /&gt;
  bit3: bottom screen backlight on&lt;br /&gt;
  bit4: top screen backlight off&lt;br /&gt;
  bit5: top screen backlight on&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| s&lt;br /&gt;
| ??&lt;br /&gt;
| Watchdog timer. This must be set *before* the timer is triggered, otherwise the old value is used. Value zero disables the watchdog.&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x26&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x27&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Raw volume slider state&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Brightness of the WiFi/Power LED&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| ds(0x64)&lt;br /&gt;
| ro / rw&lt;br /&gt;
| Empty battery pattern holder, repeats all written bytes&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| WiFi LED state, non-0 value turns on the WiFi LED, capped at 0x0F&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Camera LED state, 0, 3, 6-0xF = off, 1 = slowly blinking, 2 = constantly on, 4 = flash once, 5 = delay before changing to 2&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| 3D LED state, capped at 0x0F&lt;br /&gt;
|-&lt;br /&gt;
| 0x2D&lt;br /&gt;
| 0x64&lt;br /&gt;
| wo&lt;br /&gt;
| This is used for [[MCURTC:SetInfoLEDPattern|controlling]] the notification LED (see [[MCURTC:SetInfoLEDPatternHeader]] as well), when this register is written. It&#039;s possible to write data here with size less than 0x64, and only that portion of the pattern data will get overwritten. Reading from this register only returns zeroes, so it&#039;s considered write-only. Writing past the size of this register seems to do nothing.&lt;br /&gt;
|-&lt;br /&gt;
| 0x2E&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| This [[MCURTC:GetInfoLEDStatus|returns]] the notification LED status when read (1 means new cycle started)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2F&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
- 0x37&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| RTC time (system clock). 7 bytes are read from this. The upper nibble of each byte encodes 10s (BCD), so each byte is post-processed with (byte &amp;amp; 0xF) + (10 * (byte &amp;gt;&amp;gt; 4)).&lt;br /&gt;
  byte 0: seconds&lt;br /&gt;
  byte 1: minutes&lt;br /&gt;
  byte 2: hours&lt;br /&gt;
  byte 3: current day of the week (unused)&lt;br /&gt;
  byte 4: days&lt;br /&gt;
  byte 5: months&lt;br /&gt;
  byte 6: years&lt;br /&gt;
  byte 7: leap year counter (unused)&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
- 0x3C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| RTC alarm registers&lt;br /&gt;
Register 0x3B could be used to upload [[MCU_Services#MCU_firmware_versions|MCU firmware]] if some conditions are met.&lt;br /&gt;
|-&lt;br /&gt;
| 0x3D&lt;br /&gt;
0x3E&lt;br /&gt;
| s (2)&lt;br /&gt;
| ro&lt;br /&gt;
| RTC tick counter (resets to 0 when the seconds increase)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3F&lt;br /&gt;
| s&lt;br /&gt;
| wo&lt;br /&gt;
| Peripheral power related? bit0 seems to depower everything, pressing the power key afterwards instantly turns the whole 3DS off&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Pedometer state (?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| Index selector for register 0x44&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???, accelometer related&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???, accelometer related&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Gyro Y(?) axis rotation (0x00 = flat, 0x40 = 3DS standing on right side, 0xBE = 3DS standing on left side)&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Gyro Z(?) axis rotation (0x00 = flat, 0x40 = 3DS standing horizontally, 0xBE = 3DS base is horizontally upside-down)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| s&lt;br /&gt;
| ro&lt;br /&gt;
| Gyro X(?) axis rotation (0x00 = 3DS base facing upwards, 0x40 = face-down flat, 0xBE = standing(?) flat)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| PedometerStepCount (for the current day)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x4F&lt;br /&gt;
| 0x156&lt;br /&gt;
| ro&lt;br /&gt;
| ???&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???&lt;br /&gt;
|-&lt;br /&gt;
| 0x51&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ???&lt;br /&gt;
|-&lt;br /&gt;
| 0x52&lt;br /&gt;
- 0x57&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| DSP volume slider 0% volume offset (setting this to 0xFF will esentially mute the DSP as it&#039;s the volume slider&#039;s maximum raw value)&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| DSP volume slider 100% volume offset (setting both this and the above to 0 will disable the volume slider with 100% volume, setting this to a lower value than the above will make the volume slider have only 2 states; on and off)&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| s&lt;br /&gt;
| rw&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x5B&lt;br /&gt;
- 0x5F&lt;br /&gt;
| s&lt;br /&gt;
| ro(?)&lt;br /&gt;
| ? (these seem to be invalid regsiters)&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ds(1)&lt;br /&gt;
| ro&lt;br /&gt;
first byte is wo&lt;br /&gt;
| Looping queue register&lt;br /&gt;
Writing to first byte resets the queue position to the nth element&lt;br /&gt;
Reading from this register causes the values to shift up by `readsize-1`(needs confirmation) bytes after returning `readsize-1` bytes from the top of the stack (first byte is read-only, so is always zero)&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| ds(0x100)&lt;br /&gt;
| rw&lt;br /&gt;
| Writing to this register pushes values on top of register 0x60&#039;s stack. Reading from this register doesn&#039;t advance the stack.&lt;br /&gt;
The first byte is used to store flags for managing FIRM/NS state - bit0 = &amp;quot;WirelessDisabled&amp;quot;, bit1 = &amp;quot;SoftwareClosed&amp;quot;, bit2 = &amp;quot;PowerOffInitiated&amp;quot;, bit4 = &amp;quot;LegacyJumpProhibited&amp;quot;. This register survives power-off, but does not seem to be saved to non-volatile storage (does not survive battery pulls). This register doesn&#039;t seem to actually control MCU behaviour by itself, it just seems to be used for storing arbitrary data.&lt;br /&gt;
|-&lt;br /&gt;
| 0x62 - 0x7E&lt;br /&gt;
| s&lt;br /&gt;
| invalid (ro)&lt;br /&gt;
| These registers don&#039;t exist at all, thus reading them will yield 0xFF&lt;br /&gt;
|-&lt;br /&gt;
| 0x7F&lt;br /&gt;
| 19(?)&lt;br /&gt;
| ro&lt;br /&gt;
| Various system state information.&lt;br /&gt;
  byte 06: battery related? (seems to decrease while charging and increase while discharging)&lt;br /&gt;
  byte 09: system model (see [[Cfg:GetSystemModel#System_Model_Values|Cfg:GetSystemModel]] for values)&lt;br /&gt;
  byte 10: power LED related? 0 is off, 1 is red&lt;br /&gt;
  byte 13: RGB LED red intensity&lt;br /&gt;
  byte 14: RGB LED green intensity&lt;br /&gt;
  byte 15: RGB LED blue intensity&lt;br /&gt;
  byte 17: WiFi LED brightness&lt;br /&gt;
  byte 18: raw button states?&lt;br /&gt;
    bit0: unset while power button is held&lt;br /&gt;
    bit1: unset while home button is held&lt;br /&gt;
    bit2: unset while Wifi slider is held&lt;br /&gt;
    bit5: unset while the charging LED is active&lt;br /&gt;
    bit6: unset while charger is plugged in&lt;br /&gt;
    &lt;br /&gt;
    this byte is reset to 0 before an svcBreak takes effect&lt;br /&gt;
|-&lt;br /&gt;
| 0x80&lt;br /&gt;
- 0xFF&lt;br /&gt;
| s&lt;br /&gt;
| invalid (ro)&lt;br /&gt;
| These registers don&#039;t exist at all, thus reading them will yield 0xFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: the letter &amp;quot;s&amp;quot; in the size field means that the given register is in a &amp;quot;shared register pool&amp;quot;, meaning if you read/write with size more than 1 you can read the next `readamount-1` of shared registers. It&#039;s possible to corrupt the shared value of a &amp;quot;non-shared&amp;quot; register by writing into a shared register with a size bigger than one. Writing more than 0x100 bytes into a shared register will corrupt all writable registers, including the shared portion of &amp;quot;non-shared&amp;quot; registers.&lt;br /&gt;
&lt;br /&gt;
Non-shared register: it&#039;s a register separate from the shared register pool. Messing with these registers will not affect the shared register pool at all.&lt;br /&gt;
&lt;br /&gt;
== Device 5 &amp;amp; 6 ==&lt;br /&gt;
LCD controllers for main/sub displays, most likely.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Register&lt;br /&gt;
!  Width&lt;br /&gt;
!  Name&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 8&lt;br /&gt;
| CMD_IN/CMD_RESULT1&lt;br /&gt;
| Write to trigger a command? Seen commands: 0xFF=Reset?, 0x62=IsFinished?. Result is stored in CMD_RESULT1:CMD_RESULT0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| 8&lt;br /&gt;
| CMD_RESULT0&lt;br /&gt;
| Read result &lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0xFE&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Device 10 ==&lt;br /&gt;
See the datasheet linked to on the [[Hardware]] page for reference.&lt;br /&gt;
&lt;br /&gt;
== Device 12 ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  REGISTER&lt;br /&gt;
!  WIDTH&lt;br /&gt;
!  DESCRIPTION &lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 21&lt;br /&gt;
| DebugPad state.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is the DebugPad device, see [[HID_Shared_Memory|here]].&lt;br /&gt;
&lt;br /&gt;
== Device 13 ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Raw I2C register address&lt;br /&gt;
!  Internal register address&lt;br /&gt;
!  Width&lt;br /&gt;
!  Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x40&lt;br /&gt;
| RHR / THR (data receive/send FIFO)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x1&lt;br /&gt;
| 0x1&lt;br /&gt;
| IER&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0x1&lt;br /&gt;
| FCR/IIR&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 0x3&lt;br /&gt;
| 0x1&lt;br /&gt;
| LCR&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x1&lt;br /&gt;
| MCR&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| 0x5&lt;br /&gt;
| 0x1&lt;br /&gt;
| LSR&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x6&lt;br /&gt;
| 0x1&lt;br /&gt;
| MSR/TCR&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x7&lt;br /&gt;
| 0x1&lt;br /&gt;
| SPR/TLR&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x1&lt;br /&gt;
| TXLVL&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| 0x9&lt;br /&gt;
| 0x1&lt;br /&gt;
| RXLVL&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0xA&lt;br /&gt;
| 0x1&lt;br /&gt;
| IODir&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0xB&lt;br /&gt;
| 0x1&lt;br /&gt;
| IOState&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 0xC&lt;br /&gt;
| 0x1&lt;br /&gt;
| IoIntEna&lt;br /&gt;
|-&lt;br /&gt;
| 0x68&lt;br /&gt;
| 0xD&lt;br /&gt;
| 0x1&lt;br /&gt;
| reserved&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| 0xE&lt;br /&gt;
| 0x1&lt;br /&gt;
| IOControl&lt;br /&gt;
|-&lt;br /&gt;
| 0x78&lt;br /&gt;
| 0xF&lt;br /&gt;
| 0x1&lt;br /&gt;
| EFCR&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
See the [http://www.alldatasheet.net/datasheet-pdf/pdf/347838/NXP/SC16IS750IBS.html datasheet] linked to on the [[Hardware]] page for reference. From that datasheet, for the structure of the I2C register address u8: &amp;quot;Bit 0 is not used, bits 2:1 select the channel, bits 6:3 select one of the UART internal registers. Bit 7 is not used with the I2C-bus interface, but it is used by the SPI interface to indicate a read or a write operation.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Device 14 ==&lt;br /&gt;
&lt;br /&gt;
Used by [[Config_Services|Cfg]]-sysmodule via the i2c::EEP service. This is presumably EEPROM going by the service name.&lt;br /&gt;
&lt;br /&gt;
The Cfg-module code which loads the [[Flash_Filesystem|CCAL]](nandro:/sys/{HWCAL0.dat/HWCAL1.dat}) file from NAND will load it from I2C instead, if a certain state flag is non-zero. Likewise for the function which writes CCAL to NAND. HMAC/hash verification after loading is skipped when the CCAL was loaded from I2C.&lt;br /&gt;
&lt;br /&gt;
== Device 15 ==&lt;br /&gt;
This the New3DS [[NFC_Services|NFC]] controller &amp;quot;I2C&amp;quot; interface. This device is accessed via the WriteDeviceRaw/ReadDeviceRaw I2C service [[I2C_Services|commands]].&lt;br /&gt;
&lt;br /&gt;
Since the *Raw commands are used with this, this device has no I2C registers. Instead, raw data is transfered after the I2C device is selected. Hence, WriteDeviceRaw is used for sending commands to the controller, while ReadDeviceRaw is for receiving responses from the controller. Certain commands may return multiple command responses.&lt;br /&gt;
&lt;br /&gt;
Command request / response structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x1&lt;br /&gt;
| Normally 0x10?&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 0x1&lt;br /&gt;
| Command source / destination.&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0x1&lt;br /&gt;
| CmdID&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 0x1&lt;br /&gt;
| Payload size.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following the above header is the payload data(when payload size is non-zero), with the size specified in the header. The command response payload is usually at least 1-byte, where that byte appears to be normally 0x0. For command requests the payload data is the command parameters.&lt;br /&gt;
&lt;br /&gt;
For command requests sent to the NFC tag itself, Cmd[1]=0x0 and CmdID=0x0. The command request payload data here is the actual command request data for the NFC tag, starting with the CmdID u8 at payload+0.&lt;br /&gt;
&lt;br /&gt;
During NFC module startup, a certain command is sent to the controller which eventually(after various cmd-reply headers etc) returns the following the payload after the first byte in the payload:&lt;br /&gt;
 000000: 44 65 63 20 32 32 20 32 30 31 32 31 34 3a 35 33  Dec 22 201214:53 &lt;br /&gt;
 000010: 3a 35 30 01 05 0d 46 05 1b 79 20 07 32 30 37 39  :50...F..y .2079&lt;br /&gt;
 000020: 31 42 35                                         1B5&lt;br /&gt;
&lt;br /&gt;
Or that is: &amp;quot;Dec 22 201214:53:50&amp;lt;binary&amp;gt;20791B5&amp;quot;. Therefore, this appears to return the part-number of the NFC controller(other command request(s) / response(s) use this part-number value too).&lt;br /&gt;
&lt;br /&gt;
=== NFC controller commands  ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!  CmdRequest[1]&lt;br /&gt;
!  CmdID&lt;br /&gt;
!  Payload data for parameters&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x2E&lt;br /&gt;
| 0x2F&lt;br /&gt;
| Firmware image for this chunk, size varies.&lt;br /&gt;
| This is used during NFC module startup to upload the firmware image to the NFC controller. This is used repeatedly to upload multiple chunks of the image.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20393</id>
		<title>3DS Virtual Console</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20393"/>
		<updated>2017-10-10T12:36:22Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* NAND Savegame on SD */ terminology fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are several types of VC titles: NES/GB/GBC VC titles, SNES VC titles, GameGear VC titles and GBA VC titles.&lt;br /&gt;
Except for GBA VC, the games are ran using emulators.&lt;br /&gt;
&lt;br /&gt;
=NES/GB/GBC VC=&lt;br /&gt;
An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS). The emulator build includes support for all these three platforms, not specific to just the included ROM platform.&lt;br /&gt;
&lt;br /&gt;
This emulator includes GBA support, however the GBA emulation for this this is somewhat slow. This was presumably implemented before AGB_FIRM was.&lt;br /&gt;
&lt;br /&gt;
Unlike Wii VC, the 3DS VC ROMs for NES use [http://pastebin.com/KLeWt2W3 the &amp;quot;TNES&amp;quot; header].&lt;br /&gt;
&lt;br /&gt;
==RomFS==&lt;br /&gt;
* &amp;quot;rom:/rom/&amp;quot; This directory contains the ROM file(s). Filenames used under here don&#039;t matter: the filename is determined by the emulator app by doing a directory read.&lt;br /&gt;
* &amp;quot;rom:/shaders/&amp;quot; This directory contains GPU shaders used by the emulator app: .shbin, .csdr, and .obj.&lt;br /&gt;
* &amp;quot;rom:/VCM/&amp;quot; This directory contains graphics, audio, and text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/agb.bin&amp;quot; GBA BIOS.&lt;br /&gt;
* &amp;quot;rom:/buildtime.txt&amp;quot; Emulator app build timestamp.&lt;br /&gt;
* &amp;quot;rom:/config.ini&amp;quot; Emulator configuration .ini, contains sections for all supported 3DS VC platforms.&lt;br /&gt;
* &amp;quot;rom:/&amp;lt;rom_name&amp;gt;.patch&amp;quot; rom_name = filename from the rom directory. This .ini contains patches for the ROM.&lt;br /&gt;
* &amp;quot;rom:/shader.shbin&amp;quot; GPU shader.&lt;br /&gt;
&lt;br /&gt;
==Savedata==&lt;br /&gt;
The savedata can contain:&lt;br /&gt;
* &amp;quot;rsm1.dat&amp;quot;: Same format as the below rsm2.dat. Probably used for the &amp;quot;restore-point&amp;quot;.&lt;br /&gt;
* &amp;quot;rsm2.dat&amp;quot;: Current emulator save-state, for storing/loading state at VC-title launch/exit.&lt;br /&gt;
* &amp;quot;sav.dat&amp;quot;: The actual savedata used by the emulated ROM.&lt;br /&gt;
* &amp;quot;SecureValue&amp;quot;: The random number used by [[Anti Savegame Restore]]. No known version of the emulator implements both savestates and secure value.&lt;br /&gt;
Overwriting sav.dat with 0xFF-bytes doesn&#039;t have any affect on the actual emulator. Doing that with most of the rsm*.dat data doesn&#039;t crash anything.&lt;br /&gt;
&lt;br /&gt;
=SNES VC=&lt;br /&gt;
An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS).&lt;br /&gt;
SNES VC titles are New 3DS exclusive.&lt;br /&gt;
&lt;br /&gt;
==RomFS==&lt;br /&gt;
* &amp;quot;rom:/ErrorMessage/&amp;quot; This directory contains text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/shader/&amp;quot; This directory contains .shbin GPU shaders used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/VCM/&amp;quot; This directory contains text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/caravel.bcsar&amp;quot; This file contains audio used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/ctrl_change.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/data.bin&amp;quot; This file contains the ROM and other data. See below for documentation.&lt;br /&gt;
* &amp;quot;rom:/ErrorMessage.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/KTR-XXXX.icn&amp;quot; Copy of the SMDH of the game.&lt;br /&gt;
* &amp;quot;rom:/shader.shbin&amp;quot; GPU shader.&lt;br /&gt;
* &amp;quot;rom:/nnfont_RectDrawerShader.shbin&amp;quot; GPU shader.&lt;br /&gt;
* &amp;quot;rom:/VCM.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
&lt;br /&gt;
===data.bin structure===&lt;br /&gt;
The file begins with a header (all values are little-endian):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000100&lt;br /&gt;
|-&lt;br /&gt;
| 0x04&lt;br /&gt;
| 0x4&lt;br /&gt;
| File size&lt;br /&gt;
|-&lt;br /&gt;
| 0x08&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000030&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000050&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of the ROM (always 0x00000060 in official VC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 0x4&lt;br /&gt;
| End of the ROM&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of the footer region (presumably an index for the PCM audio samples). Matches end of file/file size if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of decompressed SDD-1 graphics data region. Matches end of file/file size if no SDD-1 chip is present&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 0x8&lt;br /&gt;
| Product ID (KTR-XXXX), determines filenames in savedata&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x1&lt;br /&gt;
| Emulation speed in FPS (always 0x3C in official VC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| 0x3&lt;br /&gt;
| ROM size&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x35&lt;br /&gt;
| 0x3&lt;br /&gt;
| Size of the converted PCM audio samples region (starting after ROM). 0 if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| 0x2&lt;br /&gt;
| Footer region size. 0 if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x3B&lt;br /&gt;
| 0x2&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x3D&lt;br /&gt;
| 0x2&lt;br /&gt;
| Game preset ID? (varies for each game). Incremental, started with 0x10XX values in old releases, newest ones have 0x11XX (with XX being back to low values).&lt;br /&gt;
|-&lt;br /&gt;
| 0x3F&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0x2&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x1&lt;br /&gt;
| Sound volume&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| 0x1&lt;br /&gt;
| ROM type (0x15 == HiROM/0x14 == LoROM)&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| 0xE&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000003&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000001&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0x8&lt;br /&gt;
| Always 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The 0x60 header is followed by the SNES ROM, often altered to replace audio samples with pointers to external PCM audio files converted from the game, presumably to speed up emulation (these pointers can be found by looking for &amp;quot;PCMF&amp;quot; in the ROM, as seen on [https://github.com/Plombo/vcromclaim/blob/master/snesrestore.py Wii VC]).&lt;br /&gt;
The ROM is then optionally followed by the PCM audio files, by the SDD-1 decompressed graphics data (presumably the emulator doesn&#039;t properly emulate the chip because of hardware constraints) and by a footer which appears to be an index for the PCM audio data.&lt;br /&gt;
There are no setting fields for specific cart features, and it appears that the emulator has &amp;quot;game presets&amp;quot; stored in its own code, which determine the cart expansion chip and probably more game-specific settings. Each official VC release has a different preset ID in the header.&lt;br /&gt;
&lt;br /&gt;
==Savedata==&lt;br /&gt;
The savedata contains:&lt;br /&gt;
* &amp;quot;KTR-XXXX.cfg&amp;quot;: Appears to contain the &amp;quot;preset ID&amp;quot; and possibly more game/save information.&lt;br /&gt;
* &amp;quot;KTR-XXXX.vea&amp;quot;: Current emulator save-state, for storing/loading state at VC-title launch/exit.&lt;br /&gt;
* &amp;quot;KTR-XXXX.ves&amp;quot;: The actual savedata used by the emulated ROM.&lt;br /&gt;
&lt;br /&gt;
Filenames are determined in the ROM header.&lt;br /&gt;
&lt;br /&gt;
=GBA VC=&lt;br /&gt;
GBA VC is run by [[FIRM|AGB_FIRM]]. RomFS isn&#039;t used for GBA VC titles, but can be found empty within GBA VC titles. The NCCH [[ExeFS]] contains the same files as a normal application. The [[ExeFS]]:/.code contains the GBA VC ROM followed by a 0x360 byte long footer.&lt;br /&gt;
&lt;br /&gt;
===Footer===&lt;br /&gt;
All values in the GBA VC footer are little-endian.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x004&lt;br /&gt;
|  0x4&lt;br /&gt;
|  GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x008&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save type (see below)&lt;br /&gt;
|-&lt;br /&gt;
| 0x020&lt;br /&gt;
| 0x4&lt;br /&gt;
| LCD ghosting (01-FF, lower values equal more ghosting)&lt;br /&gt;
|-&lt;br /&gt;
| 0x024&lt;br /&gt;
| 0x300&lt;br /&gt;
| Video LUT (black to full, rgbrgbrgb...)?,&amp;lt;br/&amp;gt;three different types of this data have been observed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x338&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x344&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x350&lt;br /&gt;
| 0x4&lt;br /&gt;
| Magic &#039;.CAA&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0x35A&lt;br /&gt;
| 0x2&lt;br /&gt;
| High two bytes of GBA ROM file size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save types:&lt;br /&gt;
* 0x0: EEPROM 8k&lt;br /&gt;
* 0x1: EEPROM 8k (?)&lt;br /&gt;
* 0x2: EEPROM 64k&lt;br /&gt;
* 0x3: EEPROM 64k (?)&lt;br /&gt;
* 0x4: Flash 512k (Atmel, ID: 0x3D1F) + RTC&lt;br /&gt;
* 0x5: Flash 512k (Atmel, ID: 0x3D1F)&lt;br /&gt;
* 0x6: Flash 512k (SST, ID: 0xD4BF) + RTC&lt;br /&gt;
* 0x7: Flash 512k (SST, ID: 0xD4BF)&lt;br /&gt;
* 0x8: Flash 512k (Panasonic, ID: 0x1B32) + RTC&lt;br /&gt;
* 0x9: Flash 512k (Panasonic, ID: 0x1B32)&lt;br /&gt;
* 0xA: Flash 1Mbit (Macronix, ID: 0x09C2) + RTC&lt;br /&gt;
* 0xB: Flash 1Mbit (Macronix, ID: 0x09C2)&lt;br /&gt;
* 0xC: Flash 1Mbit (Sanyo, ID: 0x1362) + RTC&lt;br /&gt;
* 0xD: Flash 1Mbit (Sanyo, ID: 0x1362)&lt;br /&gt;
* 0xE: SRAM/FRAM 256k&lt;br /&gt;
&lt;br /&gt;
Everything above 0xE results in no save chip and nothing being saved to NAND.&lt;br /&gt;
&lt;br /&gt;
===NAND Savegame===&lt;br /&gt;
AGB_FIRM saves its active save memory to NAND on exit, this is then immediately picked up by NATIVE_FIRM on reboot by checking [[CONFIG_Registers#CFG_BOOTENV|CFG_BOOTENV]]. From there, this is verified and copied out to SD (also see below). The savegame format is as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x0&lt;br /&gt;
|  0x4&lt;br /&gt;
|  Magic (&#039;.SAV&#039;)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0xC&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x10&lt;br /&gt;
| AES-CMAC of the SHA256 hash of 0x30..0x200 + the entire save itself, keyslot 0x24, keyY from process9 .rodata&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x10&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x1&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 0x4&lt;br /&gt;
| Number of times saved (unused?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x8&lt;br /&gt;
| AGB TitleID&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x10&lt;br /&gt;
| SD card CID from the console the save was made on (verified on load)&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save start addr (always 0x200)&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save size&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0x8&lt;br /&gt;
| Always 0xFF (?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x68&lt;br /&gt;
| 0x198&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===NAND Savegame on SD===&lt;br /&gt;
A NAND savegame copied to the SD by process9 is identical to its counterpart on the NAND partition, save for the CMAC. For SD copies on retail units, the CMAC is recalculated as the AES-CMAC of the (SHA256 hash of (&amp;quot;CTR-SIGN&amp;quot; + AGB TitleID (little endian) + SHA256 hash of (&amp;quot;CTR-SAV0&amp;quot; + SHA256 hash of (0x30..0x200 + the entire save itself)))), using keyslot 0x30 set up with the keyY from movable.sed. For SD copies on devkit units, the CMAC is recalculated using the SHA256 hash of 0x30..0x200 + the entire save itself, using a different key from process9 .rodata.&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20392</id>
		<title>3DS Virtual Console</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20392"/>
		<updated>2017-10-10T12:29:30Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* NAND Savegame on SD */ Fixed endianness of the title ID&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are several types of VC titles: NES/GB/GBC VC titles, SNES VC titles, GameGear VC titles and GBA VC titles.&lt;br /&gt;
Except for GBA VC, the games are ran using emulators.&lt;br /&gt;
&lt;br /&gt;
=NES/GB/GBC VC=&lt;br /&gt;
An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS). The emulator build includes support for all these three platforms, not specific to just the included ROM platform.&lt;br /&gt;
&lt;br /&gt;
This emulator includes GBA support, however the GBA emulation for this this is somewhat slow. This was presumably implemented before AGB_FIRM was.&lt;br /&gt;
&lt;br /&gt;
Unlike Wii VC, the 3DS VC ROMs for NES use [http://pastebin.com/KLeWt2W3 the &amp;quot;TNES&amp;quot; header].&lt;br /&gt;
&lt;br /&gt;
==RomFS==&lt;br /&gt;
* &amp;quot;rom:/rom/&amp;quot; This directory contains the ROM file(s). Filenames used under here don&#039;t matter: the filename is determined by the emulator app by doing a directory read.&lt;br /&gt;
* &amp;quot;rom:/shaders/&amp;quot; This directory contains GPU shaders used by the emulator app: .shbin, .csdr, and .obj.&lt;br /&gt;
* &amp;quot;rom:/VCM/&amp;quot; This directory contains graphics, audio, and text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/agb.bin&amp;quot; GBA BIOS.&lt;br /&gt;
* &amp;quot;rom:/buildtime.txt&amp;quot; Emulator app build timestamp.&lt;br /&gt;
* &amp;quot;rom:/config.ini&amp;quot; Emulator configuration .ini, contains sections for all supported 3DS VC platforms.&lt;br /&gt;
* &amp;quot;rom:/&amp;lt;rom_name&amp;gt;.patch&amp;quot; rom_name = filename from the rom directory. This .ini contains patches for the ROM.&lt;br /&gt;
* &amp;quot;rom:/shader.shbin&amp;quot; GPU shader.&lt;br /&gt;
&lt;br /&gt;
==Savedata==&lt;br /&gt;
The savedata can contain:&lt;br /&gt;
* &amp;quot;rsm1.dat&amp;quot;: Same format as the below rsm2.dat. Probably used for the &amp;quot;restore-point&amp;quot;.&lt;br /&gt;
* &amp;quot;rsm2.dat&amp;quot;: Current emulator save-state, for storing/loading state at VC-title launch/exit.&lt;br /&gt;
* &amp;quot;sav.dat&amp;quot;: The actual savedata used by the emulated ROM.&lt;br /&gt;
* &amp;quot;SecureValue&amp;quot;: The random number used by [[Anti Savegame Restore]]. No known version of the emulator implements both savestates and secure value.&lt;br /&gt;
Overwriting sav.dat with 0xFF-bytes doesn&#039;t have any affect on the actual emulator. Doing that with most of the rsm*.dat data doesn&#039;t crash anything.&lt;br /&gt;
&lt;br /&gt;
=SNES VC=&lt;br /&gt;
An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS).&lt;br /&gt;
SNES VC titles are New 3DS exclusive.&lt;br /&gt;
&lt;br /&gt;
==RomFS==&lt;br /&gt;
* &amp;quot;rom:/ErrorMessage/&amp;quot; This directory contains text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/shader/&amp;quot; This directory contains .shbin GPU shaders used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/VCM/&amp;quot; This directory contains text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/caravel.bcsar&amp;quot; This file contains audio used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/ctrl_change.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/data.bin&amp;quot; This file contains the ROM and other data. See below for documentation.&lt;br /&gt;
* &amp;quot;rom:/ErrorMessage.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/KTR-XXXX.icn&amp;quot; Copy of the SMDH of the game.&lt;br /&gt;
* &amp;quot;rom:/shader.shbin&amp;quot; GPU shader.&lt;br /&gt;
* &amp;quot;rom:/nnfont_RectDrawerShader.shbin&amp;quot; GPU shader.&lt;br /&gt;
* &amp;quot;rom:/VCM.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
&lt;br /&gt;
===data.bin structure===&lt;br /&gt;
The file begins with a header (all values are little-endian):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000100&lt;br /&gt;
|-&lt;br /&gt;
| 0x04&lt;br /&gt;
| 0x4&lt;br /&gt;
| File size&lt;br /&gt;
|-&lt;br /&gt;
| 0x08&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000030&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000050&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of the ROM (always 0x00000060 in official VC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 0x4&lt;br /&gt;
| End of the ROM&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of the footer region (presumably an index for the PCM audio samples). Matches end of file/file size if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of decompressed SDD-1 graphics data region. Matches end of file/file size if no SDD-1 chip is present&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 0x8&lt;br /&gt;
| Product ID (KTR-XXXX), determines filenames in savedata&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x1&lt;br /&gt;
| Emulation speed in FPS (always 0x3C in official VC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| 0x3&lt;br /&gt;
| ROM size&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x35&lt;br /&gt;
| 0x3&lt;br /&gt;
| Size of the converted PCM audio samples region (starting after ROM). 0 if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| 0x2&lt;br /&gt;
| Footer region size. 0 if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x3B&lt;br /&gt;
| 0x2&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x3D&lt;br /&gt;
| 0x2&lt;br /&gt;
| Game preset ID? (varies for each game). Incremental, started with 0x10XX values in old releases, newest ones have 0x11XX (with XX being back to low values).&lt;br /&gt;
|-&lt;br /&gt;
| 0x3F&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0x2&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x1&lt;br /&gt;
| Sound volume&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| 0x1&lt;br /&gt;
| ROM type (0x15 == HiROM/0x14 == LoROM)&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| 0xE&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000003&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000001&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0x8&lt;br /&gt;
| Always 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The 0x60 header is followed by the SNES ROM, often altered to replace audio samples with pointers to external PCM audio files converted from the game, presumably to speed up emulation (these pointers can be found by looking for &amp;quot;PCMF&amp;quot; in the ROM, as seen on [https://github.com/Plombo/vcromclaim/blob/master/snesrestore.py Wii VC]).&lt;br /&gt;
The ROM is then optionally followed by the PCM audio files, by the SDD-1 decompressed graphics data (presumably the emulator doesn&#039;t properly emulate the chip because of hardware constraints) and by a footer which appears to be an index for the PCM audio data.&lt;br /&gt;
There are no setting fields for specific cart features, and it appears that the emulator has &amp;quot;game presets&amp;quot; stored in its own code, which determine the cart expansion chip and probably more game-specific settings. Each official VC release has a different preset ID in the header.&lt;br /&gt;
&lt;br /&gt;
==Savedata==&lt;br /&gt;
The savedata contains:&lt;br /&gt;
* &amp;quot;KTR-XXXX.cfg&amp;quot;: Appears to contain the &amp;quot;preset ID&amp;quot; and possibly more game/save information.&lt;br /&gt;
* &amp;quot;KTR-XXXX.vea&amp;quot;: Current emulator save-state, for storing/loading state at VC-title launch/exit.&lt;br /&gt;
* &amp;quot;KTR-XXXX.ves&amp;quot;: The actual savedata used by the emulated ROM.&lt;br /&gt;
&lt;br /&gt;
Filenames are determined in the ROM header.&lt;br /&gt;
&lt;br /&gt;
=GBA VC=&lt;br /&gt;
GBA VC is run by [[FIRM|AGB_FIRM]]. RomFS isn&#039;t used for GBA VC titles, but can be found empty within GBA VC titles. The NCCH [[ExeFS]] contains the same files as a normal application. The [[ExeFS]]:/.code contains the GBA VC ROM followed by a 0x360 byte long footer.&lt;br /&gt;
&lt;br /&gt;
===Footer===&lt;br /&gt;
All values in the GBA VC footer are little-endian.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x004&lt;br /&gt;
|  0x4&lt;br /&gt;
|  GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x008&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save type (see below)&lt;br /&gt;
|-&lt;br /&gt;
| 0x020&lt;br /&gt;
| 0x4&lt;br /&gt;
| LCD ghosting (01-FF, lower values equal more ghosting)&lt;br /&gt;
|-&lt;br /&gt;
| 0x024&lt;br /&gt;
| 0x300&lt;br /&gt;
| Video LUT (black to full, rgbrgbrgb...)?,&amp;lt;br/&amp;gt;three different types of this data have been observed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x338&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x344&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x350&lt;br /&gt;
| 0x4&lt;br /&gt;
| Magic &#039;.CAA&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0x35A&lt;br /&gt;
| 0x2&lt;br /&gt;
| High two bytes of GBA ROM file size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save types:&lt;br /&gt;
* 0x0: EEPROM 8k&lt;br /&gt;
* 0x1: EEPROM 8k (?)&lt;br /&gt;
* 0x2: EEPROM 64k&lt;br /&gt;
* 0x3: EEPROM 64k (?)&lt;br /&gt;
* 0x4: Flash 512k (Atmel, ID: 0x3D1F) + RTC&lt;br /&gt;
* 0x5: Flash 512k (Atmel, ID: 0x3D1F)&lt;br /&gt;
* 0x6: Flash 512k (SST, ID: 0xD4BF) + RTC&lt;br /&gt;
* 0x7: Flash 512k (SST, ID: 0xD4BF)&lt;br /&gt;
* 0x8: Flash 512k (Panasonic, ID: 0x1B32) + RTC&lt;br /&gt;
* 0x9: Flash 512k (Panasonic, ID: 0x1B32)&lt;br /&gt;
* 0xA: Flash 1Mbit (Macronix, ID: 0x09C2) + RTC&lt;br /&gt;
* 0xB: Flash 1Mbit (Macronix, ID: 0x09C2)&lt;br /&gt;
* 0xC: Flash 1Mbit (Sanyo, ID: 0x1362) + RTC&lt;br /&gt;
* 0xD: Flash 1Mbit (Sanyo, ID: 0x1362)&lt;br /&gt;
* 0xE: SRAM/FRAM 256k&lt;br /&gt;
&lt;br /&gt;
Everything above 0xE results in no save chip and nothing being saved to NAND.&lt;br /&gt;
&lt;br /&gt;
===NAND Savegame===&lt;br /&gt;
AGB_FIRM saves its active save memory to NAND on exit, this is then immediately picked up by NATIVE_FIRM on reboot by checking [[CONFIG_Registers#CFG_BOOTENV|CFG_BOOTENV]]. From there, this is verified and copied out to SD (also see below). The savegame format is as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x0&lt;br /&gt;
|  0x4&lt;br /&gt;
|  Magic (&#039;.SAV&#039;)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0xC&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x10&lt;br /&gt;
| AES-CMAC of the SHA256 hash of 0x30..0x200 + the entire save itself, keyslot 0x24, keyY from process9 .rodata&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x10&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x1&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 0x4&lt;br /&gt;
| Number of times saved (unused?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x8&lt;br /&gt;
| AGB TitleID&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x10&lt;br /&gt;
| SD card CID from the console the save was made on (verified on load)&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save start addr (always 0x200)&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save size&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0x8&lt;br /&gt;
| Always 0xFF (?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x68&lt;br /&gt;
| 0x198&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===NAND Savegame on SD===&lt;br /&gt;
A NAND savegame copied to the SD by process9 is identical to its counterpart on the NAND partition, save for the CMAC. For SD copies on retail units, the CMAC is recalculated as the AES-CMAC of the (SHA256 hash of (&amp;quot;CTR-SIGN&amp;quot; + Title ID (little endian) + SHA256 hash of (&amp;quot;CTR-SAV0&amp;quot; + SHA256 hash of (0x30..0x200 + the entire save itself)))), using keyslot 0x30 set up with the keyY from movable.sed. For SD copies on devkit units, the CMAC is recalculated using the SHA256 hash of 0x30..0x200 + the entire save itself, using a different key from process9 .rodata.&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20391</id>
		<title>3DS Virtual Console</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20391"/>
		<updated>2017-10-10T12:27:22Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* GBA VC */ Add information about CMACs on SD AGBSAVE copies&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are several types of VC titles: NES/GB/GBC VC titles, SNES VC titles, GameGear VC titles and GBA VC titles.&lt;br /&gt;
Except for GBA VC, the games are ran using emulators.&lt;br /&gt;
&lt;br /&gt;
=NES/GB/GBC VC=&lt;br /&gt;
An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS). The emulator build includes support for all these three platforms, not specific to just the included ROM platform.&lt;br /&gt;
&lt;br /&gt;
This emulator includes GBA support, however the GBA emulation for this this is somewhat slow. This was presumably implemented before AGB_FIRM was.&lt;br /&gt;
&lt;br /&gt;
Unlike Wii VC, the 3DS VC ROMs for NES use [http://pastebin.com/KLeWt2W3 the &amp;quot;TNES&amp;quot; header].&lt;br /&gt;
&lt;br /&gt;
==RomFS==&lt;br /&gt;
* &amp;quot;rom:/rom/&amp;quot; This directory contains the ROM file(s). Filenames used under here don&#039;t matter: the filename is determined by the emulator app by doing a directory read.&lt;br /&gt;
* &amp;quot;rom:/shaders/&amp;quot; This directory contains GPU shaders used by the emulator app: .shbin, .csdr, and .obj.&lt;br /&gt;
* &amp;quot;rom:/VCM/&amp;quot; This directory contains graphics, audio, and text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/agb.bin&amp;quot; GBA BIOS.&lt;br /&gt;
* &amp;quot;rom:/buildtime.txt&amp;quot; Emulator app build timestamp.&lt;br /&gt;
* &amp;quot;rom:/config.ini&amp;quot; Emulator configuration .ini, contains sections for all supported 3DS VC platforms.&lt;br /&gt;
* &amp;quot;rom:/&amp;lt;rom_name&amp;gt;.patch&amp;quot; rom_name = filename from the rom directory. This .ini contains patches for the ROM.&lt;br /&gt;
* &amp;quot;rom:/shader.shbin&amp;quot; GPU shader.&lt;br /&gt;
&lt;br /&gt;
==Savedata==&lt;br /&gt;
The savedata can contain:&lt;br /&gt;
* &amp;quot;rsm1.dat&amp;quot;: Same format as the below rsm2.dat. Probably used for the &amp;quot;restore-point&amp;quot;.&lt;br /&gt;
* &amp;quot;rsm2.dat&amp;quot;: Current emulator save-state, for storing/loading state at VC-title launch/exit.&lt;br /&gt;
* &amp;quot;sav.dat&amp;quot;: The actual savedata used by the emulated ROM.&lt;br /&gt;
* &amp;quot;SecureValue&amp;quot;: The random number used by [[Anti Savegame Restore]]. No known version of the emulator implements both savestates and secure value.&lt;br /&gt;
Overwriting sav.dat with 0xFF-bytes doesn&#039;t have any affect on the actual emulator. Doing that with most of the rsm*.dat data doesn&#039;t crash anything.&lt;br /&gt;
&lt;br /&gt;
=SNES VC=&lt;br /&gt;
An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS).&lt;br /&gt;
SNES VC titles are New 3DS exclusive.&lt;br /&gt;
&lt;br /&gt;
==RomFS==&lt;br /&gt;
* &amp;quot;rom:/ErrorMessage/&amp;quot; This directory contains text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/shader/&amp;quot; This directory contains .shbin GPU shaders used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/VCM/&amp;quot; This directory contains text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/caravel.bcsar&amp;quot; This file contains audio used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/ctrl_change.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/data.bin&amp;quot; This file contains the ROM and other data. See below for documentation.&lt;br /&gt;
* &amp;quot;rom:/ErrorMessage.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/KTR-XXXX.icn&amp;quot; Copy of the SMDH of the game.&lt;br /&gt;
* &amp;quot;rom:/shader.shbin&amp;quot; GPU shader.&lt;br /&gt;
* &amp;quot;rom:/nnfont_RectDrawerShader.shbin&amp;quot; GPU shader.&lt;br /&gt;
* &amp;quot;rom:/VCM.arc&amp;quot; This file contains graphics used by the emulator app.&lt;br /&gt;
&lt;br /&gt;
===data.bin structure===&lt;br /&gt;
The file begins with a header (all values are little-endian):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000100&lt;br /&gt;
|-&lt;br /&gt;
| 0x04&lt;br /&gt;
| 0x4&lt;br /&gt;
| File size&lt;br /&gt;
|-&lt;br /&gt;
| 0x08&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000030&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000050&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of the ROM (always 0x00000060 in official VC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 0x4&lt;br /&gt;
| End of the ROM&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of the footer region (presumably an index for the PCM audio samples). Matches end of file/file size if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x4&lt;br /&gt;
| Start of decompressed SDD-1 graphics data region. Matches end of file/file size if no SDD-1 chip is present&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 0x8&lt;br /&gt;
| Product ID (KTR-XXXX), determines filenames in savedata&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x1&lt;br /&gt;
| Emulation speed in FPS (always 0x3C in official VC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| 0x3&lt;br /&gt;
| ROM size&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x35&lt;br /&gt;
| 0x3&lt;br /&gt;
| Size of the converted PCM audio samples region (starting after ROM). 0 if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| 0x2&lt;br /&gt;
| Footer region size. 0 if PCM data is missing&lt;br /&gt;
|-&lt;br /&gt;
| 0x3B&lt;br /&gt;
| 0x2&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x3D&lt;br /&gt;
| 0x2&lt;br /&gt;
| Game preset ID? (varies for each game). Incremental, started with 0x10XX values in old releases, newest ones have 0x11XX (with XX being back to low values).&lt;br /&gt;
|-&lt;br /&gt;
| 0x3F&lt;br /&gt;
| 0x1&lt;br /&gt;
| Always 0x2&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x1&lt;br /&gt;
| Sound volume&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| 0x1&lt;br /&gt;
| ROM type (0x15 == HiROM/0x14 == LoROM)&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| 0xE&lt;br /&gt;
| Always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000003&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x00000001&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0x8&lt;br /&gt;
| Always 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The 0x60 header is followed by the SNES ROM, often altered to replace audio samples with pointers to external PCM audio files converted from the game, presumably to speed up emulation (these pointers can be found by looking for &amp;quot;PCMF&amp;quot; in the ROM, as seen on [https://github.com/Plombo/vcromclaim/blob/master/snesrestore.py Wii VC]).&lt;br /&gt;
The ROM is then optionally followed by the PCM audio files, by the SDD-1 decompressed graphics data (presumably the emulator doesn&#039;t properly emulate the chip because of hardware constraints) and by a footer which appears to be an index for the PCM audio data.&lt;br /&gt;
There are no setting fields for specific cart features, and it appears that the emulator has &amp;quot;game presets&amp;quot; stored in its own code, which determine the cart expansion chip and probably more game-specific settings. Each official VC release has a different preset ID in the header.&lt;br /&gt;
&lt;br /&gt;
==Savedata==&lt;br /&gt;
The savedata contains:&lt;br /&gt;
* &amp;quot;KTR-XXXX.cfg&amp;quot;: Appears to contain the &amp;quot;preset ID&amp;quot; and possibly more game/save information.&lt;br /&gt;
* &amp;quot;KTR-XXXX.vea&amp;quot;: Current emulator save-state, for storing/loading state at VC-title launch/exit.&lt;br /&gt;
* &amp;quot;KTR-XXXX.ves&amp;quot;: The actual savedata used by the emulated ROM.&lt;br /&gt;
&lt;br /&gt;
Filenames are determined in the ROM header.&lt;br /&gt;
&lt;br /&gt;
=GBA VC=&lt;br /&gt;
GBA VC is run by [[FIRM|AGB_FIRM]]. RomFS isn&#039;t used for GBA VC titles, but can be found empty within GBA VC titles. The NCCH [[ExeFS]] contains the same files as a normal application. The [[ExeFS]]:/.code contains the GBA VC ROM followed by a 0x360 byte long footer.&lt;br /&gt;
&lt;br /&gt;
===Footer===&lt;br /&gt;
All values in the GBA VC footer are little-endian.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x004&lt;br /&gt;
|  0x4&lt;br /&gt;
|  GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x008&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save type (see below)&lt;br /&gt;
|-&lt;br /&gt;
| 0x020&lt;br /&gt;
| 0x4&lt;br /&gt;
| LCD ghosting (01-FF, lower values equal more ghosting)&lt;br /&gt;
|-&lt;br /&gt;
| 0x024&lt;br /&gt;
| 0x300&lt;br /&gt;
| Video LUT (black to full, rgbrgbrgb...)?,&amp;lt;br/&amp;gt;three different types of this data have been observed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x338&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x344&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x350&lt;br /&gt;
| 0x4&lt;br /&gt;
| Magic &#039;.CAA&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0x35A&lt;br /&gt;
| 0x2&lt;br /&gt;
| High two bytes of GBA ROM file size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save types:&lt;br /&gt;
* 0x0: EEPROM 8k&lt;br /&gt;
* 0x1: EEPROM 8k (?)&lt;br /&gt;
* 0x2: EEPROM 64k&lt;br /&gt;
* 0x3: EEPROM 64k (?)&lt;br /&gt;
* 0x4: Flash 512k (Atmel, ID: 0x3D1F) + RTC&lt;br /&gt;
* 0x5: Flash 512k (Atmel, ID: 0x3D1F)&lt;br /&gt;
* 0x6: Flash 512k (SST, ID: 0xD4BF) + RTC&lt;br /&gt;
* 0x7: Flash 512k (SST, ID: 0xD4BF)&lt;br /&gt;
* 0x8: Flash 512k (Panasonic, ID: 0x1B32) + RTC&lt;br /&gt;
* 0x9: Flash 512k (Panasonic, ID: 0x1B32)&lt;br /&gt;
* 0xA: Flash 1Mbit (Macronix, ID: 0x09C2) + RTC&lt;br /&gt;
* 0xB: Flash 1Mbit (Macronix, ID: 0x09C2)&lt;br /&gt;
* 0xC: Flash 1Mbit (Sanyo, ID: 0x1362) + RTC&lt;br /&gt;
* 0xD: Flash 1Mbit (Sanyo, ID: 0x1362)&lt;br /&gt;
* 0xE: SRAM/FRAM 256k&lt;br /&gt;
&lt;br /&gt;
Everything above 0xE results in no save chip and nothing being saved to NAND.&lt;br /&gt;
&lt;br /&gt;
===NAND Savegame===&lt;br /&gt;
AGB_FIRM saves its active save memory to NAND on exit, this is then immediately picked up by NATIVE_FIRM on reboot by checking [[CONFIG_Registers#CFG_BOOTENV|CFG_BOOTENV]]. From there, this is verified and copied out to SD (also see below). The savegame format is as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x0&lt;br /&gt;
|  0x4&lt;br /&gt;
|  Magic (&#039;.SAV&#039;)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0xC&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x10&lt;br /&gt;
| AES-CMAC of the SHA256 hash of 0x30..0x200 + the entire save itself, keyslot 0x24, keyY from process9 .rodata&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x10&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x1&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 0x4&lt;br /&gt;
| Number of times saved (unused?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x8&lt;br /&gt;
| AGB TitleID&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x10&lt;br /&gt;
| SD card CID from the console the save was made on (verified on load)&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save start addr (always 0x200)&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save size&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0x8&lt;br /&gt;
| Always 0xFF (?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x68&lt;br /&gt;
| 0x198&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===NAND Savegame on SD===&lt;br /&gt;
A NAND savegame copied to the SD by process9 is identical to its counterpart on the NAND partition, save for the CMAC. For SD copies on retail units, the CMAC is recalculated as the AES-CMAC of the (SHA256 hash of (&amp;quot;CTR-SIGN&amp;quot; + Title ID (big endian) + SHA256 hash of (&amp;quot;CTR-SAV0&amp;quot; + SHA256 hash of (0x30..0x200 + the entire save itself)))), using keyslot 0x30 set up with the keyY from movable.sed. For SD copies on devkit units, the CMAC is recalculated using the SHA256 hash of 0x30..0x200 + the entire save itself, using a different key from process9 .rodata.&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20306</id>
		<title>3DS Virtual Console</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=3DS_Virtual_Console&amp;diff=20306"/>
		<updated>2017-09-12T09:50:00Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* NAND Savegame */ - fixed a typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There&#039;s two types of VC titles: regular VC titles, and dedicated GBA VC titles.&lt;br /&gt;
&lt;br /&gt;
=Regular VC=&lt;br /&gt;
Regular VC titles: an emulator application + VC ROM in the NCCH [[RomFS]](among other things in the RomFS). The emulator build includes support for all supported VC platfms, not specific to just the included ROM platform.&lt;br /&gt;
&lt;br /&gt;
This emulator includes GBA support, however the GBA emulation for this this is somewhat slow. This was presumably implemented before AGB_FIRM was.&lt;br /&gt;
&lt;br /&gt;
Unlike Wii VC, the 3DS VC ROMs for NES use [http://pastebin.com/KLeWt2W3 the &amp;quot;TNES&amp;quot; header].&lt;br /&gt;
&lt;br /&gt;
==RomFS==&lt;br /&gt;
* &amp;quot;rom:/rom/&amp;quot; This directory contains the ROM file(s). Filenames used under here don&#039;t matter: the filename is determined by the emulator app by doing a directory read.&lt;br /&gt;
* &amp;quot;rom:/shaders/&amp;quot; This directory contains GPU shaders used by the emulator app: .shbin, .csdr, and .obj.&lt;br /&gt;
* &amp;quot;rom:/VCM/&amp;quot; This directory contains graphics, audio, and text used by the emulator app.&lt;br /&gt;
* &amp;quot;rom:/agb.bin&amp;quot; GBA BIOS.&lt;br /&gt;
* &amp;quot;rom:/buildtime.txt&amp;quot; Emulator app build timestamp.&lt;br /&gt;
* &amp;quot;rom:/config.ini&amp;quot; Emulator configuration .ini, contains sections for all supported 3DS VC platforms.&lt;br /&gt;
* &amp;quot;rom:/&amp;lt;rom_name&amp;gt;.patch&amp;quot; rom_name = filename from the rom directory. This .ini contains patches for the ROM.&lt;br /&gt;
* &amp;quot;rom:/shader.shbin&amp;quot; GPU shader.&lt;br /&gt;
&lt;br /&gt;
==Savedata==&lt;br /&gt;
The savedata can contain:&lt;br /&gt;
* &amp;quot;rsm1.dat&amp;quot;: Same format as the below rsm2.dat. Probably used for the &amp;quot;restore-point&amp;quot;.&lt;br /&gt;
* &amp;quot;rsm2.dat&amp;quot;: Current emulator save-state, for storing/loading state at VC-title launch/exit.&lt;br /&gt;
* &amp;quot;sav.dat&amp;quot;: The actual savedata used by the emulated ROM.&lt;br /&gt;
* &amp;quot;SecureValue&amp;quot;: The random number used by [[Anti Savegame Restore]]. No known version of the emulator implements both savestates and secure value.&lt;br /&gt;
Overwriting sav.dat with 0xFF-bytes doesn&#039;t have any affect on the actual emulator. Doing that with most of the rsm*.dat data doesn&#039;t crash anything.&lt;br /&gt;
&lt;br /&gt;
=GBA VC=&lt;br /&gt;
GBA VC is run by [[FIRM|AGB_FIRM]]. RomFS isn&#039;t used for GBA VC titles, but can be found empty within GBA VC titles. The NCCH [[ExeFS]] contains the same files as a normal application. The [[ExeFS]]:/.code contains the GBA VC ROM followed by a 0x360 byte long footer.&lt;br /&gt;
&lt;br /&gt;
===Footer===&lt;br /&gt;
All values in the GBA VC footer are little-endian.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x004&lt;br /&gt;
|  0x4&lt;br /&gt;
|  GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x008&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save type (see below)&lt;br /&gt;
|-&lt;br /&gt;
| 0x020&lt;br /&gt;
| 0x4&lt;br /&gt;
| LCD ghosting (01-FF, lower values equal more ghosting)&lt;br /&gt;
|-&lt;br /&gt;
| 0x024&lt;br /&gt;
| 0x300&lt;br /&gt;
| Video LUT (black to full, rgbrgbrgb...)?,&amp;lt;br/&amp;gt;three different types of this data have been observed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x338&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x344&lt;br /&gt;
| 0x4&lt;br /&gt;
| GBA ROM Filesize&lt;br /&gt;
|-&lt;br /&gt;
| 0x350&lt;br /&gt;
| 0x4&lt;br /&gt;
| Magic &#039;.CAA&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0x35A&lt;br /&gt;
| 0x2&lt;br /&gt;
| High two bytes of GBA ROM file size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save types:&lt;br /&gt;
* 0x0: EEPROM 8k&lt;br /&gt;
* 0x1: EEPROM 8k (?)&lt;br /&gt;
* 0x2: EEPROM 64k&lt;br /&gt;
* 0x3: EEPROM 64k (?)&lt;br /&gt;
* 0x4: Flash 512k (Atmel, ID: 0x3D1F) + RTC&lt;br /&gt;
* 0x5: Flash 512k (Atmel, ID: 0x3D1F)&lt;br /&gt;
* 0x6: Flash 512k (SST, ID: 0xD4BF) + RTC&lt;br /&gt;
* 0x7: Flash 512k (SST, ID: 0xD4BF)&lt;br /&gt;
* 0x8: Flash 512k (Panasonic, ID: 0x1B32) + RTC&lt;br /&gt;
* 0x9: Flash 512k (Panasonic, ID: 0x1B32)&lt;br /&gt;
* 0xA: Flash 1Mbit (Macronix, ID: 0x09C2) + RTC&lt;br /&gt;
* 0xB: Flash 1Mbit (Macronix, ID: 0x09C2)&lt;br /&gt;
* 0xC: Flash 1Mbit (Sanyo, ID: 0x1362) + RTC&lt;br /&gt;
* 0xD: Flash 1Mbit (Sanyo, ID: 0x1362)&lt;br /&gt;
* 0xE: SRAM/FRAM 128k&lt;br /&gt;
&lt;br /&gt;
Everything above 0xE results in no save chip and nothing being saved to NAND.&lt;br /&gt;
&lt;br /&gt;
===NAND Savegame===&lt;br /&gt;
AGB_FIRM saves its active save memory to NAND on exit, this is then immediately picked up by NATIVE_FIRM on reboot by checking [[CONFIG_Registers#CFG_BOOTENV|CFG_BOOTENV]]. From there, this is verified and copied out to SD. The savegame format is as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  START&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x0&lt;br /&gt;
|  0x4&lt;br /&gt;
|  Magic (&#039;.SAV&#039;)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0xC&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x10&lt;br /&gt;
| AES-CMAC of the SHA256 hash of 0x30..0x200 + the entire save itself, keyslot 0x24, keyY from process9 .rodata&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x10&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 0x4&lt;br /&gt;
| Always 0x1&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 0x4&lt;br /&gt;
| Number of times saved (unused?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x8&lt;br /&gt;
| AGB TitleID&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 0x10&lt;br /&gt;
| SD card CID from the console the save was made on (verified on load)&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save start addr (always 0x200)&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| 0x4&lt;br /&gt;
| Save size&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| 0x8&lt;br /&gt;
| Always 0xFF (?)&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| 0x4&lt;br /&gt;
| See [[ARM7_Registers|here]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x68&lt;br /&gt;
| 0x198&lt;br /&gt;
| Always 0xFF&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=NCSD&amp;diff=19399</id>
		<title>NCSD</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=NCSD&amp;diff=19399"/>
		<updated>2017-01-23T12:20:10Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* NCSD header */ fixed bad reserved size and offset&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:File formats]]&lt;br /&gt;
This page documents the format of NCSD.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
There are two known specialisations of the NCSD container format. The CTR Cart Image (CCI) format and the 3DS&#039; raw [[Flash Filesystem#NAND structure|NAND format]]. CCI is the format of game ROM images.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CTR System Update (CSU)&#039;&#039;&#039; is a variant of CCI, where the only difference is in the file extension. This is used with developer System Updates and associated [[3DS Development Unit Software|Tools]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NCSD images start with a NCSD header, followed by up to a maximum of 8 [[NCCH]] partitions.&lt;br /&gt;
&lt;br /&gt;
For CCI images, the partitions are reserved as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  [[NCCH]] Index&lt;br /&gt;
!  Reserved Use&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Executable Content ([[NCCH#CXI|CXI]])&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| E-Manual ([[NCCH#CFA|CFA]])&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| [[Download Play]] Child container ([[NCCH#CFA|CFA]])&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| New3DS [[System_Update_CFA|Update Data]] ([[NCCH#CFA|CFA]])&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| [[System_Update_CFA|Update Data]] ([[NCCH#CFA|CFA]])&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The format of partitions can be determined from the partition FS flags (normally these are zero for CCI/CSU NCSD Images).&lt;br /&gt;
&lt;br /&gt;
== NCSD header ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
|  0x000&lt;br /&gt;
|  0x100&lt;br /&gt;
|  RSA-2048 SHA-256 signature of the NCSD header&lt;br /&gt;
|-&lt;br /&gt;
|  0x100&lt;br /&gt;
|  4&lt;br /&gt;
|  Magic Number &#039;NCSD&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  0x104&lt;br /&gt;
|  4&lt;br /&gt;
|  Size of the NCSD image, in media units (1 media unit = 0x200 bytes)&lt;br /&gt;
|-&lt;br /&gt;
|  0x108&lt;br /&gt;
|  8&lt;br /&gt;
|  Media ID&lt;br /&gt;
|-&lt;br /&gt;
|  0x110&lt;br /&gt;
|  8&lt;br /&gt;
|  Partitions FS type (0=None, 1=Normal, 3=FIRM, 4=AGB_FIRM save)&lt;br /&gt;
|-&lt;br /&gt;
|  0x118&lt;br /&gt;
|  8&lt;br /&gt;
|  Partitions crypt type (each byte corresponds to a partition in the partition table)&lt;br /&gt;
|-&lt;br /&gt;
|  0x120&lt;br /&gt;
|  0x40=(4+4)*8&lt;br /&gt;
|  Offset &amp;amp; Length partition table, in media units&lt;br /&gt;
|-&lt;br /&gt;
|  0x160&lt;br /&gt;
|  0xA0&lt;br /&gt;
|  ...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For carts,&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
|  0x160&lt;br /&gt;
|  0x20&lt;br /&gt;
|  Exheader SHA-256 hash&lt;br /&gt;
|-&lt;br /&gt;
|  0x180&lt;br /&gt;
|  0x4&lt;br /&gt;
|  Additional header size&lt;br /&gt;
|-&lt;br /&gt;
|  0x184&lt;br /&gt;
|  0x4&lt;br /&gt;
|  Sector zero offset&lt;br /&gt;
|-&lt;br /&gt;
|  0x188&lt;br /&gt;
|  8&lt;br /&gt;
|  Partition Flags (See Below)&lt;br /&gt;
|-&lt;br /&gt;
|  0x190&lt;br /&gt;
|  0x40=8*8&lt;br /&gt;
|  Partition ID table &lt;br /&gt;
|-&lt;br /&gt;
|  0x1D0&lt;br /&gt;
|  0x20&lt;br /&gt;
|  Reserved&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F0&lt;br /&gt;
| 0xE&lt;br /&gt;
| Reserved?&lt;br /&gt;
|-&lt;br /&gt;
| 0x1FE&lt;br /&gt;
| 0x1&lt;br /&gt;
| Support for this was implemented with [[9.6.0-24|9.6.0-X]] FIRM. Bit0=1 enables using bits 1-2, it&#039;s unknown what these two bits are actually used for(the value of these two bits get compared with some other value during NCSD verification/loading). This appears to enable a new, likely hardware-based, antipiracy check on cartridges.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1FF&lt;br /&gt;
| 0x1&lt;br /&gt;
| Support for this was implemented with [[9.6.0-24|9.6.0-X]] FIRM, see below regarding save crypto.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For NAND,&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
|  0x160&lt;br /&gt;
|  0x5E&lt;br /&gt;
|  Unknown&lt;br /&gt;
|-&lt;br /&gt;
|  0x1BE&lt;br /&gt;
|  0x42&lt;br /&gt;
|  Encrypted MBR partition-table, for the TWL partitions(key-data used for this keyslot is console-unique).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== NCSD Signature ===&lt;br /&gt;
The RSA pubk used for gamecard NCSD is stored in [[Memory_layout|ITCM]]. The separate pubk used for NAND NCSD is stored in Process9 .(ro)data instead of ITCM.&lt;br /&gt;
&lt;br /&gt;
=== Partition Flags ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Byte Index&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Backup Write Wait Time (The time to wait to write save to backup after the card is recognized (0-255 seconds)).NATIVE_FIRM loads this flag from the gamecard NCSD header starting with [[6.0.0-11]].&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (SDK 3.X+)&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Media Platform Index (1 = CTR)&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Media Type Index (0 = Inner Device, 1 = Card1, 2 = Card2, 3 = Extended Device)&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Media Unit Size i.e. u32 MediaUnitSize = 0x200*2^flags[6];&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (Only SDK 2.X)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Partition Flags (In Terms of Save Crypto Determination) ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Byte Index&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Starting with [[6.0.0-11]] NATIVE_FIRM will use this flag to determine the gamecard [[Savegames|savegame]] keyY method, when flag[3] is set. 0 = [[2.0.0-2]] hashed keyY, 1 = [[Savegames|new]] keyY method implemented with [[6.0.0-11]]. 0x0A = implemented with [[9.3.0-21|9.3.0-X]]. On Old3DS this is identical to the [[2.2.0-4]] crypto. On New3DS this is identical to the [[2.2.0-4]] crypto, except with New3DS-only gamecard savedata [[AES|keyslots]].&lt;br /&gt;
Starting with [[9.6.0-24|9.6.0-X]] FIRM, Process9 now sets &amp;lt;savecrypto_stateval&amp;gt; to partitionflag[1] + &amp;lt;the u8 value from NCSD+0x1FF&amp;gt;, instead of just setting it to partitionflag[1].&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Support for this flag was implemented in NATIVE_FIRM with [[2.0.0-2]]. When this flag is set the hashed gamecard [[Savegames|savegame]] keyY method is used, this likely still uses the repeating-CTR however. With [[6.0.0-11]] the system will determine the gamecard savegame keyY method via flag[1], instead of just using the hashed keyY via this flag.&lt;br /&gt;
|-th&lt;br /&gt;
| 7&lt;br /&gt;
| This flag enables using the hashed gamecard [[Savegames|savegame]] keyY method, support for this flag was implemented in NATIVE_FIRM with [[2.2.0-4]]. All games with the NCSD image finalized since [[2.2.0-4]](and contains [[2.2.0-4]]+ in the system update partition) have this flag set, this flag also enables using new CTR method as well.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Starting with [[9.6.0-24|9.6.0-X]] FIRM, Process9 will just write val0 to a state field then return 0, instead of returning an error when the save crypto type isn&#039;t recognized. This was the *only* actual functionality change in the Old3DS Process9 function for gamecard savedata crypto init.&lt;br /&gt;
&lt;br /&gt;
== Card Info Header ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  OFFSET&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x200&lt;br /&gt;
|  4&lt;br /&gt;
|  CARD2: Writable Address In Media Units (For &#039;On-Chip&#039; Savedata). CARD1: Always 0xFFFFFFFF.&lt;br /&gt;
|-&lt;br /&gt;
|  0x204&lt;br /&gt;
|  4&lt;br /&gt;
|  Card Info Bitmask&lt;br /&gt;
|-&lt;br /&gt;
|  0x208&lt;br /&gt;
|  0x108&lt;br /&gt;
|  Reserved1&lt;br /&gt;
|-&lt;br /&gt;
|  0x310&lt;br /&gt;
|  2&lt;br /&gt;
|  Title version&lt;br /&gt;
|-&lt;br /&gt;
|  0x312&lt;br /&gt;
|  2&lt;br /&gt;
|  Card revision&lt;br /&gt;
|-&lt;br /&gt;
|  0x208&lt;br /&gt;
|  0xCEE&lt;br /&gt;
|  Reserved2&lt;br /&gt;
|-&lt;br /&gt;
|  0x1000&lt;br /&gt;
|  0x10&lt;br /&gt;
|  Card seed keyY (first u64 is Media ID (same as first NCCH partitionId))&lt;br /&gt;
|-&lt;br /&gt;
|  0x1010&lt;br /&gt;
|  0x10&lt;br /&gt;
|  Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see [[CTRCARD_Registers|CTRCARD_SECSEED]])&lt;br /&gt;
|-&lt;br /&gt;
|  0x1020&lt;br /&gt;
|  0x10&lt;br /&gt;
|  Card seed AES-MAC&lt;br /&gt;
|-&lt;br /&gt;
|  0x1030&lt;br /&gt;
|  0xC&lt;br /&gt;
|  Card seed nonce&lt;br /&gt;
|-&lt;br /&gt;
|  0x103C&lt;br /&gt;
|  0xC4&lt;br /&gt;
|  Reserved3&lt;br /&gt;
|-&lt;br /&gt;
|  0x1100&lt;br /&gt;
|  0x100&lt;br /&gt;
|  Copy of first NCCH header (excluding RSA signature)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Development Card Info Header Extension ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  OFFSET&lt;br /&gt;
!  SIZE&lt;br /&gt;
!  DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
|  0x1200&lt;br /&gt;
|  0x200&lt;br /&gt;
|  CardDeviceReserved1&lt;br /&gt;
|-&lt;br /&gt;
|  0x1400&lt;br /&gt;
|  0x10&lt;br /&gt;
|  TitleKey&lt;br /&gt;
|-&lt;br /&gt;
|  0x1410&lt;br /&gt;
|  0xF0&lt;br /&gt;
|  CardDeviceReserved2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that a particular flashcard vendor puts what many refer to as &amp;quot;private headers&amp;quot; here in place of actual development card information. This header is constituted by a cartridge-unique Id obtained from [[Process_Services_PXI|pxi:ps9::GetRomId]] and the title-unique cart ID (identical for all carts of the same title; can be retrieved using the NTR gamecard protocol command 0x90 or through the CTR protocol commands 0x90 or 0xA2).&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
[https://github.com/3dshax/ctr/tree/master/ctrtool ctrtool] - (CMD)(Windows/Linux) Parsing NCSD files&lt;br /&gt;
&lt;br /&gt;
[[3DSExplorer]] - (GUI)(Windows Only) Parsing NCSD files&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Serials&amp;diff=18445</id>
		<title>Serials</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Serials&amp;diff=18445"/>
		<updated>2016-10-22T11:04:43Z</updated>

		<summary type="html">&lt;p&gt;D0k3: /* Fix check digit formula (old formula does not work for certain combinations) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page talks about the 3DS products&#039; serial number and model number structures (the console, manual, accessories, games, etc...).&lt;br /&gt;
&lt;br /&gt;
== Console Serial Numbers ==&lt;br /&gt;
&lt;br /&gt;
A 3DS console serial number is composed of at least two letters followed by nine decimal digits.  The ninth digit is a &amp;quot;check digit&amp;quot;, meaning that it is derived from the other digits.&lt;br /&gt;
&lt;br /&gt;
The check digit is an industry-standard algorithm, the one used for UPC codes.  To calculate the check digit of a 3DS console, separate the non-check digits into &amp;quot;odd&amp;quot; and &amp;quot;even&amp;quot; groups, where the &amp;quot;odd&amp;quot; group is digits in odd-numbered positions, and the &amp;quot;even&amp;quot; group is digits in even-numbered positions.  (The first digit is &amp;quot;odd&amp;quot;, with &amp;quot;first&amp;quot; representing &amp;quot;1&amp;quot;.)&lt;br /&gt;
&lt;br /&gt;
After separating the digits, add the digits in each group together.  Multiply the sum of the even digits by 3, then add the sum of the odd digits. To calculate the check digit, take this value modulo 10, and if not 0, subtract from 10.&lt;br /&gt;
&lt;br /&gt;
Example: CW404567772&lt;br /&gt;
&lt;br /&gt;
The non-check digits are 40456777.  Separating into odd and even groups, we get the following:&lt;br /&gt;
&lt;br /&gt;
Odds: 4 + 4 + 6 + 7 = 21&lt;br /&gt;
Evens: 0 + 5 + 7 + 7 = 19&lt;br /&gt;
&lt;br /&gt;
Applying the algorithm, we get ((3 * 19) + 21) % 10 = 8, which is not 0, thus 10 - 8 = 2, matching the example&#039;s check digit.&lt;br /&gt;
&lt;br /&gt;
The letter prefixes are a letter specifying the device, followed by one letter specifying the region in which it was sold.  In some regions, a third letter is present; a current guess is that this letter distinguishes among factories for a given sales region.  Note that several different sales regions&#039; console may be considered to be the same region for region-locking purposes, such as Europe and Australia.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Model !! Device Prefix (Retail) !! Device Prefix (Dev)&lt;br /&gt;
|-&lt;br /&gt;
| 3DS || C || E&lt;br /&gt;
|-&lt;br /&gt;
| 3DS XL/LL || S&lt;br /&gt;
|-&lt;br /&gt;
| 2DS || A || P&lt;br /&gt;
|-&lt;br /&gt;
| New 3DS || Y || Y&lt;br /&gt;
|-&lt;br /&gt;
| New 3DS XL/LL || Q || Q&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Development units with the same prefix as retail can be distinguished by development units having a 0 as the first digit of the serial number portion.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sales Region !! Region Lock !! Region Suffix&lt;br /&gt;
|-&lt;br /&gt;
| Japan || Japan || JF, JH, JM&lt;br /&gt;
|-&lt;br /&gt;
| North America || North America || W&lt;br /&gt;
|-&lt;br /&gt;
| Middle East / Southeast Asia || North America || S&lt;br /&gt;
|-&lt;br /&gt;
| Europe || Europe || EF, EH, EM&lt;br /&gt;
|-&lt;br /&gt;
| Australia || Europe || AH&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Console Models ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Device !! Product Code&lt;br /&gt;
|-&lt;br /&gt;
| 3DS || CTR&lt;br /&gt;
|-&lt;br /&gt;
| 3DS XL/LL || SPR&lt;br /&gt;
|-&lt;br /&gt;
| 2DS || FTR&lt;br /&gt;
|-&lt;br /&gt;
| [[New 3DS]] || KTR&lt;br /&gt;
|-&lt;br /&gt;
| [[New 3DS]] XL/LL || RED&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DS had the product code NTR, so we see the TR is recurring.&lt;br /&gt;
&lt;br /&gt;
== Title ID and Unique ID ==&lt;br /&gt;
&#039;&#039;see [[Titles]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== NCCH Product Code ==&lt;br /&gt;
&lt;br /&gt;
This serial is similiar to the &amp;quot;physical serial&amp;quot; described later in this page; it is the canonical identifier for a specific title in the field of business formalities with Nintendo, but this is not reflected in the 3DS&#039;s software architecture (where it is vastly unused in favor of the Title ID: it is therefore considered the successor of the &amp;quot;internal name&amp;quot; contained in ROMs of previous handhelds), is not guaranteed to be unique.&lt;br /&gt;
&lt;br /&gt;
The product code is located in a [[NCCH]]&#039;s header (not its ExHeader).&lt;br /&gt;
&lt;br /&gt;
The product code &amp;quot;CTR-P-CTAP&amp;quot; is the default generic product code for NCCH files. Most [[NCSD|NCCHs apart from the first one]] in a title are generally CTR-P-CTAP.&lt;br /&gt;
Referring to &amp;quot;the product code of a title&amp;quot; is therefore a simplification for &amp;quot;the product code of the NCCH in its first partition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
So, for example, a Japanese copy of Ridge Racer 3D would have a product code of &amp;quot;CTR-P-ARRJ&amp;quot; and a serial of &amp;quot;LNA-CTR-ARRJ-JPN&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A Nintendo-assigned product code follows this format, however, there is no requirement for a product code to match or resemble this structure as long as it&#039;s within the length limit:&lt;br /&gt;
&lt;br /&gt;
[CTR/KTR]-[Category letter]-[Type][Identifier][Region]-[Sub ID]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Category letter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| P || Cartridge software, or downloadable versions of them.&lt;br /&gt;
|-&lt;br /&gt;
| N || Digital-only releases, including [[Title list|system applications and applets]].&lt;br /&gt;
|-&lt;br /&gt;
| M || [[DLC]]&lt;br /&gt;
|-&lt;br /&gt;
| T || [[eShop Demos]], excluding so-called &amp;quot;special demos&amp;quot; which are category N.&lt;br /&gt;
|-&lt;br /&gt;
| U || [[Title list#0004000E - Add-on Content (Updates)|Patches]] for category P titles.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;sub ID&amp;quot; only applies to DLC, demos, and local copies of Download Play titles. It&#039;s a 2-digit number associated with the [[Title list|Title ID Variation]].&lt;br /&gt;
&lt;br /&gt;
See the next chapter for explanation of the other components of the Product Code.&lt;br /&gt;
&lt;br /&gt;
== Physical (only?) Serial ==&lt;br /&gt;
&lt;br /&gt;
[Product][Retail/Demo]-CTR-[Type][Identifier][Region]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Length !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Product || 2 || Product type (cartridges are LN, game boxes are TS, instruction manuals are MA, leaflets are FA, quick-start guides are MK)&lt;br /&gt;
|-&lt;br /&gt;
| Retail/Demo || 1 || Retail (A) or Demo (Z)&lt;br /&gt;
|-&lt;br /&gt;
| CTR/KTR || 3 || Platform. CTR = 3DS, KTR = New 3DS&lt;br /&gt;
|-&lt;br /&gt;
| Type || 1 || [A/C/H/J/K/S/P/T] - Retail / C is part of the default serial &#039;CTAP&#039; / H is used for built in applications like [[Mii Maker]] / J is for a normal eShop Title / K is unknown, seen in Mighty Gunvolt / S is usually a 3D Classics eShop title / P is used with GBA eShop titles / T is used with NES eShop titles.&lt;br /&gt;
|-&lt;br /&gt;
| Identifier || 2 || game name (two alphanumeric characters).&lt;br /&gt;
|-&lt;br /&gt;
| Region || 1 || [E/P/J/K/C/Y/Z/A] - English (US) / PAL (Europe/Australia) / Japanese (Japan) / Korean (Korea) / Chinese (China/Taiwan) / Unknown (Japan/Korea?) (seen in Johnny&#039;s Payday Panic (Korea)) / Unknown (seen in Mighty Gunvolt) / All (region-free)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The longer version of the serial number adds a geographical region (usually because of extra languages).&lt;br /&gt;
&lt;br /&gt;
Those are 3 letters codes at the end of the serial (can be found mostly on demos).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, the code of the Canadian version of Mario Kart 7 is CAN (link removed, links to incorrect image).&lt;br /&gt;
&lt;br /&gt;
=== Electronic Manuals ===&lt;br /&gt;
&lt;br /&gt;
Some eShop titles have [[NCCH#CFA|Electronic Manuals]] which store the product code at the end of the &#039;Health &amp;amp; Safety&#039; section of the manual. However,   product codes can differ from the above format as shown below:&lt;br /&gt;
&lt;br /&gt;
CTR-[P/N/T/U]-[Type][Identifier][Region]-[Region]-[Digit]&lt;br /&gt;
&lt;br /&gt;
CTR-[Type][Identifier][Region]-[Region]-[Digit]&lt;br /&gt;
&lt;br /&gt;
* P/N/T/U - Same as in product code structure&lt;br /&gt;
* [Type][Identifier][Region] - Same as in serial structure&lt;br /&gt;
* [Region] - A three character representation of the title region, i.e. &#039;EUR&#039; (not always present)&lt;br /&gt;
* [Digit] - A single digit usually &#039;1&#039; or &#039;0&#039; (not always present)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These alternate versions of the product code, potentially found in [[NCCH#CFA|Electronic Manuals]] don&#039;t represent the actual product code, as found in the game&#039;s CXI. They are only found in the game&#039;s Home Menu manual, and on the game&#039;s packaging and external labeling.&lt;br /&gt;
&lt;br /&gt;
==Back of Card Serial==&lt;br /&gt;
AREPY10111&lt;br /&gt;
&lt;br /&gt;
[Identifier]-[Production Month]-[Production Year]-[Revision]-[Production Run?]&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Config_Savegame&amp;diff=17512</id>
		<title>Config Savegame</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Config_Savegame&amp;diff=17512"/>
		<updated>2016-06-15T09:28:39Z</updated>

		<summary type="html">&lt;p&gt;D0k3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the format of the [[Config_Services|Cfg]] [[System_SaveData|NAND]] savegame. These blocks can be accessed with the Cfg service commands.&lt;br /&gt;
&lt;br /&gt;
==Structure of save-file &amp;quot;/config&amp;quot;==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x2&lt;br /&gt;
| Total entries&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0x2&lt;br /&gt;
| Data entries offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x4558&lt;br /&gt;
| Block entries&lt;br /&gt;
|-&lt;br /&gt;
| 0x455C&lt;br /&gt;
| &lt;br /&gt;
| Data for the entries&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The filesize for this /config file is 0x8000-bytes.&lt;br /&gt;
&lt;br /&gt;
==Configuration block entry ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x4&lt;br /&gt;
| BlkID&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x4&lt;br /&gt;
| Offset to the data for this block when size is &amp;gt;4, otherwise this word is the data for this block&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x2&lt;br /&gt;
| Size&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 0x2&lt;br /&gt;
| Flags&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Configuration blocks==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  BlkID&lt;br /&gt;
!  Size&lt;br /&gt;
!  Flags&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| 0x2&lt;br /&gt;
| ?&lt;br /&gt;
| Config savegame version?&lt;br /&gt;
|-&lt;br /&gt;
| 0x00030001&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0xE&lt;br /&gt;
| Changes when data / time is changed in settings (read by CECD)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00040000&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by HID)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00040001&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by HID)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00040002&lt;br /&gt;
| 0x12&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by HID)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00040003&lt;br /&gt;
| 0xC&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by HID)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00050001&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by GSP)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00050002&lt;br /&gt;
| 0x38&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by GSP)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00050003&lt;br /&gt;
| 0x20&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by GSP)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00050005&lt;br /&gt;
| 0x20&lt;br /&gt;
|?&lt;br /&gt;
| Stereo camera settings?&lt;br /&gt;
|-&lt;br /&gt;
| 0x00050006&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0x8&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| 0x00070001&lt;br /&gt;
| 0x1&lt;br /&gt;
|?&lt;br /&gt;
| Sound output mode (mono/stereo/surround)?&lt;br /&gt;
|-&lt;br /&gt;
| 0x00080000&lt;br /&gt;
| 0xC00&lt;br /&gt;
| 0x2?&lt;br /&gt;
| WiFi configuration slot 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x00080001&lt;br /&gt;
| 0xC00&lt;br /&gt;
| 0x2?&lt;br /&gt;
| WiFi configuration slot 1&lt;br /&gt;
|-&lt;br /&gt;
| 0x00080002&lt;br /&gt;
| 0xC00&lt;br /&gt;
| 0x2?&lt;br /&gt;
| WiFi configuration slot 2&lt;br /&gt;
|-&lt;br /&gt;
| 0x00090000&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x2?&lt;br /&gt;
| This contains a u64 ID, used by processes using [[NWMUDS:InitializeWithVersion]]. The first word is the same as [[CfgS:GetLocalFriendCodeSeed|LocalFriendCodeSeed]], while the latter is a separate word.&lt;br /&gt;
|-&lt;br /&gt;
| 0x00090001&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0xE&lt;br /&gt;
| This console-unique u64 used by [[Cfg:GenHashConsoleUnique|GenHashConsoleUnique]] is generated with the LocalFriendCodeSeed and with random data&lt;br /&gt;
|-&lt;br /&gt;
| 0x000A0000&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 0xE&lt;br /&gt;
| Username&lt;br /&gt;
|-&lt;br /&gt;
| 0x000A0001&lt;br /&gt;
| 0x2&lt;br /&gt;
| 0xE&lt;br /&gt;
| Birthday (u8 month, u8 day)&lt;br /&gt;
|-&lt;br /&gt;
| 0x000A0002&lt;br /&gt;
| 0x1&lt;br /&gt;
| 0xA&lt;br /&gt;
| Language&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| 0x000B0000&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x8&lt;br /&gt;
| CountryInfo&lt;br /&gt;
|-&lt;br /&gt;
| 0x000B0001&lt;br /&gt;
| 0x800&lt;br /&gt;
| 0x2?&lt;br /&gt;
| Country name in UTF-16, every 0x80-bytes is an entry for each language, in the order of the Language table below (not all entries are set)&lt;br /&gt;
|-&lt;br /&gt;
| 0x000B0002&lt;br /&gt;
| 0x800&lt;br /&gt;
| 0x2?&lt;br /&gt;
| State name in UTF-16, every 0x80-bytes is an entry for each language&lt;br /&gt;
|-&lt;br /&gt;
| 0x000B0003&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0xE&lt;br /&gt;
| Pair of 16-bit values, meaning unknown but related to address (ZIP code?)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| 0x000C0000&lt;br /&gt;
| 0xC0&lt;br /&gt;
| 0x8&lt;br /&gt;
| Restricted photo exchange data, and other info&lt;br /&gt;
|-&lt;br /&gt;
| 0x000C0001&lt;br /&gt;
| 0x14&lt;br /&gt;
|?&lt;br /&gt;
| Same as above?&lt;br /&gt;
|-&lt;br /&gt;
| 0x000D0000&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x2&lt;br /&gt;
| u16 at offset 0x0: [[SMDH#EULA_Version|EULA Version]] which was agreed to.&lt;br /&gt;
|-&lt;br /&gt;
| 0x000F0000&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x8?&lt;br /&gt;
| Unknown, used by [[NS]] on dev-units for [[SVC|svcKernelSetState]], where Type is 6. During NS startup on debug-units, NS compares the u32 from +8 in this config-block with the [[Configuration_Memory#APPMEMTYPE|APPMEMTYPE]]. When those don&#039;t match NS starts a FIRM-launch (with the same FIRM titleID as the currently running one) to boot into a FIRM with the APPMEMTYPE value from this config-block&lt;br /&gt;
|-&lt;br /&gt;
| 0x000F0004&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x8?&lt;br /&gt;
| The first u8 is the System-Model [[Cfg:GetSystemModel|value]], the last 3-bytes are unknown&lt;br /&gt;
|-&lt;br /&gt;
| 0x00110000&lt;br /&gt;
| 0x4&lt;br /&gt;
|?&lt;br /&gt;
| The low u16 indicates whether the system setup is required, such as when the system is booted for the first time or after doing a [[System Settings|System Format]]: 0 = setup required, non-zero = no setup required&lt;br /&gt;
|-&lt;br /&gt;
| 0x00110001&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0xA?&lt;br /&gt;
| TitleID of the menu to launch, used by [[NS]] on dev units (this block can be edited on dev units with [[3DS Development Unit Software#Config|Config]])&lt;br /&gt;
|-&lt;br /&gt;
| 0x00120000&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x8&lt;br /&gt;
| ? (read by HID)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00130000&lt;br /&gt;
| 0x4&lt;br /&gt;
|?&lt;br /&gt;
| If response is 0x100 then debug mode is enabled.&lt;br /&gt;
|-&lt;br /&gt;
| 0x00160000&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x8?&lt;br /&gt;
| Unknown, first byte is used by config service-cmd [[Config_Services|0x00070040]]. (Unknown whether the last 3-bytes are used)&lt;br /&gt;
|-&lt;br /&gt;
| 0x00190000&lt;br /&gt;
| 0x1&lt;br /&gt;
| 0x8?&lt;br /&gt;
| Unknown. NFC-module checks for value1/non-value1.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The developer unit TID block only exists on developer units.&lt;br /&gt;
&lt;br /&gt;
===Languages===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  ID&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| JP&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| EN&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| FR&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| DE&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| IT&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| ES&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| ZH&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| KO&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| NL&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| PT&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| RU&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| TW&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===CountryInfo===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Byte&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
|?&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|?&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
|?&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Country code, same as DSi/Wii country codes. Value 0xFF is invalid.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===0x000A0000 Block===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Byte&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0-0x13&lt;br /&gt;
| UTF-16 username, with no NULL-terminator.&lt;br /&gt;
|-&lt;br /&gt;
| 0x14-17&lt;br /&gt;
| Usually zero?&lt;br /&gt;
|-&lt;br /&gt;
| 0x18-0x1B&lt;br /&gt;
| u32 NGWord version the username was last checked with. If this value is less than the u32 stored in the NGWord CFA &amp;quot;romfs:/version.dat&amp;quot;, the system then checks the username string with the bad-word list CFA again, then updates this field with the value from the CFA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===LCD display config===&lt;br /&gt;
There seems to be some sort of LCD display configuration stored in this cfg. When using the cfg-save from an Old3DS on a New3DS without formatting the cfg first, the bottom-screen display is somewhat off(which is fixed by formatting the cfg-save).&lt;/div&gt;</summary>
		<author><name>D0k3</name></author>
	</entry>
</feed>