melonDS aims at providing fast and accurate Nintendo DS emulation. While it is still a work in progress, it has a pretty solid set of features:

• Nearly complete core (CPU, video, audio, ...)
• JIT recompiler for fast emulation
• OpenGL renderer, 3D upscaling
• RTC, microphone, lid close/open
• Joystick support
• Savestates
• Various display position/sizing/rotation modes
• (WIP) Wifi: local multiplayer, online connectivity
• (WIP) DSi emulation
• DLDI
• (WIP) GBA slot add-ons
• and more are planned!







Download melonDS

If you're running into trouble: Howto/FAQ
melonDS 1.0 is out
Finally, the "proper" melonDS 1.0 release is here. Sorry that it took so long...


Anyway, this is pretty much the same as the 1.0 RC, but we fixed a bunch of bugs that were found in said RC.


Namely, you can now use multiple windows with OpenGL under Windows.

However, depending on how good your OpenGL driver is, doing so may reduce performance. It's due to having multiple OpenGL contexts sharing data, but for now we don't really know what we can do about it. If you have ideas, let us know!

Speaking of multiple windows, I also added a way to tell melonDS windows apart, because things could get pretty confusing. They now get a tag in their title, for example [p1:w2] means first multiplayer instance, second window.


We also merged asie's add-on support PR, so this release includes support for the Motion Pak and the Guitar Grip.

We merged some other PRs. Among which, lower audio latency.


This release also includes the DSi camera fixes that were discussed in the previous posts. DSi titles that ran into issues while trying to use the camera should now work with no problems.

However, since they tend to also use the DSP at the same time, the performance will be abysmal...

... read more
Let's Golf: the horseman of apocalypse that wasn't one
I figure I need to resolve the dramatic tension from the previous post.

So the issue we had was a screen-sized DMA3 transfer interfering with NDMA1, which is used to transfer camera data...


Shortly after I made that post, I recalled that Jakly mentioned VRAM timings, and started to figure it out.

I said that when I reproduced the setup in a homebrew, it would trigger a data overrun error and get stuck. But there was one thing I was missing: my homebrew was using a camera resolution of 256x192, with DMA set to run every 4 scanlines, the standard stuff. However, Let's Golf uses cropping to achieve a resolution of 144x144, and runs the DMA every 7 scanlines. This means more time between each NDMA1 transfer.

Regarding VRAM, the DSi supports accessing it over the 32-bit bus, instead of the old 16-bit bus. One effect is that this makes it possible to write to VRAM in 8-bit units, which wasn't possible on the DS. Another effect is that it affects timings: for example, a 32-bit DMA transfer from main RAM to VRAM would take 2 cycles per word, instead of 3.

I did the math, and with such timings, the screen-sized DMA3 transfer would have enough time that it could run between two NDMA1 transfers without disrupting the camera operation. But with the 16-bit bus timings, DMA3 would definitely take too long.

I even modified my homebrew to use the same 144x144 resolution as Let's Golf, and added a key to toggle the 32-bit bus for VRAM (via SCFG_EXT9 bit 13). Suddenly, my homebrew was running just fine as long as the 32-bit bus was enabled, but when it was disabled, it would trigger the data overrun error and get stuck.

So, basically, this is nothing fancy, just a case of "this works out of pure luck".


I added support for the new VRAM timings in melonDS. But this wasn't enough, Let's Golf would still get stuck.

... read more
More camera trouble...
So I had made a nice post about Let's Golf and how it was fixed...

But, obviously, as far as DSi camera support is concerned, it wasn't all.


I looked at another game that was running into issues with the camera: Assassin's Creed II. The Wanted feature in the menu uses the camera, if you're playing the game on a DSi, but on melonDS, it just showed nothing at all.

Quick investigation showed why.

Normally, when using the camera, games will set up the DMA with a block length of N scanlines, and a total length matching the length of the full camera picture. The DMA channel will also be set to trigger an IRQ when it's done.

However, this game does things differently. The DMA channel has no total length setting, and is just set to repeat infinitely. It transfers picture data to a small temporary buffer, from which the game reads when needed. No idea why they did it this way, but regardless, shows why it's good to emulate things accurately. Anyway, a NDMA channel that is set to "repeat infinitely" will trigger an IRQ after each block, but due to an oversight, melonDS never triggered any IRQ.

After fixing this, I did have the camera feed showing up in the game's UI thing, but it was rolling. Heh. Couldn't have been so simple.

This turned out to be because of the timings for the camera transfer. The timings melonDS used were a big fat guess, and were way too fast for that game.

I dug up my old camera test homebrew and modified it to track camera timings from the DSi. Took some time to figure out the logic behind the numbers I was getting -- there was more time between camera DMA transfers when running in 256x192 mode, than in 640x480 mode. In fact, it makes sense: internally, the camera always runs at 640x480, and the HSync/VSync are the same, but when told to output a 256x192 picture, the camera simply skips some of the scanlines.

... read more
Windows OpenGL issues fixed, finally!
I went on a quest and battled the worst enemy imaginable.

Worse than a thousand orcs.

I fought endless privacy settings screens. Warded off all sorts of bullshit offers. Resisted the temptation to throw my brain in a lake.

I installed Windows 10 on my old laptop Crepe, so I could finally fix the issues with multiple windows and OpenGL.

CasualPokePlayer greatly helped me understand the problem, too.

Basically, due to the way melonDS works, when using OpenGL, we create the GL context on the UI thread, then use it on the emu thread exclusively. This is so that the OpenGL renderers can access OpenGL without needing extra locking. Window redrawing is also done on the emu thread.

The issue was due to how I originally implemented the multi-window mode. When a second window is created, it shares its GL context with its parent window. This way, everything OpenGL related will work on all windows. Except it turned out that the parent context was created on the UI thread, then made current on the emu thread, before the child context was created. Windows doesn't like that, and thus, fails to create the child context.

So it took some reworking to get this working smoothly, but the issue is fixed now.

This means that the proper 1.0 release will be soon -- for real. This issue was the last show stopper, basically.

... read more
DSi bugfixes
So, yeah... The current mood around melonDS is "it does most things pretty well already", as far as emulation is concerned. While it's certainly true for the DS side of things, there's still a lot to do with the DSi. And this randomly piqued my interest.

Notably, we still have a bunch of games that can't get ingame, generally hanging on something DSP-related.

So I took one of those games: Let's Golf.



When run for the first time, the game has you create a profile, by first entering your name, then taking a selfie to be used as a profile icon. All fine. However, here the game freezes before you can get to the selfie part.


So I dug into it to try and figure out why it was freezing. We knew it was trying to use the DSP, but not much beyond that... anyway, I extracted the game's DSP binary to get more insight. The DSP was just running its main loop, waiting for incoming commands. On the other hand, the ARM9 was stuck, waiting for... something.

The ARM9 was using the PDATA registers to read the DSP memory, however, that got stuck. The bug turned out to be silly: PDATA reads/writes can have a fixed length set, but the code handling them wasn't calculating that length correctly, so there wasn't enough data being returned. Hence the ARM9 getting stuck.

When fixing that, I could get to the selfie screen thingy.



... read more
Proper melonDS 1.0 release "soon"
Apologies for taking so long to do a proper release.

Regardless, I think most, if not all, of the bugs that were found in the 1.0 RC have been fixed, so expect the proper 1.0 release soon. Hopefully.

The main issue would be the lack of functional Windows CI, but we're working on it...

We also have fun plans in mind for further releases, but we'll see once we get there.
Technical issues #2
You might have noticed the lack of Windows builds on the nightlies page.

Sorry about it. The Windows CI is broken. Our CI expert Nadia has been on it for a while, so hopefully it should be back up again... someday.


On the flip side, the little loser stopped trying to take the server down, so that's atleast one positive.
Technical issues
It appears that in the past days there have been resource usage spikes on our server. So either someone is trying to DDoS us, or the AI garbage bots are hitting our site.

I'm going to come up with a response to this, but in the meantime, there may be technical issues (like earlier, MySQL was down for some reason). Sorry about it.

Edit- we should be mostly good now. I thought it was AI slop taking us down, but it turned out to be a little moron spamming the board's search system with absurdly long queries. So yeah, problem solved.
Small DLDI fix, and maybe more
Mental health still complicated. Getting somewhat better...

I made a more personal blog, to post about other fun projects of mine (including the WiiU gamepad stuff) and other fun shit. If you're interested, it's here: https://arisotura.dreamwidth.org/


Anyway, I committed a fix to melonDS. May not seem like a lot, but after months of not touching the code at all, it's something.

Just today, I heard about a DLDI test program failing on melonDS, which piqued my interest.



I'd have thought DLDI was a solved problem, so this was interesting. What's going on there?


DLDI is a standard interface that was developed to allow clean support for different DS linkers. Since they all have different hardware interfaces and different ways to access their storage medium (CF or SD card), homebrew apps would need to embed drivers for each linker they intended to support, which would be quite a mess.

Instead, the homebrew itself only includes a DLDI stub, with a simple header and dummy functions. The linker's loader then patches the homebrew with its own DLDI driver when loading it: the DLDI stub is replaced with the linker's driver, which contains the adequate code for accessing the linker's storage medium. The driver contains some simple functions, like "initialize", "is the card inserted", "read sectors", "write sectors", etc.

melonDS implements DLDI in a similar way.

... read more
melonDS RC bugs
The RC has lasted quite long, heh...

It seems that a recurring problem with it is that multiple windows don't work with OpenGL. The issue is that it seems to be a Windows problem -- I tested it on Fedora and it works fine (although there is another weird bug related to hiDPI scaling).

If you've paid attention to the window decorations on my screenshots, you've prolly seen it -- the last Windows I've been willing to use was Windows 7, but I use Linux now...

The aforementioned OpenGL issue is likely related to context sharing, so hopefully not a complex issue. I'd just need to install recent Windows in a VM of sorts, or have someone else do the testing and fixing.

I guess that's also why I'm less motivated by melonDS these days... my brain is all about the intellectual stimulation and challenge. I guess a lot of emudevs are like me too, it's more fun to go after emulation bugs or reverse-engineer hardware :P

We'll come up with a fix, though.

We always do.