<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Coranac &#187; nds</title>
	<atom:link href="http://www.coranac.com/category/nds/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coranac.com</link>
	<description>my own little world</description>
	<lastBuildDate>Sat, 19 Nov 2011 16:43:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>setds 1.01 and an annoying yet oddly fitting bug</title>
		<link>http://www.coranac.com/2010/04/setds-1-01/</link>
		<comments>http://www.coranac.com/2010/04/setds-1-01/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 19:09:21 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[nds]]></category>
		<category><![CDATA[setds]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=189</guid>
		<description><![CDATA[It seems that a bug in the hiscore entry code that I thought I&#8217;d fixed over a month ago got resurrected in setds v1.0. So I fixed it &#8211; refixed it &#8211; today and we&#8217;re now at setds v1.01. &#160; Sigh. Gaddammit &#62;_&#60;]]></description>
			<content:encoded><![CDATA[<p>
It seems that a bug in the hiscore entry code that I <i>thought</i> I&#8217;d fixed over a month ago got resurrected in setds v1.0. So I fixed it &ndash; <i>re</i>fixed it &ndash; today and we&#8217;re now at <a href="[$HOME/projects/setds">setds v1.01</a>.
</p>
<p><div>&nbsp;</div></p>
<p>
<small>Sigh. Gaddammit <kbd>&gt;_&lt;</kbd></small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2010/04/setds-1-01/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>setds 1.0</title>
		<link>http://www.coranac.com/2010/04/setds-1-0/</link>
		<comments>http://www.coranac.com/2010/04/setds-1-0/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 08:57:34 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[nds]]></category>
		<category><![CDATA[setds]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=185</guid>
		<description><![CDATA[I&#8217;ve finally taken the time to add proper saving that works on hardware (at least on my R4, which is the only card I have right now). I&#8217;ve also fixed a very annoying game-hanging bug and did some tweaking here and there, like correcting the decay constant so that I can finally get the scores [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve finally taken the time to add proper saving that works on hardware<br />
(at least on my R4, which is the only card I have right now). I&#8217;ve also fixed a<br />
very annoying game-hanging bug and did some tweaking here and there, like<br />
correcting the decay constant so that I can finally get the scores that I was used to on tatset (2300+, wooo!).
</p>
<p>
This is pretty much where I wanted to go with this game, so it&#8217;s now version 1.0. I may add some other things later, but for now I guess it&#8217;s done.
</p>
<h4>Changes</h4>
<ul>
<li>new: FAT saving enabled <kbd>:D</kbd>. It&#8217;s intended for<br />
    <a href="http://www.devkitpro.org/hbmenu">argv-capable</a><br />
    cards, though. You can still save without one of those, but you&#8217;ll have to<br />
    put in a little work.
  </li>
<li>
    new: Reset/Back buttons for high-score screen.
  </li>
<li>
    fix: Bug in shuffle code. Fixes the occasional hang at start of a new game.
  </li>
<li>
    tweak: I&#8217;ve altered the decay constant slightly; it should be closer to<br />
    the original tatset now. The upshot is that scores will be a little higher.
  </li>
<li>
    tweak: Slightly bigger buttons.
  </li>
</ul>
<h4>Links</h4>
<ul>
<li><a href="http://www.coranac.com/projects/setds">setds project page</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2010/04/setds-1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DMA vs ARM9, round 2 : invalidate considered harmful</title>
		<link>http://www.coranac.com/2010/03/dma-vs-arm9-round-2/</link>
		<comments>http://www.coranac.com/2010/03/dma-vs-arm9-round-2/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 17:29:08 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[nds]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=175</guid>
		<description><![CDATA[It would seem these two aren&#8217;t finished with each other yet. &#160; A while ago, I wrote an article about NDS caching , how it can interfere with DMA transfers and what you can do about them. A little later I got a pingback from ant512, who had tried the &#8220;safe&#8221; DMA routines I made [...]]]></description>
			<content:encoded><![CDATA[<p>
It would seem these two aren&#8217;t finished with each other yet.
</p>
<p><div>&nbsp;</div></p>
<p>
A while ago, I wrote<br />
<a href="http://www.coranac.com/dma-vs-arm9-fight/">an article about NDS caching</a><br />
, how it can interfere with DMA transfers and what you can do about them.<br />
A little later I got a<br />
<a href="http://ant.simianzombie.com/?p=1114">pingback from ant512</a>,<br />
who had tried the &ldquo;safe&rdquo; DMA routines I made and found they<br />
weren&#8217;t nearly as safe as I&#8217;d hoped. I&#8217;m still not sure what the actual<br />
problem was, but this incident did make me think about one possible<br />
reason, namely the one that will be discussed in this post: problematic<br />
cache invalidation.
</p>
<p><h3 id="sec-tests">1
Test base
</h3>
</p>
<p>
But first things first. Let&#8217;s start with some simple test code, see below.<br />
We have a simple struct definition, two arrays using this struct, and<br />
some default data for both arrays that we&#8217;ll use later.
</p>
<div class="cpp">
<div class="cpp proglist" style=" "><span class="co1">// A random struct, 32-bits in size.</span><br />
<span class="kw1">struct</span> Foo<br />
{<br />
&nbsp; &nbsp; u8&nbsp; type;<br />
&nbsp; &nbsp; u8&nbsp; id;<br />
&nbsp; &nbsp; u16 data;<br />
} ALIGN(<span class="nu0">4</span>);</p>
<p><span class="co1">// Define some globals. We only use 4 of each.</span><br />
Foo g_src[<span class="nu0">16</span>] ALIGN(<span class="nu0">32</span>);<br />
Foo g_dst[<span class="nu0">16</span>] ALIGN(<span class="nu0">32</span>);</p>
<p><span class="kw1">const</span> Foo c_fooIn[<span class="nu0">2</span>][<span class="nu0">4</span>]= <br />
{<br />
&nbsp; &nbsp; { &nbsp; <span class="co1">// Initial source data.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0&#215;55</span>, <span class="nu0">0</span>, <span class="nu0">0&#215;5111</span> }, <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0&#215;55</span>, <span class="nu0">1</span>, <span class="nu0">0&#215;5111</span> },<br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0&#215;55</span>, <span class="nu0">2</span>, <span class="nu0">0&#215;5111</span> }, <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0&#215;55</span>, <span class="nu0">3</span>, <span class="nu0">0&#215;5111</span> } <br />
&nbsp; &nbsp; }, <br />
&nbsp; &nbsp; { &nbsp; <span class="co1">// Initial destination data.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0xDD</span>, <span class="nu0">0</span>, <span class="nu0">0xD111</span> },<br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0xDD</span>, <span class="nu0">1</span>, <span class="nu0">0xD111</span> },<br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0xDD</span>, <span class="nu0">2</span>, <span class="nu0">0xD111</span> },<br />
&nbsp; &nbsp; &nbsp; &nbsp; { <span class="nu0">0xDD</span>, <span class="nu0">3</span>, <span class="nu0">0xD111</span> } <br />
&nbsp; &nbsp; }, <br />
};</div>
</div>
<p>
And now we&#8217;re going to do some simple things with these arrays that<br />
we always do: some reads, some writes, and a struct copy. And for the<br />
copying, I&#8217;m going to use DMA, because DMA-transfers are fast,<br />
amirite<span class="fnote"><a href="#ft-nr1" title="No I&#8217;m not. For NDS WRAM-WRAM copies, DMA is actually
slow as hell and outperformed by every other method. But hopefully more
on that later. For now, though, I need the DMA for testing
purposes.">(1)</a></span>? The specific actions I will do are the following:
</p>
<h5>Initialization</h5>
<ul>
<li>Zero out <code>g_src</code> and <code>g_dst</code>.</li>
<li>Initialize the arrays with some data, in this case from<br />
    <code>c_fooIn</code>.</li>
<li>Cache-Flush both arrays to ensure they&#8217;re uncached.</li>
</ul>
<h5>Testing</h5>
<ul>
<li>Modify element in <code>g_src</code>, namely <code>g_src[0]</code>.</li>
<li>Modify an element in <code>g_dst</code>, namely <code>g_dst[3]</code>.</li>
<li>DMA-copy <code>g_src[0]</code> to <code>g_dst[3]</code>.</li>
</ul>
<p>
In other words, this:
</p>
<div class="cpp">
<div class="cpp proglist" style=" "><span class="kw1">void</span> test_init()<br />
{<br />
&nbsp; &nbsp; <span class="co1">// Zero out everything</span><br />
&nbsp; &nbsp; <span class="kw3">memset</span>(g_src, <span class="nu0">0</span>, <span class="kw3">sizeof</span>(g_src));<br />
&nbsp; &nbsp; <span class="kw3">memset</span>(g_dst, <span class="nu0">0</span>, <span class="kw3">sizeof</span>(g_dst));</p>
<p>&nbsp; &nbsp; <span class="co1">// Fill 4 of each.</span><br />
&nbsp; &nbsp; <span class="kw1">for</span>(<span class="kw1">int</span> i=<span class="nu0">0</span>; i&lt;<span class="nu0">4</span>; i++)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; g_src[i]= c_fooIn[<span class="nu0">0</span>][i];<br />
&nbsp; &nbsp; &nbsp; &nbsp; g_dst[i]= c_fooIn[<span class="nu0">1</span>][i];<br />
&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; <span class="co1">// Flush data to be sure.</span><br />
&nbsp; &nbsp; DC_FlushRange(g_src, <span class="kw3">sizeof</span>(g_src));<br />
&nbsp; &nbsp; DC_FlushRange(g_dst, <span class="kw3">sizeof</span>(g_dst));<br />
}</p>
<p><span class="kw1">void</span> test_dmaCopy()<br />
{<br />
&nbsp; &nbsp; test_init();</p>
<p>&nbsp; &nbsp; <span class="co1">// Change g_src[0] and g_dst[3]</span><br />
&nbsp; &nbsp; g_src[<span class="nu0">0</span>].id += <span class="nu0">0&#215;10</span>;<br />
&nbsp; &nbsp; g_src[<span class="nu0">0</span>].data= <span class="nu0">0&#215;5222</span>;</p>
<p>&nbsp; &nbsp; g_dst[<span class="nu0">3</span>].id += <span class="nu0">0&#215;10</span>;<br />
&nbsp; &nbsp; g_dst[<span class="nu0">3</span>].data= <span class="nu0">0xD333</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// DMA src[0] into dst[0];</span><br />
&nbsp; &nbsp; dmaCopy(&amp;g_src[<span class="nu0">0</span>], &amp;g_dst[<span class="nu0">0</span>], <span class="kw3">sizeof</span>(Foo));<br />
}</div>
</div>
<p>
Note that there is nothing spectacularly interesting going on here.<br />
There&#8217;s just your average struct definition, run of the mill array<br />
definitions, and boring old accesses without even any pointer magic<br />
that might hint at something tricky going on. Yes, alignment is forced,<br />
but that just makes the test more reliable. Also, the fact that I&#8217;m<br />
incrementing <code>Foo.id</code> rather than just reading from it is<br />
only because ARM9 cache is read-allocate, and I need to have these<br />
things end up in cache. The main point is that the actions in<br />
<code>test_dmaCopy()</code> are very ordinary.
</p>
<p><h3 id="sec-results">2
Results
</h3>
</p>
<p>
It should be obvious what the outcome of the test should be. However,<br />
when you run the test (on hardware! not emulator), the result seems to<br />
be something different.
</p>
<div class="none">
<div class="none proglist" style=" "><span class="co1">// Just dmaCopy.</span></p>
<p>&nbsp; &nbsp; <span class="co1">// Result &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Expected:</span><br />
&nbsp; &nbsp; <span class="co1">// Source (hex)</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, <span class="nu0">10</span>, <span class="nu0">5222</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 10, 5222</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 01, <span class="nu0">5111</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// 55, 01, 5111</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 02, <span class="nu0">5111</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 02, 5111</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 03, <span class="nu0">5111</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 03, 5111</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">// Destination (hex)</span><br />
&nbsp; &nbsp; DD, 00, D111&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// 55, 10, 5222 (bad!)</span><br />
&nbsp; &nbsp; DD, 01, D111 &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// DD, 01, D111</span><br />
&nbsp; &nbsp; DD, 02, D111 &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// DD, 02, D111</span><br />
&nbsp; &nbsp; DD, <span class="nu0">13</span>, D333 &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// DD, 13, D333</span></div>
</div>
<p>
Notice that the changed values of <code>g_src[0]</code> never<br />
end up in <code>g_dst[0]</code>. Not only that, not even the<br />
<i>original</i> values <code>g_src[0]</code> have been copied.<br />
It&#8217;s as if the transfer never happened at all.
</p>
<p>
The reason for this was covered in detail in the original article.<br />
Basically, it&#8217;s because cache is invisible to DMA. Once a part of<br />
memory is cached, the CPU only looks to the contents of the cache and<br />
not the actual addresses, meaning that DMA not only reads out-of-date<br />
(stale) source data, but also puts it where the CPU won&#8217;t look.<br />
Two actions allow you to remedy this. The first is the<br />
<dfn>cache flush</dfn>, which write the cache-lines back to RAM and<br />
frees the cache-line. Then there&#8217;s <dfn>cache invalidate</dfn>, which<br />
just frees the cache-line. Note that in both cases, the cache is<br />
dissociated from memory.
</p>
<p>
With this information, it should be obvious what to do. When DMA-ing<br />
from RAM, you need to flush  the cache before the transfer to update<br />
the source&#8217;s memory. When DMA-ing to RAM, you need to invalidate<br />
after the transfer because now it&#8217;s actually the cache&#8217;s data that&#8217;s<br />
stale.<br />
When you think about it a little this makes perfect sense, and it&#8217;s easy<br />
enough to implement:
</p>
<div class="cpp">
<div class="cpp proglist" style=" "><span class="co1">// New DMA-code:</span><br />
&nbsp; &nbsp; DC_FlushRange(&amp;g_src[<span class="nu0">0</span>], <span class="kw3">sizeof</span>(Foo));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Flush source.</span><br />
&nbsp; &nbsp; dmaCopy(&amp;g_src[<span class="nu0">0</span>], &amp;g_dst[<span class="nu0">0</span>], <span class="kw3">sizeof</span>(Foo)); &nbsp; &nbsp; <span class="co1">// Transfer.</span><br />
&nbsp; &nbsp; DC_InvalidateRange(&amp;g_dst[<span class="nu0">0</span>], <span class="kw3">sizeof</span>(Foo)); &nbsp; &nbsp; <span class="co1">// Invalidate destination.</span></div>
</div>
<p>
Unfortunately, this doesn&#8217;t work right either. And if you think about<br />
it a lot instead of merely a little, you&#8217;ll see why. Maybe showing the<br />
results will make you see what I mean. The transfer seems to work now,<br />
but the earlier changes to <code>g_dst[3]</code> have been erased. How<br />
come?
</p>
<div class="none">
<div class="none proglist" style=" ">&nbsp; &nbsp; <span class="co1">// Result:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Expected:</span><br />
&nbsp; &nbsp; <span class="co1">// Source (hex)</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, <span class="nu0">10</span>, <span class="nu0">5222</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 10, 5222</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 01, <span class="nu0">5111</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// 55, 01, 5111</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 02, <span class="nu0">5111</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 02, 5111</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 03, <span class="nu0">5111</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 03, 5111</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">// Destination (hex)</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, <span class="nu0">10</span>, D222&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// 55, 10, 5222</span><br />
&nbsp; &nbsp; DD, 01, D111 &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// DD, 01, D111</span><br />
&nbsp; &nbsp; DD, 02, D111 &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// DD, 02, D111</span><br />
&nbsp; &nbsp; DD, <span class="nu0">13</span>, D111 &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// DD, 13, D333 (wut?)</span></div>
</div>
<p>
The problem is that a cache-invalidate invalidates entire<br />
<i>cache-lines</i>, not just the range you supply. If the start or<br />
end of the data you want invalidate does not align to a cache-line,<br />
the adjacent data contained in that line is also thrown away. I hope<br />
you can see that this is bad.
</p>
<p>
This is exactly what&#8217;s happening here. The ARM9&#8242;s cache-lines are 32<br />
bytes in size. Because of the alignment I gave the arrays, elements<br />
0 through 3 lie on the same cache-line. The changes to<br />
<code>g_dst[3]</code> occur in cache (but only because I read from it<br />
through <code>+=</code>). The invalidate of <code>g_dst[0]</code><br />
<i>also</i> invalidates <code>g_dst[3]</code>, which throws out the<br />
perfectly legit data and you&#8217;re left in a bummed state. And again,<br />
I&#8217;ve done nothing spectacularly interesting here; all I did was<br />
modify something and then invalidated data that just happened to be<br />
adjacent to it. But that was enough. Very, <i>very</i> bad.
</p>
<p>
Just to be sure, this is <i>not</i> due to a bad implementation of<br />
<code>DC_InvalidateRange()</code>. The function does exactly what it&#8217;s<br />
supposed to do. The problem is inherent in the hardware. If your<br />
data does not align correctly to cache-lines, an invalidate will apply<br />
to the adjacent data as well. If you do not want that to happen, do<br />
<i>not</i> invalidate.
</p>
<p><h3 id="sec-solution">3
Solutions
</h3>
</p>
<p>
So what to do? Well, there is one thing, but I&#8217;m not sure how foolproof<br />
this is, but instead of invalidating the destination afterwards, you<br />
can also flush it before the transfer. This frees up the cache-lines<br />
without loss of data, and then it should be safe to DMA-copy to it.
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; DC_FlushRange(&amp;g_src[<span class="nu0">0</span>], <span class="kw3">sizeof</span>(Foo));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Flush source.</span><br />
&nbsp; &nbsp; DC_FlushRange(&amp;g_dst[<span class="nu0">0</span>], <span class="kw3">sizeof</span>(Foo));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Flush destination.</span><br />
&nbsp; &nbsp; dmaCopy(&amp;g_src[<span class="nu0">0</span>], &amp;g_dst[<span class="nu0">0</span>], <span class="kw3">sizeof</span>(Foo)); &nbsp; &nbsp; <span class="co1">// Transfer.</span></div>
</div>
<div class="none">
<div class="none proglist" style=" ">&nbsp; &nbsp; <span class="co1">// Result:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Expected:</span><br />
&nbsp; &nbsp; <span class="co1">// Source (hex)</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, <span class="nu0">10</span>, <span class="nu0">5222</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 10, 5222</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 01, <span class="nu0">5111</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// 55, 01, 5111</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 02, <span class="nu0">5111</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 02, 5111</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, 03, <span class="nu0">5111</span> &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// 55, 03, 5111</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">// Destination (hex)</span><br />
&nbsp; &nbsp; <span class="nu0">55</span>, <span class="nu0">10</span>, D222&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// 55, 10, 5222</span><br />
&nbsp; &nbsp; DD, 01, D111 &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// DD, 01, D111</span><br />
&nbsp; &nbsp; DD, 02, D111 &nbsp; &nbsp; &nbsp;&nbsp; <span class="co1">// DD, 02, D111</span><br />
&nbsp; &nbsp; DD, <span class="nu0">13</span>, D333 &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// DD, 13, D333</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">// Yay \o/</span></div>
</div>
<p>
Alternatively, you can also disable the underlying reason behind the<br />
problem with invalidation: the write-buffer. The ARM9 cache allows<br />
two modes for writing: <dfn>write-through</dfn>, which also updates<br />
the memory related to the cache-line; and <dfn>write-back</dfn>, which<br />
doesn&#8217;t. Obviously, the write-back is faster, so that&#8217;s how libnds<br />
sets things up. I know that putting the cache in write-through mode<br />
fixes this problem, because in libnds 1.4.0 the write-buffer had been<br />
accidentally disabled and my test cases didn&#8217;t fail. This is probably<br />
not the route you want to take, though.
</p>
<p><h3 id="sec-conc">4
Conclusions
</h3>
</p>
<p>
So what have we learned?
</p>
<ul>
<li>
    Cache &#8211; DMA interactions suck and can cause really subtle bugs.<br />
	Ones that will only show up on hardware too.
  </li>
<li>
    Cache-flushes and invalidates cover the cache-lines of the requested<br />
	ranges, which exceed the range you actually wanted.
  </li>
<li>
    To safely DMA from cachable memory, flush the source range first.
  </li>
<li>
    Contrary to what I wrote earlier, to DMA to cachable memory,<br />
	do <i>not</i> cache-invalidate &ndash; at least not when<br />
	the range is not properly aligned to cache-lines. Instead, flush<br />
	the destination range before the transfer (at which time<br />
	invalidation should be unnecessary). That said, invalidate should<br />
	still be safe if the write-buffer is disabled.
  </li>
</ul>
<p><a href="http://www.coranac.com/files/nds/invalidate.zip">Link to test code.</a></p>
<p><div>&nbsp;</div><br />
<!-- EOF --></p>
<hr /><div class="footnotes">
<h5>Notes:</h5>
<ol>
<li id="ft-nr1"> 
  No I&#8217;m not. For NDS WRAM-WRAM copies, DMA is actually<br />
slow as hell and outperformed by every other method. But hopefully more<br />
on that later. For now, though, I need the DMA for testing<br />
purposes.
</li>
</ol>
</div
<hr />
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2010/03/dma-vs-arm9-round-2/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>I maek game :D</title>
		<link>http://www.coranac.com/2009/12/setds/</link>
		<comments>http://www.coranac.com/2009/12/setds/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 19:12:00 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[nds]]></category>
		<category><![CDATA[setds]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[game]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=139</guid>
		<description><![CDATA[<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
Okay, so it&#8217;s only a card game; but a game nonetheless. &#160; The game in question is an NDS implementation of SET. Set is a card-matching game with 81 cards (see below). The figures on the cards have four properties and 3 possibilities for each property. The key is to find three cards for which [...]]]></description>
			<content:encoded><![CDATA[<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<p>
Okay, so it&#8217;s <i>only</i> a card game; but a game nonetheless.
</p>
<p><div>&nbsp;</div></p>
<p>
The game in question is an NDS implementation of<br />

<a href="http://en.wikipedia.org/wiki/Set_%28game%29">SET</a>. <i>Set</i> is a card-matching game<br />
with 81 cards (see below). The figures on the cards have four<br />
properties and 3 possibilities for each property. The key is to find<br />
three cards for which the values of each property are either all<br />
<b>equal</b> or all <b>different</b>. Looking at the color property,<br />
for example, a &#8220;Red Red Red&#8221; combination could (yes &#8220;could&#8221;; there<br />
are still three other properties to consider) form a set.<br />
&#8220;Red Green Blue&#8221; would also work, but &#8220;Red Green Green&#8221; would not.
</p>
<p>
Further details can be found in the readme and the game itself.
</p>
<div class="cblock">
<div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>

</div>
<p><div>&nbsp;</div></p>
<p>
The game is <i>mostly</i> finished. There may be some tweaking to do<br />
here and there, but right now I don&#8217;t want to get bogged down in a<br />
massive fine-tuning-fest &ndash; especially since I&#8217;m not sure what<br />
parts need fine-tuning &hellip; and because there&#8217;s<br />
<a href="http://www.coranac.com/projects/grit">other stuff</a> I really should get<br />
back to.
</p>
<p>
That said, all important aspects work &hellip; with <b>one</b><br />
exception: hiscore saving. Yes, <i>that</i>. I&#8217;ve seen the<br />
multitude of threads on the subject but sofar I&#8217;m unsure of what would<br />
work on both hardware and emulator, so I&#8217;m leaving it as is for now.<br />
If anyone has a tidy hw+emu solution, please do tell.
</p>
<h4>Links</h4>
<ul>
<li>binary: <a href="http://www.coranac.com/files/setds-bin.zip">setds-bin.zip</a> (146k)</li>
<li>source: <a href="http://www.coranac.com/files/setds-src.zip">setds-src.zip</a> (354k)</li>
<li>readme: <a href="http://www.coranac.com/files/setds-readme.txt">setds-readme.txt</a></li>
</ul>
<p><div>&nbsp;</div></p>
<p>
Oh, and merry Christmas everybody.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2009/12/setds/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Some new notes on NDS code size</title>
		<link>http://www.coranac.com/2009/11/sizeof-new/</link>
		<comments>http://www.coranac.com/2009/11/sizeof-new/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 15:31:31 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[nds]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=133</guid>
		<description><![CDATA[When I discussed the memory footprints of several C/C++ elements, I apparently missed a very important item: operator new and related functions. I assumed new shouldn&#8217;t increase the binary that much, but boy was I wrong. The short story is that officially new should throw an exception when it can&#8217;t allocate new memory. Exceptions come [...]]]></description>
			<content:encoded><![CDATA[<p>
When I discussed the<br />
<a href="http://www.coranac.com/2009/02/some-interesting-numbers-on-nds-code-size/"><br />
memory footprints of several C/C++ elements</a>, I apparently missed a<br />
very important item: <code>operator new</code> and related functions. I<br />
assumed <code>new</code> shouldn&#8217;t increase the binary that much,<br />
but boy was I wrong.
</p>
<p>
The short story is that officially <code>new</code> should throw an<br />
exception when it can&#8217;t allocate new memory. Exceptions come with about<br />
60 kb worth of baggage. Yes, this is more or less the same stuff that<br />
goes into <code>vector</code> and <code>string</code>.
</p>
<p>
The long story, including a detailed look at a minimal binary,<br />
a binary that uses <code>new</code> and a solution to the exception overhead (in this particular case anyway) can be read below the fold.
</p>
<p><span id="more-133"></span></p>
<p><div>&nbsp;</div><ul>
  <li> <a href="#sec-base">1
Minimal project
</a> </li>
  <li> <a href="#sec-std-new">2
Standard C++ new/delete
</a> </li>
  <li> <a href="#sec-own-new">3
Custom new/delete
</a> </li>
  <li> <a href="#sec-conc">4
Other considerations and conclusions.
</a> </li>
</ul>
</p>
<p><h2 id="sec-base">1
Minimal project
</h2>
</p>
<p>
The following is essentially an empty project. It should represent<br />
the smallest binary you can get with the current DKA (r26) and<br />
libnds (1.3.7). This is the primary reference case.
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">#include &lt;nds.h&gt;</p>
<p><span class="kw1">int</span> main()<br />
{<br />
&nbsp; &nbsp; <span class="kw1">while</span>() ;<br />
}</div>
</div>
<p>
This actually already leads to a binary of 53.5 kb. To analyze what<br />
goes on in there, we can look at the map file. <i>Not</i> the mapfile<br />
generated by the linker, mind you, but by the <tt>arm-eabi-nm</tt> tool,<br />
whose generated files are considerably easier to read. To use this tool,<br />
add the following line to <code>$(BUILD)</code> rule in the makefile,<br />
so that it looks like below. If you want to know what the flags mean,<br />
please <a href="http://sourceware.org/binutils/docs/binutils/nm.html">RTFM</a>.
</p>
<div class="make">
<div class="make proglist" style=" ">$(<span class="re2">BUILD</span>):<br />
&nbsp; &nbsp; @[ -d <span class="re0">$@</span> ] || mkdir -p <span class="re0">$@</span><br />
&nbsp; &nbsp; @make &#8211;no-print-directory -C $(<span class="re2">BUILD</span>) -f $(<span class="re2">CURDIR</span>)/Makefile<br />
&nbsp; &nbsp; arm-eabi-nm -Sn $(<span class="re2">OUTPUT</span>).elf &gt; $(<span class="re2">BUILD</span>)/$(<span class="re2">TARGET</span>).map</div>
</div>
<p>
And this is the resulting mapfile, in full.
</p>
<div class="none">
<div class="none proglist" style=" ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w _Jv_RegisterClasses<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w __deregister_frame_info<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w __register_frame_info<br />
00080000 N _stack<br />
01000000 A __vectors_end<br />
01000000 A __vectors_start<br />
01000100 A __itcm_start<br />
01000100 000000c8 T irqTable<br />
010001c8 T IntrMain<br />
010001fc t findIRQ<br />
01000218 t no_handler<br />
01000228 t jump_intr<br />
0100023c t got_handler<br />
0100025c t IntrRet<br />
01000290 A __itcm_end<br />
02000000 T __text_start<br />
02000000 T _start<br />
02000194 t ILoop<br />
02000198 t checkARGV<br />
020001dc t .copyforward<br />
020001f0 t .copybackward<br />
02000200 t .copydone<br />
02000214 t ClearMem<br />
02000228 t ClrLoop<br />
02000238 t CopyMemCheck<br />
0200023c t CopyMem<br />
0200024c t CIDLoop<br />
02000300 T _init<br />
02000310 t __do_global_dtors_aux<br />
0200033c t frame_dummy<br />
0200037c 00000004 T main<br />
02000380 000000ec T initSystem<br />
0200046c 00000012 T ledBlink<br />
02000480 0000002c T powerOff<br />
020004ac 00000030 T powerOn<br />
020004dc 00000018 T systemSleep<br />
020004f4 00000010 T powerValueHandler<br />
02000504 00000044 T systemMsgHandler<br />
02000548 00000164 t fifoInternalSend<br />
020006ac 00000038 T fifoSendAddress<br />
020006e4 00000048 T fifoSendValue32<br />
0200072c 00000070 T fifoGetAddress<br />
0200079c 00000074 T fifoSetAddressHandler<br />
02000810 00000070 T fifoGetValue32<br />
02000880 00000074 T fifoSetValue32Handler<br />
020008f4 00000024 T fifoCheckAddress<br />
02000918 00000024 T fifoCheckDatamsg<br />
0200093c 00000024 T fifoCheckValue32<br />
02000960 00000094 t fifoInternalSendInterrupt<br />
020009f4 00000010 t __timeoutvbl<br />
02000a04 000001b8 T fifoInit<br />
02000bbc 00000100 T fifoGetDatamsg<br />
02000cbc 0000040c t fifoInternalRecvInterrupt<br />
020010c8 000000a8 T fifoSetDatamsgHandler<br />
02001170 00000070 T fifoSendDatamsg<br />
020011e0 00000002 T irqDummy<br />
020011e4 0000006c T irqSet<br />
02001250 0000004c T irqInit<br />
0200129c 00000030 T irqInitHandler<br />
020012cc 00000060 T irqEnable<br />
0200132c 00000060 T irqDisable<br />
0200138c 0000002c T irqClear<br />
020013c0 T swiSoftReset<br />
020013c4 T swiDelay<br />
020013c8 T swiIntrWait<br />
020013cc T swiWaitForVBlank<br />
020013d0 T swiSleep<br />
020013d4 T swiChangeSoundBias<br />
020013d8 T swiDivide<br />
020013dc T swiRemainder<br />
020013e2 T swiDivMod<br />
020013ee T swiCopy<br />
020013f2 T swiFastCopy<br />
020013f6 T swiSqrt<br />
020013fa T swiCRC16<br />
020013fe T swiIsDebugger<br />
02001402 T swiUnpackBits<br />
02001406 T swiDecompressLZSSWram<br />
0200140a T swiDecompressLZSSVram<br />
0200140e T swiDecompressHuffman<br />
02001412 T swiDecompressRLEWram<br />
02001416 T swiDecompressRLEVram<br />
0200141a T swiWaitForIRQ<br />
0200141e T swiDecodeDelta8<br />
02001422 T swiDecodeDelta16<br />
02001426 T swiSetHaltCR<br />
02001430 00000030 T __libc_fini_array<br />
02001460 00000050 T __libc_init_array<br />
020014b4 00000080 T memcpy<br />
02001534 00000006 T _times_r<br />
0200153c 0000002c T _gettimeofday_r<br />
02001568 00000014 T _times<br />
0200157c 00000052 T build_argv<br />
020015d0 0000000c T __errno<br />
020015dc T _fini<br />
020015e8 A __text_end<br />
020015e8 00000004 R _global_impure_ptr<br />
020015f0 A __exidx_end<br />
020015f0 A __exidx_start<br />
020015f0 t __frame_dummy_init_array_entry<br />
020015f0 A __init_array_start<br />
020015f0 A __preinit_array_end<br />
020015f0 A __preinit_array_start<br />
020015f4 t __do_global_dtors_aux_fini_array_entry<br />
020015f4 A __fini_array_start<br />
020015f4 A __init_array_end<br />
020015f8 r __EH_FRAME_BEGIN__<br />
020015f8 r __FRAME_END__<br />
020015f8 A __fini_array_end<br />
020015fc d __JCR_END__<br />
020015fc d __JCR_LIST__<br />
02001600 A __data_start<br />
02001600 D __dso_handle<br />
02001600 A __ewram_start<br />
02001604 00000004 D fifo_freewords<br />
02001608 00000004 D fifo_send_queue<br />
0200160c 00000004 D fifo_buffer_free<br />
02001610 00000004 D fifo_receive_queue<br />
02001618 00000004 D _impure_ptr<br />
02001620 00000428 d impure_data<br />
02001a48 A __bss_start<br />
02001a48 A __bss_start__<br />
02001a48 A __bss_vma<br />
02001a48 A __data_end<br />
02001a48 A __dtcm_lma<br />
02001a48 A __itcm_lma<br />
02001a48 b completed.2775<br />
02001a4c b object.2787<br />
02001a64 00000004 b __timeout<br />
02001a68 00000004 B processing<br />
02001a6c 00000004 B fake_heap_end<br />
02001a70 00000004 B fake_heap_start<br />
02001a74 00000004 B theTime<br />
02001a78 00000040 B fifo_datamsg_data<br />
02001ab8 00000800 B fifo_buffer<br />
02001bd8 A __vectors_lma<br />
020022b8 00000040 B fifo_value32_func<br />
020022f8 00000040 B fifo_address_func<br />
02002338 00000040 B fifo_value32_data<br />
02002378 00000040 B fifo_value32_queue<br />
020023b8 00000040 B fifo_data_queue<br />
020023f8 00000040 B fifo_address_data<br />
02002438 00000040 B fifo_datamsg_func<br />
02002478 00000040 B fifo_address_queue<br />
020024b8 00000004 B punixTime<br />
020024bc A __bss_end<br />
020024bc A __bss_end__<br />
020024bc A __end__<br />
020024bc A _end<br />
023ff000 A __eheap_end<br />
023ff000 A __ewram_end<br />
027fff70 a _libnds_argv<br />
0b000000 A __dtcm_end<br />
0b000000 A __dtcm_start<br />
0b000000 A __sbss_end<br />
0b000000 A __sbss_start<br />
0b000000 A __sbss_start__<br />
0b003d00 A __sp_usr<br />
0b003e00 A __sp_irq<br />
0b003f00 A __sp_svc<br />
0b003ff8 A __irq_flags<br />
0b003ffc A __irq_vector<br />
0b004000 A __dtcm_top</div>
</div>
<p>
Now, I expect you can&#8217;t really tell much from this, so here&#8217;s a summary.
</p>
<div class="none">
<div class="none proglist" style=" ">[map]<br />
begin &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; size&nbsp; &nbsp; &nbsp; Description<br />
02000000 &#8211; 0200033c &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : crt0.S (roughly)<br />
0200037c &#8211; 02000380 &nbsp; &nbsp; 0004 &nbsp; &nbsp;: main.c<br />
02000380 &#8211; 02000548 &nbsp; &nbsp; 01C8&nbsp; &nbsp; : libnds system init/handlers<br />
02000548 &#8211; 020011e0 &nbsp; &nbsp; 0C98&nbsp; &nbsp; : libnds fifo routines<br />
020011e0 &#8211; 020013c0 &nbsp; &nbsp; 01E0&nbsp; &nbsp; : libnds interrupt.c<br />
020013c0 &#8211; 02001430 &nbsp; &nbsp; 0070&nbsp; &nbsp; : libnds bios.s<br />
02001430 &#8211; 020015e8 &nbsp; &nbsp; 01B8&nbsp; &nbsp; : libc misc<br />
020015e8 A __text_end<br />
020015e8 &#8211; 02001600 &nbsp; &nbsp; 0018&nbsp; &nbsp; : C/C++ ctor/dtor overhead, etc?<br />
02001600 &#8211; 02001618 &nbsp; &nbsp; 0018&nbsp; &nbsp; : libnds fifo data<br />
02001618 &#8211; 02001a48 &nbsp; &nbsp; 0430&nbsp; &nbsp; : impure ?!?<br />
02001a48 &#8211; 02001a78 &nbsp; &nbsp; 0030&nbsp; &nbsp; : misc bookkeeping</p>
<p>02001a78 &#8211; 020024b8 &nbsp; &nbsp; 0A40&nbsp; &nbsp; : libnds fifo data + pointers<br />
020024bc A _end</p>
<p>000024bc &#8211; 0000D630 0000B174&nbsp; &nbsp; : ???<br />
[/map]</div>
</div>
<p>
The <code>0100:xxxx</code> and <code>0B00:xxxx</code> ranges belong to<br />
ITCM and DTCM, so those are irrelevant when looking at main RAM size.<br />
The libc, impure and misc bookkeeping sections are stuff related to the<br />
C library and C overhead, accounting for about 1.5 kb. The boot code,<br />
<tt>crt0.S</tt> also covers close to 1.0 kb. As expected, the code for<br />
<code>main.c</code> &ndash;the actual project&ndash; is more or less<br />
nothing.
</p>
<p>
The rest, about 7 kb, is libnds. Now, you may say that this is quite a bit<br />
of overhead, but it really isn&#8217;t. Pretty much all of it relates to<br />
interrupts and the fifo system, which takes care of ARM7-ARM9<br />
communication. You <i>need</i> to have these parts. Okay, you could try<br />
to roll your own to shrink this down to the bare essentials, but in all<br />
likelihood that&#8217;s more trouble than it&#8217;s worth.
</p>
<p><div>&nbsp;</div></p>
<p>
The observant of you should have noticed something: we&#8217;re only at 9.5 kb,<br />
but the file size is 53.5 kb. So what the hell happened to the other 44 kb?<br />
Well, I don&#8217;t know, to be honest. It doesn&#8217;t appear in MWRAM to be sure.<br />
It&#8217;s probably the stuff <tt>ndstool</tt> adds. My guess it that that&#8217;s<br />
where the ARM7 binary goes, along with the icon, titles and possibly<br />
DLDI interfaces, but I really can&#8217;t say right now.
</p>
<p><h2 id="sec-std-new">2
Standard C++ new/delete
</h2>
</p>
<p>
And now, let&#8217;s look at what happens when you invoke <code>new</code>.
</p>
<div class="none">
<div class="none proglist" style=" ">void test_std_new()<br />
{<br />
&nbsp; &nbsp; u8 *ptr= new u8[<span class="nu0">8</span>];<br />
&nbsp; &nbsp; delete[] ptr;<br />
}</p>
<p>int main()<br />
{<br />
&nbsp; &nbsp; while(<span class="nu0">1</span>) ;<br />
}</div>
</div>
<p>
Just this small thing increases the file size to 117 kb! And remember,<br />
that&#8217;s not merely a doubling of the size, as 44 kb of the binary is not<br />
put in memory. The memory load has gone from about 10 kb to over 70 kb.<br />
What causes this increase? Well, let&#8217;s see:
</p>
<div class="none">
<div class="none proglist" style=" ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w _Jv_RegisterClasses<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w __deregister_frame_info<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w __gnu_Unwind_Find_exidx<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w __register_frame_info<br />
00080000 N _stack<br />
01000000 A __vectors_end<br />
01000000 A __vectors_start<br />
01000100 A __itcm_start<br />
01000100 000000c8 T irqTable<br />
010001c8 T IntrMain<br />
010001fc t findIRQ<br />
01000218 t no_handler<br />
01000228 t jump_intr<br />
0100023c t got_handler<br />
0100025c t IntrRet<br />
01000290 A __itcm_end<br />
02000000 T __text_start<br />
02000000 T _start<br />
02000194 t ILoop<br />
02000198 t checkARGV<br />
020001dc t .copyforward<br />
020001f0 t .copybackward<br />
02000200 t .copydone<br />
02000214 t ClearMem<br />
02000228 t ClrLoop<br />
02000238 t CopyMemCheck<br />
0200023c t CopyMem<br />
0200024c t CIDLoop<br />
02000300 T _init<br />
02000310 t __do_global_dtors_aux<br />
0200033c t frame_dummy<br />
0200037c 00000004 T main<br />
02000380 00000012 T _Z12test_std_newv<br />
02000394 000000ec T initSystem<br />
02000480 00000012 T ledBlink<br />
02000494 0000002c T powerOff<br />
020004c0 00000030 T powerOn<br />
020004f0 00000018 T systemSleep<br />
02000508 00000010 T powerValueHandler<br />
02000518 00000044 T systemMsgHandler<br />
0200055c 00000164 t fifoInternalSend<br />
020006c0 00000038 T fifoSendAddress<br />
020006f8 00000048 T fifoSendValue32<br />
02000740 00000070 T fifoGetAddress<br />
020007b0 00000074 T fifoSetAddressHandler<br />
02000824 00000070 T fifoGetValue32<br />
02000894 00000074 T fifoSetValue32Handler<br />
02000908 00000024 T fifoCheckAddress<br />
0200092c 00000024 T fifoCheckDatamsg<br />
02000950 00000024 T fifoCheckValue32<br />
02000974 00000094 t fifoInternalSendInterrupt<br />
02000a08 00000010 t __timeoutvbl<br />
02000a18 000001b8 T fifoInit<br />
02000bd0 00000100 T fifoGetDatamsg<br />
02000cd0 0000040c t fifoInternalRecvInterrupt<br />
020010dc 000000a8 T fifoSetDatamsgHandler<br />
02001184 00000070 T fifoSendDatamsg<br />
020011f4 00000002 T irqDummy<br />
020011f8 0000006c T irqSet<br />
02001264 0000004c T irqInit<br />
020012b0 00000030 T irqInitHandler<br />
020012e0 00000060 T irqEnable<br />
02001340 00000060 T irqDisable<br />
020013a0 0000002c T irqClear<br />
020013d0 T swiSoftReset<br />
020013d4 T swiDelay<br />
020013d8 T swiIntrWait<br />
020013dc T swiWaitForVBlank<br />
020013e0 T swiSleep<br />
020013e4 T swiChangeSoundBias<br />
020013e8 T swiDivide<br />
020013ec T swiRemainder<br />
020013f2 T swiDivMod<br />
020013fe T swiCopy<br />
02001402 T swiFastCopy<br />
02001406 T swiSqrt<br />
0200140a T swiCRC16<br />
0200140e T swiIsDebugger<br />
02001412 T swiUnpackBits<br />
02001416 T swiDecompressLZSSWram<br />
0200141a T swiDecompressLZSSVram<br />
0200141e T swiDecompressHuffman<br />
02001422 T swiDecompressRLEWram<br />
02001426 T swiDecompressRLEVram<br />
0200142a T swiWaitForIRQ<br />
0200142e T swiDecodeDelta8<br />
02001432 T swiDecodeDelta16<br />
02001436 T swiSetHaltCR<br />
02001440 00000054 t d_make_comp<br />
02001494 0000003a t d_make_name<br />
020014d0 00000058 t d_number<br />
02001528 0000004c t d_call_offset<br />
02001574 00000096 t d_cv_qualifiers<br />
0200160c 00000060 t d_template_param<br />
0200166c 00000160 t d_substitution<br />
020017cc 00000050 t d_append_char<br />
0200181c 00000084 t d_find_pack<br />
020018a0 00000090 t d_source_name<br />
02001930 00000240 t d_expression<br />
02001b70 0000056c t d_type<br />
020020dc 0000009a t d_bare_function_type<br />
02002178 000000ec t d_operator_name<br />
02002264 00000136 t d_unqualified_name<br />
0200239c 000000ca t d_expr_primary<br />
02002468 000000aa t d_template_args<br />
02002514 0000022c t d_name<br />
02002740 0000039c t d_encoding<br />
02002adc 00000060 t d_exprlist<br />
02002b3c 0000008a t d_growable_string_callback_adapter<br />
02002bc8 00000098 t d_append_buffer<br />
02002c60 000000a0 t d_append_string<br />
02002d00 000001f8 t d_print_array_type<br />
02002ef8 00000108 t d_print_mod_list<br />
02003000 00000234 t d_print_function_type<br />
02003234 00000ba0 t d_print_comp<br />
02003dd4 000001c0 t d_demangle_callback<br />
02003f94 0000002e T __gcclibcxx_demangle_callback<br />
02003fc4 000000c0 T __cxa_demangle<br />
02004084 000000c8 t d_print_mod<br />
0200414c 00000104 t d_print_cast<br />
02004250 0000009c t d_print_expr_op<br />
020042ec 000000a8 t d_print_subexpr<br />
02004398 T __cxa_end_cleanup<br />
020043a4 T __aeabi_uidiv<br />
020043a4 0000007a T __udivsi3<br />
02004420 0000000e T __aeabi_uidivmod<br />
02004430 00000002 T __aeabi_idiv0<br />
02004430 00000002 T __aeabi_ldiv0<br />
02004430 00000002 T __div0<br />
02004434 00000010 t _Unwind_decode_target2<br />
02004444 0000002a T _Unwind_VRS_Get<br />
02004470 0000001a t _Unwind_GetGR<br />
0200448c 0000002a T _Unwind_VRS_Set<br />
020044b8 0000001c t _Unwind_SetGR<br />
020044d4 00000020 t selfrel_offset31<br />
020044f4 00000074 t search_EIT_table<br />
02004568 00000004 T _Unwind_GetCFA<br />
0200456c 00000002 T _Unwind_Complete<br />
02004570 00000016 T _Unwind_DeleteException<br />
02004588 000002bc t __gnu_unwind_pr_common<br />
02004844 0000000e W __aeabi_unwind_cpp_pr2<br />
02004854 0000000e W __aeabi_unwind_cpp_pr1<br />
02004864 0000000e T __aeabi_unwind_cpp_pr0<br />
02004874 000000d0 t get_eit_entry<br />
02004944 0000005a t restore_non_core_regs<br />
020049a0 00000080 T __gnu_Unwind_Backtrace<br />
02004a20 000000e4 t unwind_phase2_forced<br />
02004b04 00000018 T __gnu_Unwind_ForcedUnwind<br />
02004b1c 00000034 t unwind_phase2<br />
02004b50 00000060 T __gnu_Unwind_RaiseException<br />
02004bb0 0000001e T __gnu_Unwind_Resume_or_Rethrow<br />
02004bd0 00000040 T __gnu_Unwind_Resume<br />
02004c10 00000268 T _Unwind_VRS_Pop<br />
02004e80 0000001c T __restore_core_regs<br />
02004e80 0000001c T restore_core_regs<br />
02004e9c T __gnu_Unwind_Restore_VFP<br />
02004ea4 T __gnu_Unwind_Save_VFP<br />
02004eac T __gnu_Unwind_Restore_VFP_D<br />
02004eb4 T __gnu_Unwind_Save_VFP_D<br />
02004ebc T __gnu_Unwind_Restore_VFP_D_16_to_31<br />
02004ec4 T __gnu_Unwind_Save_VFP_D_16_to_31<br />
02004ecc T __gnu_Unwind_Restore_WMMXD<br />
02004f10 T __gnu_Unwind_Save_WMMXD<br />
02004f54 T __gnu_Unwind_Restore_WMMXC<br />
02004f68 T __gnu_Unwind_Save_WMMXC<br />
02004f7c 0000002a T _Unwind_RaiseException<br />
02004f7c 0000002a T ___Unwind_RaiseException<br />
02004fa8 0000002a T _Unwind_Resume<br />
02004fa8 0000002a T ___Unwind_Resume<br />
02004fd4 0000002a T _Unwind_Resume_or_Rethrow<br />
02004fd4 0000002a T ___Unwind_Resume_or_Rethrow<br />
02005000 0000002a T _Unwind_ForcedUnwind<br />
02005000 0000002a T ___Unwind_ForcedUnwind<br />
0200502c 0000002a T _Unwind_Backtrace<br />
0200502c 0000002a T ___Unwind_Backtrace<br />
02005058 00000036 t next_unwind_byte<br />
02005090 00000006 T _Unwind_GetTextRelBase<br />
02005098 00000006 T _Unwind_GetDataRelBase<br />
020050a0 0000001a t _Unwind_GetGR<br />
020050bc 0000000e t unwind_UCB_from_context<br />
020050cc 00000018 T _Unwind_GetLanguageSpecificData<br />
020050e4 0000000e T _Unwind_GetRegionStart<br />
020050f4 000002e8 T __gnu_unwind_execute<br />
020053dc 0000002a T __gnu_unwind_frame<br />
02005408 0000000e T abort<br />
02005418 0000002c T fputc<br />
02005444 00000026 T _fputc_r<br />
0200546c 0000005c T _fputs_r<br />
020054c8 0000001c T fputs<br />
020054e4 00000324 T __sfvwrite_r<br />
0200580c 0000007c T _fwrite_r<br />
02005888 00000028 T fwrite<br />
020058b0 00000030 T __libc_fini_array<br />
020058e0 00000050 T __libc_init_array<br />
02005934 00000018 T free<br />
0200594c 00000018 T malloc<br />
02005964 00000504 T _malloc_r<br />
02005e68 00000080 T memchr<br />
02005ee8 00000058 T memcmp<br />
02005f40 00000080 T memcpy<br />
02005fc0 000000a0 T memmove<br />
02006060 00000094 T memset<br />
020060f4 00000002 T __malloc_lock<br />
020060f8 00000002 T __malloc_unlock<br />
020060fc 00000064 T putc<br />
02006160 0000005e T _putc_r<br />
020061c0 0000001c T realloc<br />
020061dc 00000360 T _realloc_r<br />
0200653c 0000005c T _raise_r<br />
02006598 00000018 T raise<br />
020065b0 00000036 T _init_signal_r<br />
020065e8 00000014 T _init_signal<br />
020065fc 00000056 T __sigtramp_r<br />
02006654 00000018 T __sigtramp<br />
0200666c 00000040 T _signal_r<br />
020066ac 0000001c T signal<br />
020066cc 00000044 T sprintf<br />
02006710 00000040 T _sprintf_r<br />
02006750 0000005c T strcmp<br />
020067ac 0000004c T strcpy<br />
020067f8 0000006c T strlen<br />
02006864 000000ac T strncmp<br />
02006910 00000134 t __sprint_r<br />
02006a44 000015d6 T _svfprintf_r<br />
02008020 00000020 T write<br />
02008040 000000c4 T __swbuf_r<br />
02008104 0000001c T __swbuf<br />
02008120 00000042 T _wcrtomb_r<br />
02008164 00000020 T wcrtomb<br />
02008184 000000da T _wcsrtombs_r<br />
02008260 00000028 T wcsrtombs<br />
02008288 000002c8 T _wctomb_r<br />
02008550 000000d0 T __swsetup_r<br />
02008620 00000154 t quorem<br />
02008774 00000e9c T _dtoa_r<br />
02009610 00000114 T _fflush_r<br />
02009724 00000030 T fflush<br />
02009758 00000002 T __sfp_lock_acquire<br />
0200975c 00000002 T __sfp_lock_release<br />
02009760 00000002 T __sinit_lock_acquire<br />
02009764 00000002 T __sinit_lock_release<br />
02009768 00000004 t __fp_lock<br />
0200976c 00000004 t __fp_unlock<br />
02009770 0000001c T __fp_unlock_all<br />
0200978c 0000001c T __fp_lock_all<br />
020097a8 00000014 T _cleanup_r<br />
020097bc 00000014 T _cleanup<br />
020097d0 0000004c t std<br />
0200981c 0000005c T __sinit<br />
02009878 00000030 T __sfmoreglue<br />
020098a8 00000090 T __sfp<br />
02009938 000000a4 T _malloc_trim_r<br />
020099dc 000001ac T _free_r<br />
02009b88 00000064 T _fwalk_reent<br />
02009bec 0000005c T _fwalk<br />
02009c4c 0000000c T __locale_charset<br />
02009c58 00000008 T _localeconv_r<br />
02009c60 00000008 T localeconv<br />
02009c68 00000254 T _setlocale_r<br />
02009ebc 0000001c T setlocale<br />
02009ed8 000000e8 T __smakebuf_r<br />
02009fc0 0000065e T _mbtowc_r<br />
0200a620 00000016 T _Bfree<br />
0200a638 00000054 T __hi0bits<br />
0200a68c 00000068 T __lo0bits<br />
0200a6f4 00000042 T __mcmp<br />
0200a738 00000050 T __ulp<br />
0200a788 0000009c T __b2d<br />
0200a824 00000064 T __ratio<br />
0200a888 00000044 T _mprec_log10<br />
0200a8cc 00000048 T __copybits<br />
0200a914 00000054 T __any_on<br />
0200a968 00000052 T _Balloc<br />
0200a9bc 000000e4 T __d2b<br />
0200aaa0 00000120 T __mdiff<br />
0200abc0 000000c4 T __lshift<br />
0200ac84 00000164 T __multiply<br />
0200ade8 00000016 T __i2b<br />
0200ae00 000000a4 T __multadd<br />
0200aea4 000000b8 T __pow5mult<br />
0200af5c 0000009c T __s2b<br />
0200aff8 00000024 T __isinfd<br />
0200b01c 00000020 T __isnand<br />
0200b03c 00000010 T __sclose<br />
0200b04c 00000030 T __sseek<br />
0200b07c 0000003c T __swrite<br />
0200b0b8 0000002c T __sread<br />
0200b0e4 0000005c T _calloc_r<br />
0200b140 000000a2 T _fclose_r<br />
0200b1e4 00000018 T fclose<br />
0200b200 0000004c T _close_r<br />
0200b250 00000054 T _fstat_r<br />
0200b2a8 0000000a T _getpid_r<br />
0200b2b4 00000004 T _isatty_r<br />
0200b2b8 0000000a T _kill_r<br />
0200b2c4 0000004c T _lseek_r<br />
0200b314 0000004c T _read_r<br />
0200b364 00000054 T _sbrk_r<br />
0200b3b8 00000006 T _times_r<br />
0200b3c0 0000002c T _gettimeofday_r<br />
0200b3ec 00000014 T _times<br />
0200b400 0000004c T _write_r<br />
0200b450 00000014 T _exit<br />
0200b468 00000052 T build_argv<br />
0200b4bc 00000020 T __get_handle<br />
0200b4dc 0000003c T __alloc_handle<br />
0200b518 0000002c T __release_handle<br />
0200b544 00000014 T setDefaultDevice<br />
0200b558 0000007c T AddDevice<br />
0200b5d4 00000068 T FindDevice<br />
0200b63c 00000020 T GetDeviceOpTab<br />
0200b65c 00000024 T RemoveDevice<br />
0200b680 T __aeabi_idiv<br />
0200b680 00000094 T __divsi3<br />
0200b714 0000000e T __aeabi_idivmod<br />
0200b724 T __aeabi_drsub<br />
0200b72c 00000314 T __aeabi_dsub<br />
0200b72c 00000314 T __subdf3<br />
0200b730 00000310 T __adddf3<br />
0200b730 00000310 T __aeabi_dadd<br />
0200ba40 00000024 T __aeabi_ui2d<br />
0200ba40 00000024 T __floatunsidf<br />
0200ba64 00000028 T __aeabi_i2d<br />
0200ba64 00000028 T __floatsidf<br />
0200ba8c 00000040 T __aeabi_f2d<br />
0200ba8c 00000040 T __extendsfdf2<br />
0200bacc 00000074 T __aeabi_ul2d<br />
0200bacc 00000074 T __floatundidf<br />
0200bae0 00000060 T __aeabi_l2d<br />
0200bae0 00000060 T __floatdidf<br />
0200bb40 00000290 T __aeabi_dmul<br />
0200bb40 00000290 T __muldf3<br />
0200bdd0 0000020c T __aeabi_ddiv<br />
0200bdd0 0000020c T __divdf3<br />
0200bfdc 00000094 T __gedf2<br />
0200bfdc 00000094 T __gtdf2<br />
0200bfe4 0000008c T __ledf2<br />
0200bfe4 0000008c T __ltdf2<br />
0200bfec 00000084 T __cmpdf2<br />
0200bfec 00000084 T __eqdf2<br />
0200bfec 00000084 T __nedf2<br />
0200c070 00000034 T __aeabi_cdrcmple<br />
0200c08c 00000018 T __aeabi_cdcmpeq<br />
0200c08c 00000018 T __aeabi_cdcmple<br />
0200c0a4 00000018 T __aeabi_dcmpeq<br />
0200c0bc 00000018 T __aeabi_dcmplt<br />
0200c0d4 00000018 T __aeabi_dcmple<br />
0200c0ec 00000018 T __aeabi_dcmpge<br />
0200c104 00000018 T __aeabi_dcmpgt<br />
0200c11c 0000005c T __aeabi_d2iz<br />
0200c11c 0000005c T __fixdfsi<br />
0200c178 0000000c T __errno<br />
0200c184 0000000c T _ZdaPv<br />
0200c190 0000004c t _ZL21base_of_encoded_valuehP15_Unwind_Context<br />
0200c1dc 0000016c t _ZL17parse_lsda_headerP15_Unwind_ContextPKhP16lsda_header_info<br />
0200c348 0000073a T __gxx_personality_v0<br />
0200ca84 00000010 T _ZSt13set_terminatePFvvE<br />
0200ca94 00000010 T _ZSt14set_unexpectedPFvvE<br />
0200caa4 00000020 T _ZN10__cxxabiv111__terminateEPFvvE<br />
0200cac4 00000010 T _ZSt9terminatev<br />
0200cad4 0000000c T _ZN10__cxxabiv112__unexpectedEPFvvE<br />
0200cae0 00000010 T _ZSt10unexpectedv<br />
0200caf0 00000018 T _Znaj<br />
0200cb08 0000010e T _ZN9__gnu_cxx27__verbose_terminate_handlerEv<br />
0200cc18 00000010 T _ZdlPv<br />
0200cc28 000000f8 T __cxa_type_match<br />
0200cd20 00000062 T __cxa_begin_cleanup<br />
0200cd84 0000006a T __gnu_end_cleanup<br />
0200cdf0 00000020 T __cxa_bad_typeid<br />
0200ce10 00000020 T __cxa_bad_cast<br />
0200ce30 00000048 T __cxa_call_terminate<br />
0200ce78 00000122 T __cxa_call_unexpected<br />
0200cf9c 00000004 T __cxa_get_exception_ptr<br />
0200cfa0 00000012 T _ZSt18uncaught_exceptionv<br />
0200cfb4 00000086 T __cxa_end_catch<br />
0200d03c 00000086 T __cxa_begin_catch<br />
0200d0c4 0000000c T _ZNSt9exceptionD2Ev<br />
0200d0d0 0000000c T _ZNSt9exceptionD1Ev<br />
0200d0dc 0000000c T _ZNSt13bad_exceptionD2Ev<br />
0200d0e8 0000000c T _ZNSt13bad_exceptionD1Ev<br />
0200d0f4 0000000c T _ZN10__cxxabiv115__forced_unwindD2Ev<br />
0200d100 0000000c T _ZN10__cxxabiv115__forced_unwindD1Ev<br />
0200d10c 0000000c T _ZN10__cxxabiv119__foreign_exceptionD2Ev<br />
0200d118 0000000c T _ZN10__cxxabiv119__foreign_exceptionD1Ev<br />
0200d124 00000008 T _ZNKSt9exception4whatEv<br />
0200d12c 00000008 T _ZNKSt13bad_exception4whatEv<br />
0200d134 00000000 T _ZNKSt13bad_exhelpimtrappedinabinaryfactoryEv<br />
0200d134 0000001c T _ZN10__cxxabiv119__foreign_exceptionD0Ev<br />
0200d150 0000001c T _ZN10__cxxabiv115__forced_unwindD0Ev<br />
0200d16c 0000001c T _ZNSt9exceptionD0Ev<br />
0200d188 0000001c T _ZNSt13bad_exceptionD0Ev<br />
0200d1a4 00000008 T __cxa_get_globals_fast<br />
0200d1ac 00000008 T __cxa_get_globals<br />
0200d1b4 00000068 T __cxa_rethrow<br />
0200d21c 0000005c T __cxa_throw<br />
0200d278 00000034 t _ZL23__gxx_exception_cleanup19_Unwind_Reason_CodeP21_Unwind_Control_Block<br />
0200d2ac 00000026 T __cxa_current_exception_type<br />
0200d2d4 0000001c T _ZN10__cxxabiv123__fundamental_type_infoD1Ev<br />
0200d2f0 0000001c T _ZN10__cxxabiv123__fundamental_type_infoD2Ev<br />
0200d30c 00000020 T _ZN10__cxxabiv123__fundamental_type_infoD0Ev<br />
0200d32c 00000010 T _ZSt15set_new_handlerPFvvE<br />
0200d33c 00000008 T _ZNKSt9bad_alloc4whatEv<br />
0200d344 0000001c T _ZNSt9bad_allocD1Ev<br />
0200d360 0000001c T _ZNSt9bad_allocD2Ev<br />
0200d37c 00000020 T _ZNSt9bad_allocD0Ev<br />
0200d39c 0000006a T _Znwj<br />
0200d408 00000004 T _ZNK10__cxxabiv119__pointer_type_info14__is_pointer_pEv<br />
0200d40c 0000004c T _ZNK10__cxxabiv119__pointer_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj<br />
0200d458 0000001c T _ZN10__cxxabiv119__pointer_type_infoD1Ev<br />
0200d474 0000001c T _ZN10__cxxabiv119__pointer_type_infoD2Ev<br />
0200d490 00000020 T _ZN10__cxxabiv119__pointer_type_infoD0Ev<br />
0200d4b0 00000014 T __cxa_pure_virtual<br />
0200d4c4 0000002e T _ZNK10__cxxabiv120__si_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE<br />
0200d4f4 00000096 T _ZNK10__cxxabiv120__si_class_type_info12__do_dyncastEiNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE<br />
0200d58c 00000048 T _ZNK10__cxxabiv120__si_class_type_info20__do_find_public_srcEiPKvPKNS_17__class_type_infoES2_<br />
0200d5d4 0000001c T _ZN10__cxxabiv120__si_class_type_infoD1Ev<br />
0200d5f0 0000001c T _ZN10__cxxabiv120__si_class_type_infoD2Ev<br />
0200d60c 00000020 T _ZN10__cxxabiv120__si_class_type_infoD0Ev<br />
0200d62c 0000000c T _ZNSt9type_infoD2Ev<br />
0200d638 0000000c T _ZNSt9type_infoD1Ev<br />
0200d644 0000000c T _ZNKSt9type_infoeqERKS_<br />
0200d650 00000004 T _ZNKSt9type_info14__is_pointer_pEv<br />
0200d654 00000004 T _ZNKSt9type_info15__is_function_pEv<br />
0200d658 0000000c T _ZNKSt9type_info10__do_catchEPKS_PPvj<br />
0200d664 00000004 T _ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv<br />
0200d668 0000001c T _ZNSt9type_infoD0Ev<br />
0200d684 00000008 T _ZNKSt8bad_cast4whatEv<br />
0200d68c 0000001c T _ZNSt8bad_castD1Ev<br />
0200d6a8 0000001c T _ZNSt8bad_castD2Ev<br />
0200d6c4 00000020 T _ZNSt8bad_castD0Ev<br />
0200d6e4 00000008 T _ZNKSt10bad_typeid4whatEv<br />
0200d6ec 0000001c T _ZNSt10bad_typeidD1Ev<br />
0200d708 0000001c T _ZNSt10bad_typeidD2Ev<br />
0200d724 00000020 T _ZNSt10bad_typeidD0Ev<br />
0200d744 0000003e T _ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv<br />
0200d784 00000012 T _ZNK10__cxxabiv117__class_type_info20__do_find_public_srcEiPKvPKS0_S2_<br />
0200d798 00000020 T _ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE<br />
0200d7b8 0000004a T _ZNK10__cxxabiv117__class_type_info12__do_dyncastEiNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE<br />
0200d804 00000034 T _ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj<br />
0200d838 0000001c T _ZN10__cxxabiv117__class_type_infoD1Ev<br />
0200d854 0000001c T _ZN10__cxxabiv117__class_type_infoD2Ev<br />
0200d870 00000020 T _ZN10__cxxabiv117__class_type_infoD0Ev<br />
0200d890 00000002 t _GLOBAL__I___cxa_allocate_exception<br />
0200d894 0000003c T __cxa_free_dependent_exception<br />
0200d8d0 0000003c T __cxa_free_exception<br />
0200d90c 00000084 T __cxa_allocate_dependent_exception<br />
0200d990 00000088 T __cxa_allocate_exception<br />
0200da18 00000018 W _ZNK10__cxxabiv117__pbase_type_info15__pointer_catchEPKS0_PPvj<br />
0200da30 00000064 T _ZNK10__cxxabiv117__pbase_type_info10__do_catchEPKSt9type_infoPPvj<br />
0200da94 0000001c T _ZN10__cxxabiv117__pbase_type_infoD1Ev<br />
0200dab0 0000001c T _ZN10__cxxabiv117__pbase_type_infoD2Ev<br />
0200dacc 00000020 T _ZN10__cxxabiv117__pbase_type_infoD0Ev<br />
0200daec T _fini<br />
0200daf8 A __text_end<br />
0200e1dc 000000c4 r standard_subs<br />
0200e2a0 00000280 r cplus_demangle_builtin_types<br />
0200e520 00000350 r cplus_demangle_operators<br />
0200e884 00000004 R _global_impure_ptr<br />
0200e9ec 00000010 r blanks.3548<br />
0200e9fc 00000010 r zeroes.3549<br />
0200ea94 00000030 r lconv<br />
0200eadc 00000048 r JIS_state_table<br />
0200eb24 00000048 r JIS_action_table<br />
0200eb70 000000c8 R __mprec_tens<br />
0200ec38 0000000c r p05.2435<br />
0200ec48 00000028 R __mprec_bigtens<br />
0200ec70 00000028 R __mprec_tinytens<br />
0200ec98 0000005c R dotab_stdnull<br />
0200f4f8 00000014 R _ZTVN10__cxxabiv115__forced_unwindE<br />
0200f510 00000008 R _ZTISt9exception<br />
0200f518 00000014 R _ZTVSt9exception<br />
0200f530 00000008 R _ZTIN10__cxxabiv115__forced_unwindE<br />
0200f538 00000012 R _ZTSSt13bad_exception<br />
0200f54c 00000024 R _ZTSN10__cxxabiv119__foreign_exceptionE<br />
0200f594 00000008 R _ZTIN10__cxxabiv119__foreign_exceptionE<br />
0200f5a0 00000014 R _ZTVSt13bad_exception<br />
0200f5b8 0000000d R _ZTSSt9exception<br />
0200f5c8 00000014 R _ZTVN10__cxxabiv119__foreign_exceptionE<br />
0200f5e0 00000020 R _ZTSN10__cxxabiv115__forced_unwindE<br />
0200f600 0000000c R _ZTISt13bad_exception<br />
0200f60c 00000010 V _ZTIPKe<br />
0200f61c 00000010 V _ZTIPe<br />
0200f62c 00000008 V _ZTIe<br />
0200f634 00000010 V _ZTIPKd<br />
0200f644 00000010 V _ZTIPd<br />
0200f654 00000008 V _ZTId<br />
0200f65c 00000010 V _ZTIPKf<br />
0200f66c 00000010 V _ZTIPf<br />
0200f67c 00000008 V _ZTIf<br />
0200f684 00000010 V _ZTIPKy<br />
0200f694 00000010 V _ZTIPy<br />
0200f6a4 00000008 V _ZTIy<br />
0200f6ac 00000010 V _ZTIPKx<br />
0200f6bc 00000010 V _ZTIPx<br />
0200f6cc 00000008 V _ZTIx<br />
0200f6d4 00000010 V _ZTIPKm<br />
0200f6e4 00000010 V _ZTIPm<br />
0200f6f4 00000008 V _ZTIm<br />
0200f6fc 00000010 V _ZTIPKl<br />
0200f70c 00000010 V _ZTIPl<br />
0200f71c 00000008 V _ZTIl<br />
0200f724 00000010 V _ZTIPKj<br />
0200f734 00000010 V _ZTIPj<br />
0200f744 00000008 V _ZTIj<br />
0200f74c 00000010 V _ZTIPKi<br />
0200f75c 00000010 V _ZTIPi<br />
0200f76c 00000008 V _ZTIi<br />
0200f774 00000010 V _ZTIPKt<br />
0200f784 00000010 V _ZTIPt<br />
0200f794 00000008 V _ZTIt<br />
0200f79c 00000010 V _ZTIPKs<br />
0200f7ac 00000010 V _ZTIPs<br />
0200f7bc 00000008 V _ZTIs<br />
0200f7c4 00000010 V _ZTIPKh<br />
0200f7d4 00000010 V _ZTIPh<br />
0200f7e4 00000008 V _ZTIh<br />
0200f7ec 00000010 V _ZTIPKa<br />
0200f7fc 00000010 V _ZTIPa<br />
0200f80c 00000008 V _ZTIa<br />
0200f814 00000010 V _ZTIPKc<br />
0200f824 00000010 V _ZTIPc<br />
0200f834 00000008 V _ZTIc<br />
0200f83c 00000010 V _ZTIPKDi<br />
0200f84c 00000010 V _ZTIPDi<br />
0200f85c 00000008 V _ZTIDi<br />
0200f864 00000010 V _ZTIPKDs<br />
0200f874 00000010 V _ZTIPDs<br />
0200f884 00000008 V _ZTIDs<br />
0200f88c 00000010 V _ZTIPKw<br />
0200f89c 00000010 V _ZTIPw<br />
0200f8ac 00000008 V _ZTIw<br />
0200f8b4 00000010 V _ZTIPKb<br />
0200f8c4 00000010 V _ZTIPb<br />
0200f8d4 00000008 V _ZTIb<br />
0200f8dc 00000010 V _ZTIPKv<br />
0200f8ec 00000010 V _ZTIPv<br />
0200f8fc 00000008 V _ZTIv<br />
0200f904 00000004 V _ZTSPKe<br />
0200f908 00000003 V _ZTSPe<br />
0200f90c 00000002 V _ZTSe<br />
0200f910 00000004 V _ZTSPKd<br />
0200f914 00000003 V _ZTSPd<br />
0200f918 00000002 V _ZTSd<br />
0200f91c 00000004 V _ZTSPKf<br />
0200f920 00000003 V _ZTSPf<br />
0200f924 00000002 V _ZTSf<br />
0200f928 00000004 V _ZTSPKy<br />
0200f92c 00000003 V _ZTSPy<br />
0200f930 00000002 V _ZTSy<br />
0200f934 00000004 V _ZTSPKx<br />
0200f938 00000003 V _ZTSPx<br />
0200f93c 00000002 V _ZTSx<br />
0200f940 00000004 V _ZTSPKm<br />
0200f944 00000003 V _ZTSPm<br />
0200f948 00000002 V _ZTSm<br />
0200f94c 00000004 V _ZTSPKl<br />
0200f950 00000003 V _ZTSPl<br />
0200f954 00000002 V _ZTSl<br />
0200f958 00000004 V _ZTSPKj<br />
0200f95c 00000003 V _ZTSPj<br />
0200f960 00000002 V _ZTSj<br />
0200f964 00000004 V _ZTSPKi<br />
0200f968 00000003 V _ZTSPi<br />
0200f96c 00000002 V _ZTSi<br />
0200f970 00000004 V _ZTSPKt<br />
0200f974 00000003 V _ZTSPt<br />
0200f978 00000002 V _ZTSt<br />
0200f97c 00000004 V _ZTSPKs<br />
0200f980 00000003 V _ZTSPs<br />
0200f984 00000002 V _ZTSs<br />
0200f988 00000004 V _ZTSPKh<br />
0200f98c 00000003 V _ZTSPh<br />
0200f990 00000002 V _ZTSh<br />
0200f994 00000004 V _ZTSPKa<br />
0200f998 00000003 V _ZTSPa<br />
0200f99c 00000002 V _ZTSa<br />
0200f9a0 00000004 V _ZTSPKc<br />
0200f9a4 00000003 V _ZTSPc<br />
0200f9a8 00000002 V _ZTSc<br />
0200f9ac 00000005 V _ZTSPKDi<br />
0200f9b4 00000004 V _ZTSPDi<br />
0200f9b8 00000003 V _ZTSDi<br />
0200f9bc 00000005 V _ZTSPKDs<br />
0200f9c4 00000004 V _ZTSPDs<br />
0200f9c8 00000003 V _ZTSDs<br />
0200f9cc 00000004 V _ZTSPKw<br />
0200f9d0 00000003 V _ZTSPw<br />
0200f9d4 00000002 V _ZTSw<br />
0200f9d8 00000004 V _ZTSPKb<br />
0200f9dc 00000003 V _ZTSPb<br />
0200f9e0 00000002 V _ZTSb<br />
0200f9e4 00000004 V _ZTSPKv<br />
0200f9e8 00000003 V _ZTSPv<br />
0200f9ec 00000002 V _ZTSv<br />
0200f9f0 0000000c R _ZTIN10__cxxabiv123__fundamental_type_infoE<br />
0200f9fc 00000028 R _ZTSN10__cxxabiv123__fundamental_type_infoE<br />
0200fa28 00000020 R _ZTVN10__cxxabiv123__fundamental_type_infoE<br />
0200fa48 00000014 R _ZTVSt9bad_alloc<br />
0200fa60 0000000d R _ZTSSt9bad_alloc<br />
0200fa70 0000000c R _ZTISt9bad_alloc<br />
0200fa8c 00000001 R _ZSt7nothrow<br />
0200fa90 00000024 R _ZTSN10__cxxabiv119__pointer_type_infoE<br />
0200fab4 0000000c R _ZTIN10__cxxabiv119__pointer_type_infoE<br />
0200fac0 00000024 R _ZTVN10__cxxabiv119__pointer_type_infoE<br />
0200fb08 0000002c R _ZTVN10__cxxabiv120__si_class_type_infoE<br />
0200fb38 0000000c R _ZTIN10__cxxabiv120__si_class_type_infoE<br />
0200fb44 00000025 R _ZTSN10__cxxabiv120__si_class_type_infoE<br />
0200fb6c 00000008 R _ZTISt9type_info<br />
0200fb74 0000000d R _ZTSSt9type_info<br />
0200fb88 00000020 R _ZTVSt9type_info<br />
0200fba8 0000000c R _ZTISt8bad_cast<br />
0200fbb4 0000000c R _ZTSSt8bad_cast<br />
0200fbc0 00000014 R _ZTVSt8bad_cast<br />
0200fbe8 00000014 R _ZTVSt10bad_typeid<br />
0200fc00 0000000c R _ZTISt10bad_typeid<br />
0200fc1c 0000000f R _ZTSSt10bad_typeid<br />
0200fc30 0000002c R _ZTVN10__cxxabiv117__class_type_infoE<br />
0200fc60 0000000c R _ZTIN10__cxxabiv117__class_type_infoE<br />
0200fc6c 00000022 R _ZTSN10__cxxabiv117__class_type_infoE<br />
0200fc90 0000000c R _ZTIN10__cxxabiv117__pbase_type_infoE<br />
0200fc9c 00000022 R _ZTSN10__cxxabiv117__pbase_type_infoE<br />
0200fcc0 00000024 R _ZTVN10__cxxabiv117__pbase_type_infoE<br />
0200ff44 A __exidx_start<br />
02010364 A __exidx_end<br />
02010364 t __frame_dummy_init_array_entry<br />
02010364 A __init_array_start<br />
02010364 A __preinit_array_end<br />
02010364 A __preinit_array_start<br />
0201036c t __do_global_dtors_aux_fini_array_entry<br />
0201036c A __fini_array_start<br />
0201036c A __init_array_end<br />
02010370 r __EH_FRAME_BEGIN__<br />
02010370 A __fini_array_end<br />
02011114 r __FRAME_END__<br />
02011118 d __JCR_END__<br />
02011118 d __JCR_LIST__<br />
0201111c A __data_start<br />
0201111c D __dso_handle<br />
0201111c A __ewram_start<br />
02011120 00000004 D fifo_freewords<br />
02011124 00000004 D fifo_send_queue<br />
02011128 00000004 D fifo_buffer_free<br />
0201112c 00000004 D fifo_receive_queue<br />
02011130 00000004 D _impure_ptr<br />
02011138 00000428 d impure_data<br />
02011560 00000408 D __malloc_av_<br />
02011968 00000004 D __malloc_sbrk_base<br />
0201196c 00000004 D __malloc_trim_threshold<br />
02011970 00000004 d charset<br />
02011974 0000000c d last_lc_ctype.1268<br />
02011980 0000000c D __lc_ctype<br />
0201198c 0000000c d last_lc_messages.1270<br />
02011998 0000000c d lc_messages.1269<br />
020119a4 00000004 D __mb_cur_max<br />
020119a8 00000004 d defaultDevice<br />
020119ac 00000040 D devoptab_list<br />
020119ec 00000004 D _ZN10__cxxabiv119__terminate_handlerE<br />
020119f0 00000004 D _ZN10__cxxabiv120__unexpected_handlerE<br />
020119f4 A __bss_start<br />
020119f4 A __bss_start__<br />
020119f4 A __bss_vma<br />
020119f4 A __data_end<br />
020119f4 A __dtcm_lma<br />
020119f4 A __itcm_lma<br />
020119f4 b completed.2775<br />
020119f8 b object.2787<br />
02011a10 00000004 b __timeout<br />
02011a14 00000004 B processing<br />
02011a18 00000001 b _ZZN9__gnu_cxx27__verbose_terminate_handlerEvE11terminating<br />
02011a1c 0000000c b _ZL10eh_globals<br />
02011a28 00000004 B __new_handler<br />
02011a2c 00000004 b _ZL15dependents_used<br />
02011a30 000001e0 b _ZL17dependents_buffer<br />
02011b84 A __vectors_lma<br />
02011c10 00000004 b _ZL14emergency_used<br />
02011c18 00000800 b _ZL16emergency_buffer<br />
02012418 00000004 B __malloc_top_pad<br />
0201241c 00000028 B __malloc_current_mallinfo<br />
02012444 00000004 B __malloc_max_sbrked_mem<br />
02012448 00000004 B __malloc_max_total_mem<br />
0201244c 00000004 B __nlocale_changed<br />
02012450 00000004 B __mlocale_changed<br />
02012454 00000004 B _PathLocale<br />
02012458 00000004 b heap_start.2602<br />
0201245c 00000004 B fake_heap_end<br />
02012460 00000004 B fake_heap_start<br />
02012464 00000008 B __syscalls<br />
0201246c 00001000 b handles<br />
0201346c 00000004 B theTime<br />
02013470 00000040 B fifo_datamsg_data<br />
020134b0 00000800 B fifo_buffer<br />
02013cb0 00000040 B fifo_value32_func<br />
02013cf0 00000040 B fifo_address_func<br />
02013d30 00000040 B fifo_value32_data<br />
02013d70 00000040 B fifo_value32_queue<br />
02013db0 00000040 B fifo_data_queue<br />
02013df0 00000040 B fifo_address_data<br />
02013e30 00000040 B fifo_datamsg_func<br />
02013e70 00000040 B fifo_address_queue<br />
02013eb0 00000004 B punixTime<br />
02013eb4 A __bss_end<br />
02013eb4 A __bss_end__<br />
02013eb4 A __end__<br />
02013eb4 A _end<br />
023ff000 A __eheap_end<br />
023ff000 A __ewram_end<br />
027fff70 a _libnds_argv<br />
0b000000 A __dtcm_end<br />
0b000000 A __dtcm_start<br />
0b000000 A __sbss_end<br />
0b000000 A __sbss_start<br />
0b000000 A __sbss_start__<br />
0b003d00 A __sp_usr<br />
0b003e00 A __sp_irq<br />
0b003f00 A __sp_svc<br />
0b003ff8 A __irq_flags<br />
0b003ffc A __irq_vector<br />
0b004000 A __dtcm_to</div>
</div>
<p>
Well, I did say this was going to be the <i>long</i> story, didn&#8217;t I?<br />
Everything that was in the base project is in here as well. The<br />
additional parts can summarized as follows.
</p>
<div class="none">
<div class="none proglist" style=" "><span class="co2"># Additions w.r.t the base case.</span><br />
02001440 &#8211; 02004398 &nbsp; &nbsp; 2F58&nbsp; &nbsp; : d_* routines<br />
020043a4 &#8211; 02004434 &nbsp; &nbsp; 0090&nbsp; &nbsp; : software div (__aeabi_uidiv etc)<br />
02004434 &#8211; 02005408 &nbsp; &nbsp; 0FD4&nbsp; &nbsp; : exception unwind routines<br />
02005418 &#8211; 0200b680 &nbsp; &nbsp; <span class="nu0">6268</span>&nbsp; &nbsp; : various libc : printf et al, malloc,mem*,locale, Device, etc<br />
0200b680 &#8211; 0200c184 &nbsp; &nbsp; 0B04&nbsp; &nbsp; : div and FP math routines. (for printf)<br />
0200c190 &#8211; 0200daf8 &nbsp; &nbsp; <span class="nu0">1968</span>&nbsp; &nbsp; : exception/typeinfo routines.<br />
0200daf8 A __text_end<br />
0200e1dc &#8211; 0200ff44 &nbsp; &nbsp; 1D68&nbsp; &nbsp; : exception/typeinfo strings and pointers.<br />
02013eb4 A _end</div>
</div>
<p>
There are three main areas to discern:
</p>
<ul>
<li>
    <code>d_*()</code> routines, presumably for debug printing.<br />
	(size: 12k)
  </li>
<li>
    Stdio formatting and related. This includes file handling, device<br />
	handling and many forms of <code>printf</code>, which brings a<br />
	whole lot of bagage (some allocation, format parsing and<br />
	math/floating point routines). There&#8217;s also some abort and<br />
	signalling routines. (size: 28k).
  </li>
<li>
    Exception handling. Not just routines for handling them, but also<br />
	the typeinfo stuff required, the output strings and the output<br />
	string pointers. (size: 18k)
  </li>
</ul>
<p>
These roughly 60k of stuff is the overhead of exceptions &ndash;<br />
any <i>potential</i> exception. In this case, it&#8217;s because<br />
<code>new</code> requires a <code>bad_alloc</code> exception when it&#8217;s<br />
unable to allocate more.
</p>
<p>
The problem is that exceptions have<br />
many dependencies: to do exception handling, you keep track and unwind<br />
the stack. You also need to be able to tell the type of exception<br />
thrown, which requires RTTI. And then you say which exception was<br />
thrown, so you need error messages, <i>and</i> a list of pointers to<br />
those messages, <i>and</i> a way to format and write those messages,<br />
hence the <code>d_*()</code> routines and all the stdio stuff.
</p>
<p><h2 id="sec-own-new">3
Custom new/delete
</h2>
</p>
<p>
There is a way around this, though: redefine <code>new</code> and<br />
related functions. Technically speaking, this is a <i>bad</i> idea<br />
if you don&#8217;t know what you&#8217;re doing, but it can be done. Note that<br />
you would need overload four operators: <code>new</code>,<br />
<code>delete</code> and their array counterparts.
</p>
<div class="none">
<div class="none proglist" style=" ">void* operator new(size_t size) &nbsp; &nbsp; { &nbsp; return malloc(size);&nbsp; &nbsp; }</p>
<p>void operator delete(void *p) &nbsp; &nbsp; &nbsp; { &nbsp; free(p);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>void* operator new[](size_t size) &nbsp; { &nbsp; return malloc(size);&nbsp; &nbsp; }</p>
<p>void operator delete[](void *p) &nbsp; &nbsp; { &nbsp; free(p);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p></div>
</div>
<p>
This way, you just incur the cost of <code>malloc()</code> and<br />
<code>free()</code>, which are only about 3k. But again, this is going<br />
against the standard and you&#8217;ll really have to ask yourself if the<br />
(at best) 2% of main RAM you save with this is really worth it.
</p>
<p><div>&nbsp;</div></p>
<p>More on this can be read at<br />
<a href="http://brewforums.qualcomm.com/showthread.php?t=2033"></p>
<p>http://brewforums.qualcomm.com/showthread.php?t=2033</a>.</p>
<p><h2 id="sec-conc">4
Other considerations and conclusions.
</h2>
</p>
<p>
The binary size is <i>not</i> the same as the main RAM footprint.<br />
About 44 kb other stuff.
</p>
<p>
The overhead of the standard <code>new</code> is 60 kb, which is all<br />
due to exceptions. You <i>cannot</i> remove it by<br />
using the compiler options <tt>-fno-exceptions</tt> and<br />
<tt>-fno-rtti</tt>, because that only affects your own code, not the<br />
standard libraries. You can remove this overhead by using overloading<br />
<code>new</code> and related functions, but you have to be really<br />
careful with this.
</p>
<p>
I&#8217;ve also done a little bit of testing with <code>vector</code>, and<br />
it seems that <code>vector</code>&#8216;s overhead also comes from<br />
<code>new</code> and can be removed the same way. However, other parts<br />
of <code>vector</code> (and STL) may use other exceptions, so it&#8217;s<br />
quite possible it won&#8217;t work in all cases.
</p>
<p>
Note that roughly 28 kb of the exception overhead is actually<br />
stdio related &ndash; specifically formatted printing:<br />
<code>*printf</code>. If you&#8217;re using <code>printf</code> anyway, the<br />
effective overhead of exceptions is reduced considerably.
</p>
<p>
Finally, remember that the exception overhead amounts to roughly 2% of<br />
main RAM at most. In most homebrew cases it won&#8217;t matter that much.<br />
When it does start to affect your app, you will likely have other parts<br />
that are easier and safer to optimize out.
</p>
<p><div>&nbsp;</div></p>
<p><a href="/files/misc/minimal.zip">Test project + notes.</a><div>&nbsp;</div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2009/11/sizeof-new/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>DMA vs ARM9 &#8211; fight!</title>
		<link>http://www.coranac.com/2009/05/dma-vs-arm9-fight/</link>
		<comments>http://www.coranac.com/2009/05/dma-vs-arm9-fight/#comments</comments>
		<pubDate>Thu, 28 May 2009 21:07:10 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[nds]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[dma]]></category>
		<category><![CDATA[research]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=68</guid>
		<description><![CDATA[<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize(http://www.coranac.com/img/post/arm9vsdma/cache_eg01.png&amp;#8221; width=&amp;#8221;300&amp;#8243;&lt;br /&gt;
	  cap=&amp;#8221;RAM[0&amp;#93; is written to. No change to cache.) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize(http://www.coranac.com/img/post/arm9vsdma/cache_eg02.png&amp;#8221; width=&amp;#8221;300&amp;#8243;&lt;br /&gt;
	  cap=&amp;#8221;Read from RAM[1&amp;#93;. Cache-line 0 = RAM Block 0.) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize(http://www.coranac.com/img/post/arm9vsdma/cache_eg04.png&amp;#8221; width=&amp;#8221;300&amp;#8243;&lt;br /&gt;
	  cap=&amp;#8221;Read from RAM[3&amp;#93;. This was in cache, so data's read&lt;br /&gt;
	  from there, not RAM.) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
1 The ARM 9 core 2 Cache example 3 Cache vs DMA solution 4 Test cases 5 Conclusions DMA, or Direct Memory Access, is a hardware method for transferring data. As it&#8217;s hardware-driven, it&#8217;s pretty damn fast(1). As such, it&#8217;s pretty much the standard method for copying on the NDS. Unfortunately, as many people have [...]]]></description>
			<content:encoded><![CDATA[<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize(http://www.coranac.com/img/post/arm9vsdma/cache_eg01.png&amp;#8221; width=&amp;#8221;300&amp;#8243;&lt;br /&gt;
	  cap=&amp;#8221;RAM[0&amp;#93; is written to. No change to cache.) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize(http://www.coranac.com/img/post/arm9vsdma/cache_eg02.png&amp;#8221; width=&amp;#8221;300&amp;#8243;&lt;br /&gt;
	  cap=&amp;#8221;Read from RAM[1&amp;#93;. Cache-line 0 = RAM Block 0.) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize(http://www.coranac.com/img/post/arm9vsdma/cache_eg04.png&amp;#8221; width=&amp;#8221;300&amp;#8243;&lt;br /&gt;
	  cap=&amp;#8221;Read from RAM[3&amp;#93;. This was in cache, so data's read&lt;br /&gt;
	  from there, not RAM.) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<br />
<b>Warning</b>:  getimagesize() [<a href='function.getimagesize'>function.getimagesize</a>]: Filename cannot be empty in <b>/home/coranac/public_html/wordpress/wp-content/plugins/crnfilters.php</b> on line <b>466</b><br />
<p></p>
<p><ul>
  <li> <a href="#sec-arm9">1
The ARM 9 core
</a> </li>
  <li> <a href="#sec-example">2
Cache example
</a> </li>
  <li> <a href="#sec-solu">3
Cache vs DMA solution
</a> </li>
  <li> <a href="#sec-tests">4
Test cases
</a> </li>
  <li> <a href="#sec-conc">5
Conclusions
</a> </li>
</ul>
</p>
<p>
DMA, or Direct Memory Access, is a hardware method for transferring<br />
data. As it&#8217;s hardware-driven, it&#8217;s pretty damn fast<span class="fnote"><a href="#ft-nr1" title="Well,
quite fast anyway. In some circumstances CPU-based transfers
are faster, but that&#8217;s a story for another day.">(1)</a></span>. As such,<br />
it&#8217;s pretty much the standard method for copying on the NDS.<br />
Unfortunately, as many people have noticed, it doesn&#8217;t always work.
</p>
<p>
There are two principle reasons for this: cache and TCM. These are<br />
two memory regions of the ARM9 that DMA is unaware of, which can lead<br />
to incorrect transfers. In this post, I&#8217;ll discuss the cache, TCM and<br />
their interactions (or lack thereof) with DMA.
</p>
<p>
The majority of the post is actually about cache. Cache basically<br />
determines the speed of your app, so it&#8217;s worth looking into in more<br />
detail. Why it and DMA don&#8217;t like each other much will become clear<br />
along the way. I&#8217;ll also present a number of test cases that show<br />
the conflicting areas, and some functions to deal with these problems.
</p>
<p><span id="more-68"></span></p>
<p><h2 id="sec-arm9">1
The ARM 9 core
</h2>
</p>
<p><div class="cptfr" style="width:200px;">
  <a href="" target="_blank">  <img src="" id="img-arm9"
    alt="" width="200" /></a><br />
  <b>Fig&nbsp;1. </b>
</div>
</p>
<p>
The first thing to know is that the DMA trouble only relates to the<br />
ARM9 processor of the NDS. Work with the ARM7 should be fine. The most<br />
relevant items of the ARM9 are illustrated by Fig&nbsp;1.<br />
The processor consists of the actual logic unit, and caches and two<br />
<dfn>Tightly Coupled Memory</dfn> (TCM) units. There are two caches<br />
and TCMs, one for data and one for instructions. The point here is<br />
that (as far as I know), these areas are <i>on the chip</i>, and<br />
as such accessible only by the CPU itself. CPU-only, as in not the<br />
DMA controller.
</p>
<p><h3 id="ssec-arm9-tcm">1.1
ITCM and DTCM
</h3>
</p>
<p>
The Instruction and Data TCM areas (ITCM and DTCM) are basically<br />
fast-RAM areas. Technically the addresses of these sections are<br />
arbitrary, but set to the 0100:0000 and 0B00:0000 ranges,<br />
respectively, in libnds. Exactly which addresses they use isn&#8217;t<br />
important though, since that&#8217;s all taken care of by the linker anyway.<br />
What <i>is</i> important is that the stack (where local variables<br />
and function arguments go<span class="fnote"><a href="#ft-nr2" title="Well, sometimes. Usually these go in
CPU registers, but this is not the right place for that discussion
either.">(2)</a></span>) is also put in DTCM. This means that you can&#8217;t<br />
use DMA with local arrays. It also means that you can&#8217;t use a local<br />
variable as a source for a DMA-fill. This is why the NDS ARM9 has<br />
special DMA registers for these, called<br />
<a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">REG_DMA<i>n</i>FILL</a>.
</p>
<div class="cpp">
<div class="cpp proglist" style=" "><span class="kw1">#define</span> DMA_FILL16&nbsp; (DMA_ENABLE | DMA_START_NOW | DMA_SRC_FIX)</p>
<p><span class="co1">// This doesn&#8217;t work on ARM: `fill&#8217; is in unreachable DTCM.</span><br />
<span class="co1">// Should work on ARM7 though.</span><br />
<span class="kw1">void</span> dmaFill_bad()<br />
{<br />
&nbsp; &nbsp; <span class="kw1">volatile</span> u16 fill= <span class="nu0">0</span>;<br />
&nbsp; &nbsp; REG_DMA3SAD= &amp;fill;<br />
&nbsp; &nbsp; REG_DMA3DAD= VRAM_A;<br />
&nbsp; &nbsp; REG_DMA3CNT= DMA_FILL16 | <span class="nu0">256</span>*<span class="nu0">192</span>;<br />
}</p>
<p><span class="co1">// This does work on ARM9, </span><br />
<span class="co1">// but not ARM7 which has no REG_DMAnFILL registers.</span><br />
<span class="kw1">void</span> dmaFill_good()<br />
{<br />
&nbsp; &nbsp; REG_DMA3FILL= <span class="nu0">0</span>;<br />
&nbsp; &nbsp; REG_DMA3SAD= &amp;REG_DMA3FILL;<br />
&nbsp; &nbsp; REG_DMA3DAD= VRAM_A;<br />
&nbsp; &nbsp; REG_DMA3CNT= DMA_FILL16 | <span class="nu0">256</span>*<span class="nu0">192</span>;<br />
}</div>
</div>
<p>
The DMA-fill routines in libnds correctly use <code>REG_DMAnFILL</code><br />
so fortunately you don&#8217;t have to worry about that. However, copying from<br />
local arrays is still impossible, and there&#8217;s just no way around that<br />
using just DMA.
</p>
<p><h3 id="ssec-arm9-cache">1.2
Cache
</h3>
</p>
<p>
The cache for the ARM9 is a little more complicated. Or perhaps<br />
&ldquo;obscured&rdquo; is a better term here. The TCMs have<br />
addresses, so you can toy with them yourself. The cache, however,<br />
is completely hidden from the view of the user.<br />
Before going into detail about how the cache works and why DMA<br />
and cache hate each other, let&#8217;s look at why cache is useful,<br />
especially in light of you not being able to use it directly.
</p>
<p><div>&nbsp;</div></p>
<p>
Where there is memory, there are waitstates. Generally, a CPU can handle<br />
data faster than the RAM can supply it, so the CPU will have to wait<br />
until it can continue. The slowdown can easily be a factor 100 on<br />
PCs, or even millions if you include disk memory. Fortunately, it&#8217;s<br />
only about ten for the NDS, I think, but that&#8217;s still quite a bit.
</p>
<p>
Cache is one method of getting around memory waitstates. Instead of<br />
having to go to RAM all the time for something, you store recently used<br />
data in an area that the CPU can have faster access to. Then next<br />
time it needs that data, it can retrieve it from there instead of<br />
going to RAM again. For good measure, the area around the data is also<br />
cached, because that might be accessed soon as well. Since<br />
closely-related data is often stored closely together as well, the<br />
caching process can significantly increase the overall speed of an<br />
application.
</p>
<p><h3 id="ssec-arm9-ndscache">1.3
The NDS ARM9 cache
</h3>
</p>
<p>
<a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolcacheandtcm">GBATEK</a> gives us the<br />
following information about the cache that the NDS has:
</p>
<blockquote><p>
  Data Cache 4KB, Instruction Cache 8KB<br />
  4-way set associative method<br />
  Cache line 8 words (32 bytes)<br />
  Read-allocate method (ie. writes are not allocating cache lines)<br />
  Round-robin and Pseudo-random replacement algorithms selectable<br />
  Cache Lockdown, Instruction Prefetch, Data Preload<br />
  Data write-through and write-back modes selectable
</p></blockquote>
<p>
Which to most people will probably mean absolutely nothing. Now, I&#8217;m<br />
not exactly an expert in all things cache, but I&#8217;ll try to explain what<br />
it all means.
</p>
<p>
First, as noted earlier, there are actually two caches: one for<br />
data and one for instructions. Having a separate instruction cache is nice<br />
because then you can be sure that a function that processes a lot of<br />
data won&#8217;t push the that function out of the cache. Instruction cache<br />
also means that loops in code will be in cache except for perhaps the<br />
first iteration. Effectively, all the code that really matters (i.e.,<br />
inner loops that do most of the work) will always be in fast memory<br />
automatically.
</p>
<p>
It is common that cache works in groups of bytes instead of individual<br />
bytes. These groups are the <dfn>cache lines</dfn>. A cache line maps<br />
onto a RAM chunk of the same size, and if anything within a chunk<br />
is to be put in cache, the whole line will be filled. The NDS cache<br />
lines are 32 bytes long.
</p>
<p>
This is probably a good time to introduce two important terms:<br />
cache hit and cache miss. A <dfn>cache hit</dfn> is when the data<br />
you&#8217;re looking for is already in cache and so access is fast. A<br />
<dfn>cache miss</dfn> is when it&#8217;s not in cache. This means two things.<br />
First, the access will be slow thanks to the memory waitstates.<br />
Second, if this triggers a cache-line fill, you&#8217;ll have to wait for<br />
the <i>entire cache line</i> to be read. While this block read will<br />
be faster than if you were reading the block without cache, it&#8217;ll<br />
still take longer than getting just the byte or so you were looking<br />
for. Moral of the story: cache hit good, cache miss bad.
</p>
<p>
Cache hits and misses add a consequence to how your data is stored.<br />
If data is tightly packed and sequential (think structs/arrays), you&#8217;re<br />
more likely to have cache hits and work will be fast. If the data is<br />
all over the place (linked lists for example), the chance of cache<br />
misses increases dramatically.
</p>
<p><div>&nbsp;</div></p>
<p>
That is how cached or non-cached data operates. What&#8217;s also important<br />
is when data is put in cache in the first place &ndash; when cache<br />
allocation occurs. There are two types here: <dfn>read-allocate</dfn><br />
or <dfn>write-allocate</dfn>, These terms refer to whether a<br />
cache-line will be tied to a memory block when it&#8217;s from, or when<br />
it&#8217;s written to, respectively. As you can see from the GBATEK data,<br />
the NDS cache is read-allocate. A memory-write will not require a new<br />
cache line.
</p>
<p>
Now, Suppose a block is in cache and something is written to that block.<br />
This write will update the data in cache, but what about the RAM it&#8217;s<br />
tied to? The process dealing with this is called the <dfn>write policy</dfn>,<br />
and two options exist. There&#8217;s <dfn>write-through</dfn>, which means that<br />
both cache and RAM are written to. In <dfn>write-back</dfn> mode, only the<br />
cached data is changed; RAM is <i>not</i> updated! This is the main<br />
cause of trouble with DMA. Apparently, the write policy is selectable,<br />
but it&#8217;ll usually be write-back.
</p>
<p><div>&nbsp;</div></p>
<p>
Lastly, there&#8217;s the <dfn>replacement policy</dfn>, which stipulates<br />
how cache lines relate to RAM, and when to kick data out ot cache.<br />
Unfortunately I don&#8217;t know much about this part, but it&#8217;s of lesser<br />
importance anyway. The rest of the terms do not affect the potential<br />
cache-DMA conflict either. For more details, visit the wikipedia page<br />
on 
<a href="http://en.wikipedia.org/wiki/CPU_cache">CPU_cache</a>.
</p>
<p><h2 id="sec-example">2
Cache example
</h2>
</p>
<p>
At this point I think it&#8217;s useful to give an example of how it works<br />
in practice. For this, I will use a fictional CPU that uses a cache with<br />
following properties.
</p>
<ul>
<li>2 cache lines, 4 bytes each.</li>
<li>Read-allocate and write-back.</li>
<li>Direct mapped cache: RAM-block <i>n</i> goes into cache-line<br />
    <i>n</i>%2. In other words, even blocks go to line 0, odd blocks<br />
    to line 1.
  </li>
</ul>
<p>
The next set of pictures illustrate what happens when you do a<br />
number of reads and writes. Fig&nbsp;2 shows the basic<br />
system in the initial state. There is the CPU on the left with the<br />
core and two cache lines. I&#8217;ve also included a register called <i>x</i><br />
here for convenience. On the right there is 16 bytes of RAM,<br />
distributed over four 4-byte blocks (the equivalents of the cache<br />
lines). RAM is already initialized; cache is still empty. In the<br />
figures, green is used to indicate reads from RAM (loads) and purple<br />
for writes (stores).
</p>
<div class="cblock">
<table cellpadding=4>
<tbody valign=top>
<tr>
<td>
    <div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-eg00"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;2. </b>
</div>

  </td>
<td>
    <div class="cpt" style="width:px;">
  <a href="http://www.coranac.com/img/post/arm9vsdma/cache_eg01.png&#8221; width=&#8221;300&#8243;<br />
	  cap=&#8221;RAM[0&#93; is written to. No change to cache." target="_blank">  <img src="http://www.coranac.com/img/post/arm9vsdma/cache_eg01.png&#8221; width=&#8221;300&#8243;<br />
	  cap=&#8221;RAM[0&#93; is written to. No change to cache." id="img-eg01"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;3. </b>
</div>

  </td>
</tr>
<tr>
<td>
    <div class="cpt" style="width:px;">
  <a href="http://www.coranac.com/img/post/arm9vsdma/cache_eg02.png&#8221; width=&#8221;300&#8243;<br />
	  cap=&#8221;Read from RAM[1&#93;. Cache-line 0 = RAM Block 0." target="_blank">  <img src="http://www.coranac.com/img/post/arm9vsdma/cache_eg02.png&#8221; width=&#8221;300&#8243;<br />
	  cap=&#8221;Read from RAM[1&#93;. Cache-line 0 = RAM Block 0." id="img-eg02"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;4. </b>
</div>

  </td>
<td>
    <div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-eg03"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;5. </b>
</div>

  </td>
</tr>
<tr>
<td>
    <div class="cpt" style="width:px;">
  <a href="http://www.coranac.com/img/post/arm9vsdma/cache_eg04.png&#8221; width=&#8221;300&#8243;<br />
	  cap=&#8221;Read from RAM[3&#93;. This was in cache, so data's read<br />
	  from there, not RAM." target="_blank">  <img src="http://www.coranac.com/img/post/arm9vsdma/cache_eg04.png&#8221; width=&#8221;300&#8243;<br />
	  cap=&#8221;Read from RAM[3&#93;. This was in cache, so data's read<br />
	  from there, not RAM." id="img-eg04"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;6. </b>
</div>

  </td>
<td>
    <div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-eg05"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;7. </b>
</div>

  </td>
</tr>
<tr>
<td>
    <div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-eg06"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;8. </b>
</div>

  </td>
<td>
    <div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-eg07a"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;9. </b>
</div>

  </td>
</tr>
</tbody>
</table>
</div>
<ol start=0>
<li>
    Initial state.
  </li>
<li>
    <code>RAM[0]= 'R'</code>. A write to RAM does not trigger cache<br />
    allocation, so it goes straight to RAM. Slowly.
  </li>
<li>
    <code>x= RAM[1]</code>. The read from RAM[1] causes a cache<br />
	allocation RAM[1] is part of block 0 (even), so that goes into<br />
	cache line 0. Line 0 and block 0 are identical.<br />
	Cache miss + allocation; very slow.
  </li>
<li>
    <code>RAM[2]= RAM[3]= 'S'</code>. Two writes; this is where it<br />
    gets tricky. These addresses are in cache (block 0), and I<br />
	said this cache was in write-back mode. This means that the writes<br />
	go to the cache, but <i>NOT</i> the actual RAM. So now the data<br />
	in cache is different that the equivalent block in RAM: the RAM&#8217;s<br />
	gone <dfn>stale</dfn>. This is a cache hit; a fast write.
  </li>
<li>
    <code>x= RAM[3]</code>. Again, RAM[3] is cached, so data is taken<br />
    from cache instead of from RAM. <i>x</i> is now <code>'S'</code>,<br />
    as was expected from the last statement. The fact the real RAM[3]<br />
    is different doesn&#8217;t matter, because the CPU doesn&#8217;t look there<br />
	anyway. If something <i>other</i> than the CPU (like, say, DMA)<br />
	reads from RAM[3], though, chaos ensues. Cache hit, fast read.
  </li>
<li>
    <code>x= RAM[4]</code>. RAM[4] is in block 1, which wasn&#8217;t cached<br />
    yet, so a new line is allocated. Block 1 goes into line 1, because<br />
    it&#8217;s an odd-numbered block. Very slow operation.
  </li>
<li>
    <code>RAM[4]= RAM[5]= 'T'</code>. Much like before, The writes go<br />
    into cache rather than the real RAM. Another cache hit.
  </li>
<li>
    <code>x= RAM[8]</code>. This is also an interesting case. Two<br />
	things happen here. RAM[8] belongs to block 2 (even), which hadn&#8217;t<br />
	been cached yet. It&#8217;s supposed to go into line 0, but that&#8217;s<br />
	already filled. The new data will replace the old data. Cache line is<br />
	tied to block 0, so addresses 0 through 3 will be filled with the<br />
	data from line 0; this block is now up to date again. After that,<br />
	line 0 receives the data from block 2. Cache write-out + new<br />
	allocation; this should be awful.
  </li>
</ol>
<p>
This should cover all important cases: reads/writes to non-cached<br />
addresses, to cached addresses and a little bit about allocation<br />
and replacements. At some points, cache and RAM start to disagree. This<br />
wouldn&#8217;t be a problem if RAM was only accessed by the CPU, but<br />
unfortunately it isn&#8217;t.
</p>
<p><div class=note>
<div  class=nhcare>On cache timings</div>
</p>
<p>
To be completely honest, I have not really tested the cycle-times<br />
for the various cases. All I have to go on is<br />
<a href="http://nocash.emubase.de/gbatek.htm#dsmemorytimings">gbatek:memory timings</a> and<br />
educated guesswork. The estimates <i>should</i> make sense, but I<br />
don&#8217;t have much in the way of evidence at present, not would I know<br />
exactly how to get that in the first place, as experimenting with<br />
cache can be tricky.
</p>
<p></div>
</p>
<p><h2 id="sec-solu">3
Cache vs DMA solution
</h2>
</p>
<p>
Fig&nbsp;5 and Fig&nbsp;8 illustrate the main<br />
problem. The data in RAM is out of date and when DMA tries to read<br />
it, it actually uses the wrong data. the reverse is also possible.<br />
DMA could write to RAM that had been cached; in this case it&#8217;s actually<br />
the cache that&#8217;s out of date.
</p>
<p>
The solution to this is to align cache and RAM manually. The two<br />
actions involved are called flushing and invalidating. A<br />
<dfn>cache flush</dfn> dumps the contents of cache back into RAM. Now<br />
that cache and RAM contain the same data again, it&#8217;s safe to DMA-read<br />
from. An <dfn>invalidate</dfn> tells the CPU to simply delete cache<br />
lines, because its assumptions regarding the contents of the original<br />
RAM have become invalid. The next CPU-read would come from RAM again.<br />
This is what you need after DMA writes to RAM.
</p>
<p>
Fig&nbsp;10 and Fig&nbsp;11 pick up from<br />
case 6 (Fig&nbsp;8). They show what happens when you<br />
flush or invalidate a cache line. You actually supply a RAM block<br />
number because the cache lines themselves are completely hidden from<br />
view.
</p>
<ol start=7>
<li>
    <b>Flush block 0</b>. In this case, you want to synchronize RAM<br />
  block 0 to the cache. Since block 0 is indeed in cache and using<br />
  line 0. Therefore, the contents of line 0 are written back to block 0.
  </li>
<li>
    <b>Invalidate block 1</b>. Suppose that previously, some contents of<br />
    block 1 had been written to without cache&#8217;s knowledge, so that cache<br />
    is out of date. The invalidate throws away the line related to<br />
	block 1, making RAM the primary source for the block again.
  </li>
</ol>
<div class="cblock">
<table cellpadding=4>
<tr>
<td>
    <div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-eg07b"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;10. </b>
</div>

  </td>
<td>
    <div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-eg08"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;11. </b>
</div>

  </td>
</tr>
</table>
</div>
<p><div class=note>
<div  class=nhgood>When to Flush/Invalidate</div>
</p>
<ul>
<li>
    A cache flush writes cached data back to RAM.<br />
	This is required <i>before</i> DMA-reads.
  </li>
<li>
    A cache invalidate frees cache lines, causing the next read<br />
	to be from RAM. This is required <i>after</i> DMA-writes.
  </li>
</ul>
<p>
Get the operation or the timing wrong,<br />
<a href="http://www.youtube.com/watch?v=NjLUMG4Kpf4"><i>and<br />
they dock ya</i></a>!</p>
<p><small>I mean, uhm &hellip; and you get memory corruption. Yeah.</small>
</p>
<p></div>
</p>
<p><h3 id="ssec-solu-libnds">3.1
libnds cache functions
</h3>
</p>
<p>
libnds contains functions to<br />
<a href="http://libnds.devkitpro.org/a00065.html">flush or invalidate</a>.<br />
They can either affect the whole cache, or just certain address ranges.<br />
I am unsure of the timings of these functions, but I expect there will<br />
be a cost. Invalidating itself could be fast, but it&#8217;d make all<br />
subsequent reads cache misses. A flush would require a large amount of<br />
of writes to memory. To keep these costs down, use the ranged versions<br />
as much as possible.
</p>
<div class="cpp">
<div class="cpp proglist" style=" "><span class="co1">//! Flush the entire data cache to memory.</span><br />
<span class="kw1">void</span> DC_FlushAll()<br />
<span class="co1">//! Flush the data cache for a range of addresses to memory.</span><br />
<span class="kw1">void</span> DC_FlushRange(<span class="kw1">const</span> <span class="kw1">void</span> *base, u32 size)</p>
<p><span class="co1">//! Iinvalidate the entire data cache.</span><br />
<span class="kw1">void</span> DC_InvalidateAll()<br />
<span class="co1">//! Invalidate the data cache for a range of addresses.</span><br />
<span class="kw1">void</span> DC_InvalidateRange(<span class="kw1">const</span> <span class="kw1">void</span> *base, u32 size)</p>
<p><span class="co1">//! Invalidate entire instruction cache.</span><br />
<span class="kw1">void</span> IC_InvalidateAll()<br />
<span class="co1">//! Invalidate the instruction cache for a range of addresses. </span><br />
<span class="kw1">void</span> IC_InvalidateRange(<span class="kw1">const</span> <span class="kw1">void</span> *base, u32 size)</div>
</div>
<p><h3 id="ssec-solu-proc">3.2
Some safe DMA functions
</h3>
</p>
<p>
To guard against potential DMA failures, it&#8217;s useful to have a few<br />
functions that take care of those themselves. <code>dmaCopySafe()</code><br />
and <code>dmaFillSafe()</code> check if DMA can reach the source and<br />
destination regions and will return <code>false</code> if not. They<br />
also check what chunk-size is appropriate by looking at the source,<br />
destination and size. Odd alignments fail completely; word-alignment<br />
and sizes use 32-bit transfers and the rest uses 16-bit transfers.<br />
They also flush and invalidate where appropriate.
</p>
<p>
Note that for a completely safe version, you&#8217;d need much more checking.<br />
For example, each region has its own size that would have to be looked<br />
at, and some sections are read-only like ROM. Checking for all<br />
possibilities, however would just make the function too unwieldy and<br />
have therefore been omitted.
</p>
<div class="cpp">
<div class="cpp proglist" style=" "><span class="co1">//! Copy data from a src to a dst via DMA in a cache/section safe manner.</span><br />
<span class="coMULTI">/*! The ARM9&#8242;s DMA doesn&#8217;t play well with the cache and can&#8217;t access <br />
&nbsp; &nbsp; ITCM or DTCM. This means that a basic DMA copy may not work as <br />
&nbsp; &nbsp; expected. This function flushes or invalidates cache if necessary and <br />
&nbsp; &nbsp; will only copy if the ranges are accessible.<br />
&nbsp; &nbsp; param src &nbsp; Source pointer.<br />
&nbsp; &nbsp; param dst &nbsp; Destination pointer.<br />
&nbsp; &nbsp; param size&nbsp; Size (in bytes) to copy.<br />
&nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; True if the copy succeeded.<br />
&nbsp; &nbsp; note&nbsp; &nbsp; &nbsp; &nbsp; It&#8217;s possible I missed some invalid cases, YHBW.<br />
*/</span><br />
<span class="kw1">bool</span> dmaCopySafe(<span class="kw1">const</span> <span class="kw1">void</span> *src, <span class="kw1">void</span> *dst, u32 size)<br />
{<br />
&nbsp; &nbsp; u32 srca= (u32)src, dsta= (u32)dst;</p>
<p>&nbsp; &nbsp; <span class="co1">// Check TCMs and BIOS (0&#215;01000000, 0x0B000000, 0xFFFF0000).</span><br />
&nbsp; &nbsp; <span class="co1">//# NOTE: probably incomplete checks.</span><br />
&nbsp; &nbsp; <span class="kw1">if</span>((srca&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0&#215;01</span> || (srca&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0x0B</span> || (srca&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0xFF</span>)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">false</span>;<br />
&nbsp; &nbsp; <span class="kw1">if</span>((dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0&#215;01</span> || (dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0x0B</span> || (dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0xFF</span>)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">false</span>;</p>
<p>&nbsp; &nbsp; <span class="kw1">if</span>((srca|dsta) &amp; <span class="nu0">1</span>) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Fail on byte copy.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">false</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">while</span>(REG_DMA3CNT &amp; DMA_BUSY) ;</p>
<p>&nbsp; &nbsp; <span class="kw1">if</span>((srca&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0&#215;02</span>)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Write cache back to memory.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; DC_FlushRange(src, size);</p>
<p>&nbsp; &nbsp; <span class="kw1">if</span>((srca|dsta|size) &amp; <span class="nu0">3</span>)<br />
&nbsp; &nbsp; &nbsp; &nbsp; dmaCopyHalfWords(<span class="nu0">3</span>, src, dst, size);<br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; dmaCopyWords(<span class="nu0">3</span>, src, dst, size);</p>
<p>&nbsp; &nbsp; <span class="kw1">if</span>((dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0&#215;02</span>)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Set cache of dst range to &#8216;dirty&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; DC_InvalidateRange(dst, size);</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">true</span>;<br />
}</p>
<p><span class="co1">//! Fill a dst with a fill via DMA in a cache/section safe manner.</span><br />
<span class="coMULTI">/*! The ARM9&#8242;s DMA doesn&#8217;t play well with the cache and can&#8217;t access <br />
&nbsp; &nbsp; ITCM or DTCM. This means that a basic DMA fill may not work as <br />
&nbsp; &nbsp; expected. This function flushes or invalidates cache if necessary and <br />
&nbsp; &nbsp; will only fill if the ranges are accessible.<br />
&nbsp; &nbsp; param fill&nbsp; Fill value.<br />
&nbsp; &nbsp; param dst &nbsp; Destination pointer.<br />
&nbsp; &nbsp; param size&nbsp; Size (in bytes) to copy.<br />
&nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; True if the fill succeeded.<br />
&nbsp; &nbsp; note&nbsp; &nbsp; &nbsp; &nbsp; It&#8217;s possible I missed some invalid cases, YHBW.<br />
*/</span><br />
<span class="kw1">bool</span> dmaFillSafe(u32 fill, <span class="kw1">void</span> *dst, u32 size)<br />
{<br />
&nbsp; &nbsp; u32 dsta= (u32)dst;</p>
<p>&nbsp; &nbsp; <span class="co1">// Check TCMs and BIOS (0&#215;01000000, 0x0B000000, 0xFFFF0000).</span><br />
&nbsp; &nbsp; <span class="co1">//# NOTE: probably incomplete checks.</span><br />
&nbsp; &nbsp; <span class="kw1">if</span>((dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0&#215;01</span> || (dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0x0B</span> || (dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0xFF</span>)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">false</span>;</p>
<p>&nbsp; &nbsp; <span class="kw1">if</span>(dsta &amp; <span class="nu0">1</span>)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Fail on byte fill.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">false</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">while</span>(REG_DMA3CNT &amp; DMA_BUSY) ;</p>
<p>&nbsp; &nbsp; <span class="kw1">if</span>((dsta|size) &amp; <span class="nu0">3</span>)<br />
&nbsp; &nbsp; &nbsp; &nbsp; dmaFillHalfWords(fill, dst, size);<br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; dmaFillWords(fill, dst, size);</p>
<p>&nbsp; &nbsp; <span class="kw1">if</span>((dsta&gt;&gt;<span class="nu0">24</span>)==<span class="nu0">0&#215;02</span>)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Set cache of dst range to &#8216;dirty&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; DC_InvalidateRange(dst, size);</p>
<p>&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">true</span>;<br />
}</div>
</div>
<p><h2 id="sec-tests">4
Test cases
</h2>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" id="img-test-scheme"
    alt="" width="" /></a><br />
  <b>Fig&nbsp;12. </b>
</div>
</p>
<p>
All this talk about what to do and when is nice and all, but it&#8217;s<br />
always best to run a few tests to see if everything happens like you<br />
expected. Fig&nbsp;12 illustrates how the tests operate.<br />
There are two source bitmaps of the letters &lsquo;A&rsquo; and<br />
&lsquo;B&rsquo;. In each test case, one of these is copied into<br />
a secondary buffer by either a CPU- or DMA-based copy. This<br />
second buffer is blitted to VRAM in two different places via<br />
a CPU- or DMA-based blit. At various points, a flush or invalidate<br />
may be inserted to see the effects.
</p>
<p>
In terms of code, ever case is split into two parts. First, there&#8217;s a<br />
setup that initializes each case. This clears the console and prints<br />
some description for the case and erases the RAM buffer and the VRAM<br />
rectangles. The second part alternatively copies the letters into the<br />
buffer, does cache operations, and blits. Since the first part is<br />
boring, only the case-specific part will be given here.
</p>
<p><h3 id="ssec-test-01">4.1
<br />
Direct blit: &lsquo;A&rsquo; &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; cpuBlit(&amp;bmpA, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpA, X_DMA, X_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both correct.<br />
<b>Explanation</b>: the data in the source buffer never changes,<br />
so this should always be okay.
</p>
<p><h3 id="ssec-test-02">4.2
<br />
Indirect Blit I: &lsquo;B&rsquo; &rarr; buffer &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; <span class="kw3">memcpy</span>(bmpBuf.data, bmpB.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both correct.<br />
<b>Explanation</b>: buffer used for the first time, so no cache<br />
incoherency possible. Yet.
</p>
<p><h3 id="ssec-test-03">4.3
<br />
Indirect Blit II: &lsquo;A&rsquo; &rarr; buffer &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; <span class="kw3">memcpy</span>(bmpBuf.data, bmpA.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: CPU okay, DMA blit corrupted.<br />
<b>Explanation</b>: The buffered data is in cache, so the<br />
<code>memcpy()</code> to the buffer goes to cache as well. Meanwhile,<br />
the actual buffer (in RAM) still holds (parts of) &lsquo;B&rsquo;,<br />
which is where DMA gets its data from. The result is a mix of<br />
&lsquo;A&rsquo; and &lsquo;B&rsquo; for <code>dmaBlit()</code>. It&#8217;s<br />
a mix because apparently some cache lines have already been flushed<br />
out by the replacement policy.
</p>
<p><h3 id="ssec-test-04">4.4
<br />
Indirect Blit + flush: &lsquo;B&rsquo; &rarr; buffer, flush &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; <span class="kw3">memcpy</span>(bmpBuf.data, bmpB.data, SIZE);<br />
&nbsp; &nbsp; DC_FlushRange(bmpBuf.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both correct.<br />
<b>Explanation</b>: again, the <code>memcpy()</code> will result in<br />
corrupt data in RAM, but this time we force the up-to-date cache lines<br />
back to RAM to get cache and RAM in synch again. At this point, both<br />
the CPU and DMA-based blits will use the correct data.
</p>
<p><h3 id="ssec-test-05">4.5
<br />
Indirect Blit + invalidate: &lsquo;A&rsquo; &rarr; buffer, invalidate &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; <span class="kw3">memcpy</span>(bmpBuf.data, bmpA.data, SIZE);<br />
&nbsp; &nbsp; DC_InvalidateRange(bmpBuf.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both screwed in the same way.<br />
<b>Explanation</b>: as said in the note, you need to do the right<br />
operation at the right time. This is an example of what happens if you<br />
don&#8217;t. A cache invalidate simply erases cache lines. The data in RAM is<br />
now considered valid. However, after the <code>memcpy()</code>, RAM<br />
<i>isn&#8217;t</i> valid, as one can see from case 3. This is why now both<br />
blits fail.<br />
<a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/NiceJobBreakingItHero">Nice<br />
job breaking it, hero.</a>
</p>
<p><h3 id="ssec-test-06">4.6
<br />
Indirect Blit III: &lsquo;A&rsquo; (dma)&rarr; buffer &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; dmaCopy(bmpA.data, bmpBuf.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: CPU blit fail.<br />
<b>Explanation</b>: in this case, the source&rarr;buffer transfer is done<br />
via DMA rather than the CPU-based <code>memcpy()</code>. This time the<br />
CPU doesn&#8217;t know the contents of RAM have been altered. At this point,<br />
the cache will contain mostly the cleared data from the<br />
<code>memset()</code> done in the case set-up; <code>cpuBlit()</code><br />
will pick up some straggling lines from RAM during blit, resulting in<br />
the image you see here. Naturally, <code>dmaBlit()</code> works<br />
properly.
</p>
<p><h3 id="ssec-test-07">4.7
<br />
Indirect Blit + invalidate II: &lsquo;B&rsquo;<br />
  (dma)&rarr; buffer, invalidate &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; dmaCopy(bmpB.data, bmpBuf.data, SIZE);<br />
&nbsp; &nbsp; DC_InvalidateRange(bmpBuf.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both correct.<br />
<b>Explanation</b>: as case 6, but with an invalidate after the<br />
transfer to the buffer. The invalidate removes the allocated cache<br />
lines, so that the next CPU-reads come from RAM. Unlike case 5,<br />
RAM <i>is</i> the most up-to-date area, so the invalidate works as<br />
it&#8217;s supposed to.
</p>
<p><h3 id="ssec-test-08">4.8
<br />
Indirect Blit + invalidate/flush: &lsquo;A&rsquo;<br />
  &rarr; buffer, invalidate/flush &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; <span class="kw3">memcpy</span>(bmpBuf.data, bmpA.data, SIZE);<br />
&nbsp; &nbsp; DC_InvalidateRange(bmpBuf.data, SIZE);<br />
&nbsp; &nbsp; DC_FlushRange(bmpBuf.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both fail.<br />
<b>Explanation</b>: The invalidate frees cache lines (see case 5).<br />
The subsequent flush does nothing, because no lines are associated<br />
with those addresses anymore.
</p>
<p>
This is an example of what I like to call LOL-type programming.<br />
As in &ldquo;What are you doing?!?&rdquo; &#8211; &ldquo;I dunno lol&rdquo;.<br />
This type of coding generally indicates a very confused mind that<br />
hopes that if you throw enough shit against a wall maybe something<br />
will hold up. He may have heard terms like flush and invalidate<br />
used around DMA and decided to try them randomly. This never works.<br />
If you find code like this, be afraid; very, <i>very</i> afraid.<br />
This will likely not be the only instance of cargo-cult programming<br />
in the code-base and it&#8217;d be best to consider the whole thing suspect.
</p>
<p><h3 id="ssec-test-09">4.9
<br />
dmaSafe I: &lsquo;B&rsquo; &rarr; buffer (safe)&rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; <span class="kw3">memcpy</span>(bmpBuf.data, bmpB.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlitSafe(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both correct.<br />
<b>Explanation</b>: this uses the <code>dmaCopySafe()</code> function given<br />
previously in the DMA blitter. Since that function checks whether a<br />
flush is appropriate, everything should be fine. And it is.
</p>
<p><h3 id="ssec-test-10">4.10
<br />
dmaSafe II: &lsquo;A&rsquo; (safedma)&rarr; buffer &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; dmaCopySafe(bmpA.data, bmpBuf.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpBuf, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlitSafe(&amp;bmpBuf, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: both correct.<br />
<b>Explanation</b>: <code>dmaCopySafe()</code> also performs an<br />
invalidate if necessary so, again, it all works.
</p>
<p><h3 id="ssec-test-11">4.11
<br />
Buffer in stack: &lsquo;B&rsquo; &rarr; local buffer &rarr; VRAM
</h3>
</p>
<p><div class="cpt" style="width:px;">
  <a href="" target="_blank">  <img src="" 
    alt="" width="" /></a><br />
  
</div>
</p>
<div class="cpp">
<div class="cpp proglist" style=" ">&nbsp; &nbsp; u16 localBuf[<span class="nu0">16</span>*<span class="nu0">16</span>];<br />
&nbsp; &nbsp; MiniBmp bmpLocal= { <span class="nu0">16</span>, <span class="nu0">16</span>, localBuf };</p>
<p>&nbsp; &nbsp; <span class="kw3">memcpy</span>(localBuf, bmpB.data, SIZE);</p>
<p>&nbsp; &nbsp; cpuBlit(&amp;bmpLocal, X_CPU, Y_CPU);<br />
&nbsp; &nbsp; dmaBlit(&amp;bmpLocal, X_DMA, Y_DMA);</div>
</div>
<p class=ni>
<b>Result</b>: DMA fail.<br />
<b>Explanation</b>: in this case, I&#8217;m using a local buffer for the<br />
bitmap instead of a global one. The difference here is that a local<br />
buffer goes onto the stack, which is in DTCM rather than RAM. As<br />
discussed earlier, DTCM is invisible to DMA, so <code>dmaBlit()</code><br />
doesn&#8217;t work. Note that using <code>dmaBlitSafe()</code> wouldn&#8217;t<br />
work either, but at least you&#8217;d get an return value indicating failure<br />
back instead of nothing at all.
</p>
<p><div>&nbsp;</div></p>
<p><div class=note>
<div  class=nhcare>Hardware vs emulator</div>
</p>
<p>
As far as I know <i>all</i> current NDS emulators do not emulate<br />
cache properly, so that these tests would actually seem produce correct<br />
results. &ldquo;correct&rdquo; in the sense that they reproduce the<br />
target image, not that they give similar results as hardware.
</p>
<p></div>
</p>
<p><h2 id="sec-conc">5
Conclusions
</h2>
</p>
<ul>
<li>
    The ARM9 has DTCM and ITCM sections that DMA can&#8217;t access. DMA<br />
    transfers to and from there will fail. Because the stack is in<br />
    DTCM, this includes transfers to/from (non-static) local variables.
  </li>
<li>
    The ARM9 has cache that DMA can&#8217;t see either. If DMA tries to<br />
	read/write from RAM block that have been cached, the wrong data<br />
	<i>may</i> be transferred.
  </li>
<li>
    The ARM9 uses 32-byte cache lines that are initiated when addresses<br />
    are read from, but not when written to (read-allocate). It also uses a<br />
    write-back policy: cached data is written back to RAM only when the<br />
    cache line is replaced.
  </li>
<li>
    Cache-miss bad; cache-hit good. Stale cache also bad, since it&#8217;s the cause<br />
    of incorrect DMA transfers.
  </li>
<li>
    DMA-reads from RAM should be preceded by a cache flush, which writes<br />
    cache lines back to RAM.
  </li>
<li>
    DMA-writes to RAM should be preceded or followed by a cache<br />
	invalidate, which clears cache lines so that the next CPU-read will be<br />
	from RAM again.
  </li>
<li>
    As far as I know, most emulators do not handle DMA-DTCM correctly.<br />
	None emulate cache. If you suddenly find corrupted data after<br />
	copying on hardware but not emulators, look at your DMA calls.
  </li>
<li>
    Making graphics with rounded corners and intricate wide lines take<br />
    <i>forever</i> to get right.
  </li>
</ul>
<p><div>&nbsp;</div></p>
<p>
Related test project: <a href="/files/nds/arm9vsdma.zip">arm9vsdma.zip</a></p>
<hr /><div class="footnotes">
<h5>Notes:</h5>
<ol>
<li id="ft-nr1"> 
  Well,<br />
<i>quite</i> fast anyway. In some circumstances CPU-based transfers<br />
are faster, but that&#8217;s a story for another day.
</li>
<li id="ft-nr2"> 
  Well, sometimes. Usually these go in<br />
CPU registers, but this is not the right place for that discussion<br />
either.
</li>
</ol>
</div
<hr />
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2009/05/dma-vs-arm9-fight/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Some interesting numbers on NDS code size</title>
		<link>http://www.coranac.com/2009/02/some-interesting-numbers-on-nds-code-size/</link>
		<comments>http://www.coranac.com/2009/02/some-interesting-numbers-on-nds-code-size/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 22:50:40 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[nds]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[codesize]]></category>
		<category><![CDATA[research]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=66</guid>
		<description><![CDATA[Even though the total size of code is usually small compared to assets, there are still some concerns about a number of systems. Most notably among these are stdio, iostream and several STL components like vectors and strings. I&#8217;ve seen people voice concerns about these items, but I don&#8217;t think I&#8217;ve ever seen any measurements [...]]]></description>
			<content:encoded><![CDATA[<p>
Even though the total size of code is usually small compared to assets, there are still some concerns about a number of systems. Most notably among these are stdio, iostream and several STL components like vectors and strings. I&#8217;ve seen people voice concerns about these items, but I don&#8217;t think I&#8217;ve ever seen any measurements of them. So here are some.
</p>
<table id="tbl-footprint"<br />
  border=1 cellpadding=2 cellspacing=0><br />
<caption align=bottom>
  <b>Table&nbsp;1</b> : Memory footprint of some C/C++ components in bytes. Items may not be strictly cumulative.<br />
</caption>
<tr>
<td>Barebones: just VBlank code</td>
<td>14516</td>
</tr>
<tr>
<td>base+printf</td>
<td>71148</td>
</tr>
<tr>
<td>base+iprintf</td>
<td>54992</td>
</tr>
<tr>
<td>base+iostream</td>
<td>266120</td>
</tr>
<tr>
<td>base+fopen</td>
<td>56160</td>
</tr>
<tr>
<td>base+fstream</td>
<td>260288</td>
</tr>
<tr>
<td>base+&lt;string&gt;</td>
<td>59384</td>
</tr>
<tr>
<td>base+&lt;vector&gt;</td>
<td>59624</td>
</tr>
<tr>
<td>base+&lt;string&gt;+&lt;vector&gt;</td>
<td>59648</td>
</tr>
</table>
<p>
The sizes in Table&nbsp;1 are for a bare source file with just the VBlank initialization and <code>swiWaitForVBlank()</code> plus whatever&#8217;s necessary to use a particular component. For the IO parts this means a call to <code>consoleDemoInit()</code>; for vectors and strings, it means defining a variable.
</p>
<p><div>&nbsp;</div></p>
<p>
Even an empty project is already 15k in size. Almost all of this is FIFO code, which is required for the ARM9 and ARM7 to communicate. Adding <code>consoleDemoInit()</code> and a  <code>printf()</code> call adds roughly 71k. Printf has a lot of bagage: you have to have basic IO hooks, character type functions, allocations, decimal <i>and</i> floating point routines and more.
</p>
<p>
Because <code>printf()</code> uses the usually unnecessary floating point routines for float conversions, it is often suggested to use the integer-only variant <code>iprintf()</code>. In that case, it comes down to 55k. The difference is mostly due to two functions: <code>_vfprintf_r()</code> and <code>_dtoa_r()</code>, for 5.8k and 3.6k, respectively. The rest is made up of dozens of smaller functions. While the difference is relatively large, considering the footprint of the other components, the extra 16k is probably not that big of a deal. For the record, there is no difference in speed between the two. Well, almost: if the format string doesn&#8217;t contain formatting parts, <code>printf()</code> is actually considerably faster. Another point of note is that the 55k for <code>iprintf()</code> is actually already added just by using <code>consoleDemoInit()</code>.
</p>
<p>
And now the big one. People have said that C++ iostream was heavy, and indeed it is. 266k! That&#8217;s a quite a lot, especially since the benefits of using iostream over stdio is rather slim if not actually negative<span class="fnote"><a href="#ft-nr1" title="Yes, I said negative. Even though it has the benefit of being typesafe and extensible, the value of these advantages are somewhat exaggerated, especially since it has several drawback as well (see FQA:ch 15 for details). For one thing, try finding the iostream equivalent of &#8220;%08X&#8221;, or formatted anything for that matter. For early grit code I was actually using iostream until I got to actually writing the export code. I couldn&#8217;t move back to stdio fast enough.">(1)</a></span>. Don&#8217;t use iostream in NDS projects. Don&#8217;t even #include &lt;iostream&gt;, as that seems enough to link the whole thing in.
</p>
<p>
Related to iosteam is fstream. This also is about a quarter MB. I haven&#8217;t checked too carefully, but I think the brunt of these parts are shared, so it won&#8217;t combine to half a Meg if you use both. Something similar is true for the stdio file routines.
</p>
<p>
Why are the C++ streams so large? Well, lots of reasons, apparently. One of which is actually its potential for extensibility. Because it doesn&#8217;t work via formatting flags, none of those can be excluded like in <code>iprintf()</code>&#8216;s case. Then there&#8217;s exceptions, which adds a good deal of code as well. There also seems to be <i>tons</i> of stuff for character traits, numerical traits, money traits (wtf?!?) and iosbase stuff. These items seem small, say 4 to 40 bytes, but when there are over a thousand it adds up. Then there&#8217;s all the stuff from STL strings and allocators, type info, <i>more</i> exception stuff, error messages for the exceptions, date/time routines, locale settings and more. I tell you, looking at the mapfile for this is enough to give me a headache. And worst of all, you&#8217;ll probably use next to none of it, but it&#8217;s all linked in anyway.
</p>
<p>
Finally, some STL. This is also said to be somewhat big-boned, and yes it isn&#8217;t light. Doing anything non-trivial with either a vector or string seems to add about 60k. Fortunately, though, this is mostly the same 60k, so there are not bad effects from using both. Unfortunately, I can&#8217;t really tell where it&#8217;s all going. About 10k is spent on several <code>d_*()</code> routines like <code>d_print()</code>, which is I assume debug code. Another 10k is exceptions, type info and error messages and 10 more for. But after that it gets a little murky. In any case, even though adding STL strings and vectors includes more that necessary, 60k is a fair price for what these components give you.
</p>
<p><div>&nbsp;</div></p>
<h4>Conclusions</h4>
<p>
The smallest size for an NDS binary is about 14k. While <code>printf()</code> is larger than <code>iprintf()</code>, it&#8217;s probably not enough to worry about, so just use <code>printf()</code> until it becomes a pressing matter (and even then you could probably shrink down another part more easily anyway). There is no speed difference between the two. The C++ iostream and fstream components are not worth it. Their added value over printf and FILE routines are small when it comes to basic IO functionality. STL containers do cost a bit, but are probably worth the effort. If you need more than simple text handling or dynamic arrays and lists, I&#8217;d say go for it. But that&#8217;s just my opinion.
</p>
<p>
Please note, the tests I did for this were fairly roughly. Your mileage may vary.
</p>
<p><div>&nbsp;</div></p>
<p>
Lastly. The <a href="http://sourceware.org/binutils/"><tt>nm</tt></a> tool (or <code>arm-eabi-nm</code> for DKA) is my new best friend for executable analysis. Unlike the linker&#8217;s mapfile, <tt>nm</tt> <i>can</i> sort addresses and show symbol sizes, and doesn&#8217;t include tons of crap used for glue.</p>
<hr /><div class="footnotes">
<h5>Notes:</h5>
<ol>
<li id="ft-nr1"> 
  Yes, I said negative. Even though it has the benefit of being typesafe and extensible, the value of these advantages are somewhat exaggerated, especially since it has several drawback as well (see <a href="http://yosefk.com/c++fqa/io.html">FQA:ch 15</a> for details). For one thing, try finding the iostream equivalent of &#8220;%08X&#8221;, or formatted anything for that matter. For early grit code I was actually using iostream until I got to actually writing the export code. I couldn&#8217;t move back to stdio fast enough.
</li>
</ol>
</div
<hr />
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2009/02/some-interesting-numbers-on-nds-code-size/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NDS register overview</title>
		<link>http://www.coranac.com/2008/09/nds-register-overview/</link>
		<comments>http://www.coranac.com/2008/09/nds-register-overview/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 15:45:42 +0000</pubDate>
		<dc:creator>cearn</dc:creator>
				<category><![CDATA[nds]]></category>
		<category><![CDATA[naming]]></category>
		<category><![CDATA[registers]]></category>

		<guid isPermaLink="false">http://www.coranac.com/?p=58</guid>
		<description><![CDATA[libnds 1.3.1 updates libnds has fixed the datatypes of pretty much all registers and have moved to the GBATek nomenclature for the BG-related registers. The list has been updated to match the libnds v1.3.1. of The state of register names for NDS homebrew is a bit of a mess. First, there are the GBATek names. [...]]]></description>
			<content:encoded><![CDATA[<p><div class=note>
<div  class=nh>libnds 1.3.1 updates</div>
</p>
<p>
libnds has fixed the datatypes of pretty much all registers and<br />
have moved to the GBATek nomenclature for the BG-related<br />
registers. The list has been updated to match the libnds v1.3.1.<br />
of
</p>
<p></div>
</p>
<p>
The state of register names for NDS homebrew is a bit of a mess.<br />
First, there are the GBATek names. Since GBATek is considered<br />
<i>the</i> source of GBA/NDS information, it would make sense to<br />
adhere to those names pretty closely. But, of course, that&#8217;s not<br />
how actually is in the de facto library for NDS homebrew, libnds.
</p>
<p>
libnds has two sets of names. This probably is a result of serving<br />
different masters in its early days. One set uses<br />
<a href="http://www.auia.net/mappy/sdk/">Mappy</a>&#8216;s nomenclature.<br />
That&#8217;s the one without the <code>REG_</code> in front of it, and<br />
uses things like <code>_CR</code>, and <code>_SR</code>. This is<br />
one you&#8217;re most likely to see in the current NDS tutorials.<br />
The second set uses GBATek&#8217;s names (mostly) plus a <code>REG_</code><br />
prefix. If you&#8217;ve done GBA programming, these should feel quite<br />
familiar.
</p>
<p><div>&nbsp;</div></p>
<p><span id="more-58"></span></p>
<p>
For the most part, I don&#8217;t really care much for the the Mappy names.<br />
One reason for this is that they don&#8217;t match up with the GBATek names,<br />
making it harder to look-up what they do. More importantly, though,<br />
without any sort of prefix that indicates they&#8217;re registers, they all<br />
look like the constants you put <i>in</i> the<br />
registers. After all, that&#8217;s what all-caps usually means: a constant.<br />
When I see the identifier <code>WIN0_X0</code>, I&#8217;m more likely to<br />
think that it&#8217;s something to set a window coordinate <i>to</i>, rather<br />
than that it is how to control the window. Having to wonder constantly<br />
whether a particular identifier is a constant or a register is pretty<br />
annoying<span class="fnote"><a href="#ft-nr1" title="See also BG_TILE_BASE and
BG_TILE_RAM, for the REG_BGxCNT macro and
the VRAM address, respectively. Yeah, you can tell because obviously
RAM means memory, but it&#8217;s still an easy mistake to make, especially
since the VRAM areas are called &ldquo;base&rdquo; as well.">(1)</a></span>.<br />
But perhaps this is just me.
</p>
<p>
What&#8217;s especially grating about these names is that the elements of<br />
the <a href="http://www.coranac.com/tonc/text/affine.htm">affine matrix</a><br />
are transposed. <code>HDY</code> is actually <code>VDX</code> and vice<br />
versa. Shame, actually, because the <code>HDX-VDY</code> naming<br />
scheme does make more sense than old <code>PA-PD</code> names.
</p>
<p>
The elements <code>XDY</code> and <code>YDX</code> are also transposed<br />
&hellip; I think. It&#8217;s hard to be sure since this nomenclature is highly<br />
ambiguous anyway. I really can&#8217;t tell how the elements are supposed to<br />
be read, much less determine if they are in the correct order.
</p>
<p><div>&nbsp;</div></p>
<p>
The <code>REG_</code> registers do not suffer from those problems, but<br />
they have their own issues. The registers that had a GBA counterpart<br />
are generally okay, but in the case of the NDS-specific ones, some<br />
follow the GBATek names, some <i>almost</i> follow them<br />
(<code>MTX_LOAD_4x4</code> vs <code>REG_MTX_LOAD4x4</code>, for<br />
example; note the underscores), and some are the Mappy-like names<br />
plus prefix.
</p>
<p>
Finally, registers of both nomenclatures are grouped by topic and not<br />
necessarily by address. This makes sense from an OOP point of view,<br />
but it does mean they have been sprinkled across multiple files, making<br />
it tricky to see where the things are acrually defined. Some named are<br />
also clumped inside <tt>registers_alt.h</tt>, which is a sort of<br />
transitional file. This file is not included by <tt>nds.h</tt>, which<br />
can make it hard to know which names are included or not until you<br />
either search though the whole include hierarchy or get an error<br />
from the compiler. And then have to search the hierarchy to find out<br />
the exact spelling.
</p>
<p><div>&nbsp;</div></p>
<p>
To make it a little easier to deal with the fragmentation of the libnds<br />
headers regarding registers, here is a list of all the registers as they<br />
appear in GBATek, the primary libnds set (plus the file where they&#8217;re<br />
defined), and the alternate libnds set (<tt>registers_alt.h</tt>).<br />
I&#8217;ve also included links to where you can find the descriptions<br />
in GBATek.
</p>
<ul>
<li>
    The <b>bold black</b> names are those corresponding exactly to GBATek.
  </li>
<li>
    The <span class=rem><b>bold red</b></span> items are problematic in some<br />
    way; usually the datatype is not what is should be, or some registers<br />
    have been swapped somehow. Follow the footnotes or hover over them to<br />
	see my comments. Note that some of these are already fixed in CVS.
  </li>
<li>
    Sometimes there are gaps. In this case, that particular set has<br />
    no name for it.
  </li>
</ul>
<p><h2 id="sec-arm9">1
Arm 9 registers
</h2>
</p>
<table style="border:2px solid black;" cellpadding=2 cellspacing=0>
<col span=3 align=center>
<tr class=bg1 align=center>
<th>&nbsp;</th>
<th class="bdrL bdrR" colspan=3>GBATek / official</th>
<th class="bdrL bdrR" colspan=3>libnds primary</th>
<th class="bdrL" colspan=2>libnds alternate</th>
</tr>
<tr class=bg1 align=center>
<th class="bdrB">addr</th>
<th class="bdrL bdrB">size</th>
<th class="bdrL bdrB">name</th>
<th class="bdrL bdrR bdrB">name</th>
<th class="bdrL bdrB">file</th>
<th class="bdrL bdrB">type</th>
<th class="bdrR bdrB">name</th>
<th class="bdrL bdrB">type</th>
<th class="bdrB">name</th>
</tr>
<tr class=bg0>
<td>0400:0000</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsvideobgmodescontrol">DISPCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR"><b>REG_DISPCNT</b></td>
<td class="bdrL">vu32</td>
<td>DISPLAY_CR</td>
</tr>
<tr class=bg1>
<td>0400:0004</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiointerruptsandstatus">DISPSTAT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_DISPSTAT</b></td>
<td class="bdrL">vu16</td>
<td>DISP_SR</td>
</tr>
<tr class=bg0>
<td>0400:0006</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiointerruptsandstatus">VCOUNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_VCOUNT</b></td>
<td class="bdrL">vu16</td>
<td>DISP_Y</td>
</tr>
<tr class=bg1>
<td>0400:0008</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">bg_attribute </td>
<td class="bdrR">BACKGROUND</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0008</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">BGCTRL&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0008</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG0CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG0CNT</b></td>
<td class="bdrL">vu16</td>
<td>BG0_CR</td>
</tr>
<tr class=bg0>
<td>0400:000A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG1CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG1CNT</b></td>
<td class="bdrL">vu16</td>
<td>BG1_CR</td>
</tr>
<tr class=bg1>
<td>0400:000C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG2CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG2CNT</b></td>
<td class="bdrL">vu16</td>
<td>BG2_CR</td>
</tr>
<tr class=bg0>
<td>0400:000E</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG3CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG3CNT</b></td>
<td class="bdrL">vu16</td>
<td>BG3_CR</td>
</tr>
<tr class=bg1>
<td>0400:0010</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">REG_BGOFFSETS&nbsp;</td>
<td class="bdrL"><b>&nbsp;</b></td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0010</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG0HOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG0HOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG0_X0</td>
</tr>
<tr class=bg1>
<td>0400:0012</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG0VOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG0VOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG0_Y0</td>
</tr>
<tr class=bg0>
<td>0400:0014</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG1HOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG1HOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG1_X0</td>
</tr>
<tr class=bg1>
<td>0400:0016</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG1VOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG1VOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG1_Y0</td>
</tr>
<tr class=bg0>
<td>0400:0018</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG2HOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG2HOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG2_X0</td>
</tr>
<tr class=bg1>
<td>0400:001A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG2VOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG2VOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG2_Y0</td>
</tr>
<tr class=bg0>
<td>0400:001C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG3HOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG3HOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG3_X0</td>
</tr>
<tr class=bg1>
<td>0400:001E</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG3VOFS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG3VOFS</b></td>
<td class="bdrL">vu16</td>
<td>BG3_Y0</td>
</tr>
<tr class=bg0>
<td>0400:0020</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PA</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PA</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG2_XDX</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:0022</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG2_XDY</b><span class="fnote"><a href="#ft-nr3" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _YDX element.">(3)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:0024</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PC</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PC</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG2_YDX</b><span class="fnote"><a href="#ft-nr4" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _XDY element">(4)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:0026</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PD</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG2_YDY</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:0028</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2X</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG2X</b></td>
<td class="bdrL">vs32</td>
<td>BG2_CX</td>
</tr>
<tr class=bg1>
<td>0400:002C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2Y</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG2Y</b></td>
<td class="bdrL">vs32</td>
<td>BG2_CY</td>
</tr>
<tr class=bg0>
<td>0400:0030</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PA</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PA</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG3_XDX</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:0032</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG3_XDY</b><span class="fnote"><a href="#ft-nr3" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _YDX element.">(3)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:0034</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PC</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PC</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG3_YDX</b><span class="fnote"><a href="#ft-nr4" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _XDY element">(4)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:0036</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PD</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>BG3_YDY</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:0038</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3X</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG3X</b></td>
<td class="bdrL">vs32</td>
<td>BG3_CX</td>
</tr>
<tr class=bg1>
<td>0400:003C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3Y</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG3Y</b></td>
<td class="bdrL">vs32</td>
<td>BG3_CY</td>
</tr>
<tr class=bg0>
<td>0400:0040</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN0H</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN0H</b></td>
</tr>
<tr class=bg1>
<td>0400:0040</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN0_X1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0041</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN0_X0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0042</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN1H</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN1H</b></td>
</tr>
<tr class=bg0>
<td>0400:0042</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN1_X1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0043</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN1_X0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0044</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN0V</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN0V</b></td>
</tr>
<tr class=bg1>
<td>0400:0044</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN0_Y1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0045</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN0_Y0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0046</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN1V</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN1V</b></td>
</tr>
<tr class=bg0>
<td>0400:0046</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN1_Y1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0047</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WIN1_Y0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0048</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WININ</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">WIN_IN</td>
<td class="bdrL">vu16</td>
<td><b>REG_WININ</b></td>
</tr>
<tr class=bg1>
<td>0400:004A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WINOUT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">WIN_OUT</td>
<td class="bdrL">vu16</td>
<td><b>REG_WINOUT</b></td>
</tr>
<tr class=bg0>
<td>0400:004C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiomosaicfunction">MOSAIC</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">MOSAIC_CR</td>
<td class="bdrL rem"><b>vu32</b><span class="fnote"><a href="#ft-nr5" title="
Should be vu16, not vu32">(5)</a></span></td>
<td><b>REG_MOSAIC</b></td>
</tr>
<tr class=bg1>
<td>0400:0050</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiocolorspecialeffects">BLDCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">BLEND_CR</td>
<td class="bdrL">vu16</td>
<td>REG_BLDMOD</td>
</tr>
<tr class=bg0>
<td>0400:0052</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiocolorspecialeffects">BLDALPHA</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">BLEND_AB</td>
<td class="bdrL">vu16</td>
<td>REG_COLV</td>
</tr>
<tr class=bg1>
<td>0400:0054</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiocolorspecialeffects">BLDY</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">BLEND_Y</td>
<td class="bdrL">vu16</td>
<td>REG_COLY</td>
</tr>
<tr class=bg0>
<td>0400:0060</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3ddisplaycontrol">DISP3DCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">GFX_CONTROL</td>
<td class="bdrL">vu16</td>
<td>REG_GFX_CONTROL</td>
</tr>
<tr class=bg1>
<td>0400:0064</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode">DISPCAPCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR"><b>REG_DISPCAPCNT</b></td>
<td class="bdrL">vu32</td>
<td>DISP_CAPTURE</td>
</tr>
<tr class=bg0>
<td>0400:0068</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode">DISP_MMEM_FIFO</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR"><b>REG_ DISP_MMEM_FIFO</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:006C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsvideostuff">MASTER_BRIGHT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">BRIGHTNESS</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:00B0</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA_SRC(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:00B4</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA_DEST(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:00B8</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA_CR(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:00B0</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL rem"><b>vu32</b><span class="fnote"><a href="#ft-nr6" title="
Should be struct">(6)</a></span></td>
<td>REG_DMA&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:00B0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA0SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA0_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA0SAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00B4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA0DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA0_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA0DAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00B8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA0CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA0_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA0CNT</b></td>
</tr>
<tr class=bg1>
<td>0400:00BC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA1SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA1_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA1SAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00C0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA1DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA1_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA1DAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00C4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA1CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA1_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA1CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:00C8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA2SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA2_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA2SAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00CC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA2DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA2_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA2DAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00D0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA2CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA2_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA2CNT</b></td>
</tr>
<tr class=bg1>
<td>0400:00D4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA3SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA3_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA3SAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00D8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA3DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA3_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA3DAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00DC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA3CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA3_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA3CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:00E0</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA_FILL(n)</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg1>
<td>0400:00E0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA0FILL</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:00E4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA1FILL</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:00E8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA2FILL</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:00EC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA3FILL</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0100</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL rem"><b>vu16</b><span class="fnote"><a href="#ft-nr6" title="
Should be struct">(6)</a></span></td>
<td>REG_TIME&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0100</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER_DATA(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0102</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER_CR(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0100</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM0D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER0_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM0D</b></td>
</tr>
<tr class=bg1>
<td>0400:0102</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM0CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER0_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM0CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:0104</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM1D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER1_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM1D</b></td>
</tr>
<tr class=bg1>
<td>0400:0106</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM1CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER1_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM1CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:0108</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM2D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER2_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM2D</b></td>
</tr>
<tr class=bg1>
<td>0400:010A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM2CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER2_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM2CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:010C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM3D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER3_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM3D</b></td>
</tr>
<tr class=bg1>
<td>0400:010E</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM3CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER3_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM3CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:0130</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbakeypadinput">KEYINPUT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_KEYINPUT</b></td>
<td class="bdrL">vuint16</td>
<td>KEYS</td>
</tr>
<tr class=bg1>
<td>0400:0132</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbakeypadinput">KEYCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_KEYCNT</b></td>
<td class="bdrL">vuint16</td>
<td>KEYS_CR</td>
</tr>
<tr class=bg0>
<td>0400:0180</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCSYNC</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">REG_IPC_SYNC</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0184</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCFIFOCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">REG_IPC_FIFO_CR</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0188</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCFIFOSEND</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">REG_IPC_FIFO_TX</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:01A0</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">AUXSPICNT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">CARD_CR1</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_CR1</td>
</tr>
<tr class=bg0>
<td>0400:01A1</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">CARD_CR1H</td>
<td class="bdrL">vu8</td>
<td>REG_CARD_CR1H</td>
</tr>
<tr class=bg1>
<td>0400:01A2</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">AUXSPIDATA</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">CARD_EEPDATA</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:01A4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">CARD_CR2</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_CR2</td>
</tr>
<tr class=bg1>
<td>0400:01A8</td>
<td class="bdrL">8</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">CARD_COMMAND</td>
<td class="bdrL">vu8</td>
<td>REG_CARD_COMMAND&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:01B0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">CARD_1B0</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_1B0</td>
</tr>
<tr class=bg1>
<td>0400:01B4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">CARD_1B4</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_1B4</td>
</tr>
<tr class=bg0>
<td>0400:01B8</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">CARD_1B8</td>
<td class="bdrL">vu16</td>
<td>REG_CARD_1B8</td>
</tr>
<tr class=bg1>
<td>0400:01BA</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">CARD_1BA</td>
<td class="bdrL">vu16</td>
<td>REG_CARD_1BA</td>
</tr>
<tr class=bg0>
<td>0400:0204</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolcartridgesandmainram">EXMEMCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">memory.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_EXMEMCNT</b></td>
<td class="bdrL">vuint16</td>
<td>WAIT_CR</td>
</tr>
<tr class=bg1>
<td>0400:0208</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbainterruptcontrol">IME</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">interrupts.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_IME</b></td>
<td class="bdrL">vuint16</td>
<td>IME</td>
</tr>
<tr class=bg0>
<td>0400:0210</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterrupts">IE</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">interrupts.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR"><b>REG_IE</b></td>
<td class="bdrL">vuint32</td>
<td>IE</td>
</tr>
<tr class=bg1>
<td>0400:0214</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterrupts">IF</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">interrupts.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR"><b>REG_IF</b></td>
<td class="bdrL">vuint32</td>
<td>IF</td>
</tr>
<tr class=bg0>
<td>0400:0240</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">VRAM_CR</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0240</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_A</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_A_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_A_CR</td>
</tr>
<tr class=bg0>
<td>0400:0241</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_B</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_B_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_B_CR</td>
</tr>
<tr class=bg1>
<td>0400:0242</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_C</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_C_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_C_CR</td>
</tr>
<tr class=bg0>
<td>0400:0243</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_D</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_D_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_D_CR</td>
</tr>
<tr class=bg1>
<td>0400:0244</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_E</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_E_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_E_CR</td>
</tr>
<tr class=bg0>
<td>0400:0245</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_F</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_F_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_F_CR</td>
</tr>
<tr class=bg1>
<td>0400:0246</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_G</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_G_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_G_CR</td>
</tr>
<tr class=bg0>
<td>0400:0247</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolwram">WRAMCNT</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">WRAM_CR</td>
<td class="bdrL">vu8</td>
<td>REG_WRAM_CNT</td>
</tr>
<tr class=bg1>
<td>0400:0248</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_H</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_H_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_H_CR</td>
</tr>
<tr class=bg0>
<td>0400:0249</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMCNT_I</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">VRAM_I_CR</td>
<td class="bdrL">vu8</td>
<td>REG_VRAM_I_CR</td>
</tr>
<tr class=bg1>
<td>0400:0280</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">DIVCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_DIVCNT</b></td>
<td class="bdrL">vu16</td>
<td>DIV_CR</td>
</tr>
<tr class=bg0>
<td>0400:0290</td>
<td class="bdrL">8</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">DIV_NUMER</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs64</td>
<td class="bdrR"><b>REG_DIV_NUMER</b></td>
<td class="bdrL">vs64</td>
<td>DIV_NUMERATOR64</td>
</tr>
<tr class=bg1>
<td>0400:0290</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_DIV_NUMER_L</b></td>
<td class="bdrL">vs32</td>
<td>DIV_NUMERATOR32</td>
</tr>
<tr class=bg0>
<td>0400:0298</td>
<td class="bdrL">8</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">DIV_DENOM</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs64</td>
<td class="bdrR"><b>REG_DIV_DENOM</b></td>
<td class="bdrL">vs64</td>
<td>DIV_DENOMINATOR64</td>
</tr>
<tr class=bg1>
<td>0400:0298</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_DIV_DENOM_L</b></td>
<td class="bdrL">vs32</td>
<td>DIV_DENOMINATOR32</td>
</tr>
<tr class=bg0>
<td>0400:02A0</td>
<td class="bdrL">8</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">DIV_RESULT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs64</td>
<td class="bdrR"><b>REG_DIV_RESULT</b></td>
<td class="bdrL">vs64</td>
<td>DIV_RESULT64</td>
</tr>
<tr class=bg1>
<td>0400:02A0</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_DIV_RESULT_L</b></td>
<td class="bdrL">vs32</td>
<td>DIV_RESULT32</td>
</tr>
<tr class=bg0>
<td>0400:02A8</td>
<td class="bdrL">8</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">DIVREM_RESULT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs64</td>
<td class="bdrR"><b>REG_DIVREM_RESULT</b></td>
<td class="bdrL">vs64</td>
<td>DIV_REMAINDER64</td>
</tr>
<tr class=bg1>
<td>0400:02A8</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_DIVREM_RESULT_L</b></td>
<td class="bdrL">vs32</td>
<td>DIV_REMAINDER32</td>
</tr>
<tr class=bg0>
<td>0400:02B0</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">SQRTCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_SQRTCNT</b></td>
<td class="bdrL">vu16</td>
<td>SQRT_CR</td>
</tr>
<tr class=bg1>
<td>0400:02B4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">SQRT_RESULT</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_SQRT_RESULT</b></td>
<td class="bdrL">vs32</td>
<td>SQRT_RESULT32</td>
</tr>
<tr class=bg0>
<td>0400:02B8</td>
<td class="bdrL">8</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmaths">SQRT_PARAM</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs64</td>
<td class="bdrR"><b>REG_SQRT_PARAM</b></td>
<td class="bdrL">vs64</td>
<td>SQRT_PARAM64</td>
</tr>
<tr class=bg1>
<td>0400:02B8</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/math.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_SQRT_PARAM_L</b></td>
<td class="bdrL">vs32</td>
<td>SQRT_PARAM32</td>
</tr>
<tr class=bg0>
<td>0400:0300</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dspowermanagement">POSTFLG</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0304</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dspowermanagement">POWCNT1</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">REG_POWERCNT</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0320</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dstatus">RDLINES_COUNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0330</td>
<td class="bdrL">16</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtoonedgefog">EDGE_COLOR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">GFX_EDGE_TABLE</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0340</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3ddisplaycontrol">ALPHA_TEST_REF</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">GFX_ALPHA_TEST</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0350</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3drearplane">CLEAR_COLOR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_CLEAR_COLOR</td>
<td class="bdrL">vu32</td>
<td><b>REG_CLEAR_COLOR</b></td>
</tr>
<tr class=bg0>
<td>0400:0354</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3drearplane">CLEAR_DEPTH</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">GFX_CLEAR_DEPTH</td>
<td class="bdrL">vu16</td>
<td><b>REG_CLEAR_DEPTH</b></td>
</tr>
<tr class=bg1>
<td>0400:0356</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3drearplane">CLRIMAGE_OFFSET</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0358</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtoonedgefog">FOG_COLOR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_FOG_COLOR</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:035C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtoonedgefog">FOG_OFFSET</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_FOG_OFFSET</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0360</td>
<td class="bdrL">32</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtoonedgefog">FOG_TABLE</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8 </td>
<td class="bdrR">GFX_FOG_TABLE&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0380</td>
<td class="bdrL">64</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtoonedgefog">TOON_TABLE</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">GFX_TOON_TABLE&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0400</td>
<td class="bdrL">64</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dgeometrycommands">GXFIFO</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_FIFO</td>
<td class="bdrL">vu32</td>
<td><b>REG_GFX_FIFO</b></td>
</tr>
<tr class=bg1>
<td>0400:0440</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_MODE</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">MATRIX_CONTROL</td>
<td class="bdrL">vu32</td>
<td>REG_MTX_CONTROL</td>
</tr>
<tr class=bg0>
<td>0400:0444</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixstack">MTX_PUSH</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">MATRIX_PUSH</td>
<td class="bdrL">vu32</td>
<td><b>REG_MTX_PUSH</b></td>
</tr>
<tr class=bg1>
<td>0400:0448</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixstack">MTX_POP</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">MATRIX_POP</td>
<td class="bdrL">vu32</td>
<td><b>REG_MTX_POP</b></td>
</tr>
<tr class=bg0>
<td>0400:044C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixstack">MTX_STORE</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">MATRIX_STORE</td>
<td class="bdrL">vu32</td>
<td><b>REG_MTX_STORE</b></td>
</tr>
<tr class=bg1>
<td>0400:0450</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixstack">MTX_RESTORE</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">MATRIX_RESTORE</td>
<td class="bdrL">vu32</td>
<td><b>REG_MTX_RESTORE</b></td>
</tr>
<tr class=bg0>
<td>0400:0454</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_IDENTITY</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">MATRIX_IDENTITY</td>
<td class="bdrL">vu32</td>
<td><b>REG_MTX_IDENTITY</b></td>
</tr>
<tr class=bg1>
<td>0400:0458</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_LOAD_4x4</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_LOAD4x4</td>
<td class="bdrL">vf32</td>
<td>REG_MTX_LOAD4x4</td>
</tr>
<tr class=bg0>
<td>0400:045C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_LOAD_4x3</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_LOAD4x3</td>
<td class="bdrL">vf32</td>
<td>REG_MTX_LOAD4x3</td>
</tr>
<tr class=bg1>
<td>0400:0460</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_MULT_4x4</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_MULT4x4</td>
<td class="bdrL">vf32</td>
<td>REG_MTX_MULT4x4</td>
</tr>
<tr class=bg0>
<td>0400:0464</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_MULT_4x3</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_MULT4x3</td>
<td class="bdrL">vf32</td>
<td>REG_MTX_MULT4x3</td>
</tr>
<tr class=bg1>
<td>0400:0468</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_MULT_3x3</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_MULT3x3</td>
<td class="bdrL">vf32</td>
<td>REG_MTX_MULT3x3</td>
</tr>
<tr class=bg0>
<td>0400:046C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_SCALE</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_SCALE</td>
<td class="bdrL">vint32</td>
<td><b>REG_MTX_SCALE</b></td>
</tr>
<tr class=bg1>
<td>0400:0470</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">MTX_TRANS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_TRANSLATE</td>
<td class="bdrL">vint32</td>
<td>REG_MTX_TRANSLATE</td>
</tr>
<tr class=bg0>
<td>0400:0480</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonattributes">COLOR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_COLOR</td>
<td class="bdrL">vu32</td>
<td><b>REG_COLOR</b></td>
</tr>
<tr class=bg1>
<td>0400:0484</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonlightparameters">NORMAL</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_NORMAL</td>
<td class="bdrL">vu32</td>
<td><b>REG_NORMAL</b></td>
</tr>
<tr class=bg0>
<td>0400:0488</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtextureattributes">TEXCOORD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_TEX_COORD</td>
<td class="bdrL">vu32</td>
<td>REG_TEXT_COORD</td>
</tr>
<tr class=bg1>
<td>0400:048C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">VTX_16</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_VERTEX16</td>
<td class="bdrL">vu32</td>
<td>REG_VERTEX16</td>
</tr>
<tr class=bg0>
<td>0400:0490</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">VTX_10</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_VERTEX10</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0494</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">VTX_XY</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_VERTEX_XY</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0498</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">VTX_XZ</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_VERTEX_XZ</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:049C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">VTX_YZ</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_VERTEX_YZ</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:04A0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">VTX_DIFF</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_VERTEX_DIFF</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:04A4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonattributes">POLYGON_ATTR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_POLY_FORMAT</td>
<td class="bdrL">vu32</td>
<td>REG_POLY_FORMAT</td>
</tr>
<tr class=bg0>
<td>0400:04A8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtextureattributes">TEXIMAGE_PARAM</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_TEX_FORMAT</td>
<td class="bdrL">vu32</td>
<td>REG_TEXT_FORMAT</td>
</tr>
<tr class=bg1>
<td>0400:04AC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtextureattributes">PLTT_BASE</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_PAL_FORMAT</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:04C0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonlightparameters">DIF_AMB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_DIFFUSE_AMBIENT</td>
<td class="bdrL">vu32</td>
<td>REG_DIFFUSE_AMBIENT</td>
</tr>
<tr class=bg1>
<td>0400:04C4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonlightparameters">SPE_EMI</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_SPECULAR_EMISSION</td>
<td class="bdrL">vu32</td>
<td>REG_SPECULAR_EMISSION</td>
</tr>
<tr class=bg0>
<td>0400:04C8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonlightparameters">LIGHT_VECTOR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_LIGHT_VECTOR</td>
<td class="bdrL">vu32</td>
<td><b>REG_LIGHT_VECTOR</b></td>
</tr>
<tr class=bg1>
<td>0400:04CC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonlightparameters">LIGHT_COLOR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_LIGHT_COLOR</td>
<td class="bdrL">vu32</td>
<td><b>REG_LIGHT_COLOR</b></td>
</tr>
<tr class=bg0>
<td>0400:04D0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygonlightparameters">SHININESS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_SHININESS</td>
<td class="bdrL">vu32</td>
<td><b>REG_SHININESS</b></td>
</tr>
<tr class=bg1>
<td>0400:0500</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">BEGIN_VTXS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_BEGIN</td>
<td class="bdrL">vu32</td>
<td>REG_GFX_BEGIN</td>
</tr>
<tr class=bg0>
<td>0400:0504</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices">END_VTXS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_END</td>
<td class="bdrL">vu32</td>
<td>REG_GFX_END</td>
</tr>
<tr class=bg1>
<td>0400:0540</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3ddisplaycontrol">SWAP_BUFFERS</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_FLUSH</td>
<td class="bdrL">vu32</td>
<td>REG_GFX_FLUSH</td>
</tr>
<tr class=bg0>
<td>0400:0580</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3ddisplaycontrol">VIEWPORT</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_VIEWPORT</td>
<td class="bdrL">vu32</td>
<td>REG_GFX_VIEWPORT</td>
</tr>
<tr class=bg1>
<td>0400:05C0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtests">BOX_TEST</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">GFX_BOX_TEST</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:05C4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtests">POS_TEST</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_POS_TEST</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:05C8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtests">VEC_TEST</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0600</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dstatus">GXSTAT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">GFX_STATUS</td>
<td class="bdrL">vu32</td>
<td>REG_GFX_STATUS</td>
</tr>
<tr class=bg1>
<td>0400:0604</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dstatus">RAM_COUNT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0604</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">u16</td>
<td class="bdrR">GFX_POLYGON_RAM_USAGE</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0606</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">u16</td>
<td class="bdrR">GFX_VERTEX_RAM_USAGE</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0610</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3ddisplaycontrol">DISP_1DOT_DEPTH</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">u16</td>
<td class="bdrR">GFX_CUTOFF_DEPTH</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0620</td>
<td class="bdrL">10</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtests">POS_RESULT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">GFX_POS_RESULT&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0620</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">POINT_RESULT&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0630</td>
<td class="bdrL">6</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dtests">VEC_RESULT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">VECTOR_RESULT&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0640</td>
<td class="bdrL">40</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">CLIPMTX_RESULT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_READ_CLIP&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0680</td>
<td class="bdrL">24</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply">VECMTX_RESULT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR">MATRIX_READ_VECTOR&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:1000</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsvideobgmodescontrol">DISPCNT_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR"><b>REG_DISPCNT_SUB</b></td>
<td class="bdrL">vu32</td>
<td>SUB_DISPLAY_CR</td>
</tr>
<tr class=bg1>
<td>0400:1008</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">bg_attribute </td>
<td class="bdrR">BACKGROUND_SUB</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:1008</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">BGCTRL_SUB&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:1008</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG0CNT_SUB</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG0CNT_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG0_CR</b></td>
</tr>
<tr class=bg0>
<td>0400:100A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG1CNT_SUB</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG1CNT_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG1_CR</b></td>
</tr>
<tr class=bg1>
<td>0400:100C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG2CNT_SUB</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG2CNT_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG2_CR</b></td>
</tr>
<tr class=bg0>
<td>0400:100E</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgcontrol">BG3CNT_SUB</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG3CNT_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG3_CR</b></td>
</tr>
<tr class=bg1>
<td>0400:1010</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">REG_BGOFFSETS_SUB</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:1010</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG0HOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG0HOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG0_X0</b></td>
</tr>
<tr class=bg1>
<td>0400:1012</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG0VOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG0VOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG0_Y0</b></td>
</tr>
<tr class=bg0>
<td>0400:1014</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG1HOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG1HOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG1_X0</b></td>
</tr>
<tr class=bg1>
<td>0400:1016</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG1VOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG1VOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG1_Y0</b></td>
</tr>
<tr class=bg0>
<td>0400:1018</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG2HOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG2HOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG2_X0</b></td>
</tr>
<tr class=bg1>
<td>0400:101A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG2VOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG2VOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG2_Y0</b></td>
</tr>
<tr class=bg0>
<td>0400:101C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG3HOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG3HOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG3_X0</b></td>
</tr>
<tr class=bg1>
<td>0400:101E</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgscrolling">BG3VOFS_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_BG3VOFS_SUB</b></td>
<td class="bdrL">vu16</td>
<td><b>SUB_BG3_Y0</b></td>
</tr>
<tr class=bg0>
<td>0400:1020</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PA_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PA_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG2_XDX</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:1022</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PB_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PB_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG2_XDY</b><span class="fnote"><a href="#ft-nr3" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _YDX element.">(3)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:1024</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PC_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PC_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG2_YDX</b><span class="fnote"><a href="#ft-nr4" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _XDY element">(4)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:1026</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2PD_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG2PD_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG2_YDY</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:1028</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2X_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG2X_SUB</b></td>
<td class="bdrL">vs32</td>
<td><b>SUB_BG2_CX</b></td>
</tr>
<tr class=bg1>
<td>0400:102C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG2Y_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG2Y_SUB</b></td>
<td class="bdrL">vs32</td>
<td><b>SUB_BG2_CY</b></td>
</tr>
<tr class=bg0>
<td>0400:1030</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PA_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PA_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG3_XDX</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:1032</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PB_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PB_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG3_XDY</b><span class="fnote"><a href="#ft-nr3" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _YDX element.">(3)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:1034</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PC_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PC_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG3_YDX</b><span class="fnote"><a href="#ft-nr4" title="
Ambiguous terms: X/Y for both vector and coordinate.
Should probably be _XDY element">(4)</a></span></td>
</tr>
<tr class=bg1>
<td>0400:1036</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3PD_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs16</td>
<td class="bdrR"><b>REG_BG3PD_SUB</b></td>
<td class="bdrL">vs16</td>
<td class="rem"><b>SUB_BG3_YDY</b><span class="fnote"><a href="#ft-nr2" title="
Ambiguous terms: X/Y for both vector and coordinate.">(2)</a></span></td>
</tr>
<tr class=bg0>
<td>0400:1038</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3X_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG3X_SUB</b></td>
<td class="bdrL">vs32</td>
<td><b>SUB_BG3_CX</b></td>
</tr>
<tr class=bg1>
<td>0400:103C</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiobgrotationscaling">BG3Y_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/background.h</td>
<td class="bdrL">vs32</td>
<td class="bdrR"><b>REG_BG3Y_SUB</b></td>
<td class="bdrL">vs32</td>
<td><b>SUB_BG3_CY</b></td>
</tr>
<tr class=bg0>
<td>0400:1040</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN0H_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN0H_SUB</b></td>
</tr>
<tr class=bg1>
<td>0400:1040</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN0_X1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:1041</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN0_X0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:1042</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN1H_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN1H_SUB</b></td>
</tr>
<tr class=bg0>
<td>0400:1042</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN1_X1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:1043</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN1_X0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:1044</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN0V_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN0V_SUB</b></td>
</tr>
<tr class=bg1>
<td>0400:1044</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN0_Y1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:1045</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN0_Y0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:1046</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WIN1V_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td><b>REG_WIN1V_SUB</b></td>
</tr>
<tr class=bg0>
<td>0400:1046</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN1_Y1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:1047</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR">SUB_WIN1_Y0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:1048</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WININ_SUB</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">SUB_WIN_IN</td>
<td class="bdrL">vu16</td>
<td><b>REG_WININ_SUB</b></td>
</tr>
<tr class=bg1>
<td>0400:104A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiowindowfeature">WINOUT_SUB</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">SUB_WIN_OUT</td>
<td class="bdrL">vu16</td>
<td><b>REG_WINOUT_SUB</b></td>
</tr>
<tr class=bg0>
<td>0400:104C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiomosaicfunction">MOSAIC_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">SUB_MOSAIC_CR</td>
<td class="bdrL rem"><b>vu32</b><span class="fnote"><a href="#ft-nr5" title="
Should be vu16, not vu32">(5)</a></span></td>
<td><b>REG_MOSAIC_SUB</b></td>
</tr>
<tr class=bg1>
<td>0400:1050</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiocolorspecialeffects">BLDCNT_SUB</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">SUB_BLEND_CR</td>
<td class="bdrL">vu16</td>
<td>REG_BLDMOD_SUB</td>
</tr>
<tr class=bg0>
<td>0400:1052</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiocolorspecialeffects">BLDALPHA_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">SUB_BLEND_AB</td>
<td class="bdrL">vu16</td>
<td>REG_COLV_SUB</td>
</tr>
<tr class=bg1>
<td>0400:1054</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiocolorspecialeffects">BLDY_SUB</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">SUB_BLEND_Y</td>
<td class="bdrL">vu16</td>
<td>REG_COLY_SUB</td>
</tr>
<tr class=bg0>
<td>0400:106C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsvideostuff">MASTER_BRIGHT_SUB</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm9/video.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>SUB_BRIGHTNESS</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0410:0000</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCFIFORECV</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">REG_IPC_FIFO_RX</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_DATA</td>
</tr>
<tr class=bg0>
<td>0410:0010</td>
<td class="bdrL">4</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">CARD_DATA_RD</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_DATA_RD</td>
</tr>
</table>
<p><h2 id="sec-arm7">2
Arm 7 registers
</h2>
</p>
<table style="border:2px solid black;" cellpadding=2 cellspacing=0>
<col span=3 align=center>
<tr class=bg1 align=center>
<th>&nbsp;</th>
<th class="bdrL bdrR" colspan=3>GBATek / official</th>
<th class="bdrL bdrR" colspan=3>libnds primary</th>
<th class="bdrL" colspan=2>libnds alternate</th>
</tr>
<tr class=bg1 align=center>
<th class="bdrB">addr</th>
<th class="bdrL bdrB">size</th>
<th class="bdrL bdrB">name</th>
<th class="bdrL bdrR bdrB">name</th>
<th class="bdrL bdrB">file</th>
<th class="bdrL bdrB">type</th>
<th class="bdrR bdrB">name</th>
<th class="bdrL bdrB">type</th>
<th class="bdrB">name</th>
</tr>
<tr class=bg1>
<td>0400:0004</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiointerruptsandstatus">DISPSTAT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_DISPSTAT</b></td>
<td class="bdrL">vu16</td>
<td>DISP_SR</td>
</tr>
<tr class=bg0>
<td>0400:0006</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#lcdiointerruptsandstatus">VCOUNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_VCOUNT</b></td>
<td class="bdrL">vu16</td>
<td>DISP_Y</td>
</tr>
<tr class=bg1>
<td>0400:00B0</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA_SRC(n)</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg0>
<td>0400:00B4</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA_DEST(n)</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg1>
<td>0400:00B8</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA_CR(n)</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg0>
<td>0400:00B0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA0SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA0_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA0SAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00B4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA0DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA0_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA0DAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00B8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA0CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA0_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA0CNT</b></td>
</tr>
<tr class=bg1>
<td>0400:00BC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA1SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA1_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA1SAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00C0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA1DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA1_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA1DAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00C4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA1CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA1_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA1CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:00C8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA2SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA2_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA2SAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00CC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA2DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA2_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA2DAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00D0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA2CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA2_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA2CNT</b></td>
</tr>
<tr class=bg1>
<td>0400:00D4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA3SAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA3_SRC</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA3SAD</b></td>
</tr>
<tr class=bg0>
<td>0400:00D8</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA3DAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA3_DEST</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA3DAD</b></td>
</tr>
<tr class=bg1>
<td>0400:00DC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsdmatransfers">DMA3CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">dma.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">DMA3_CR</td>
<td class="bdrL">vu32</td>
<td><b>REG_DMA3CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:0100</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER_DATA(n)</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg1>
<td>0400:0102</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER_CR(n)</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg0>
<td>0400:0100</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM0D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER0_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM0D</b></td>
</tr>
<tr class=bg1>
<td>0400:0102</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM0CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER0_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM0CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:0104</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM1D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER1_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM1D</b></td>
</tr>
<tr class=bg1>
<td>0400:0106</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM1CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER1_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM1CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:0108</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM2D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER2_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM2D</b></td>
</tr>
<tr class=bg1>
<td>0400:010A</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM2CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER2_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM2CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:010C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM3D</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER3_DATA</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM3D</b></td>
</tr>
<tr class=bg1>
<td>0400:010E</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbatimers">TM3CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">timer.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">TIMER3_CR</td>
<td class="bdrL">vu16</td>
<td><b>REG_TM3CNT</b></td>
</tr>
<tr class=bg0>
<td>0400:0120</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsabsentlinkport">SIODATA32</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">SIO_DATA32</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg1>
<td>0400:0120</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SIO_MULTI_0</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0122</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SIO_MULTI_1</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0124</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SIO_MULTI_2</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0126</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SIO_MULTI_3</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0128</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsabsentlinkport">SIOCNT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">REG_SIOCNT</td>
<td class="bdrL">vu16</td>
<td><b>REG_SIOCNT</b></td>
</tr>
<tr class=bg0>
<td>0400:012A</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">SIO_DATA8</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:012A</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SIO_MULTI_SEND</td>
<td class="bdrL">vu16</td>
<td><b>REG_SIOMLT_SEND</b></td>
</tr>
<tr class=bg0>
<td>0400:012C</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsabsentlinkport">SIOSEL</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td><b>&nbsp;</b></td>
</tr>
<tr class=bg1>
<td>0400:0130</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbakeypadinput">KEYINPUT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_KEYINPUT</b></td>
<td class="bdrL">vuint16</td>
<td>KEYS</td>
</tr>
<tr class=bg0>
<td>0400:0132</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbakeypadinput">KEYCNT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_KEYCNT</b></td>
<td class="bdrL">vuint16</td>
<td>KEYS_CR</td>
</tr>
<tr class=bg1>
<td>0400:0134</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsabsentlinkport">RCNT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_RCNT</b></td>
<td class="bdrL">vu16</td>
<td>REG_RCNT</td>
</tr>
<tr class=bg0>
<td>0400:0136</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dskeypad">EXTKEYIN</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">REG_KEYXY</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0138</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsrealtimeclockrtc">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">RTC_CR</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0138</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL"> vuint8</td>
<td class="bdrR">RTC_CR8</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0140</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsabsentlinkport">JOYCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">vu16</td>
<td>REG_HS_CTRL</td>
</tr>
<tr class=bg0>
<td>0400:0180</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCSYNC</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">REG_IPC_SYNC</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0184</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCFIFOCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">REG_IPC_FIFO_CR</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0188</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCFIFOSEND</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">REG_IPC_FIFO_TX</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:01A0</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">AUXSPICNT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">CARD_CR1</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_CR1</td>
</tr>
<tr class=bg0>
<td>0400:01A1</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">CARD_CR1H</td>
<td class="bdrL">vu8</td>
<td>REG_CARD_CR1H</td>
</tr>
<tr class=bg1>
<td>0400:01A2</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">AUXSPIDATA</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">CARD_EEPDATA</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:01A4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">ROMCTRL</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">CARD_CR2</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_CR2</td>
</tr>
<tr class=bg1>
<td>0400:01A8</td>
<td class="bdrL">8</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">CARD_COMMAND&nbsp;</td>
<td class="bdrL">vu8</td>
<td>REG_CARD_COMMAND&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:01B0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">CARD_1B0</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_1B0</td>
</tr>
<tr class=bg1>
<td>0400:01B4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">CARD_1B4</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_1B4</td>
</tr>
<tr class=bg0>
<td>0400:01B8</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">CARD_1B8</td>
<td class="bdrL">vu16</td>
<td>REG_CARD_1B8</td>
</tr>
<tr class=bg1>
<td>0400:01BA</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">CARD_1BA</td>
<td class="bdrL">vu16</td>
<td>REG_CARD_1BA</td>
</tr>
<tr class=bg0>
<td>0400:01C0</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsserialperipheralinterfacebusspi">SPICNT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_SPICNT</b></td>
<td class="bdrL">vuint16</td>
<td>SERIAL_CR</td>
</tr>
<tr class=bg1>
<td>0400:01C2</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsserialperipheralinterfacebusspi">SPIDATA</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/serial.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_SPIDATA</b></td>
<td class="bdrL">vuint16</td>
<td>SERIAL_DATA</td>
</tr>
<tr class=bg0>
<td>0400:0204</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolcartridgesandmainram">EXMEMSTAT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">memory.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_EXMEMSTAT</b></td>
<td class="bdrL">vuint16</td>
<td>WAIT_CR</td>
</tr>
<tr class=bg1>
<td>0400:0206</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dspowermanagement">WIFIWAITCNT</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0208</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#gbainterruptcontrol">IME</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">interrupts.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR"><b>REG_IME</b></td>
<td class="bdrL">vuint16</td>
<td>IME</td>
</tr>
<tr class=bg1>
<td>0400:0210</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterrupts">IE</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">interrupts.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR"><b>REG_IE</b></td>
<td class="bdrL">vuint32</td>
<td>IE</td>
</tr>
<tr class=bg0>
<td>0400:0214</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterrupts">IF</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">interrupts.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR"><b>REG_IF</b></td>
<td class="bdrL">vuint32</td>
<td>IF</td>
</tr>
<tr class=bg1>
<td>0400:0240</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolvram">VRAMSTAT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0241</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolwram">WRAMSTAT</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0300</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dspowermanagement">POSTFLG</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">HALT_CR</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0301</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dspowermanagement">HALTCNT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrR">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0304</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dspowermanagement">POWCNT2</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">system.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR">REG_POWERCNT</td>
<td class="bdrL">vu16</td>
<td>POWER_CR</td>
</tr>
<tr class=bg0>
<td>0400:0308</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsmemorycontrolbios">BIOSPROT</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">memory.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">PROTECTION</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:04&#215;0</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundchannels015">SOUNDxCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">SCHANNEL_CR(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0400</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">SCHANNEL_VOL(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0402</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">SCHANNEL_PAN(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:04&#215;4</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundchannels015">SOUNDxSAD</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">SCHANNEL_SOURCE(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:04&#215;8</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundchannels015">SOUNDxTMR</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vint16</td>
<td class="bdrR">SCHANNEL_TIMER(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:04xA</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundchannels015">SOUNDxPNT</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SCHANNEL_REPEAT_POINT(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:04xC</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundchannels015">SOUNDxLEN</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">SCHANNEL_LENGTH(n)</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0500</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcontrolregisters">SOUNDCNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SOUND_CR</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0500</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL">&nbsp;</td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint8</td>
<td class="bdrR">SOUND_MASTER_VOL</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0504</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcontrolregisters">SOUNDBIAS</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vuint16</td>
<td class="bdrR">SOUND_BIAS</td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0508</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcapture">SNDCAP0CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR"><b>REG_SNDCAP0CNT</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0509</td>
<td class="bdrL">1</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcapture">SNDCAP1CNT</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vu8</td>
<td class="bdrR"><b>REG_SNDCAP1CNT</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0510</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcapture">SNDCAP0DAD</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR"><b>REG_SNDCAP0DAD</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:0514</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcapture">SNDCAP0LEN</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_SNDCAP0LEN</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0400:0518</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcapture">SNDCAP1DAD</a></td>
<td class="bdrL bdrR">R/W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR"><b>REG_SNDCAP1DAD</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg0>
<td>0400:051C</td>
<td class="bdrL">2</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dssoundcapture">SNDCAP1LEN</a></td>
<td class="bdrL bdrR">W</td>
<td class="bdrL">arm7/audio.h</td>
<td class="bdrL">vu16</td>
<td class="bdrR"><b>REG_SNDCAP1LEN</b></td>
<td class="bdrL">&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class=bg1>
<td>0410:0000</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dsinterprocesscommunicationipc">IPCFIFORECV</a></td>
<td class="bdrL bdrR">R</td>
<td class="bdrL">ipc.h</td>
<td class="bdrL">vu32</td>
<td class="bdrR">REG_IPC_FIFO_RX</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_DATA</td>
</tr>
<tr class=bg0>
<td>0410:0010</td>
<td class="bdrL">4</td>
<td class="bdrL"><a href="http://nocash.emubase.de/gbatek.htm#dscartridgeioports">&nbsp;</a></td>
<td class="bdrL bdrR">&nbsp;</td>
<td class="bdrL">card.h</td>
<td class="bdrL">vuint32</td>
<td class="bdrR">CARD_DATA_RD</td>
<td class="bdrL">vu32</td>
<td>REG_CARD_DATA_RD</td>
</tr>
</table>
<hr /><div class="footnotes">
<h5>Notes:</h5>
<ol>
<li id="ft-nr1"> 
  See also <code>BG_TILE_BASE</code> and<br />
<code>BG_TILE_RAM</code>, for the <code>REG_BGxCNT</code> macro and<br />
the VRAM address, respectively. Yeah, you can tell because obviously<br />
RAM means memory, but it&#8217;s still an easy mistake to make, especially<br />
since the VRAM areas are called &ldquo;base&rdquo; as well.
</li>
<li id="ft-nr2"> 
  <br />
Ambiguous terms: X/Y for both vector and coordinate.
</li>
<li id="ft-nr3"> 
  <br />
Ambiguous terms: X/Y for both vector and coordinate.<br />
Should probably be _YDX element.
</li>
<li id="ft-nr4"> 
  <br />
Ambiguous terms: X/Y for both vector and coordinate.<br />
Should probably be _XDY element
</li>
<li id="ft-nr5"> 
  <br />
Should be vu16, not vu32
</li>
<li id="ft-nr6"> 
  <br />
Should be struct
</li>
</ol>
</div
<hr />
]]></content:encoded>
			<wfw:commentRss>http://www.coranac.com/2008/09/nds-register-overview/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

<!--
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
</head>
<body>
<p>
My database has called in sick. Please imagine some 
annoying elevator tune till he gets back.
</p>
<p>
<small>[[Doo-di-doo tooo. Dum-di-dum-di-doo-dooo.]]</small>
</p>
</body>
</html>

-->
