<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>mGBA</title>
    <description>mGBA is an open-source Game Boy Advance emulator, copyright &amp;copy; 2013&amp;ndash;2017 Jeffrey Pfau. This project is not affiliated in any way with Nintendo. Game Boy Advance is a registered trademark of Nintendo Co., Ltd.</description>
    <link>https://mgba.io/</link>
    <atom:link href="https://mgba.io/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Tue, 24 Jul 2018 14:00:16 -0700</pubDate>
    <lastBuildDate>Tue, 24 Jul 2018 14:00:16 -0700</lastBuildDate>
    <generator>Jekyll v3.6.2</generator>
    
      <item>
        <title>mGBA 0.6.3</title>
        <description>&lt;p&gt;A new release of mGBA, version 0.6.3, is available. This version is a bugfix release to address some major audio and video regressions that snuck into 0.6.2. As such, all users of 0.6.2 are encouraged to update, especially if they are playing Game Boy games.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Bugfixes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;GB Audio: Revert unsigned audio changes&lt;/li&gt;
  &lt;li&gt;GB Video: Fix bad merge (fixes &lt;a href=&quot;https://mgba.io/i/1040&quot;&gt;#1040&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Video: Fix OBJ blending regression (fixes &lt;a href=&quot;mgba.io/i/1037&quot;&gt;#1037&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get it now in the &lt;a href=&quot;/downloads.html&quot;&gt;Downloads&lt;/a&gt; section. Binaries are available for Windows, Ubuntu, macOS, 3DS, Vita, and Wii, and the source code is available for all other platforms.&lt;/p&gt;
</description>
        <pubDate>Sat, 14 Apr 2018 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2018/04/14/mgba-0.6.3/</link>
        <guid isPermaLink="true">https://mgba.io/2018/04/14/mgba-0.6.3/</guid>
        
        <category>announcement</category>
        
        <category>release</category>
        
        
      </item>
    
      <item>
        <title>mGBA 0.6.2</title>
        <description>&lt;p&gt;A new release of mGBA, version 0.6.2, is available. This version is a bugfix release, which contains many stability and accuracy fixes. An extensive list of changes follows after the cut.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Bugfixes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Core: Fix ROM patches not being unloaded when disabled (fixes mgba.io/i/962)&lt;/li&gt;
  &lt;li&gt;3DS: Fix opening files in directory names with trailing slashes&lt;/li&gt;
  &lt;li&gt;LR35902: Fix watchpoints not reporting new value&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix MBC2 saves (fixes mgba.io/i/954)&lt;/li&gt;
  &lt;li&gt;GB Memory: HDMAs should not start when LCD is off (fixes mgba.io/i/310)&lt;/li&gt;
  &lt;li&gt;GB Memory: Fix OAM DMA blocking regions (fixes mgba.io/i/1013)&lt;/li&gt;
  &lt;li&gt;GB Video: Only trigger STAT write IRQs when screen is on (fixes mgba.io/i/912)&lt;/li&gt;
  &lt;li&gt;GBA: Fix some GBA ROM misdetection (fixes mgba.io/i/978)&lt;/li&gt;
  &lt;li&gt;GBA: Fix SharkPort saves for EEPROM games&lt;/li&gt;
  &lt;li&gt;GBA Audio: Increase PSG volume (fixes mgba.io/i/932)&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Fix incorrect exit condition in LZ77&lt;/li&gt;
  &lt;li&gt;GBA Cheats: Fix PARv3 slide codes (fixes mgba.io/i/919)&lt;/li&gt;
  &lt;li&gt;GBA Cheats: Fix slide codes not initializing properly&lt;/li&gt;
  &lt;li&gt;GBA DMA: ROM reads are forced to increment&lt;/li&gt;
  &lt;li&gt;GBA Hardware: RTC accuracy improvements&lt;/li&gt;
  &lt;li&gt;GBA I/O: Fix writing to DISPCNT CGB flag (fixes mgba.io/i/902)&lt;/li&gt;
  &lt;li&gt;GBA Memory: Fix copy-on-write memory leak&lt;/li&gt;
  &lt;li&gt;GBA Memory: Partially revert prefetch changes (fixes mgba.io/i/840)&lt;/li&gt;
  &lt;li&gt;GBA Savedata: Fix crash when resizing flash&lt;/li&gt;
  &lt;li&gt;GBA Video: Force align 256-color tiles&lt;/li&gt;
  &lt;li&gt;GBA Video: OBJWIN can change blend params after OBJ is drawn (fixes mgba.io/i/921)&lt;/li&gt;
  &lt;li&gt;PSP2: Fix issues causing poor audio&lt;/li&gt;
  &lt;li&gt;Python: Fix package directory&lt;/li&gt;
  &lt;li&gt;Qt: Fix locale being set to English on settings save (fixes mgba.io/i/906)&lt;/li&gt;
  &lt;li&gt;Qt: Fix opening in fullscreen (fixes mgba.io/i/993)&lt;/li&gt;
  &lt;li&gt;Wii: Fix screen tear when unpausing&lt;/li&gt;
  &lt;li&gt;Wii: Fix various setup and teardown drawing issues (fixes mgba.io/i/988)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Misc:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;3DS: Scale font based on glyph heights (fixes mgba.io/i/961)&lt;/li&gt;
  &lt;li&gt;GB MBC: Remove erroneous bank 0 wrapping&lt;/li&gt;
  &lt;li&gt;GBA: Improve multiboot image detection&lt;/li&gt;
  &lt;li&gt;PSP2: Use system enter key by default&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get it now in the &lt;a href=&quot;/downloads.html&quot;&gt;Downloads&lt;/a&gt; section. Binaries are available for Windows, Ubuntu, macOS, 3DS, Vita, and Wii, and the source code is available for all other platforms.&lt;/p&gt;
</description>
        <pubDate>Tue, 03 Apr 2018 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2018/04/03/mgba-0.6.2/</link>
        <guid isPermaLink="true">https://mgba.io/2018/04/03/mgba-0.6.2/</guid>
        
        <category>announcement</category>
        
        <category>release</category>
        
        
      </item>
    
      <item>
        <title>Revisiting &quot;Holy Grail&quot; Bugs in Emulation</title>
        <description>&lt;p&gt;Debugging is not an easy task, and Holy Grail bugs are an exceptionally difficult class of bugs to squash. Discovering the root issue, figuring out the error in logic leading to the issue, and finally stamping out the issue &lt;em&gt;without introducing new issues&lt;/em&gt; can be a long and arduous process. Sometimes one part can be easier than others, and sometimes every step is difficult. But common to all bugs is the required time, dedication, and ingenuity required.&lt;/p&gt;

&lt;p&gt;It has been been a few months writing my first two articles on Holy Grail bugs, and it would seem that the articles piqued interest in these bugs, possibly bringing renewed dedication and new insights and ingenuity into the process. As such, some of the biggest, toughest bugs across multiple systems have now been solved, once and for all.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-phantom-of-pinball-fantasies&quot;&gt;The Phantom of Pinball Fantasies&lt;/h2&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/sameboy-pinball-fantasies.png&quot; alt=&quot;Pinball Fantasies running properly inside SameBoy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I had previously written about a bugbear for Game Boy emulation, &lt;a href=&quot;/2017/05/29/holy-grail-bugs/#pinball-fantasies&quot;&gt;Pinball Fantasies&lt;/a&gt;. With its complicated sequence of tightly timed IRQs &lt;em&gt;almost&lt;/em&gt; always working, but one single misfire being enough to take down the entire game, it seemed like this bug might never be squashed.&lt;/p&gt;

&lt;p&gt;After helping author the Pinball Fantasies section in the previous article, I noticed that Lior became very focused on solving the issue once and for all. A few months later, sure enough, he did solve the issue. Not only did it require accurate emulation of video timing and stat IRQ blocking, already two very difficult topics, the process brought to light the fact that Game Boy interrupt timing is far more complex than previously believed.&lt;/p&gt;

&lt;p&gt;Gekkio released information and a test case demonstrating some very peculiar behavior involving how interrupts are processed: the cycle in which an interrupt is triggered is &lt;em&gt;not&lt;/em&gt; the same cycle in which the type of interrupt triggered is observed. There is a one cycle window in which you can confuse the Game Boy’s interrupt system by changing interrupt parameters.&lt;/p&gt;

&lt;p&gt;Interrupt processing on the Game Boy has three important pieces. The &lt;code class=&quot;highlighter-rouge&quot;&gt;EI&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;DI&lt;/code&gt; instructions enable and disable interrupts globally, adjusting what is known as the &lt;code class=&quot;highlighter-rouge&quot;&gt;IME&lt;/code&gt; register; the specific interrupt types that are enabled, known as the &lt;code class=&quot;highlighter-rouge&quot;&gt;IE&lt;/code&gt; register; and the list of currently asserted interrupts, known as the &lt;code class=&quot;highlighter-rouge&quot;&gt;IF&lt;/code&gt; register. The hypothetical flow for interrupt processing is fairly simple:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Check if &lt;code class=&quot;highlighter-rouge&quot;&gt;IME&lt;/code&gt; is on—that is, if interrupts are enabled globally. if not, continue normally.&lt;/li&gt;
  &lt;li&gt;Check if any bits set in &lt;code class=&quot;highlighter-rouge&quot;&gt;IF&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;IE&lt;/code&gt; overlap by doing a bitwise &lt;code class=&quot;highlighter-rouge&quot;&gt;AND&lt;/code&gt;, and iff so an interrupt is triggered.&lt;/li&gt;
  &lt;li&gt;The least significant bit set of &lt;code class=&quot;highlighter-rouge&quot;&gt;IF AND IE&lt;/code&gt; informs which interrupt is triggered.&lt;/li&gt;
  &lt;li&gt;Jump to the appropriate interrupt vector in memory for that interrupt type.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The big revelation here was that steps 2 and 3 &lt;em&gt;do not occur at the same time&lt;/em&gt;. If you can manage to assert &lt;code class=&quot;highlighter-rouge&quot;&gt;IF AND IE&lt;/code&gt; in one cycle and &lt;em&gt;change&lt;/em&gt; one of the values before the interrupt vector jump occurs, strange things happen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If the least significant bit of &lt;code class=&quot;highlighter-rouge&quot;&gt;IF AND IE&lt;/code&gt; changes during dispatch the jump is to the interrupt vector specified after the change.&lt;/li&gt;
  &lt;li&gt;Or, if &lt;code class=&quot;highlighter-rouge&quot;&gt;IF AND IE&lt;/code&gt; is zero during dispatch the CPU jumps to the reset vector at 0 instead of an interrupt vector.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a hyper-specific edge case that, much like other hyper-specific edge cases, seems to affect only one or two games. In this case, those games are Pinball Fantasies and Pinball Deluxe, which both use the same engine code.&lt;/p&gt;

&lt;p&gt;Further, if this behavior is incorrectly emulated by assuming that asserting and then de-asserting the interrupt during the same instruction starts dispatch many games start to crash, such as &lt;a href=&quot;https://mgba.io/i/1000&quot;&gt;Pokémon Pinball&lt;/a&gt;. Interrupt dispatch should only occur if the IRQ is asserted at the end of an instruction, and this edge case only occurs if the assertion changes mid-dispatch.&lt;/p&gt;

&lt;p&gt;Lior also discovered that interrupt timing can appear to be delayed by a cycle while halted, but it depends on both the specific model of Game Boy and specific interrupt raised.&lt;/p&gt;

&lt;p&gt;While it may sound strange for an interrupt to be delayed by one cycle, the exact reason for such a thing happening is fairly simple. The LR35902 processor used in the Game Boy has two different types of timings: M-cycles, which are the instruction-level clock and occur at quarter of the master clock frequency, and T-states, which occur every master clock cycle and are sometimes referred to as sub-cycles due to the fact that they make up the separate steps taken by instructions. While an M-cycle can be thought of as the CPU performing one complete task, e.g. adding two numbers, T-states are even lower level. For addition, it may look something like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Load value in register &lt;code class=&quot;highlighter-rouge&quot;&gt;B&lt;/code&gt; into the &lt;a href=&quot;https://en.wikipedia.org/wiki/Arithmetic_logic_unit&quot;&gt;arithmetic logic unit&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Load value in register &lt;code class=&quot;highlighter-rouge&quot;&gt;C&lt;/code&gt; into the ALU.&lt;/li&gt;
  &lt;li&gt;Perform the addition using the ALU.&lt;/li&gt;
  &lt;li&gt;Store the result of the addition into register &lt;code class=&quot;highlighter-rouge&quot;&gt;A&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is only an example however; it’s significantly less clear on the Game Boy how T-states lay out individual instructions and seems to be more relevant to how memory operations are performed than ALU operations.&lt;/p&gt;

&lt;p&gt;So clearly if an interrupt is triggered it has to happen on one of these four T-states, right? All a delayed interrupt would mean is that the T-state on which an interrupt request is processed is before the cycle in which that IRQ is asserted. Take this example of T-state timing:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;IF: 00&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;IE: 01&lt;/code&gt;, &lt;em&gt;No IRQ asserted&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;IF: 00&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;IE: 01&lt;/code&gt;, &lt;em&gt;No IRQ asserted&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;IF: 01&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;IE: 01&lt;/code&gt;, &lt;em&gt;IRQ asserted&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;IF: 01&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;IE: 01&lt;/code&gt;, &lt;em&gt;IRQ asserted&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the IRQ check happens on T-state 3 or 4 then the IRQ occurs before the next instruction is processed. However, if the IRQ check happens on T-state 1 or 2 then the IRQ would appear to be delayed one cycle despite being asserted during the “previous” instruction. Indeed, different interrupt sources will assert on different T-state.&lt;/p&gt;

&lt;p&gt;Due to the complexities involved in emulating T-states, plus the lack of requirement of emulating T-states at all for 99% of games, many emulators &lt;em&gt;do not emulate at a T-state level&lt;/em&gt;, making this type of accuracy difficult to attain without “tricks” or hacks of some sort. But again, it seemed to be needed for Pinball Fantasies.&lt;/p&gt;

&lt;p&gt;With most of that information now verified, Pinball Fantasies now runs in SameBoy. The same cannot be said of mGBA however, due to the current mess of the video timing implementation. Hopefully soon it will work in mGBA too, but for now it’s still beyond all but one accurate emulator.&lt;/p&gt;

&lt;h2 id=&quot;the-great-gba-dma-disaster&quot;&gt;The Great GBA DMA Disaster&lt;/h2&gt;

&lt;p&gt;Although I did not write a section on it in the previous articles on Holy Grail bugs, there was one bug that perplexed me for two years. Namely, there are a handful of games that use DMA from invalid memory (usually from the address 0) to clear regions of memory. VBA implements this pretty simply: if you’re doing a DMA from 0, then write 0 to the destination. This seemed sort of sensible, until I noticed that I could not get this same behavior to reproduce on actual hardware, no matter the configuration I used. The behavior was always different.&lt;/p&gt;

&lt;p&gt;Let’s take a step back for a bit so we can truly understand how bizarre this bug is. Some of you reading this article probably don’t even know what a DMA is. It stands for &lt;a href=&quot;https://en.wikipedia.org/wiki/Direct_memory_access&quot;&gt;direct memory access&lt;/a&gt; and refers to a piece of hardware that can perform memory transfers without using the main processor. The Game Boy Advance contains four different DMA channels, numbered 0 through 3. Each DMA channel can be programmed to do memory copies between addresses with various different start timings, such as immediately starting, or start on horizontal blanking. However, only one DMA can be transferring at a time, leaving the other suspended until it completes. Further, the main CPU is also paused while this happens.&lt;/p&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/lufia-scanlines.png&quot; alt=&quot;Lufia tries to do a fade effect. Emphasis on &amp;quot;tries&amp;quot;.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The main uses for DMA on the GBA are a small list: transferring large chunks of data from the cartridge into main memory, doing EEPROM read/writes, copying video parameters every scanline (this is for example one way to create the faux-3D “mode 7” effects), or buffering audio. Different DMA channels have special purposes or restrictions, too, such as only DMAs 1 and 2 can be used for audio buffering, and DMA 0 cannot access the cartridge bus at all. DMA channel 3 is mostly used for general purpose “immediate” transfers, channels 1 and 2 for the two different audio channels, and channel 0 gets very little use.&lt;/p&gt;

&lt;p&gt;All of the DMA channels can access RAM, but beyond that things vary. Documentation available online says that only DMA channel 3 can access the ROM, and none of the DMA channels can access the BIOS region of memory. But no documents refer to what happens if you &lt;em&gt;try&lt;/em&gt; to do this. As previously mentioned, VBA writes 0 to the DMA’s destination, but what happens on hardware is not only nearly-completely detached from this implementation but is also far, far more complicated. In fact, when I first started trying to reproduce this bug on hardware, I &lt;em&gt;never&lt;/em&gt; got zeroes filling the destination memory.&lt;/p&gt;

&lt;p&gt;The first thing I observed was that trying to write an invalid source address to the DMA configuration register resulted in the DMA not actually updating the source address. After doing a DMA copy from a valid region later DMAs from an invalid region appeared to do another DMA from the old source. This seemed like a perfectly reasonable explanation at first: the reconfiguration just fails so it uses the old configuration. Yet this didn’t explain why several games expected zeroes to be written to the destination.&lt;/p&gt;

&lt;p&gt;I sat on this bug for a while because I knew I needed to write hardware tests to figure out what was actually going on, but oddly enough those tests just seemed to prove that what I was doing was &lt;em&gt;almost&lt;/em&gt; right. Never did I get out zeroes; I always got memory from the previous DMA’s source in the destination. Although these tests did prove fruitful for other reasons, as they showed a few shortcomings in documentation online, no matter how many tests I wrote or DMA configurations I directly took from which that did this, the result never was zeroes.&lt;/p&gt;

&lt;p&gt;But then I noticed something that could only be explained in a very specific way. Namely, when doing a 32-bit transfer it would write out the same 16-bit value mirrored. But that specific value did not appear anywhere in the source. The 16-bit value appeared as part of a larger chunk of memory, but I was doing a 32-bit transfer. It was then that I realized that what’s going on isn’t that the source address isn’t being updated, it’s that the source data is being cached. The last value that the previous DMA copied was written out repeatedly. And due to the nature of the other tests I’d written this was never actually demonstrated.&lt;/p&gt;

&lt;p&gt;It had seemed like the pieces were starting to fall into place…but I still wasn’t getting zeroes. And the games definitely expected zeroes from these configuration. Even looking at the previous transfers, they didn’t end with zeroes. There were still major pieces missing.&lt;/p&gt;

&lt;p&gt;Then it clicked. Only one DMA can be running at a time. The cached value from the previous transfer &lt;em&gt;is shared among all DMA channels&lt;/em&gt;. The DMA channels aren’t completely independent, so when one DMA finishes a transfer its last value is left in the cache, so if another DMA cannot access its source address…it uses the other DMA’s last value! I quickly tried implementing this and what I discovered was that suddenly every single one of the bugs relating to invalid DMA source addresses was fixed, all at once.&lt;/p&gt;

&lt;p&gt;The awful, nasty truth is just that the DMA transfer register is shared between all four DMA channels. Since the audio DMAs were generally copying silence when this zero-writing occurs the cached value in the DMA buffer can be abused to write as many zeroes as desired wherever into memory.&lt;/p&gt;

&lt;p&gt;Meanwhile, VBA just writes zeroes because that’s what the games use this edge case for. But now I know why.&lt;/p&gt;

&lt;h2 id=&quot;the-improbable-but-correct-lady-sia-bugfix&quot;&gt;The Improbable But Correct Lady Sia Bugfix&lt;/h2&gt;

&lt;p class=&quot;gallery&quot;&gt;&lt;img src=&quot;/assets/lady-sia.png&quot; alt=&quot;Lady Sia glitch&quot; /&gt; &lt;img src=&quot;/assets/lady-sia-noglitch.png&quot; alt=&quot;Lady Sia fixed&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the first Holy Grail bugs article I said the &lt;a href=&quot;/2017/05/29/holy-grail-bugs/#lady-sia&quot;&gt;Lady Sia bug&lt;/a&gt; would haunt me to my grave, but I’m still alive and this bug isn’t. And despite my dramatic take on the magnitude of this bug the solution ended up being quite mundane. Slightly strange, but still mundane: my “best guess” in the previous article was that enabling a background layer was just latched for three scanlines, but it seemed like a particularly strange thing to take that long. Almost everything either take effect the next scanline or the next frame. Three scanlines was an obvious outlier so it sounded immediately wrong.&lt;/p&gt;

&lt;p&gt;But when talking about this bug with another emulator developer, they dug up posts on the GBAdev forums about “garbage” for a few scanlines when meddling with background layers being enabled. So maybe it wasn’t outlandish after all. Well, I finally got around to writing a hardware test to see what the exact behavior of enabling a background layer mid-frame would be and…yep, it takes three scanlines. Sometimes fixes to high profile bugs end up being entirely anticlimactic, and indeed that was the case here.&lt;/p&gt;

&lt;p&gt;Turns out fixing this bug also fixed &lt;a href=&quot;https://mgba.io/b/232&quot;&gt;another long-standing bug&lt;/a&gt;. Go figure.&lt;/p&gt;

&lt;h2 id=&quot;a-slew-of-corrections-on-the-nintendo-ds&quot;&gt;A Slew of Corrections on the Nintendo DS&lt;/h2&gt;

&lt;p&gt;Before going much further I should write up some corrections to the previous article. I mentioned quite a number of DS games and included some recent developments in terms of bugfixes. However, I wrote that section of the previous article over a month prior to releasing the article and the landscape had shifted in the meantime. For example, the Tongari Boushi loading bug had been fixed in DeSmuME in addition to melonDS before I released the article, but around the same time as when I was writing it.&lt;/p&gt;

&lt;p&gt;Further, I was using the most recent release of DeSmuME to research some of the existing bugs, but that release is apparently quite out of date so things had improved even on some of those bugs too.&lt;/p&gt;

&lt;p&gt;There was also some confusion about which of the Pokémon Black/White bugs were anti-piracy measures versus just regular old emulation bugs, so I’d like to set straight what I believe to be the case:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Booting at all requires partial emulation of the modified cartridge SPI bus. This is not an anti-piracy technique, most likely; it’s just making sure that saving and loading will work. There are codes floating around that will bypass this screen but as a result saving/loading are completely broken.&lt;/li&gt;
  &lt;li&gt;Requiring the IR sensor to reply when getting EXP &lt;em&gt;does&lt;/em&gt; sound like an anti-piracy technique to me, especially since I’m not aware of there being any IR functionality involved with single player battles.&lt;/li&gt;
  &lt;li&gt;The game crashing if cartridge timing is wrong is also likely not anti-piracy and just a basic gameplay/level streaming technique that will break if the cartridge doesn’t have the same timing characteristics as the hardware it was written for. This sort of thing is actually quite common on consoles where you can get texture pops or missing assets if your disk drive starts aging, and this is likely just another manifestation of the same principle.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-dénouement-or-something-like-one&quot;&gt;The Dénouement, or Something Like One&lt;/h2&gt;

&lt;p&gt;While us emulator developers keep chugging on bugs, the landscape keeps changing. Emulators for newer consoles are shaping up more and more each day, and seemingly impossible bugs get squashed more and more. Lior has recently been making great strides with Game Boy emulation in SameBoy, implementing previously unknown behaviors in the APU and PPU, and compatibility in newer generation emulators like RPCS3 has been improving by leaps and bounds.&lt;/p&gt;

&lt;p&gt;Though it’s nearly impossibly difficult to emulate a console perfectly, at least without a hardware clone, we get closer and closer each day.&lt;/p&gt;

&lt;h2 id=&quot;postscript-a-several-month-late-explanation&quot;&gt;Postscript: A Several Month Late Explanation&lt;/h2&gt;

&lt;p&gt;Some of you out there may have also noticed that there hasn’t been a Patreon article since July, or that the Patreon was suspended at the last minute one month, or that mGBA progress has slowed down significantly.&lt;/p&gt;

&lt;p&gt;I have had significantly less time recently to work on my hobby projects since I started a new job in August. While I do not intend to drop mGBA nor stop writing articles I am severely limited in how much I can do. As a result:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The monthly article series is over. I’ll still write articles occasionally but I just don’t have the time to do them anymore with any regularity.&lt;/li&gt;
  &lt;li&gt;My DS emulator, medusa, is suspended until further notice. I’d like to revisit it at some point, but until then there are several new DS emulators to look forward to in the meantime.&lt;/li&gt;
  &lt;li&gt;Major mGBA releases are going to be very slow for the foreseeable future. Sorry, I just can’t fit working on large features into my schedule anymore so things are taking a lot longer than I expected. Though I intend to release mGBA 0.6.2 shortly that may be the last release for a while.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Work on mGBA will continue at a slowed pace and I do intend to get to several major new features, including netplay and a debug UI, sooner rather than later. However, “sooner” now means “Q2 2018 is optimistic”.&lt;/p&gt;
</description>
        <pubDate>Fri, 09 Mar 2018 00:00:00 -0800</pubDate>
        <link>https://mgba.io/2018/03/09/holy-grail-bugs-revisited/</link>
        <guid isPermaLink="true">https://mgba.io/2018/03/09/holy-grail-bugs-revisited/</guid>
        
        <category>emulation</category>
        
        <category>debugging</category>
        
        
      </item>
    
      <item>
        <title>mGBA 0.6.1</title>
        <description>&lt;p&gt;A new release of mGBA, version 0.6.1, is available. This version is a bugfix release, which contains many stability and accuracy fixes. An extensive list of changes follows after the cut.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Bugfixes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;GB, GBA: Fix crashes when attempting to identify null VFiles&lt;/li&gt;
  &lt;li&gt;GB, GBA: Fix sync to video with frameskip&lt;/li&gt;
  &lt;li&gt;GB, GBA Savedata: Fix savestate-related save overwriting (fixes &lt;a href=&quot;https://mgba.io/i/834&quot;&gt;#834&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB Audio: Fix NRx2 writes while active (fixes &lt;a href=&quot;https://mgba.io/i/866&quot;&gt;#866&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB Core: Fix palette loading when loading a foreign config&lt;/li&gt;
  &lt;li&gt;GB MBC: Pocket Cam memory should be accessible without enabling&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix SRAM sizes 4 and 5&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix RTC initialization (fixes &lt;a href=&quot;https://mgba.io/i/825&quot;&gt;#825&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix RTC loading when file size is off&lt;/li&gt;
  &lt;li&gt;GB Memory: Initialize peripheral pointers&lt;/li&gt;
  &lt;li&gt;GB Memory: Prevent accessing empty SRAM (fixes &lt;a href=&quot;https://mgba.io/i/831&quot;&gt;#831&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB Memory: Fix HDMA count starting in mode 0 (fixes &lt;a href=&quot;https://mgba.io/i/855&quot;&gt;#855&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB Memory: Actually load latch time from savestate&lt;/li&gt;
  &lt;li&gt;GB Serialize: Fix deserializing video STAT&lt;/li&gt;
  &lt;li&gt;GB Video: Fix 16-bit screenshots (fixes &lt;a href=&quot;https://mgba.io/i/826&quot;&gt;#826&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB Video: Fix potential hang when ending mode 0&lt;/li&gt;
  &lt;li&gt;GB Video: Fix read mode when enabling LCD&lt;/li&gt;
  &lt;li&gt;GBA: Reset active region as needed when loading a ROM&lt;/li&gt;
  &lt;li&gt;GBA: Fix keypad IRQs not firing when extra buttons are pressed&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Use core’s VRAM variable instead of renderer’s&lt;/li&gt;
  &lt;li&gt;GBA Cheats: Fix PARv3 multiline blocks (fixes &lt;a href=&quot;https://mgba.io/i/889&quot;&gt;#889&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA I/O: Fix reading from a few invalid I/O registers (fixes &lt;a href=&quot;https://mgba.io/i/876&quot;&gt;#876&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Savedata: Fix 512 byte EEPROM saving as 8kB (fixes &lt;a href=&quot;https://mgba.io/i/877&quot;&gt;#877&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Savedata: Fix size of SRAM saves (fixes &lt;a href=&quot;https://mgba.io/i/883&quot;&gt;#883&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Video: Fix broken sprite blending hack (fixes &lt;a href=&quot;https://mgba.io/i/532&quot;&gt;#532&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Python: Fix importing .gb or .gba before .core&lt;/li&gt;
  &lt;li&gt;Qt: Fix command line debugger closing second game&lt;/li&gt;
  &lt;li&gt;Qt: Fix LOG argument order&lt;/li&gt;
  &lt;li&gt;Qt: Fix timezone issues with time overrides&lt;/li&gt;
  &lt;li&gt;Qt: Fix sprite export pausing game indefinitely (fixes &lt;a href=&quot;https://mgba.io/i/841&quot;&gt;#841&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;SDL: Fix potential race condition when pressing keys (fixes &lt;a href=&quot;https://mgba.io/i/872&quot;&gt;#872&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Misc:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CMake: Fix CPack dependencies for libpng 1.6&lt;/li&gt;
  &lt;li&gt;GBA: Detect hardware for Pokémon FireRed ROM hacks&lt;/li&gt;
  &lt;li&gt;GBA Cheats: Improve detection of raw cheats&lt;/li&gt;
  &lt;li&gt;Qt: Don’t rebuild library view if style hasn’t changed&lt;/li&gt;
  &lt;li&gt;Qt: Allow overrides to be saved before a game is loaded&lt;/li&gt;
  &lt;li&gt;Qt: Hide mouse immediately when loading&lt;/li&gt;
  &lt;li&gt;SDL: Fix 2.0.5 build on macOS under some circumstances&lt;/li&gt;
  &lt;li&gt;VFS: Make VFile.truncate work growing files on PSV (fixes &lt;a href=&quot;https://mgba.io/i/885&quot;&gt;#885&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get it now in the &lt;a href=&quot;/downloads.html&quot;&gt;Downloads&lt;/a&gt; section. Binaries are available for Windows, Ubuntu, macOS, 3DS, Vita, and Wii, and the source code is available for all other platforms.&lt;/p&gt;
</description>
        <pubDate>Sun, 01 Oct 2017 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2017/10/01/mgba-0.6.1/</link>
        <guid isPermaLink="true">https://mgba.io/2017/10/01/mgba-0.6.1/</guid>
        
        <category>announcement</category>
        
        <category>release</category>
        
        
      </item>
    
      <item>
        <title>&quot;Holy Grail&quot; Bugs in Emulation, Part 2</title>
        <description>&lt;p&gt;It’s been two months since first writing on Holy Grail bugs in emulation and while it did pique the interest of many emulator developers there has been little movement on solving the bugs. Lior did much more research on solving Pinball Fantasies and byuu dug up a forum post implying that there is in fact a three scanline delay when enabling background layers on the GBA. However, none of the issues have been conclusively resolved.&lt;/p&gt;

&lt;p&gt;Of course, the previous article only covers two emulated platforms. There are far more than just two emulated systems out there and along with them a large share more incomprehensible issues.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;nintendo-ds-bugs&quot;&gt;Nintendo DS Bugs&lt;/h2&gt;

&lt;p&gt;With currently only two major contenders for mature DS emulators what counts as a Holy Grail bug in DS emulation is a bit more difficult to define. While development has slowed, &lt;a href=&quot;http://desmume.org&quot;&gt;DeSmuME&lt;/a&gt; is still the standout DS emulator for PCs. Seemingly contradictorily however, the oft-considered best DS emulator is &lt;a href=&quot;http://www.drastic-ds.com&quot;&gt;DraStic&lt;/a&gt;: it’s much faster, more accurate and less buggy, but has the limitations of being closed source and solely for Android&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, making it hard to peer into its development process. DraStic’s developer Exophase provided some insight into its development, citing several problematic, bizarre behaviors including games that relied on reading unmapped memory, Art Academy relying race conditions involving waiting for IRQs, or worse: expecting proper behavior for accessing. VRAM that has overlapping mappings. Yes, is a thing that the DS can do and is well-defined.&lt;/p&gt;

&lt;p&gt;There are several up-and-coming DS emulators however: &lt;a href=&quot;http://melonds.kuribo64.net&quot;&gt;melonDS&lt;/a&gt; from StapleButter, &lt;a href=&quot;https://github.com/Cydrak/dasShiny&quot;&gt;dasShiny&lt;/a&gt; from Cydrak, &lt;a href=&quot;https://github.com/shonumi/gbe-plus&quot;&gt;GBE+&lt;/a&gt; from Shonumi, &lt;a href=&quot;https://corgids.wordpress.com&quot;&gt;CorgiDS&lt;/a&gt; from PSISP, and &lt;a href=&quot;/2017/04/08/medusa/&quot;&gt;medusa&lt;/a&gt; from myself. We’ve been collaborating some, but for the most part we’ve been doing independent research. As such, we’ve discovered many of the same bugs, which has led us to put our heads together to figure out some of the more insidious ones.&lt;/p&gt;

&lt;h3 id=&quot;pokémon-blackwhite&quot;&gt;Pokémon Black/White&lt;/h3&gt;

&lt;p&gt;Pokémon Black and White versions are infamous for being difficult to emulate, and have historically been one of the most buggy games in DeSmuME. Or at least the buggiest games that people wanted to play. While the DeSmuME devs have been unwilling to put effort towards directly fixing these games there have been slow improvements to the point where the game is fairly playable. Meanwhile, DraStic also generally runs them quite well, but the newer DS emulators still struggle.&lt;/p&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/bw-save.png&quot; alt=&quot;Pokémon White failing to boot&quot; /&gt;
Pokémon’s own “Blue Screen of Death”&lt;/p&gt;

&lt;p&gt;There are three big issues that earlier phase DS emulators face with Pokémon Black and White: getting the game to boot in the first place, overcoming the anti-piracy mechanism that prevents EXP gain, and preventing seemingly random crashes. Of course, without being able to boot the game the anti-piracy issues are meaningless, so getting it to boot is the first and foremost issue.&lt;/p&gt;

&lt;p&gt;Pokémon Black and White, along with a small handful of other DS games, use special cartridges with an IR sensor onboard. When booting the game using the typical save type detections and support, which apply to 99% of DS games, players are greeted by a nasty blue screen telling them that the save data cannot be accessed. The error cannot be dismissed and the game cannot be played. As it turns out, the IR port is accessed by using a slightly modified version of the protocol that the other 99% of DS games use to load and store save data. If this variant is not properly detected and supported, the game will present this error instead. Fortunately, the variation of the save protocol used in these games is fairly easy to detect and easy to implement (save for the IR communications themselves), which in turn makes overcoming this first hurdle fairly easy. The variant merely adds a 0 byte at the beginning of sending a command for the save protocol, and other values for this first byte entail that it’s an IR command instead.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/bw-no-exp.gif&quot; alt=&quot;Pokémon Black anti-piracy triggering&quot; class=&quot;article-aside&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Although getting past the save error screen does resolve the biggest game breaking bug–not being able to play the game at all–it still does not resolve quite another gargantuan game breaking bug. When the game detects that it’s not running an official cartridge on an actual system it triggers a particularly evil anti-piracy measure: your Pokémon do not gain experience. Pokémon at its core is an RPG and experience is crucial to progression. While in theory it’s possible to power through the game without gaining experience, this is only feasible for the most &lt;del&gt;masochistic&lt;/del&gt; hardcore of players; it prevents the game from being generally accessible to players of any skill level or penchant for self-flagellation.&lt;/p&gt;

&lt;p&gt;While there are patches and Action Replay codes online to prevent the anti-piracy from failing there is no reason that the emulator should allow itself to be seen as a pirate platform. Unfortunately these unofficial game patches do not contain a description of what is being patched or how the patch works. Attempts to reverse engineer the patch have had middling results on my end. With enough research it seems that the issue actually pertains to the time it takes for the cart itself to respond with loaded data. This makes sense since the flash carts that this code is designed to protect against are designed to work with any and all cart types (in theory). As such they may not always present the same timing characteristics as other game carts. And while I’ve made strides in trying to correct this issue in medusa, it persisted.&lt;/p&gt;

&lt;p&gt;Recently StapleButter uncovered another issue that would easily catch most flash carts. When starting a game it would poll the cartridge to see if the IR sensor was present. Since flash carts do not have IR sensors the reply it received was incorrect. Further, I had not implemented any semblance of IR support into medusa yet. Once I implemented a proper reply to the polling, despite the lack of any additional IR functionality, experience began working. The first two issues have now been flattened out in medusa, but only very recently.&lt;/p&gt;

&lt;p&gt;The third issue is random game crashes. These are also theorized to stem from cart timing issues and indeed may be an extension of the anti-piracy measures. Although I have not encountered this issue myself, I have been told that it results in partially loaded maps and corrupted graphics before ultimately crashing. The crashes only occur after hours of gameplay, so saving often can help avoid lost time from crashes.&lt;/p&gt;

&lt;h3 id=&quot;final-fantasy-iii&quot;&gt;Final Fantasy III&lt;/h3&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/ff3-intro.png&quot; alt=&quot;Final Fantasy III intro getting stuck&quot; /&gt;
There’s actually a whole intro after this frame&lt;/p&gt;

&lt;p&gt;Final Fantasy III for the DS is noteworthy for being the first official release of Final Fantasy III outside of Japan. While Final Fantasy I, IV and VI were released as I, II and III internationally, and II and V eventually got released as parts of various compilations, III was isolated to a Japan-only release for sixteen years. In 2006, Square Enix released a remake for the DS that featured 3D graphics and a pre-rendered intro cutscene. At least in theory.&lt;/p&gt;

&lt;p&gt;In practice, the title screen presents issues for emulators. In DeSmuME, it locks up on a black screen unless you mash the buttons before the intro even starts. On older versions of medusa it would lock up after a few seconds, looping the last audio sample. Adjusting memory timings directly affected how long it took for the intro to freeze: the slower memory timings were, the longer it would play for. However, adjusting the memory timings also caused slowdown and other issues in other games. While the timings in medusa are currently a stand-in and very inaccurate, it was curious how adjusting the memory timings seemed to have the opposite effect in Final Fantasy III than in other games. Making things faster generally caused other games to run better due to not missing frame targets, but the intro movie would lock up sooner and sooner the faster I made memory timings. Meanwhile, if the memory timings were significantly slower the intro would work far better.&lt;/p&gt;

&lt;p&gt;I talked with Cydrak who provided some insight into the issue. Sie had previously mentioned a game which require extremely tight synchronization between the two CPUs of the DS. Tighter synchronization between the CPUs leads to far better accuracy, but much, much slower emulation. Fearing that I’d need to tighten up the synchronization, I started to take a deeper look.&lt;/p&gt;

&lt;p&gt;Medusa’s synchronization timings between the two CPUs are fixed at compile time. This means that while it can be adjusted, it cannot be adjusted without recompiling the project. The standard value is roughly 2000 cycles at 66 MHz, which amounts to about 30µs of emulated CPU time. Making the synchronization tighter, I found a lower bound at around 1500 cycles before games would refuse to run, and an upper bound of around 3000 cycles. However, adjusting the synchronization timing &lt;em&gt;had no noticeable effect&lt;/em&gt; for me. As such, I left it alone and moved onto other issues.&lt;/p&gt;

&lt;p&gt;While I did eventually find the proper fix to allow the entire intro to play flawlessly, it wasn’t until I had looked into fixing another game that I figured out what the issue was…&lt;/p&gt;

&lt;h3 id=&quot;tongari-boushi-to-oshare-na-mahou-tsukai&quot;&gt;Tongari Boushi to Oshare na Mahou Tsukai&lt;/h3&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/tongari-loading.gif&quot; alt=&quot;Tongari Boushi loading forever&quot; /&gt;
Even worse than the macOS beachball&lt;/p&gt;

&lt;p&gt;It’s well known that DeSmuME is…a bit buggy. Most games work quite well with only smaller bugs, but there are a handful of games that just do not boot or get in-game. One such game is the obscure Japan-only title Tongari Boushi to Oshare na Mahou Tsukai (とんがりボウシとおしゃれな&lt;ruby&gt;魔法使&lt;rp&gt;(&lt;/rp&gt;&lt;rt&gt;まほうつか&lt;/rt&gt;&lt;rp&gt;)&lt;/rp&gt;&lt;/ruby&gt;い). When loaded in DeSmuME and development versions of other DS emulators it would get to a loading screen and…spin. Forever. Given that it’s an obscure Japan-only title there had probably not been much investigation into why it was broken, either.&lt;/p&gt;

&lt;p&gt;Fast-forward to StapleButter doing research for melonDS. While looking into issues relating to cartridge timings he realized that the GBATEK documentation on cartridge timings omitted some important information. GBATEK is &lt;em&gt;extremely&lt;/em&gt; good documentation for GBA (unsurprisingly) but does contain a few errata. Meanwhile, GBATEK’s DS documentation is far more lackluster: while it covers most topics relating to DS hardware, many of the sections contain underwhelming or flat-out wrong information. One such section was the DS cartridge section. It does contain mostly factual information and certainly enough information to cover more than just the basics. It mentions basic information about the cartridge timings as well, but it has one glaring omission.&lt;/p&gt;

&lt;p&gt;The DS cartridge protocol supports a handful of modes, mostly corresponding to cartridge encryption. In addition to raw access mode, there are also KEY1 and KEY2, which are different encryption modes for ROM startup (as boot code can be put into a region known as the “secure area”) and general ROM data access. For the most part games only use KEY2 encryption after the initial boot process. Since the initial boot process is handled by the firmware before control is passed off to the ROM it is not critical to emulate KEY1 mode if firmware booting is not supported. As such emulator developers tend to ignore the KEY1-specific information in GBATEK, at least until far later in development. As it turns out, that’s where the glaring omission is. There is timing information pertaining to both KEY1 and KEY2 modes that is only marked as KEY1.&lt;/p&gt;

&lt;p&gt;DS cartridge transfers take place in three parts. First, the game sends a command to the cartridge itself, telling it what address to read from, in which mode to operate, and various other parameters. Second, data is transferred from the cartridge back to the DS, visible from the software side as four bytes at a time. However, some processing is done on the cartridge side to prepare the data for transfer, which necessitating operations to be done in blocks. Thus, the third part is the delay taken for the processing in between blocks. There is also a delay taken from sending the initial command to the cartridge and data being available to be read from the cartridge. These timings are referred to by GBATEK as “gaps”. Notably, though, the gaps are not handled automatically by the hardware: these timings are not universal between all DS cartridges and as such games will set the timing parameters in software for the gaps before performing transfers.&lt;/p&gt;

&lt;p&gt;GBATEK does document these settings but says they only apply to KEY1. There is no mention whatsoever of how gaps work for KEY2, or even a mention of their existence. But this doesn’t make sense: the data still needs to be buffered or otherwise processed before it can be transferred. Since cartridges have &lt;a href=&quot;https://en.wikipedia.org/wiki/Random_access&quot;&gt;random access&lt;/a&gt; buffering must be able to be done at transfer start time. This in turn means that a startup gap must exist. Indeed, when using the parameters for KEY1 gaps for KEY2 accesses the infinite loading time of Tongari Boushi becomes finite, Final Fantasy III’s intro movie functions properly, and various other glitches just disappear. And again, it is important to remember that documentation, especially reverse-engineered documentation, is not infallible and must be subjected to scrutiny when seeming contradictions are present.&lt;/p&gt;

&lt;h2 id=&quot;snes-bugs&quot;&gt;SNES Bugs&lt;/h2&gt;

&lt;p&gt;I personally have only worked on emulating three different platforms. Many other platforms are known for some of their emulation difficulties, so I’ve sought out seasoned accuracy-focused developers of other platforms, starting with the obvious choice: with his hyperfocus on accuracy and the SNES byuu had some stories to tell.&lt;/p&gt;

&lt;h3 id=&quot;speedy-gonzales-los-gatos-bandidos&quot;&gt;Speedy Gonzales: Los Gatos Bandidos&lt;/h3&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/speedy-button.png&quot; alt=&quot;The infamous button&quot; /&gt;
Game over I guess?&lt;/p&gt;

&lt;p&gt;Speed Gonzales for the SNES has a notorious bug that historically affected all emulators. In level 6-1, part one of the level Galactical Galaxies, there is a button to be pressed for the game to progress. A casual player would run up to the button, press it, and…the game would lock up. The music continues but the player can no longer do anything. The game has no save system, so that means quite a lot of play time down the drain. And until 2010, this affected every single SNES emulator. Fifteen years after the game came out. So what causes such an issue? In the interest of perfect accuracy, byuu dug into the details.&lt;/p&gt;

&lt;p&gt;The basic premise of the bug is that the game hits a tight loop where it is perpetually reading a value from unmapped memory at &lt;code class=&quot;highlighter-rouge&quot;&gt;$225C&lt;/code&gt;. The loop will only exit if this points to a memory address that contains a value meeting specific criteria. As discussed in my &lt;a href=&quot;/2017/05/29/holy-grail-bugs/#mega-man-battle-network-4&quot;&gt;previous article on Holy Grail bugs&lt;/a&gt; some systems have open bus behavior, which means that reading from an unmapped address leads to reading back the last value that was passed on the bus. In this case, the value is the last byte of the load instruction, &lt;code class=&quot;highlighter-rouge&quot;&gt;$18&lt;/code&gt;, which is read back twice from the bus—once for the low byte, once for the high—yielding the address &lt;code class=&quot;highlighter-rouge&quot;&gt;$1818&lt;/code&gt;. The value at this memory address would never fulfill the exit condition so the loop would never exit. And in most emulators, the bus reads could never change, always yielding the same address. Another previous article, this time on the differences between &lt;a href=&quot;/2017/04/30/emulation-accuracy/&quot;&gt;cycle accuracy and other forms of accuracy&lt;/a&gt;, all but a cycle-accurate emulator would make it impossible for another value to be read. After all, if the instruction is uninterruptable no value could be loaded onto the bus between the last byte of the instruction and the load performed by the instruction.&lt;/p&gt;

&lt;p&gt;Enter cycle accuracy. When you drop the assumption that instructions cannot be interrupted and allow other events to occur in the middle of an instruction a lot of things change. In this case, something interesting happens: suddenly the value on the bus can, in rare circumstances, change. After some false starts byuu realized that an HDMA—a specialized kind of hardware load that is performed in between scanlines—could trigger between the load of the instruction itself and the load performed by the execution. Thus, in the case where the HDMA fired at &lt;em&gt;just&lt;/em&gt; the right time, the value read off the bus would &lt;em&gt;not&lt;/em&gt; be &lt;code class=&quot;highlighter-rouge&quot;&gt;$18&lt;/code&gt;. As it turns out if it read back a 0 the new address would contain a value that &lt;em&gt;did&lt;/em&gt; let the loop exit. Indeed, this was the solution. After hundreds of person-hours of investigation, that was one Holy Grail bug down.&lt;/p&gt;

&lt;h3 id=&quot;magical-drop&quot;&gt;Magical Drop&lt;/h3&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/magical-drop.png&quot; alt=&quot;Magical Drop &amp;quot;game over&amp;quot;&quot; /&gt;
You’re stuck here forever&lt;/p&gt;

&lt;p&gt;So what happens when you have a bug in an emulator that…sometimes reproduces on hardware, but not always? Even worse, the probability of it occurring on hardware varies from unit to unit? It’s a difficult situation and it’s one that plagues the Japan-only game Magical Drop.&lt;/p&gt;

&lt;p&gt;The Super Nintendo era had a wave of block-matching puzzle games like Panel de Pon (Tetris Attack in the US), Puyo Puyo, or Columns. In this same vein, Magical Drop features a slight variation on the match-3 formula. The game has several modes, including a versus mode and an endless mode. The game is also notable for having voice clips that play in some emulators but not others. Also in some emulators, endless mode really is endless.&lt;/p&gt;

&lt;p&gt;Usually endless or marathon modes function by giving you a variant of the gameplay that does not have a set win condition. Rather, you keep playing until you max out the score counter (and you can keep playing after that too) or you hit a failure condition and get a game over. Like many match-3 games, the failure condition is when you can no longer fit blocks on your screen. The player character then exclaims in disappointment and you can enter your initials for the high score screen.&lt;/p&gt;

&lt;p&gt;But in higan, and &lt;em&gt;sometimes&lt;/em&gt; on consoles too, the game over screen never appears. The player character keeps hanging their head in shame, and the game softlocks. You can’t enter your initials. The words “Game Over” never appear. Buttons do nothing. So what triggers this softlock? Well, that remains partially unsolved, but investigation into the issue opened a whole can of worms.&lt;/p&gt;

&lt;p&gt;Much like the issues with voice clips never playing the issue appears to be related to the SNES’s sound chip. The S-DSP handles processing audio samples into the final output audio. It allows for making various adjustments to the audio in the process, including pitch, echo, &lt;a href=&quot;https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope&quot;&gt;ADSR&lt;/a&gt;, and more. The game adjusts the state of S-DSP to tune how things are to be output.&lt;/p&gt;

&lt;p&gt;So…what happens if a game fails to initialize the S-DSP before it uses it? Well, the current hypothesis is that…we don’t know. Or at least we don’t definitively know. A common failure case for older game consoles is that when hardware isn’t properly initialized its state is actually somewhat &lt;em&gt;random&lt;/em&gt;. The exact details of this randomization vary from device to device, but this can and has led to games whose behavior will change dramatically based on some random state. Magical Drop happens to be one of those games. Though it’s not entirely clear which part of the S-DSP is causing the hang. A hypothesis is the state of the pitch adjustment, but this has yet to be properly confirmed.&lt;/p&gt;

&lt;p&gt;One of the issues with fixing the S-DSP randomness is that much of the internal state is opaque beyond the S-DSP itself, making it difficult to tell what should be random and what shouldn’t be. Another issue is due to a lack of proper test cases to ensure nothing breaks. In fact, byuu attempted to randomize the entire S-DSP state, and sure enough, it broke things that previously worked. For example, King of Dragons would randomly drop sound effects and channels. Further, which ones were missing varied every boot. So clearly some things weren’t random…but some things are. The issue has not yet been fully investigated on hardware, but research is ongoing and will hopefully yield a further understanding as it continues. Until then, well, you’re resigned to using less accurate emulators for this specific game.&lt;/p&gt;

&lt;h2 id=&quot;thats-four-consoles-down&quot;&gt;That’s four consoles down&lt;/h2&gt;

&lt;p&gt;So what’s next? Well I’ve only addressed Holy Grail bugs in four consoles so far. There are many consoles out there more complex and less well understood than the SNES or the GB, and with them their own sets of issues. We’ve barely even scratched the surface of older consoles, and newer ones not at all.&lt;/p&gt;

&lt;p&gt;As you get newer they get far more difficult to understand. They have more moving parts and more complex rendering pipelines. Understanding such large systems as a whole is difficult enough, but understanding ways they can break is far worse. In part 3, I plan to interview emulator developers for newer systems their takes on the difficulties in emulation. I don’t know about you but I can’t wait to find out what horrors lie buried in the Sega Saturn.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;Old versions of DraStic are available for the &lt;a href=&quot;http://openpandora.org&quot;&gt;Pandora&lt;/a&gt; open handheld, and there are rumors of other non-Android versions either upcoming or otherwise available to private parties. Further, there has been &lt;a href=&quot;http://www.drastic-ds.com/viewtopic.php?f=5&amp;amp;t=4828&quot;&gt;recent discussion&lt;/a&gt; of DraStic going open source in the not-so-longterm future. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 31 Jul 2017 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2017/07/31/holy-grail-bugs-2/</link>
        <guid isPermaLink="true">https://mgba.io/2017/07/31/holy-grail-bugs-2/</guid>
        
        <category>emulation</category>
        
        <category>debugging</category>
        
        <category>patreon</category>
        
        
      </item>
    
      <item>
        <title>mGBA 0.6.0</title>
        <description>&lt;p&gt;After many months of delays mGBA 0.6.0 is finally available. This is a major feature release. Some of the more prominent features include a library view, translations to German, Spanish and Italian, and many new debugging features. A full list of changes follows after the cut.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;changes-from-052&quot;&gt;Changes from 0.5.2&lt;/h2&gt;

&lt;h3 id=&quot;features&quot;&gt;Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Library view&lt;/li&gt;
  &lt;li&gt;Sprite viewer&lt;/li&gt;
  &lt;li&gt;Debugging console&lt;/li&gt;
  &lt;li&gt;Improved memory viewer&lt;/li&gt;
  &lt;li&gt;Memory search&lt;/li&gt;
  &lt;li&gt;Command line ability to override configuration values&lt;/li&gt;
  &lt;li&gt;Add option to allow preloading the entire ROM before running&lt;/li&gt;
  &lt;li&gt;Add option for whether rewinding restores save games&lt;/li&gt;
  &lt;li&gt;Savestates now contain any RTC override data&lt;/li&gt;
  &lt;li&gt;Add option to lock video to integer scaling&lt;/li&gt;
  &lt;li&gt;LR35902: Watchpoints&lt;/li&gt;
  &lt;li&gt;LR35902/GB-Z80 disassembler&lt;/li&gt;
  &lt;li&gt;GB: Tile viewer&lt;/li&gt;
  &lt;li&gt;GB: Video/audio channel enabling/disabling&lt;/li&gt;
  &lt;li&gt;GB: Symbol table support&lt;/li&gt;
  &lt;li&gt;GB MBC: Add MBC1 multicart support&lt;/li&gt;
  &lt;li&gt;GBA: Support printing debug strings from inside a game&lt;/li&gt;
  &lt;li&gt;GBA: Better cheat type autodetection&lt;/li&gt;
  &lt;li&gt;Implement keypad interrupts&lt;/li&gt;
  &lt;li&gt;Configuration of gamepad hats&lt;/li&gt;
  &lt;li&gt;Video log recording for testing and bug reporting&lt;/li&gt;
  &lt;li&gt;Debugger: Segment/bank support&lt;/li&gt;
  &lt;li&gt;Debugger: Execution tracing&lt;/li&gt;
  &lt;li&gt;Partial Python scripting support&lt;/li&gt;
  &lt;li&gt;Qt: German translation (by Lothar Serra Mari)&lt;/li&gt;
  &lt;li&gt;Qt: Spanish translation (by Kevin López)&lt;/li&gt;
  &lt;li&gt;Qt: Italian translation (by theheroGAC)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bugfixes&quot;&gt;Bugfixes&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;ARM7: Fix MLA/&lt;em&gt;MULL/&lt;/em&gt;MLAL timing&lt;/li&gt;
  &lt;li&gt;Core: Fix crash with rewind if savestates shrink&lt;/li&gt;
  &lt;li&gt;Core: Fix interrupting a thread while on the thread (fixes &lt;a href=&quot;https://mgba.io/i/692&quot;&gt;#692&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Core: Fix directory sets crashing on close if base isn’t properly detached&lt;/li&gt;
  &lt;li&gt;FFmpeg: Fix overflow and general issues with audio encoding&lt;/li&gt;
  &lt;li&gt;GB: Fix flickering when screen is strobed quickly&lt;/li&gt;
  &lt;li&gt;GB: Fix STAT blocking&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix ROM bank overflows getting set to bank 0&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix swapping carts not detect new MBC&lt;/li&gt;
  &lt;li&gt;GB Timer: Improve DIV reset behavior&lt;/li&gt;
  &lt;li&gt;GB Timer: Fix DIV batching if TAC changes&lt;/li&gt;
  &lt;li&gt;GB Video: Reset renderer when loading state&lt;/li&gt;
  &lt;li&gt;GBA: Fix multiboot ROM loading&lt;/li&gt;
  &lt;li&gt;GBA: Fix multiboot loading resulting in too small WRAM&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Implement BitUnPack&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Fix ArcTan sign in HLE BIOS&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Fix ArcTan2 sign in HLE BIOS (fixes &lt;a href=&quot;https://mgba.io/i/689&quot;&gt;#689&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Fix INT_MIN/-1 crash&lt;/li&gt;
  &lt;li&gt;GBA Hardware: Fix crash if a savestate lies about game hardware&lt;/li&gt;
  &lt;li&gt;GBA I/O: Handle audio registers specially when deserializing&lt;/li&gt;
  &lt;li&gt;GBA Memory: Improve initial skipped BIOS state&lt;/li&gt;
  &lt;li&gt;GBA Savedata: Fix savedata unmasking (fixes &lt;a href=&quot;https://mgba.io/i/441&quot;&gt;#441&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Savedata: Update and fix Sharkport importing (fixes &lt;a href=&quot;https://mgba.io/i/658&quot;&gt;#658&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Video: Fix wrong palette on 256-color sprites in OBJWIN&lt;/li&gt;
  &lt;li&gt;GBA Video: Don’t update background scanline params in mode 0 (fixes &lt;a href=&quot;https://mgba.io/i/377&quot;&gt;#377&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Libretro: Fix saving in GB games (fixes &lt;a href=&quot;https://mgba.io/i/486&quot;&gt;#486&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;LR35902: Fix core never exiting with certain event patterns&lt;/li&gt;
  &lt;li&gt;LR35902: Fix pc overflowing current region off-by-one&lt;/li&gt;
  &lt;li&gt;LR35902: Fix decoding LD r, $imm and 0-valued immediates (fixes &lt;a href=&quot;https://mgba.io/i/735&quot;&gt;#735&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;OpenGL: Fix some shaders causing offset graphics&lt;/li&gt;
  &lt;li&gt;GB Timer: Fix sub-M-cycle DIV reset timing and edge triggering&lt;/li&gt;
  &lt;li&gt;Qt: Fix timing issues on high refresh rate monitors&lt;/li&gt;
  &lt;li&gt;Qt: Fix linking after some windows have been closed&lt;/li&gt;
  &lt;li&gt;Qt: Fix crash when changing audio settings after a game is closed&lt;/li&gt;
  &lt;li&gt;Qt: Ensure CLI backend is attached when submitting commands (fixes &lt;a href=&quot;https://mgba.io/i/662&quot;&gt;#662&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Disable “New multiplayer window” when MAX_GBAS is reached (fixes &lt;a href=&quot;https://mgba.io/i/107&quot;&gt;#107&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Fix game unpausing after frame advancing and refocusing&lt;/li&gt;
  &lt;li&gt;SDL: Fix game crash check&lt;/li&gt;
  &lt;li&gt;SDL: Fix race condition with audio thread when starting&lt;/li&gt;
  &lt;li&gt;SDL: Fix showing version number&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when loading invalid file&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when fuzzing fails to load a file&lt;/li&gt;
  &lt;li&gt;Test: Don’t rely on core for frames elapsed&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when loading invalid file&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when fuzzing fails to load a file&lt;/li&gt;
  &lt;li&gt;Tools: Fix recurring multiple times over the same library&lt;/li&gt;
  &lt;li&gt;Util: Fix overflow when loading invalid UPS patches&lt;/li&gt;
  &lt;li&gt;Util: Fix highest-fd socket not being returned by SocketAccept&lt;/li&gt;
  &lt;li&gt;Windows: Fix VDir.rewind&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;All: Add C++ header guards&lt;/li&gt;
  &lt;li&gt;All: Move time.h include to common.h&lt;/li&gt;
  &lt;li&gt;3DS, PSP2, Wii: Last directory loaded is saved&lt;/li&gt;
  &lt;li&gt;CMake: Add ability to just print version string&lt;/li&gt;
  &lt;li&gt;Core: New, faster event timing subsystem&lt;/li&gt;
  &lt;li&gt;Core: Clean up some thread state checks&lt;/li&gt;
  &lt;li&gt;Core: Add generic checksum function&lt;/li&gt;
  &lt;li&gt;Core: Cores can now have multiple sets of callbacks&lt;/li&gt;
  &lt;li&gt;Core: Restore sleep callback&lt;/li&gt;
  &lt;li&gt;Core: Move rewind diffing to its own thread&lt;/li&gt;
  &lt;li&gt;Core: Ability to enumerate and modify video and audio channels&lt;/li&gt;
  &lt;li&gt;Core: List memory segments in the core&lt;/li&gt;
  &lt;li&gt;Core: Move savestate creation time to extdata&lt;/li&gt;
  &lt;li&gt;Core: Config values can now be hexadecimal&lt;/li&gt;
  &lt;li&gt;Core: Improved threading interrupted detection&lt;/li&gt;
  &lt;li&gt;Debugger: Modularize CLI debugger&lt;/li&gt;
  &lt;li&gt;Debugger: Make building with debugging aspects optional&lt;/li&gt;
  &lt;li&gt;Debugger: Add functions for read- or write-only watchpoints&lt;/li&gt;
  &lt;li&gt;Debugger: Make attaching a backend idempotent&lt;/li&gt;
  &lt;li&gt;Debugger: Add mDebuggerRunFrame convenience function&lt;/li&gt;
  &lt;li&gt;Feature: Move game database from flatfile to SQLite3&lt;/li&gt;
  &lt;li&gt;Feature: Support ImageMagick 7&lt;/li&gt;
  &lt;li&gt;Feature: Make -l option explicit&lt;/li&gt;
  &lt;li&gt;FFmpeg: Return false if a file fails to open&lt;/li&gt;
  &lt;li&gt;FFmpeg: Force MP4 files to YUV420P&lt;/li&gt;
  &lt;li&gt;GB: Trust ROM header for number of SRAM banks (fixes &lt;a href=&quot;https://mgba.io/i/726&quot;&gt;#726&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB: Reset with initial state of DIV register&lt;/li&gt;
  &lt;li&gt;GB MBC: New MBC7 implementation&lt;/li&gt;
  &lt;li&gt;GB Audio: Simplify envelope code&lt;/li&gt;
  &lt;li&gt;GB Audio: Improve initial envelope samples&lt;/li&gt;
  &lt;li&gt;GB Audio: Start implementing “zombie” audio (fixes &lt;a href=&quot;https://mgba.io/i/389&quot;&gt;#389&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB Video: Improved video timings&lt;/li&gt;
  &lt;li&gt;GBA: Ignore invalid opcodes used by the Wii U VC emulator&lt;/li&gt;
  &lt;li&gt;GBA, GB: ROM is now unloaded if a patch is applied&lt;/li&gt;
  &lt;li&gt;GBA DMA: Refactor DMA out of memory.c&lt;/li&gt;
  &lt;li&gt;GBA DMA: Move DMAs to using absolute timing&lt;/li&gt;
  &lt;li&gt;GBA I/O: Clear JOYSTAT RECV flag when reading JOY_RECV registers&lt;/li&gt;
  &lt;li&gt;GBA I/O: Set JOYSTAT TRANS flag when writing JOY_TRANS registers&lt;/li&gt;
  &lt;li&gt;GBA Memory: Support for Mo Jie Qi Bing by Vast Fame (taizou)&lt;/li&gt;
  &lt;li&gt;GBA Memory: Support reading/writing POSTFLG&lt;/li&gt;
  &lt;li&gt;GBA Memory: Remove unused prefetch cruft&lt;/li&gt;
  &lt;li&gt;GBA Timer: Improve accuracy of timers&lt;/li&gt;
  &lt;li&gt;GBA Video: Clean up unused timers&lt;/li&gt;
  &lt;li&gt;GBA Video: Allow multiple handles into the same tile cache&lt;/li&gt;
  &lt;li&gt;GBA Video, GB Video: Colors are now fully scaled&lt;/li&gt;
  &lt;li&gt;GBA Video: Optimize when BLD* registers are written frequently&lt;/li&gt;
  &lt;li&gt;OpenGL: Add xBR-lv2 shader&lt;/li&gt;
  &lt;li&gt;Qt: Move last directory setting from qt.ini to config.ini&lt;/li&gt;
  &lt;li&gt;Qt: Improved HiDPI support&lt;/li&gt;
  &lt;li&gt;Qt: Expose configuration directory&lt;/li&gt;
  &lt;li&gt;Qt: Merge “Save” and “OK” buttons in shader options&lt;/li&gt;
  &lt;li&gt;Qt: Automatically load controller profile when plugged in&lt;/li&gt;
  &lt;li&gt;Qt: Rename “Resample video” option to “Bilinear filtering”&lt;/li&gt;
  &lt;li&gt;Qt: Remove audio thread&lt;/li&gt;
  &lt;li&gt;Qt: Remove audio buffer sizing in AudioProcessorQt&lt;/li&gt;
  &lt;li&gt;Qt: Re-enable QtMultimedia on Windows&lt;/li&gt;
  &lt;li&gt;Qt: Make “Mute” able to be bound to a key&lt;/li&gt;
  &lt;li&gt;Qt: Add .gb/.gbc files to the extension list in Info.plist&lt;/li&gt;
  &lt;li&gt;Qt: Relax hard dependency on OpenGL&lt;/li&gt;
  &lt;li&gt;Qt: Better highlight active key in control binding&lt;/li&gt;
  &lt;li&gt;SDL: Remove scancode key input&lt;/li&gt;
  &lt;li&gt;SDL: Automatically map controllers when plugged in&lt;/li&gt;
  &lt;li&gt;Test: Add a basic test suite&lt;/li&gt;
  &lt;li&gt;Util: Add size counting to Table&lt;/li&gt;
  &lt;li&gt;Util: Add 8-bit PNG write support&lt;/li&gt;
  &lt;li&gt;Util: Tune patch-fast extent sizes&lt;/li&gt;
  &lt;li&gt;VFS: Call msync when syncing mapped data&lt;/li&gt;
  &lt;li&gt;VFS: Allow truncating memory chunk VFiles&lt;/li&gt;
  &lt;li&gt;VFS: Fix some minor VFile issues with FILEs&lt;/li&gt;
  &lt;li&gt;VFS: Optimize expanding in-memory files&lt;/li&gt;
  &lt;li&gt;VFS: Add VFileFIFO for operating on circle buffers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;changes-from-06-beta-1&quot;&gt;Changes from 0.6 beta 1&lt;/h2&gt;

&lt;h3 id=&quot;features-1&quot;&gt;Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Qt: Italian translation (by theheroGAC)&lt;/li&gt;
  &lt;li&gt;Qt: Updated German translation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bugfixes-1&quot;&gt;Bugfixes&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Core: Fix rewinding getting out of sync (fixes &lt;a href=&quot;https://mgba.io/i/791&quot;&gt;#791&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB Audio: Fix incorrect channel 4 iteration&lt;/li&gt;
  &lt;li&gt;GB Audio: Fix zombie mode bit masking&lt;/li&gt;
  &lt;li&gt;GB Serialize: Fix timer serialization&lt;/li&gt;
  &lt;li&gt;GB Video: Fix LYC regression&lt;/li&gt;
  &lt;li&gt;GBA SIO: Improve SIO Normal dummy driver (fixes &lt;a href=&quot;https://mgba.io/i/520&quot;&gt;#520&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Timer: Fix count-up timing overflowing timer 3&lt;/li&gt;
  &lt;li&gt;PSP2: Use custom localtime_r since newlib version is broken (fixes &lt;a href=&quot;https://mgba.io/i/560&quot;&gt;#560&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Fix memory search close button (fixes &lt;a href=&quot;https://mgba.io/i/769&quot;&gt;#769&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Fix window icon being stretched&lt;/li&gt;
  &lt;li&gt;Qt: Fix initial window size (fixes &lt;a href=&quot;https://mgba.io/i/766&quot;&gt;#766&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Fix data directory path&lt;/li&gt;
  &lt;li&gt;Qt: Fix controls not saving on non-SDL builds&lt;/li&gt;
  &lt;li&gt;Qt: Fix translation initialization (fixes &lt;a href=&quot;https://mgba.io/i/776&quot;&gt;#776&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Fix patch loading while a game is running&lt;/li&gt;
  &lt;li&gt;Qt: Fix shader selector on Ubuntu (fixes &lt;a href=&quot;https://mgba.io/i/767&quot;&gt;#767&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Fix GL-less build&lt;/li&gt;
  &lt;li&gt;Qt: Fix Software renderer not handling alpha bits properly&lt;/li&gt;
  &lt;li&gt;Qt: Fix screen background improperly stretching&lt;/li&gt;
  &lt;li&gt;SDL: Fix cheats not loading&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;miscellaneous-1&quot;&gt;Miscellaneous&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;GB Serialize: Add MBC state serialization&lt;/li&gt;
  &lt;li&gt;GBA Memory: Call crash callbacks regardless of if hard crash is enabled&lt;/li&gt;
  &lt;li&gt;GBA Timer: Improve accuracy of timers&lt;/li&gt;
  &lt;li&gt;PSP2: Update toolchain to use vita.cmake&lt;/li&gt;
  &lt;li&gt;Qt: Add language selector&lt;/li&gt;
  &lt;li&gt;Qt: Minor text fixes&lt;/li&gt;
  &lt;li&gt;Qt: Move shader settings into main settings window&lt;/li&gt;
  &lt;li&gt;Qt: Dismiss game crashing/failing dialogs when a new game loads&lt;/li&gt;
  &lt;li&gt;Qt: Properly ship Qt translations&lt;/li&gt;
  &lt;li&gt;SDL: Remove writing back obtained samples (fixes &lt;a href=&quot;https://mgba.io/i/768&quot;&gt;#768&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;downloads&quot;&gt;Downloads&lt;/h2&gt;

&lt;p&gt;Get it now in the &lt;a href=&quot;/downloads.html&quot;&gt;Downloads&lt;/a&gt; section. Binaries are available for Windows, Ubuntu, macOS, Nintendo 3DS, Wii, and PlayStation Vita, and the source code is available for all other platforms.&lt;/p&gt;

&lt;p&gt;If you enjoy using mGBA and wish to give back, there is a list of ways to donate on the &lt;a href=&quot;/donate.html&quot;&gt;donations page&lt;/a&gt;, including an &lt;a href=&quot;https://www.patreon.com/mgba&quot;&gt;mGBA Patreon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 16 Jul 2017 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2017/07/16/mgba-0.6.0/</link>
        <guid isPermaLink="true">https://mgba.io/2017/07/16/mgba-0.6.0/</guid>
        
        <category>announcement</category>
        
        <category>release</category>
        
        
      </item>
    
      <item>
        <title>Cracking the GBA BIOS</title>
        <description>&lt;p&gt;A computer must perform a series of initialization tasks when turned on before it becomes ready for use. Once these tasks, generally referred to as &lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Bootstrapping&quot;&gt;booting&lt;/a&gt;&lt;/em&gt;, are complete, control passes over to the main system. On many systems, especially on specialized systems such as video game consoles, there is a fixed set of initialization routines for the boot process stored in read-only memory inside the system. This is usually referred to as the boot ROM.&lt;/p&gt;

&lt;p&gt;When emulating a system, there are two ways to emulate the boot process. One approach is to initialize the emulated state to reflect the state of an already booted system. But from an accuracy-focused, low-level emulation perspective, starting the emulation from a clean slate and run the boot ROM directly is often more desirable.&lt;/p&gt;

&lt;p&gt;There are advantages and disadvantages to both approaches, but the most notable disadvantage to the boot ROM approach is that it necessitates having a copy of the boot ROM itself. Since the boot ROM is actual code and not a system design, it is potentially copyrightable and leads to concerns with distribution. Thus many emulators that use a boot ROM require users to obtain a copy separately from the emulator.&lt;/p&gt;

&lt;p&gt;Further, many systems contain protections to prevent the boot ROM from being directly accessed or dumped. All Nintendo handhelds have protections. But due to the complexity of these boot ROMs many emulators actually require them to be provided to run at all. However, these protections make it difficult to dump the boot ROMs.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;On some systems accessing the boot ROM from software is simply not possible without hardware modifications. Such is the case for the Game Boy, which completely removes all traces of the boot ROM from memory before handing any control over to the game. More complex boot ROMs may be multiple stages, with the earlier stages being progressively more difficult to dump.&lt;/p&gt;

&lt;p&gt;The downside of more complex boot ROMs is that they often contain security vulnerabilities that can allow code execution early in the boot process. The 3DS’s “sighax” or the Wii’s &lt;a href=&quot;http://wiibrew.org/wiki/Signing_bug&quot;&gt;“trucha” bug&lt;/a&gt; are two notable examples. Early code execution can be an easy way dump the entirety of a boot ROM. While it may be possible to mitigate some of these bugs in software, the issues can only be properly fixed via a hardware revision. Depending on when in a system’s lifecycle these issues are publicized a hardware revision might not occur.&lt;/p&gt;

&lt;p&gt;The Game Boy Advance sits in a middle-ground between primitive boot ROMs such as the Game Boy’s that mostly just exist to bring up a logo and run basic checks on the cartridge, and more advanced systems like the 3DS which contain a full operating system. Before the DSi, no Nintendo handhelds contained operating systems&lt;sup id=&quot;fnref:ds-boot&quot;&gt;&lt;a href=&quot;#fn:ds-boot&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. However, the GBA and DS contain code in ROM that act as utility functionality to the game software in addition to the boot code. This utility code is what leads to the ROM being referred to as BIOS&lt;sup id=&quot;fnref:bios-definition&quot;&gt;&lt;a href=&quot;#fn:bios-definition&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; instead of boot ROM, and To avoid having to reimplement this functionality many GBA and DS emulators require copies of the BIOS. It also means that at least some of the BIOS must remain present in memory at all times, so the simple trick of merely removing the boot ROM from memory isn’t possible.&lt;/p&gt;

&lt;p&gt;The GBA BIOS is very small, only 16 kiB, so it only contains a small amount of code. A good chunk of it is data, such as the boot logo and sound effect. It also contains routines for copying memory quickly, doing decompression, some basic math operations, some sound functionality that is  used by about three games total&lt;sup id=&quot;fnref:agbsound&quot;&gt;&lt;a href=&quot;#fn:agbsound&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, and a handful of low-level hardware interactions. Due to the design of the ARM CPU that the GBA uses, it also includes the &lt;a href=&quot;https://en.wikipedia.org/wiki/Interrupt_vector_table&quot;&gt;interrupt vector table&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The interrupt vector table is used by the CPU to know what code to run under specific circumstances: where the boot code is, what happens when an &lt;a href=&quot;https://en.wikipedia.org/wiki/Interrupt_request_(PC_architecture)&quot;&gt;interrupt request&lt;/a&gt; occurs, what happens when a &lt;a href=&quot;https://en.wikipedia.org/wiki/Trap_(computing)&quot;&gt;trap&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/System_call&quot;&gt;system call&lt;/a&gt; or other software interrupt occurs, and a handful of other things. In practice, only hardware interrupts (IRQs) and software interrupts (SWIs) occur on the GBA after initial boot or reset.&lt;sup id=&quot;fnref:arm-exceptions&quot;&gt;&lt;a href=&quot;#fn:arm-exceptions&quot; class=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; The ARM architecture defines two specific locations in the memory &lt;a href=&quot;https://en.wikipedia.org/wiki/Address_space&quot;&gt;address space&lt;/a&gt; where the interrupt vector table can reside, and as such the entirety of the BIOS is located contiguously at the very base of the address space.&lt;/p&gt;

&lt;p&gt;Nintendo’s primary approach to preventing unintended access to the BIOS is simple: if the currently executing code is in BIOS, you have full access. Otherwise, you have no access. The former is absolutely required: the boot code and many of the math functions absolutely require data lookup to be able to function at all. The latter prevents games from easily being able to dump anything. And since games call the BIOS functions by using software interrupts, they don’t need to know any of the layout of the BIOS; simply use an identifying number for the function and the BIOS looks up where it is while running the software interrupt handler. Moreover, all of the routines that are used for copying or accessing memory have checks to prevent them from being used to copy out BIOS memory.&lt;/p&gt;

&lt;p&gt;Well, All of them except for one of the sound ones. Software interrupt $1F, sometimes known as MidiKey2Freq, is intended to be used for converting musical note from a &lt;a href=&quot;https://en.wikipedia.org/wiki/MIDI&quot;&gt;MIDI&lt;/a&gt; key to an actual frequency. This is useful for transforming song data into a format that is directly applicable to audio mixing code or hardware. However, the first input to this function is a memory location that contains song data, and not a raw value. Nintendo neglected to add protections to this function and GBA homebrew developer &lt;a href=&quot;https://www.darkfader.net/gba/main.html&quot;&gt;Dark Fader&lt;/a&gt; noticed. This approach could only dump one byte at a time and proved to be very slow, but this was a single oversight in the BIOS code that allowed the entire BIOS to be dumped. This was the canonical approach for dumping the GBA BIOS for many years. After all, the implementation of exploiting the bug was &lt;a href=&quot;https://files.darkfader.net//gba/files/dumprom.cpp&quot;&gt;extremely simple&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While this was sufficient to dump the BIOS, it was thought to be the only way to dump the BIOS. All of the other functionality had been searched for vulnerabilities and no others were found. Fast forward to 2016 when I got to thinking about newer techniques in software exploitation, particularly one called &lt;a href=&quot;https://en.wikipedia.org/wiki/Return-oriented_programming&quot;&gt;return-oriented programming&lt;/a&gt;, or ROP for short. In brief, modern CPUs don’t allow you to execute arbitrary memory anymore: just because you can write to it doesn’t mean you can run from it. Only locations of memory that are marked as “executable” by the MMU can be run. ROP bypasses this by cherry-picking the very end of various functions that manipulate the state of the system in specific ways and chaining the end of that function call with a jump to the end of another function call that does another very specific set of operations.&lt;/p&gt;

&lt;p&gt;The creation of this chain is done by modifying the &lt;a href=&quot;https://en.wikipedia.org/wiki/Call_stack&quot;&gt;call stack&lt;/a&gt; directly instead via a memory bug of some sort (or creating a new stack and switching to it using a “stack pivot”). The CPU keeps track of which function called the function you’re currently in to know where to go after it’s done with the function, as well as any local variables in that function that will need to be restored when the function starts executing again.&lt;/p&gt;

&lt;p&gt;With clever crafting these ROP chains can effect arbitrary state changes, obviating non-executable memory being an obstacle. Additionally a similar, older technique that can be used in conjunction is called a “return-to-library” or “&lt;a href=&quot;https://en.wikipedia.org/wiki/Return-to-libc_attack&quot;&gt;return-to-libc&lt;/a&gt;” attack. Instead of jumping to the end of a function you jump to the beginning of a function that does a set of standard operations before returning again where it left off. One example is being able to put a memory allocation in the middle of a ROP chain. At one point I got to thinking, is it possible to construct a return-to-BIOS attack on the GBA?&lt;/p&gt;

&lt;p&gt;I previously mentioned that the way to call a BIOS function is via a software interrupt. When a software interrupt is triggered it jumps directly into the software interrupt vector in the BIOS which handles everything internally to the BIOS. However, while the function is running it is possible that the CPU will receive a &lt;em&gt;hardware&lt;/em&gt; interrupt, leading to the CPU running user code in the middle of a BIOS function before it returns execution to the BIOS function.&lt;/p&gt;

&lt;p&gt;This means you can easily write code to start a memory copy in BIOS code that will have an interrupt fire before it’s complete. But the stack is also read-write, which means the code can know which function called it and any saved local variables it may have, and then modify them. Trivially, a simple program can trawl the stack to look for the state of a copy it triggered and then adjust the source variable to point to &lt;em&gt;the start of BIOS&lt;/em&gt; and read out the entire BIOS that way. Due to timing issues this can take a few tries to get right, but is fairly reliable and a sample implementation took less than two seconds properly dump the whole BIOS.&lt;/p&gt;

&lt;p&gt;Further, if you investigate the stack in while running in the middle of an interrupt, you can dig deep enough back through the stack to find that it will return to code in the interrupt handler. And since the interrupt handler is in BIOS, this shows it’s actually possible to call code in the BIOS directly. If you know where it is. Since the interrupt handler has a separate stack, it’s pretty trivial to use this stack to find the interrupt handler is, but that’s about it.&lt;/p&gt;

&lt;p&gt;However, another questionable design on Nintendo’s part is that the interrupt stack is actually adjacent in memory to the normal stack and has no protections. You can inspect that stack to find where the function is: near the bottom of the IRQ stack is the address to where the IRQ interrupted the copy. After you’ve recovered the address of the copy, you can jump directly into it and…jump right past the bounds checking to the inner loop. Just fiddle with the CPU state a bit to set it up to be copying the BIOS instead of any other region and set the length. This removes any of the timing guesswork from the previous approach, but requires a bit more trickery due to the difficulty of distinguishing which address is which.&lt;/p&gt;

&lt;p&gt;These are two related, completely &lt;a href=&quot;https://en.wikipedia.org/wiki/Black_box&quot;&gt;black-box&lt;/a&gt; approaches to dumping the BIOS, exploiting only Nintendo’s questionable approach to memory handling. There are no software vulnerabilities involved in this approach and require exactly zero prior knowledge of the layout or contents of the BIOS. A sample implementation of the stack modification approach and a hardcoded jump approach are implemented in my own &lt;a href=&quot;https://github.com/mgba-emu/bios-dump&quot;&gt;BIOS dumping tool&lt;/a&gt;. And while having a prior dump of the BIOS made this process far easier, it was only a convenience, not a necessity. It shows that you don’t always need software vulnerabilities to exploit a system; hardware flaws run far deeper.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:ds-boot&quot;&gt;
      &lt;p&gt;The DS had a simple firmware-based boot menu that would present a few options to the user before handing control over to a game. once the game was loaded the boot menu was no longer present in memory. Since the boot menu is in firmware alongside settings it has distinct protections from the boot ROM. It is contained in physically distinct memory from the boot ROM and the boot process must be able to load it. &lt;a href=&quot;#fnref:ds-boot&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:bios-definition&quot;&gt;
      &lt;p&gt;The term “BIOS”, which stands for “basic input/output system”, usually refers to code present on computer motherboards that handles some basic functionality, including interfacing with other hardware on the motherboard beyond the CPU. However, and there is very little in common with computer BIOS and GBA BIOS beyond the fact that they are involved in the boot process. &lt;a href=&quot;#fnref:bios-definition&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:agbsound&quot;&gt;
      &lt;p&gt;Updated versions of the sound code is present in the official Game Boy Advance SDK and as such is duplicated in most games’ ROMs. Only two obscure Japanese games are known to use the built-in version extensively. The Digital Eclipse developer splash screen in the game Phantasy Star Collection also uses it for a few seconds, but none of the rest of the game does. &lt;a href=&quot;#fnref:agbsound&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:arm-exceptions&quot;&gt;
      &lt;p&gt;ARM defines a series of exception types, including RESET (booting or rebooting), IRQ (hardware interrupt), FIQ (“fast” (high priority) hardware interrupts), SWI (software interrupts, or SVC/supervisor (operating system) calls on newer ARM versions), data aborts (invalid data memory access), prefetch aborts (invalid instruction memory access), and UNDEFINED (unknown instructions). However, many of these cannot happen on a GBA for hardware configuration reasons. FIQs cannot happen on retail GBAs due to how the CPU is wired, although code in the BIOS seems to indicate that FIQs were used by debugging hardware or devkits. Data and prefetch aborts cannot happen on the GBA due to the lack of a &lt;a href=&quot;https://en.wikipedia.org/wiki/Memory_protection&quot;&gt;memory protection unit&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Memory_management_unit&quot;&gt;memory management unit&lt;/a&gt;. UNDEFINED exceptions can occur, but only when something goes wrong and usually lead to the game crashing; they do not occur under normal operation. &lt;a href=&quot;#fnref:arm-exceptions&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 30 Jun 2017 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2017/06/30/cracking-gba-bios/</link>
        <guid isPermaLink="true">https://mgba.io/2017/06/30/cracking-gba-bios/</guid>
        
        <category>emulation</category>
        
        <category>hardware</category>
        
        <category>patreon</category>
        
        
      </item>
    
      <item>
        <title>mGBA 0.6 beta 1</title>
        <description>&lt;p&gt;mGBA 0.6.0 has been long delayed. It’s dense with new features and unfortunately not all of those features are hugely well-tested. However, it’s almost ready for release. Before a stable release, more comprehensive testing is needed. In the getting out what’s already working and promoting testing, mGBA 0.6 beta 1 is now available. The final release of mGBA 0.6.0 should be out within a few weeks.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The following features are either new and not very well tested or heavily revamped and in need of more testing. Please focus on these while testing and report any and all bugs on &lt;a href=&quot;https://mgba.io/i/&quot;&gt;GitHub&lt;/a&gt; or email bugs@mgba.io.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Game Boy support got some pretty serious changes and may be buggy in some cases.&lt;/li&gt;
  &lt;li&gt;The new debugging tools, such as the command-line debugger and the sprite viewer, may be prone to deadlocking or crashing.&lt;/li&gt;
  &lt;li&gt;The library view is quite new and not heavily tested yet.&lt;/li&gt;
  &lt;li&gt;There are now translations for German and Spanish that are not well reviewed and partially incomplete.&lt;/li&gt;
  &lt;li&gt;Performance. The core event timing was rewritten and should be faster, but may be slower in some cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following changes were made between 0.5.2 and 0.6 beta 1:&lt;/p&gt;

&lt;p&gt;Features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;GBA: Support printing debug strings from inside a game&lt;/li&gt;
  &lt;li&gt;GBA: Better cheat type autodetection&lt;/li&gt;
  &lt;li&gt;GB: Tile viewer&lt;/li&gt;
  &lt;li&gt;Sprite viewer&lt;/li&gt;
  &lt;li&gt;Debugging console&lt;/li&gt;
  &lt;li&gt;Improved memory viewer&lt;/li&gt;
  &lt;li&gt;GB: LR35902/GB-Z80 disassembler&lt;/li&gt;
  &lt;li&gt;Configuration of gamepad hats&lt;/li&gt;
  &lt;li&gt;Qt: Spanish translation (by Kevin López)&lt;/li&gt;
  &lt;li&gt;Add option for whether rewinding restores save games&lt;/li&gt;
  &lt;li&gt;Qt: German translation (by Lothar Serra Mari)&lt;/li&gt;
  &lt;li&gt;Savestates now contain any RTC override data&lt;/li&gt;
  &lt;li&gt;Command line ability to override configuration values&lt;/li&gt;
  &lt;li&gt;Add option to allow preloading the entire ROM before running&lt;/li&gt;
  &lt;li&gt;GB: Video/audio channel enabling/disabling&lt;/li&gt;
  &lt;li&gt;Add option to lock video to integer scaling&lt;/li&gt;
  &lt;li&gt;Video log recording for testing and bug reporting&lt;/li&gt;
  &lt;li&gt;Library view&lt;/li&gt;
  &lt;li&gt;Debugger: Segment/bank support&lt;/li&gt;
  &lt;li&gt;GB: Symbol table support&lt;/li&gt;
  &lt;li&gt;GB MBC: Add MBC1 multicart support&lt;/li&gt;
  &lt;li&gt;Implement keypad interrupts&lt;/li&gt;
  &lt;li&gt;LR35902: Watchpoints&lt;/li&gt;
  &lt;li&gt;Memory search&lt;/li&gt;
  &lt;li&gt;Debugger: Execution tracing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bugfixes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;LR35902: Fix core never exiting with certain event patterns&lt;/li&gt;
  &lt;li&gt;GB Timer: Improve DIV reset behavior&lt;/li&gt;
  &lt;li&gt;GBA Memory: Improve initial skipped BIOS state&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Implement BitUnPack&lt;/li&gt;
  &lt;li&gt;ARM7: Fix MLA/*MULL/*MLAL timing&lt;/li&gt;
  &lt;li&gt;GBA: Fix multiboot ROM loading&lt;/li&gt;
  &lt;li&gt;Libretro: Fix saving in GB games (fixes &lt;a href=&quot;https://mgba.io/i/486&quot;&gt;#486&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;LR35902: Fix pc overflowing current region off-by-one&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix ROM bank overflows getting set to bank 0&lt;/li&gt;
  &lt;li&gt;Qt: Fix timing issues on high refresh rate monitors&lt;/li&gt;
  &lt;li&gt;GBA Savedata: Fix savedata unmasking (fixes &lt;a href=&quot;https://mgba.io/i/441&quot;&gt;#441&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Util: Fix overflow when loading invalid UPS patches&lt;/li&gt;
  &lt;li&gt;Tools: Fix recurring multiple times over the same library&lt;/li&gt;
  &lt;li&gt;GBA I/O: Handle audio registers specially when deserializing&lt;/li&gt;
  &lt;li&gt;Util: Fix highest-fd socket not being returned by SocketAccept&lt;/li&gt;
  &lt;li&gt;Qt: Fix linking after some windows have been closed&lt;/li&gt;
  &lt;li&gt;GBA Video: Fix wrong palette on 256-color sprites in OBJWIN&lt;/li&gt;
  &lt;li&gt;Windows: Fix VDir.rewind&lt;/li&gt;
  &lt;li&gt;SDL: Fix game crash check&lt;/li&gt;
  &lt;li&gt;SDL: Fix race condition with audio thread when starting&lt;/li&gt;
  &lt;li&gt;GB: Fix flickering when screen is strobed quickly&lt;/li&gt;
  &lt;li&gt;FFmpeg: Fix overflow and general issues with audio encoding&lt;/li&gt;
  &lt;li&gt;Qt: Fix crash when changing audio settings after a game is closed&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Fix ArcTan sign in HLE BIOS&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Fix ArcTan2 sign in HLE BIOS (fixes &lt;a href=&quot;https://mgba.io/i/689&quot;&gt;#689&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GBA Video: Don’t update background scanline params in mode 0 (fixes &lt;a href=&quot;https://mgba.io/i/377&quot;&gt;#377&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Qt: Ensure CLI backend is attached when submitting commands (fixes &lt;a href=&quot;https://mgba.io/i/662&quot;&gt;#662&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Core: Fix crash with rewind if savestates shrink&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when loading invalid file&lt;/li&gt;
  &lt;li&gt;GBA Hardware: Fix crash if a savestate lies about game hardware&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when fuzzing fails to load a file&lt;/li&gt;
  &lt;li&gt;GBA: Fix multiboot loading resulting in too small WRAM&lt;/li&gt;
  &lt;li&gt;Test: Don’t rely on core for frames elapsed&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when loading invalid file&lt;/li&gt;
  &lt;li&gt;GBA Hardware: Fix crash if a savestate lies about game hardware&lt;/li&gt;
  &lt;li&gt;Test: Fix crash when fuzzing fails to load a file&lt;/li&gt;
  &lt;li&gt;Qt: Disable “New multiplayer window” when MAX_GBAS is reached (fixes &lt;a href=&quot;https://mgba.io/i/107&quot;&gt;#107&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;LR35902: Fix decoding LD r, $imm and 0-valued immediates (fixes &lt;a href=&quot;https://mgba.io/i/735&quot;&gt;#735&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;GB: Fix STAT blocking&lt;/li&gt;
  &lt;li&gt;GB MBC: Fix swapping carts not detect new MBC&lt;/li&gt;
  &lt;li&gt;GB Timer: Fix DIV batching if TAC changes&lt;/li&gt;
  &lt;li&gt;GB Video: Reset renderer when loading state&lt;/li&gt;
  &lt;li&gt;GBA BIOS: Fix INT_MIN/-1 crash&lt;/li&gt;
  &lt;li&gt;GBA Savedata: Update and fix Sharkport importing (fixes &lt;a href=&quot;https://mgba.io/i/658&quot;&gt;#658&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;OpenGL: Fix some shaders causing offset graphics&lt;/li&gt;
  &lt;li&gt;Qt: Fix game unpausing after frame advancing and refocusing&lt;/li&gt;
  &lt;li&gt;GB Timer: Fix sub-M-cycle DIV reset timing and edge triggering&lt;/li&gt;
  &lt;li&gt;Core: Fix interrupting a thread while on the thread (fixes &lt;a href=&quot;https://mgba.io/i/692&quot;&gt;#692&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Core: Fix directory sets crashing on close if base isn’t properly detached&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Misc:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SDL: Remove scancode key input&lt;/li&gt;
  &lt;li&gt;GBA Video: Clean up unused timers&lt;/li&gt;
  &lt;li&gt;Test: Add a basic test suite&lt;/li&gt;
  &lt;li&gt;GBA Video: Allow multiple handles into the same tile cache&lt;/li&gt;
  &lt;li&gt;VFS: Call msync when syncing mapped data&lt;/li&gt;
  &lt;li&gt;GBA Video, GB Video: Colors are now fully scaled&lt;/li&gt;
  &lt;li&gt;VFS: Allow truncating memory chunk VFiles&lt;/li&gt;
  &lt;li&gt;Debugger: Modularize CLI debugger&lt;/li&gt;
  &lt;li&gt;Core: Clean up some thread state checks&lt;/li&gt;
  &lt;li&gt;Debugger: Make building with debugging aspects optional&lt;/li&gt;
  &lt;li&gt;GBA Memory: Support for Mo Jie Qi Bing by Vast Fame (taizou)&lt;/li&gt;
  &lt;li&gt;GBA Memory: Support reading/writing POSTFLG&lt;/li&gt;
  &lt;li&gt;Util: Add size counting to Table&lt;/li&gt;
  &lt;li&gt;Qt: Move last directory setting from qt.ini to config.ini&lt;/li&gt;
  &lt;li&gt;3DS, PSP2, Wii: Last directory loaded is saved&lt;/li&gt;
  &lt;li&gt;GB Audio: Simplify envelope code&lt;/li&gt;
  &lt;li&gt;GB Audio: Improve initial envelope samples&lt;/li&gt;
  &lt;li&gt;Debugger: Add functions for read- or write-only watchpoints&lt;/li&gt;
  &lt;li&gt;GBA DMA: Refactor DMA out of memory.c&lt;/li&gt;
  &lt;li&gt;GBA DMA: Move DMAs to using absolute timing&lt;/li&gt;
  &lt;li&gt;All: Add C++ header guards&lt;/li&gt;
  &lt;li&gt;GBA I/O: Clear JOYSTAT RECV flag when reading JOY_RECV registers&lt;/li&gt;
  &lt;li&gt;GBA I/O: Set JOYSTAT TRANS flag when writing JOY_TRANS registers&lt;/li&gt;
  &lt;li&gt;Qt: Improved HiDPI support&lt;/li&gt;
  &lt;li&gt;Qt: Expose configuration directory&lt;/li&gt;
  &lt;li&gt;Feature: Move game database from flatfile to SQLite3&lt;/li&gt;
  &lt;li&gt;GB Audio: Start implementing “zombie” audio (fixes &lt;a href=&quot;https://mgba.io/i/389&quot;&gt;#389&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;VFS: Fix some minor VFile issues with FILEs&lt;/li&gt;
  &lt;li&gt;Core: Add generic checksum function&lt;/li&gt;
  &lt;li&gt;Feature: Support ImageMagick 7&lt;/li&gt;
  &lt;li&gt;All: Move time.h include to common.h&lt;/li&gt;
  &lt;li&gt;CMake: Add ability to just print version string&lt;/li&gt;
  &lt;li&gt;Qt: Merge “Save” and “OK” buttons in shader options&lt;/li&gt;
  &lt;li&gt;SDL: Automatically map controllers when plugged in&lt;/li&gt;
  &lt;li&gt;Qt: Automatically load controller profile when plugged in&lt;/li&gt;
  &lt;li&gt;OpenGL: Add xBR-lv2 shader&lt;/li&gt;
  &lt;li&gt;GBA, GB: ROM is now unloaded if a patch is applied&lt;/li&gt;
  &lt;li&gt;Util: Add 8-bit PNG write support&lt;/li&gt;
  &lt;li&gt;Qt: Rename “Resample video” option to “Bilinear filtering”&lt;/li&gt;
  &lt;li&gt;GBA Video: Optimize when BLD* registers are written frequently&lt;/li&gt;
  &lt;li&gt;Core: Cores can now have multiple sets of callbacks&lt;/li&gt;
  &lt;li&gt;GBA: Ignore invalid opcodes used by the Wii U VC emulator&lt;/li&gt;
  &lt;li&gt;Qt: Remove audio thread&lt;/li&gt;
  &lt;li&gt;Qt: Remove audio buffer sizing in AudioProcessorQt&lt;/li&gt;
  &lt;li&gt;Qt: Re-enable QtMultimedia on Windows&lt;/li&gt;
  &lt;li&gt;FFmpeg: Return false if a file fails to open&lt;/li&gt;
  &lt;li&gt;FFmpeg: Force MP4 files to YUV420P&lt;/li&gt;
  &lt;li&gt;Qt: Make “Mute” able to be bound to a key&lt;/li&gt;
  &lt;li&gt;Core: Restore sleep callback&lt;/li&gt;
  &lt;li&gt;Qt: Add .gb/.gbc files to the extension list in Info.plist&lt;/li&gt;
  &lt;li&gt;Feature: Make -l option explicit&lt;/li&gt;
  &lt;li&gt;Core: Ability to enumerate and modify video and audio channels&lt;/li&gt;
  &lt;li&gt;Debugger: Make attaching a backend idempotent&lt;/li&gt;
  &lt;li&gt;VFS: Optimize expanding in-memory files&lt;/li&gt;
  &lt;li&gt;VFS: Add VFileFIFO for operating on circle buffers&lt;/li&gt;
  &lt;li&gt;Core: Move rewind diffing to its own thread&lt;/li&gt;
  &lt;li&gt;Util: Tune patch-fast extent sizes&lt;/li&gt;
  &lt;li&gt;Qt: Relax hard dependency on OpenGL&lt;/li&gt;
  &lt;li&gt;GB Video: Improved video timings&lt;/li&gt;
  &lt;li&gt;Core: List memory segments in the core&lt;/li&gt;
  &lt;li&gt;Core: Move savestate creation time to extdata&lt;/li&gt;
  &lt;li&gt;Debugger: Add mDebuggerRunFrame convenience function&lt;/li&gt;
  &lt;li&gt;GBA Memory: Remove unused prefetch cruft&lt;/li&gt;
  &lt;li&gt;GB: Trust ROM header for number of SRAM banks (fixes &lt;a href=&quot;https://mgba.io/i/726&quot;&gt;#726&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Core: Config values can now be hexadecimal&lt;/li&gt;
  &lt;li&gt;GB: Reset with initial state of DIV register&lt;/li&gt;
  &lt;li&gt;GB MBC: New MBC7 implementation&lt;/li&gt;
  &lt;li&gt;Qt: Better highlight active key in control binding&lt;/li&gt;
  &lt;li&gt;Core: Improved threading interrupted detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get it now in the &lt;a href=&quot;/downloads.html&quot;&gt;Downloads&lt;/a&gt; section. Binaries are available for Windows, Ubuntu, macOS, 3DS, Wii, and Vita, and the source code is available for all other platforms.&lt;/p&gt;
</description>
        <pubDate>Thu, 29 Jun 2017 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2017/06/29/mgba-0.6-beta1/</link>
        <guid isPermaLink="true">https://mgba.io/2017/06/29/mgba-0.6-beta1/</guid>
        
        <category>announcement</category>
        
        <category>release</category>
        
        
      </item>
    
      <item>
        <title>&quot;Holy Grail&quot; Bugs in Emulation, Part 1</title>
        <description>&lt;p&gt;When developing a video game emulator the goal is to run software for that system on different hardware than the original. Further, the goal of an &lt;em&gt;accurate&lt;/em&gt; video game emulator is to run &lt;em&gt;every&lt;/em&gt; piece software for that system perfectly—or at least as close an approximation as possible. A decent emulator can be developed working from documentation of how a system behaves when running software. For the Game Boy Advance and Nintendo DS, such documentation is &lt;a href=&quot;http://problemkaputt.de/gbatek.htm&quot;&gt;GBATEK&lt;/a&gt;; for the Game Boy, the &lt;a href=&quot;http://gbdev.gg8.se/wiki/articles/Main_Page&quot;&gt;GBDev wiki&lt;/a&gt; is invaluable.&lt;/p&gt;

&lt;p&gt;Many of these document only say what will happen when the software is well-behaved. Software and hardware generally have a defined set of behaviors which, when given valid inputs, will (barring bugs) have well-defined outputs. For invalid inputs, documents often either say not to do that, or they don’t even mention them. But inevitably some software will do things that documents won’t talk about.&lt;/p&gt;

&lt;p&gt;There is the concept of &lt;a href=&quot;https://en.wikipedia.org/wiki/Garbage_in,_garbage_out&quot;&gt;Garbage In, Garbage Out&lt;/a&gt; where if the input is not valid, the output is not well defined. In such cases software may become buggy and act unpredictably; however, for perfect compatibility, emulators must maintain &lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Bug_compatibility&quot;&gt;bug-for-bug compatibility&lt;/a&gt;&lt;/em&gt; with the original system. While some sources document the “garbage-out” from invalid inputs, this information is often sparse and can be full of errata or missing edge cases.&lt;/p&gt;

&lt;p&gt;The actual debugging to discover these edge cases can be grueling. Yet even after days or weeks of research into just a single bug at a time, there are many bugs that are still incomprehensible and unsolved to the most seasoned of developers. Due to the extreme difficulty of tracking down and solving these issues I like to refer to them as &lt;em&gt;Holy Grail&lt;/em&gt; bugs.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;game-boy-bugs&quot;&gt;Game Boy Bugs&lt;/h2&gt;

&lt;p&gt;One thing about older game systems is that the hardware is often less refined and more full of edge cases and glitches. The Game Boy is a paragon example. Creating a basic Game Boy emulator is a relatively easy task and is often recommended to beginner emulator developers who want a simple target for one of their first projects. However, being full of edge cases and hardware bugs actually makes Game Boy an extremely difficult platform to emulate faithfully.&lt;/p&gt;

&lt;p&gt;Without a doubt bringing up a basic Game Boy emulator is far easier than bringing up a basic Game Boy Advance emulator. Counterintuitively however, I’ve found that debugging Game Boy emulation bugs can be far harder than debugging Game Boy Advance emulation bugs.&lt;/p&gt;

&lt;h3 id=&quot;pinball-fantasies&quot;&gt;Pinball Fantasies&lt;/h3&gt;

&lt;p class=&quot;note&quot;&gt;This section was partially written by Lior Halphon, who helped contribute much of the research involved.&lt;/p&gt;

&lt;p class=&quot;gallery&quot;&gt;&lt;img src=&quot;/assets/pinball-fantasies-title.png&quot; alt=&quot;Pinball Fantasies title screen&quot; /&gt; &lt;img src=&quot;/assets/pinball-fantasies-crash.png&quot; alt=&quot;Pinball Fantasies crash&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Amongst Game Boy emulator developers there is a notorious game that works seemingly properly in inaccurate emulators but invariably crashes after seconds of gameplay in accuracy-focused emulators: Pinball Fantasies (as well as the nearly-identical title Pinball Deluxe&lt;sup id=&quot;fnref:pinball-titles&quot;&gt;&lt;a href=&quot;#fn:pinball-titles&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;). Even &lt;a href=&quot;https://github.com/sinamas/gambatte&quot;&gt;gambatte&lt;/a&gt; and &lt;a href=&quot;http://bgb.bircd.org&quot;&gt;BGB&lt;/a&gt;, by far the two most accurate Game Boy emulators, fail spectacularly in this game.&lt;/p&gt;

&lt;p&gt;So why does the game break so utterly the more accurate the emulator gets? No one quite knows. The issue appears to stem from a slight timing issue, although where remains unknown. While a slight timing issue of this sort generally can cause frames to be duplicated erroneously or other small (but noticeable) issues, Pinball Fantasies appears to have been written in such a way that the issue actually cascades and causes the whole game to crash. But then why does this game work well in inaccurate emulators? That’s also a bit of a mystery, but it’s possibly because their timings are just wrong enough that things do not end up cascading the same way.&lt;/p&gt;

&lt;p&gt;Typical speculation involves screen timing issues. The Game Boy’s pixel processing unit (PPU) operates in a series of “modes” that tell the software what the PPU is currently doing. Mode 1 means that there are no scanlines currently drawing (either because it’s in-between frames, or the screen itself is off), and the other modes tell the game what part of a scanline is being processed: sprites, the actual pixel data, or if it’s in-between scanlines. However, various configurations of screen settings and sprites cause minute differences in the timings of these modes. The Game Boy can draw up to 10 sprites (also known as objects or OBJs) per scanline but the exact configuration of these sprites very slightly affects the timing of the PPU itself. Furthermore screen panning and “window” features also affect the timing. A scanline that has no sprites, no panning and no windows on it takes a well defined, well understood number of cycles for each of the modes. While how panning and windows affect timing is understood, once sprites are added  the timings become harder to decipher. Gekkio, author of the accuracy-focused emulator &lt;a href=&quot;https://github.com/Gekkio/mooneye-gb&quot;&gt;Mooneye GB&lt;/a&gt;, created a test suite for many of the PPU timings, including the effects of sprites, and neither BGB nor gambatte pass this test.&lt;/p&gt;

&lt;p&gt;However, &lt;a href=&quot;https://github.com/LIJI32/SameBoy&quot;&gt;SameBoy&lt;/a&gt; developer Lior Halphon did some investigation. By disabling certain features that affect scanline timings and comparing behavior in SameBoy with behavior on a Game Boy Color he determined that scanline timings were likely not the culprit. In fact, while experimenting with timing of other portions of the system Lior and I temporarily introduced many incorrect behaviors, mostly involving interrupts, each one seemed to fix the game. But all of these behaviors was incorrect and would undoubtedly break other games.&lt;/p&gt;

&lt;p&gt;Another possibility beyond timing effects of the PPU is just one of several of the other incorrectly emulated timing quirks of the Game Boy. While it is possible that each one of these quirks are emulated correctly on at least one emulator, for the game to actually work an emulator needs to either emulate all quirks perfectly or emulate specific subsets of these quirks that by chance happen to work. This also both explains why some inaccurate emulators manage to run this game, and why &lt;em&gt;introducing&lt;/em&gt; timing bugs to accurate emulators sometimes fix this game.&lt;/p&gt;

&lt;h3 id=&quot;stat-irq-glitches&quot;&gt;STAT IRQ glitches&lt;/h3&gt;

&lt;p class=&quot;gallery&quot;&gt;&lt;img src=&quot;/assets/altered-space-bugged.png&quot; alt=&quot;Altered Space without STAT glitches emulated&quot; /&gt; &lt;img src=&quot;/assets/altered-space.png&quot; alt=&quot;How Altered Space is supposed to run&quot; /&gt;&lt;/p&gt;

&lt;p&gt;One of the less-well explained, less-well known issues with the Game Boy is a series of strange behaviors regarding the STAT register and its related &lt;a href=&quot;https://en.wikipedia.org/wiki/Interrupt_request_(PC_architecture)&quot;&gt;IRQs&lt;/a&gt;. The register itself contains information about the current mode of the PPU, as well as flags that allow it to trigger an interrupt upon entering different modes. It also has a flag to enable LYC, a way to trigger an interrupt on a specific scanline.&lt;/p&gt;

&lt;p&gt;However, there are two very noteworthy bugs relating to this register that are fairly poorly documented. The first glitch actually involves how IRQs work at a hardware level. The Game Boy CPU has several possible IRQs, but all of the separate conditions that the STAT register controls are mapped to the same IRQ, collectively known as the STAT IRQ.&lt;/p&gt;

&lt;p&gt;The PPU triggers the STAT IRQ on the CPU itself by adjusting the level of the STAT IRQ line — changing one signal from a 0 to a 1&lt;sup id=&quot;fnref:line-level&quot;&gt;&lt;a href=&quot;#fn:line-level&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; to tell the CPU that a STAT IRQ condition has been fulfilled and an interrupt should occur. STAT IRQs are &lt;a href=&quot;https://en.wikipedia.org/wiki/Signal_edge&quot;&gt;edge-triggered&lt;/a&gt;, meaning that the interrupt occurs when the signal changes from a 0 to a 1, and not whenever a signal is 1. This prevents an interrupt from occurring a second time while the signal is 1 and the interrupt has already been acknowledged by the system.&lt;/p&gt;

&lt;p&gt;Edge triggers are very common in electronics engineering. Level-triggered interrupts, as mentioned, can cause interrupts to occur multiple times even if the state hasn’t changed&lt;sup id=&quot;fnref:ds-gxfifo-irq&quot;&gt;&lt;a href=&quot;#fn:ds-gxfifo-irq&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, making edge triggers far more common for this. However, in this case by trying to prevent the IRQ from occurring more than once it introduced a bug where IRQs can get missed.&lt;/p&gt;

&lt;p&gt;There is very little documentation that talks about this bug, which is sometimes referred to as &lt;em&gt;STAT IRQ blocking&lt;/em&gt;&lt;sup id=&quot;fnref:subjectivity&quot;&gt;&lt;a href=&quot;#fn:subjectivity&quot; class=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. It has long since been (at least partially) implemented in BGB and gambatte, but many other Game Boy emulators lack emulation of this bug due to the fact that it is unintuitive and very little documentation mentions it.&lt;/p&gt;

&lt;p&gt;Gekkio provided insight into the matter explaining that when the PPU transitions between different modes that are both configured to trigger IRQs the IRQ line does not lower back to 0 before raising back to 1. The signal stays at 1 the whole time. Since this eliminates signal edges, the edge-triggered IRQ does not occur for that mode at all. This is where the name STAT IRQ blocking comes from: the STAT IRQ for the next mode is effectively blocked from occurring at all. This makes sense from a hardware perspective but to someone unfamiliar with signal triggering it might seem completely unintuitive.&lt;/p&gt;

&lt;p&gt;I independently discovered this issue while &lt;a href=&quot;https://board.byuu.org/viewtopic.php?p=25527#p25527&quot;&gt;debugging the game Altered Space&lt;/a&gt;. Without emulation of STAT IRQ blocking the graphics get corrupted and the game is otherwise generally broken. Altered Space is notorious for being buggy in many emulators, but once STAT IRQ blocking is implemented most of the bugs disappear entirely.&lt;/p&gt;

&lt;p&gt;The second glitch only occurs on the Game Boy, not on the Game Boy Color. When writing to the STAT register there are actually circumstances in which an interrupt will spuriously trigger &lt;em&gt;without any of the STAT IRQ conditions being fulfilled&lt;/em&gt;. As with seemingly all obscure hardware bugs there are games that rely on this bug as well. A commonly cited game is Legend of Zerd (ザードの伝説, also known as Legend of Xerd or Zerd no Densetsu), which immediately crashes if the bug is not emulated. Likewise, the game will not run on a Game Boy Color since the bug was fixed.&lt;/p&gt;

&lt;h2 id=&quot;game-boy-advance-bugs&quot;&gt;Game Boy Advance Bugs&lt;/h2&gt;

&lt;p class=&quot;gallery&quot;&gt;&lt;img src=&quot;/assets/madden-06.png&quot; alt=&quot;Madden 06 glitch&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For the Game Boy Advance there are three games that stand out as having Holy Grail bugs: Lady Sia has a few lines in the middle of the screen that are glitched in every emulator, Madden NFL 06 and 07 have an issue where the screen is stretched to the point where it’s impossible to make anything out, and Mega Man Battle Network 4 will crash in a certain area of the game. While it’s relatively easy to work around these issues, they still indicate insufficiencies in the accuracy of emulation.&lt;/p&gt;

&lt;h3 id=&quot;mega-man-battle-network-4&quot;&gt;Mega Man Battle Network 4&lt;/h3&gt;

&lt;p&gt;The most interesting game from this list is Mega Man Battle Network 4, specifically the Blue Moon version. Until very recently, the only option for emulating this game and avoiding a crash on the WoodMan stage was to patch the game. But more notably the game is also broken &lt;em&gt;on hardware&lt;/em&gt; on the original model Nintendo DS…but &lt;em&gt;not&lt;/em&gt; on the DS Lite! This is even noted on &lt;a href=&quot;http://www.nintendo.com/consumer/systems/gameboy/trouble_specificgame.jsp#megaman&quot;&gt;Nintendo’s website&lt;/a&gt; alongside mentions of the venerable MissingNo glitch and the “internal battery has run dry” message from third generation Pokémon games.&lt;/p&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/mmbn-woodman.png&quot; alt=&quot;The relevant portion of Mega Man Battle Network 4: Blue Moon&quot; /&gt;
The infamous crashing level&lt;/p&gt;

&lt;p&gt;The root cause of this issue involves the behavior of the Game Boy Advance when reading from invalid memory. Several things can occur if the CPU tries to read from a region of memory does not exist. On modern computers this is handled by what’s known as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Memory_management_unit&quot;&gt;memory management unit&lt;/a&gt; and gives a well defined result. On systems lacking an MMU the behavior can vary widely between approaches such as getting a &lt;a href=&quot;https://en.wikipedia.org/wiki/Bus_error&quot;&gt;bus error&lt;/a&gt; or reading a fixed value such as 0.&lt;/p&gt;

&lt;p&gt;On the GBA what happens when reading from invalid memory locations is something emulator developers often refer to as “open bus”. While specific hardware has different root causes for what triggers open bus behavior, the general idea behind open bus behavior is that instead of triggering an exception or reading 0, invalid reads get back the last value given to the CPU from that bus.&lt;/p&gt;

&lt;p&gt;Due to how the &lt;a href=&quot;/2014/12/28/classic-nes/#trick-5-prefetch-abuse&quot;&gt;instruction prefetch&lt;/a&gt; works on the Game Boy Advance the data for an upcoming instruction is fetched at the beginning every instruction. This is a few bytes ahead of where the current instruction is located. That value is therefore returned by the open bus.&lt;/p&gt;

&lt;p&gt;Of course, invalid reads should never happen in well programmed games. On the GBA there are quite a few games that are not well programmed. Even high profile games such as Minish Cap can break if open bus is not implemented. What makes the Mega Man Battle Network 4 bug unique involves an even more specific edge case relating to how the memory is read. This case is so specific and so obscure that even Nintendo didn’t realize it existed while developing the DS, leading to a hardware erratum.&lt;/p&gt;

&lt;p&gt;Nintendo is no stranger to hardware errata. I mentioned some of the Game Boy hardware bugs previously, but there are far more issues than just the handful covered. By the time the Game Boy Advance rolled around all models of the same device generally had the same errata. Thus, if one model of the Game Boy Advance had a bug (and indeed, the Game Boy Advance does have some strange hardware bugs), all further models would contain the same bugs.&lt;/p&gt;

&lt;p&gt;Yet there was one exception. Sure enough it was an edge case of an edge case of undefined behavior that would only occur in exceptionally specialized circumstances within buggy code. That buggy code happened to be called Mega Man Battle Network 4: Blue Moon.&lt;/p&gt;

&lt;p&gt;In April of 2015 Martin Korth, author of the historic NO$GBA emulator and other &lt;a href=&quot;http://problemkaputt.de&quot;&gt;“nocash” emulators&lt;/a&gt;, posted &lt;a href=&quot;http://ngemu.com/threads/gba-open-bus.170809/&quot;&gt;a thread on the NGEmu forums&lt;/a&gt; that described a newly discovered behavior that he had encountered while reading invalid memory locations. The Game Boy Advance runs an old ARM CPU, and ARM CPUs of that vintage can run in two modes: ARM mode and Thumb mode. While the previous description of invalid memory reads was correct for ARM mode, the description for Thumb mode turned out to be incorrect…but only sometimes.&lt;/p&gt;

&lt;p&gt;As it turns out, depending on where the currently executing code was located, prefetch loads had slightly different effects on the memory bus. When running code directly off of the cartridge, from RAM, or from a handful of other places, the old description of Thumb behavior was correct. But there was one crucial case (and two minor cases) wherein this was incorrect.&lt;/p&gt;

&lt;p&gt;The Game Boy Advance has a second, smaller RAM bank that is located on the CPU itself. While the larger RAM bank is much larger, it is a discrete chip, making it slower to access than on-CPU memory. Thus this “internal working RAM”, as it is often called, is used for storing code that is timing-crucial. One such example is code for doing “mode 7” effects that must be executed once per scanline.&lt;/p&gt;

&lt;p&gt;The prefetch operations have slightly different effects on the open bus behavior that wasn’t discovered until much later. Mega Man Battle Network 4 would crash when finishing a battle in a certain section of WoodMan’s stage if this behavior wasn’t properly implemented. Nintendo noticed this before releasing the DS Lite, but it took emulator developers far longer.&lt;/p&gt;

&lt;p&gt;NO$GBA and mGBA became the first two emulators to properly implement this behavior, thus solving the first GBA Holy Grail Bug.&lt;/p&gt;

&lt;h3 id=&quot;lady-sia&quot;&gt;Lady Sia&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/lady-sia.png&quot; alt=&quot;Lady Sia glitch&quot; class=&quot;article-aside&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If there is an emulation bug that will haunt me to my grave it’s this one. I’ve dissected this bug down to the exact instruction where everything goes awry and I’m still not sure what is being emulated wrong to cause this issue. The visual effect of the glitch is simple: there’s a bar in the middle of the screen that shouldn’t be there. It flickers sometimes. It’s there in every emulator, but not on hardware. Tweaking the actual game itself to try and figure out if any perturbations cause the bug to appear on hardware didn’t reveal anything. It’s the most bizarre issue I’ve seen while working on mGBA.&lt;/p&gt;

&lt;p&gt;These sorts of graphical bugs are usually relatively simple to track down: figure out what is actually appearing when that bar shows up, figure out what’s causing it to appear there, and then figure out why the code is telling it to do that. Quite often, expectations about what the PPU should be doing in an odd case doesn’t reflect what a game’s expectations are, and the emulator developer needs to reconcile these to figure out what the actual behavior of hardware is.&lt;/p&gt;

&lt;p&gt;In this instance the bar is actually the bottom few pixels of the repeating pattern that makes up the ocean spray graphic. What’s causing it to appear there is that the game turns off that graphic layer in between frames and then says to turn it on about three scanlines higher than the actual repeat point of the texture. As for why the game is doing this? &lt;em&gt;I still don’t know&lt;/em&gt;. Even more interestingly, the exact timing of the toggle happens with some variability: due to audio timing the toggle can happen a few scanlines late, which is what leads to the signature flickering. However, this doesn’t happen at all on hardware.&lt;/p&gt;

&lt;p&gt;My best guess as to what’s happening is that background layer enabling and disabling is latched in such a way that enabling a layer won’t take effect until sometime after the layer itself is enabled by software. However, beyond this one bug I’ve seen no evidence to support this. While I have yet to test it on hardware I’ve seen enough games that I would expect to have run into another game that depends on this behavior.&lt;/p&gt;

&lt;p&gt;Changing rendering parameters in between scanlines is extremely common and the changes tend to take effect on the very next scanline. The most extreme example I’ve seen of this is Rayman 3 which actually changes the background mode in between scanlines. This fundamentally alters how VRAM is parsed by the PPU and what various graphics settings mean. I’d assumed up until I saw this that changing the mode while a frame is rendering would be impossible; I was proven wrong. Even this appears to effect the next scanline.&lt;/p&gt;

&lt;p&gt;If the background enable bits are indeed latched beyond the current scanline it would require thorough testing to figure out what the exact behavior is and extensive testing to make sure that changing this behavior to fix one game does not regress behavior in dozens of others. This bug defies everything I know about how background parameters work on the GBA and I have very few other ideas about what could be happening.&lt;/p&gt;

&lt;h3 id=&quot;madden-nfl-06-and-07&quot;&gt;Madden NFL 06 and 07&lt;/h3&gt;

&lt;p class=&quot;article-aside&quot;&gt;&lt;img src=&quot;/assets/madden-07.png&quot; alt=&quot;Madden 07 glitch&quot; /&gt;
There are supposed to be graphics here…&lt;/p&gt;

&lt;p&gt;The last of the Holy Grail bugs for the GBA is a bit more mundane than the others. While it doesn’t crash the game like Mega Man does it provides a bit more than a minor flickery nuisance that is in Lady Sia. When a game begins in Madden the player is presented with a coin-flip to determine who first has possession of the ball. Or something like that; I’m not familiar with the rules of the game. Regardless, due to this bug the entire screen is smeared and only sprites are visible. The entire background layer is just a mess of vertical stripes.&lt;/p&gt;

&lt;p&gt;As with the Lady Sia bug this should be relatively easy to track down. What’s going on is that the layer is no longer being scaled 1:1; instead it’s being stretched to being infinitely tall. This happens because the game overwrites the scaling parameters right before the frame is drawn. But what’s weird is that I have no idea why the game is overwriting the parameter in the first place. Before being overwritten the parameter is valid. If that write is blocked the game works fine. But for some reason the parameter gets overwritten and causes the jumble that is the game screen.&lt;/p&gt;

&lt;p&gt;While the exact solution to this issue might be as mundane as a simple timing issue with one of the memory subsystems this bug appears to plague every single GBA emulator. I’m really not quite sure why, and it leads me to believe there may be a deeper issue. The GBA may have another undocumented hardware bug. The write may be being blocked by hardware for an unknown reason. Again the solution is just unknown.&lt;/p&gt;

&lt;h3 id=&quot;dk-king-of-swing&quot;&gt;D.K.: King of Swing&lt;/h3&gt;

&lt;p&gt;An example of a bug that affected every single GBA emulator I tried it in (although it apparently worked in ancient VBA) but was &lt;em&gt;not&lt;/em&gt; in fact a Holy Grail bug was a glitch that would cause the game D.K.: King of Swing to crash upon entry to the Treacherous Twister level. What prevents this from qualifying is that the fix for the bug was actually to just follow the available documentation properly in one case. Even when working from correct documentation it is possible to misread or misremember a piece of the documentation and introduce bugs into the system. The root cause of this was such a case, and it just happened that all major emulators had overlooked this one small bit of information.&lt;/p&gt;

&lt;p&gt;The version of GBATEK I was working off of stated that one specific bit on a specific setting register was read-only. This bit, bit 15 of the WAITCNT register (address 0x4000204), specifies if the GBA is running in AGB or CGB mode. The game would try to set this bit to imply the hardware was in CGB mode, and fail if bit did get set. It’s unclear if this was intentional but it would crash upon entry to this level if the bit had the incorrect value. Despite this particular case being well-documented, every single emulator — including NO$GBA, which is by the author of GBATEK — had this bug. Given the wide presence of this bug and the simplicity of the fix I quickly reached out to developers of other GBA emulators. The bug has been fixed in all of them since.&lt;/p&gt;

&lt;h2 id=&quot;bugs-bugs-bugs&quot;&gt;Bugs, Bugs, Bugs…&lt;/h2&gt;

&lt;p&gt;As emulator development becomes increasingly in-depth focused on accuracy more and more obscure, poorly written games uncover more and more bizarre bugs. Undocumented behavior and bugs in the hardware itself are the bane of all emulator developers and there are certainly issues that have not yet been uncovered in virtually all consoles to date.&lt;/p&gt;

&lt;p&gt;There are many bugs and many stories that come from the pursuit of accurate emulation and this article only scratches the surface. In future articles I will be reaching out to other emulator developers for their Holy Grail bug stories.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:pinball-titles&quot;&gt;
      &lt;p&gt;Beyond the name and logo, I’m not entirely sure what the difference between these two titles is. Furthermore, there is also the related title Pinball Dreams, but I’ve not investigated if this game has similar issues. &lt;a href=&quot;#fnref:pinball-titles&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:line-level&quot;&gt;
      &lt;p&gt;Both the CPU and the PPU are contained within the same chip (the LR35902), so it’s hard to say if it’s a rising edge or falling edge without die shots. However, for simplicity I’m describing it as rising edge. &lt;a href=&quot;#fnref:line-level&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:ds-gxfifo-irq&quot;&gt;
      &lt;p&gt;One example of a level-triggered IRQ is the GXFIFO IRQ on the DS, which occurs when the graphics FIFO gets below a low-water mark. Until the FIFO fullness exceeds the low-water mark, an IRQ will always occur, even if the state of the FIFO does not change, after acknowledging the IRQ. &lt;a href=&quot;#fnref:ds-gxfifo-irq&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:subjectivity&quot;&gt;
      &lt;p&gt;I dislike the term STAT IRQ blocking because it implies an intent behind the bug. Perhaps a better term for this may be STAT IRQ dropping. &lt;a href=&quot;#fnref:subjectivity&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 29 May 2017 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2017/05/29/holy-grail-bugs/</link>
        <guid isPermaLink="true">https://mgba.io/2017/05/29/holy-grail-bugs/</guid>
        
        <category>emulation</category>
        
        <category>debugging</category>
        
        <category>patreon</category>
        
        
      </item>
    
      <item>
        <title>Emulation Accuracy, Speed, and Optimization</title>
        <description>&lt;p&gt;A commonly discussed topic in emulation is the “accuracy” of an emulator. The term means how close the emulation is to the behavior of the original hardware. However, there is a significant amount of complexity hidden behind this simple term. There is no simple metric for what makes an emulator “accurate”. Accuracy in emulators is thought to mean it’s slower, but has fewer bugs. Less accurate emulators are often said to be faster and “good enough” for most games. While there is a kernel of truth to these claims, there is far more to the reality of the matter.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;One of the most prevalent terms used to describe emulation accuracy is “cycle-accuracy”. The term has a specific meaning, but it is often misunderstood and over-broadly applied. Cycle accuracy, loosely, means that every single aspect of the emulated system occurs at the correct time relative to everything else. For many systems with tight timing and more direct access to the hardware, especially older systems, cycle accuracy is a key aspect of highly accurate emulation.&lt;/p&gt;

&lt;p&gt;The word “cycle” in this term refers to the fundamental unit of timing in digital logic: the clock cycle. The commonly discussed MHz and GHz quantities describing systems and processors refer to the frequency of the clock on that system. Thus, for a system that has a 16MHz processor, such as the Game Boy Advance, this means that the processor runs 16 million cycles per second. Another important piece of hardware, the bus, sometimes has a different clock rate. A bus is an interconnect that transports data between various components of the system, such as between the CPU and main memory. While the bus often runs at the same speed as the CPU, such as it does in the GBA, this is not a guarantee: in the Nintendo DS, there are two processors, the ARM7 (the same CPU as the GBA) and the ARM9, which run at different clock speeds (approximately 33MHz and 67MHz respectively), however the bus runs at the same 33MHz as the ARM7. As a result, the ARM9 may have to wait on the slower bus to get data from memory that it could get more quickly if the bus were the same speed as the ARM9’s clock rate.&lt;/p&gt;

&lt;p&gt;Cycle-count accuracy is a similar concept, but instead of every piece of hardware being emulated on the correct cycle relative to other components that act concurrently, each component acts atomically and takes the correct amount of time, but may not overlap properly with the timing of other hardware. As such, cycle-count accuracy may sound strictly inferior to cycle accuracy, and from a perfect hardware accuracy perspective, it is the case. However, cycle-count accuracy is much a much easier style of emulation to design, implement, and maintain. It is a common misconception that mGBA is now or will become cycle accurate, but to do so would require a major rewrite of some of the foundational elements of mGBA. When implemented well, cycle-count accuracy will produce very similar, and often identical, results.&lt;/p&gt;

&lt;p&gt;The primary problem that cycle accuracy solves is correctly emulating different pieces of hardware performing actions &lt;em&gt;on the same cycle&lt;/em&gt;. This may sound easy like an easy task: perform all of the individual steps that occur on a given cycle, in order, go to the next cycle, and repeat. This can become quite slow, and introduces the major difference in performance between cycle accuracy and cycle-count designs. Hardware performs all of these steps independently on any given cycle. Software is not able to perform these steps in parallel and must swap between operations. This is computationally expensive and thus &lt;em&gt;slow&lt;/em&gt;. Let’s take a look at an example.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/cycle-accuracy-comparison.svg&quot; alt=&quot;&quot; class=&quot;hero&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Assume for a moment that you have a simple CPU architecture where one operation on the CPU always takes 2 cycles, and the GPU reads a value from memory to a pixel every 1 cycle. In theory, this is emulated one cycle at a time. Perform the first half of the CPU’s operation, then do one GPU pixel draw. Next, do the second half of the CPU’s operation, and do another pixel draw. But there are many hidden complexities beneath the theory. You have to know what part of a CPU instruction happens on any given cycle, which is often implementation dependent and poorly defined. You also have to be able to store the half-finished operation to return to it later. That entails additional complexity over an atomic design, resulting in a performance hit. In an atomic design, operations are not split per cycle. Instead, each operation runs until completion, then further operations can be performed. However, if you get the order of things wrong, there can be visible consequences. One example is when memory accesses can interfere with the GPU operations, incorrect timing can result in incorrect graphics.&lt;/p&gt;

&lt;p&gt;Despite these issues, atomic operations are the basis of cycle-count accuracy. When dealing with different pieces of hardware, cycle-count accuracy has the individual operations take the correct number of cycles, and has operations able appear as if they’re occurring in the past. Combined, these create a good, though not perfect, approximation of cycle accuracy. In a cycle-count accurate model, CPU instructions cannot be pre-empted or interrupted, and other pieces of hardware operations are performed in between CPU instructions. However, by being able to schedule these hardware bits to appear in the past, they can all still take the right amount of time. The primary downside of this approach is that concurrent operations which would interact on the original hardware cannot be properly interlaced. However, depending on the age and complexity of the system, such interactions may be exceedingly rare. While older systems are full of edge cases and complex interactions, newer systems are generally more carefully designed and contain protections that prevent such interactions from occurring at all. This makes newer systems a much more attractive target for cycle-count accuracy. It’s faster and almost always “good enough”.&lt;/p&gt;

&lt;p&gt;But then, what qualifies as “good enough”? It’s a subjective and contentious subject. If a game is playable without significant, obvious bugs, most players may say it’s good enough. However, for speedrunners and TASing, any lack of accuracy is a problem. For a very long time ZSNES, while wildly inaccurate, was considered by a large swath of the SNES emulation community to be “good enough”. Even with low accuracy, many games can run near perfectly. There were always the edge cases where ZSNES fell apart entirely, but most popular games were emulated well enough that increased accuracy was not a priority. For many people, this was “good enough”. For some people, it still is. But it was far from perfect, and that sat poorly with some people.&lt;/p&gt;

&lt;p&gt;This lead to the creation of what is the most well-known example of a cycle-accurate emulator: &lt;a href=&quot;https://byuu.org/emulation/higan/&quot;&gt;higan&lt;/a&gt; (formerly bsnes). It is legendarily accurate, but also infamously slow. This is in part due to the fact that it is cycle accurate. It uses &lt;a href=&quot;https://en.wikipedia.org/wiki/Coroutine&quot;&gt;co-routines&lt;/a&gt; to switch between portions of the emulation as needed, which has a lot of overhead. Because higan is the best-known example of a cycle-accurate emulator, it has led to the misconception that cycle accuracy is necessarily extremely slow. However, much of higan’s performance issues are because the emulation is not optimized for speed. This was an intentional decision on byuu’s part to make sure that the code is ultimately readable and understandable, as byuu maintains a strict &lt;a href=&quot;https://en.wikipedia.org/wiki/Self-documenting_code&quot;&gt;code as documentation&lt;/a&gt; policy. Beyond being a means to play SNES games, byuu treats higan as a preservation project and documentation on the behavior of the SNES itself. It is possible to make a highly optimized &lt;em&gt;and&lt;/em&gt; accurate SNES emulator that would be significantly faster than higan without sacrificing much accuracy; however, no one has done this. It’s quite a daunting task, after all.&lt;/p&gt;

&lt;p&gt;When I started working on mGBA, my goals for it were for it to be both &lt;em&gt;more&lt;/em&gt; accurate than VisualBoyAdvance, and also &lt;em&gt;faster&lt;/em&gt;. While these two goals are often in opposition, there is much more to accuracy than just timing. Sometimes it comes down to issues such as incorrect graphics rendering, or invalid memory operations not being emulated properly. I found that VisualBoyAdvance had many areas that lacked great optimization, and many of the accuracy improvements required did not impact speed. With the increased speed, I also had overhead I could use to make accuracy improvements that did impact speed.&lt;/p&gt;

&lt;p&gt;Unlike the GBA emulation, the Game Boy emulation in mGBA (also known as mGB), is designed with cycle accuracy in mind. Instruction emulation is divided into tasks which occur on individual clock cycles and in between these operations other hardware can be emulated. However, through many optimizations, such as batching operations instead of running them one at a time (and splitting up a batch as needed when there are concurrent interactions), mGB is quite fast. It is far faster than an unoptimized cycle-accurate implementation would be, without sacrificing accuracy.&lt;/p&gt;

&lt;p&gt;A notable example of where cycle-count accuracy is an impediment is in the upcoming DS emulation’s GPU command &lt;a href=&quot;https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)&quot;&gt;FIFO&lt;/a&gt;. When writing commands to the GPU, the DS constructs a list of commands that have not yet been processed. New commands get appended into this list. However, the FIFO has a maximum size. When it fills up, writes block until the FIFO has enough space for the new commands. On real hardware, if the FIFO is full, the memory bus stalls, causing the ARM CPU to temporarily block in the middle of this instruction. The FIFO is then read by the GPU independently of the memory bus, and finally the memory bus can continue. Since CPU operations in medusa are treated as atomic, stalling the memory bus and processing the FIFO in the GPU in the middle of an instruction is not possible. Instead, the way medusa handles writing to a full FIFO is by caching the value to be written and telling the CPU that it cannot execute new instructions until the FIFO has space and the cached value is flushed into the FIFO. However, the ARM CPU has a set of instructions that allow you to write more than one value into memory at a time.  This means that it is possible to write more than one command into the FIFO in a single instruction and the memory bus may stall in between writes: e.g., if you write 3 commands into the FIFO, but it can only fit 1, it will stall before the third one even tries to write. This poses a large problem for medusa. The current approach, which actually violates cycle-count accuracy, is to process enough of the FIFO immediately to write the new commands. This is one specific edge case, but it is incorrect behavior and will need to be addressed.&lt;/p&gt;

&lt;p&gt;Going even further away from cycle-accuracy is the concept of high-level emulation, or HLE. Many video game systems, especially since the late ’90s, have programmable components that are not part of the emulated software itself: the components are part of the system itself and do not have major differences between games. Some examples are DSPs (as on the GameCube), system software (as on the PSP and 3DS), and &lt;a href=&quot;https://en.wikipedia.org/wiki/Microcode&quot;&gt;microcode&lt;/a&gt;-programmable devices such as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Reality_Coprocessor&quot;&gt;RSP&lt;/a&gt; on the Nintendo 64. While these components can be emulated directly (referred to as low-level emulation or LLE), it is actually possible to get away with not emulating them step by step, instruction by instruction. By writing a custom implementation of the component that has the same visible effect to the hardware, but is run as native code, instead of emulated step by step, it is possible to significantly speed up the operation. One of the downsides is that synchronization with different hardware components and proper timing becomes nearly impossible. Furthermore, HLE implementations require significant amounts of research not just on the hardware itself, but also on the microcode that runs on that hardware. Early HLE implementations are often riddled with bugs that wouldn’t be present in LLE, and can be very difficult to debug. LLE implementations, however, require copies of the code to be emulated, which is not always easy to dump, and cannot be distributed with the emulator itself due to copyrights.&lt;/p&gt;

&lt;p&gt;Tradeoffs between accuracy and speed are a difficult proposition. For older systems, accuracy is almost always preferable as they are already quite fast to emulate and usually contain tighter timing restrictions. With modern systems, HLE is practically required to emulate the systems at all. It’s a difficult balance, and there are advantages to both sides. In general, accuracy will have fewer issues in the emulated software and be more valuable for preservation, but for speed and emulating recent platforms, accuracy is not always a necessity.&lt;/p&gt;
</description>
        <pubDate>Sun, 30 Apr 2017 00:00:00 -0700</pubDate>
        <link>https://mgba.io/2017/04/30/emulation-accuracy/</link>
        <guid isPermaLink="true">https://mgba.io/2017/04/30/emulation-accuracy/</guid>
        
        <category>development</category>
        
        <category>emulation</category>
        
        <category>hardware</category>
        
        <category>patreon</category>
        
        
      </item>
    
  </channel>
</rss>
