melonDS RSS The latest news on melonDS. Introducing the compute renderer -- by Generic aka RSDuck Sat, 01 May 2021 08:42:51 +0000
Why are we doing this in the first place?
  • Enhancements such as higher resolution rendering at reasonable speeds compared to say a software rasteriser, but with less problems than the OpenGL renderer (though problems can never be fully excluded when running games differently than they were intended).

  • Fullspeed emulation of 3D games on Switch and potentially other devices which fit this weird niche where they have slow processors but pretty competent GPUs and good software side support for it.

You might have already heard of parallel-rdp from Themaister which provides a very accurate emulation of the RDP (i.e. that part of the N64 which in the end draws the triangles) running on the GPU. It has been a great inspiration for this project (which means where possible it's basically a clone). So thanks to Themaister for all the ideas and also for answering my questions!

Currently the main part of the work is done (it's already somewhat playable with a lot of games), so it's easier to list what's still missing:

  • Blending

  • Shadows

  • Equal depth testing

  • Antialiasing

  • Highlighting/Toon shading

  • Fog

  • Edgemarking

  • Rearimages

I plan on detailing some technical aspects later. Also I have not forgetten my A tour through melonDS's JIT recompiler "series", so expect to see some more posts by me here sooner or later.]]>
melonDS 0.9.2 is out! -- by Arisotura Mon, 26 Apr 2021 22:43:30 +0000
Namely, improved Mac support: there have been fixes to the JIT, but also to the interface, so things should work more smoothly under macOS.

melonDS also supports loading ROMs from the most common archive formats, now, which means users with large ROM sets should have it easier.

We also have a new menu listing the ROMs you have opened recently, making it quicker to open them again.

We got new fancy screen modes courtesy Generic. These make it possible to use 16:9 hacks along with melonDS, among other fun things. Speaking of renderers, he also went and fixed a whole bunch of OpenGL issues.

The cart interface refactor was finished in time for this release, and with it, support for NAND save memory. WarioWare DIY and Jam with the Band are now able to save correctly under melonDS.

And, as usual, there are a bunch of other misc changes, which you can find about in the changelog or commit history.


melonDS 0.9.2, Windows 64-bit
melonDS 0.9.2, Linux 64-bit
melonDS 0.9.2, Linux ARM64
melonDS 0.9.2, MacOS 64-bit
melonDS 0.9.2, MacOS ARM64
melonDS 0.9.2, MacOS universal]]>
Change to the save file handling -- by Arisotura Thu, 15 Apr 2021 01:20:06 +0000
This is when I realized that the current way melonDS handles save files was going to be problematic. Basically, if a save file already exists, melonDS will determine the save memory type from that file's size, instead of using its built-in game list. This was designed in the old days, where we had some wonky heuristics instead of the game list -- the basic idea was that if melonDS failed to determine the correct save memory type, you could provide a known good save file and it would work, bypassing the problem.

Obviously, this is also a double-edged sword. If you happen to have a save file that isn't the correct size, melonDS will pick the wrong save memory type, potentially breaking things. In the end, this strategy now seems to cause more problems than it solves, especially since we have the game list.

The NAND thing was the final nail in the coffin of this strategy. It had been assumed, from some source I don't recall, that the save memory size for NAND was 32MB, and this was nice, because each possible save memory size had only one associated type, no confusion. However, the hardware tests I did showed that the NAND save memory is actually 8MB, and this conflicts with one of the possible FLASH sizes.

(EDIT- I was corrected by another tester. The save memory for WarioWare DIY is 16MB, not 8MB.)

So I ripped the old thing out, and instead made it always rely on the game list to determine the save memory type, regardless of the save file's size. As a bonus, save files that are too big will work too, melonDS will just ignore the extra contents. Which means that, for example, DeSmuME's .dsv files could be used as-is, by just changing the extension to .sav.

If you believe this is going to be a major disadvantage, or see any issue with this, I encourage you to reply to this post.]]>
Redesigning the cart interface -- by Arisotura Tue, 13 Apr 2021 10:25:01 +0000
Anyway, this tends to show why it's good to think forward when designing your code. That being said, I need to find a balance with this. I tend to either think forward too much and end up paralyzed by questions that don't mean much, or just write code as it comes to my mind.

The cart interface in melonDS was originally built without much consideration for future. If you're wondering, the cart interface is the part of the emulator that lets emulated software access the emulated cartridge, because on the DS the cart isn't just directly mapped to CPU address space like on older consoles. Instead, there are a bunch of commands you can send to the cart to retrieve various parts of the contents, and different encryption protocols securing it up.

As melonDS became capable enough to run commercial software, emulating the cart interface was a must. So NDSCart.cpp was born. The main component is the NDSCart namespace, which originally emulated the cart interface hardware (basically the DS side) and command responses for a generic cart. There is also NDSCart_SRAM, which emulates the on-cart SPI save memory. A tad hacky, but for most games, it did the job.

But, that's the thing, not all DS carts are the same!

There were already some exceptions for homebrew ROMs, which might want to use the cart interface and, depending how old they are, need a more lax implementation of the generic cart protocol. Namely, retail carts don't let you read addresses lower than 0x8000 via the generic data read command (0xB7), because that region contains the ROM header (read via a different command), the Key1 encryption data and the secure area. However, old homebrew ROMs don't have any of that (save for the oldstyle DS header), and have their ARM9 binary start at 0x200. Newer homebrew ROMs are closer to the layout of a retail cart, mostly due to the added DSi support (the DSi header is 0x1000 bytes instead of 0x200), but, since not everybody is here to rebuild their ROMs, we still need to support the older ROMs.

Homebrew aside, there are also different types of retail carts.

A prime example is Pokémon games. The carts are fitted with a IR transceiver, which is accessed via the save-memory SPI bus. In practice, the first byte of a SPI transfer is a command for the IR transceiver. For now, we know that command 0x08 is some ping command that should reply 0xAA, and command 0x00 is the pass-through command, where any further bytes are forwarded to the save memory. Emulating this is required for Pokémon games to be playable at all. In melonDS, these commands were added to the generic save-memory code. A bit of a hack, since this means these would be 'functional' in any game instead of just Pokémon games, but it did the trick.

But there's more. Games like WarioWare DIY, or Jam with the Band, don't even use the save-memory SPI bus. They have save memory, but it's a NAND memory that is accessed via the same bus as the ROM itself, through a set of specific commands.

And then there's Pokémon Typing Adventure, which comes with its own Bluetooth keyboard. The cart is fitted with a fancypants Bluetooth controller that is accessed via the save-memory SPI bus. That controller can even send IRQs to the DS, via the cart interface's IREQ_MC line.

There's probably even more to this, who knows what sorts of obscure stuff has been produced for the DS.

On the GBA side, things aren't much better. The DS can play GBA games, which is probably not something melonDS will emulate in the near future. But there are several other possibilities here too. You have add-ons that plug into the GBA cart slot, like the Rumble Pak or the Guitar Hero grip thing. Some games can even detect that a specific game is inserted in the GBA slot and unlock features when that is the case.

At the time some GBA slot add-on support was added to melonDS, it became evident that we would need a clean interface system for both NDS and GBA carts, or this would become a large mess.

Thus, the cart_refactor branch was born. Nothing terribly exciting for now, just using OOP to build a proper interface system for NDS carts. When this is done, the same will be done to the GBA interface.

Hell, given how things are going with the Azure CI thing, the refactored interfaces might make it into melonDS 0.9.2.]]>
Release 0.9.2 coming out soon -- by Arisotura Sat, 10 Apr 2021 10:23:28 +0000
We have some cool ideas, too, but these will be for further releases.

Also, in somewhat related news, I'm starting to work on another idea. It's not related to melonDS, but it's related to the DS. For now, this is going to be a surprise, but those who have seen my Twitter lately might figure out what I'm up to. I will make a post once I've got a working prototype.]]>
Status updatezorz! -- by Arisotura Fri, 26 Mar 2021 17:44:50 +0000
First, what's new on my side?

I finished my hearing for the gender marker change thing. You know, so I can get a big fat F on my ID card. You prolly don't care a lot about my trans shenanigans but this means it's one thing out of my way, and we can now proceed to full-speed melonDSing (and hopefully not from a squat, but we're doing our best).

What else is there to say?

I can't keep my focus on one thing aaaaaa

I wanna maaaaaybe try to emulate some new fun shit in melonDS. like the pokémon keyboard thingy.

Wait, no, we need to make DSi emulation better. We can prolly add a file explorer thing, so you can put your DSiware into the thing easily, and idk what other cool features there were. Just suggest them below this post, pretty sure we can get this done together! melonDS will soar through union and friendship!]]>
Announcing ARM64 Mac (aka Apple Silicon Mac) support! -- by WaluigiWare64 Tue, 23 Mar 2021 18:57:00 +0000 StLouisCPhT for testing all the changes I made to try and get melonDS to work on ARM64 Macs. Without them, this wouldn't be possible as I don't have an ARM64 Mac (I don't have any Mac at all, however x86-64 macOS can be run in VMs). I would also like to thank Generic (aka RSDuck) for helping me out with JIT issues.

This started when a user named "Joel" (now StLouisCPhT) commented on my earlier post about compiling melonDS for ARM64 Macs. We took this to Private Messages on the forum board, and we were making progress slowly, but surely.

Here's a quick overview of the things that were needed for melonDS to run on ARM64 Macs (if you want to download the beta, scroll to the bottom of this post).

- The JIT compiler
The first issue was adding a way to get the Program Counter on ARM64 Macs. This was easy, all it needed was an ifdef to use "uc_mcontext->__ss.__pc".
The second issue was that Apple introduced W^X for JIT memory. This meant that we can only have Read-Write and Read-Execute permissions at one time, and this could be toggled by setting "pthread_jit_write_protect_np" to either true or false. This command had to be added to some location, otherwise the JIT would crash when trying to run something.

There was also another strange issue when some lines would cause the JIT to crash.

   for (int i = 0; i < (JitMemMainSize + JitMemSecondarySize) / 4; i++)
       *(((u32*)GetRWPtr()) + i) = brk_0;

Generic (aka RSDuck) told me that this was for adding breakpoint instructions to the JIT buffer. StLouisCPhT and I tried various things, but to no avail. However, once the changes were rebased on master, it seemed to work fine....

- Microphone
This wasn't affecting just ARM64 Macs, but I'll add it anyway.
We got a bug report on GitHub for the microphone not working on macOS. The solution? Add the "NSMicrophoneUsageDescription" key in the plist file, otherwise macOS would not ask for microphone access.

- Known Issues

* The fastmem checkbox is disabled: This is intentional, I cannot get fastmem to work on either x86-64 Macs or ARM64 Macs.
* Local Multiplayer doesn't work by running more than one instance on the same Mac: This needs to be investigated, although Local Multiplayer doesn't have the best support yet. It seems to work by running two copies of melonDS on different Macs though.

Well, that's all.
The beta builds for ARM64 include the libraries bundled, so you won't have to install them seperately.
melonDS 0.9.1 beta for ARM64 macOS
(For future reference, this build is based off commit 2c2e868.)]]>
Been silent lately... -- by Arisotura Sun, 31 Jan 2021 15:37:59 +0000
Anyway, you may have observed I haven't been doing a lot for melonDS lately... there are a couple reasons to that, besides that side project of fixing up vintage Macs and other shit.

I don't want to abandon melonDS, it's my project, but it's true that I have less interest into it at this point. Things like emulating new hardware features and hunting emulation bugs interest me much more than, say, UI shenanigans. As far as these things go, I tend to just accept work from other contributors, sometimes to the point of them becoming fulltime members of the 'melonDS team'. It's better this way, after all; as I say, an emulator project is like a tree: once you're done with the trunk, it branches off in a billion directions.

So, what can we attempt doing now?

I've been idly trying to figure out why DSiware will only load when installed on the NAND. So far, haven't gone very far with this, mostly because, well, my motivation tends to be an all-or-nothing thing. Either get the spark and find yourself coding until 5:00, or have a hard time doing anything at all. Also, working with the DSi firmware is a real pleasure: it's a huge spaghetti network of threads and callbacks and shit, making it a massive pain to track anything, even moreso when all you have is a bunch of ARM ASM.

From there, there would be two possibilities: a quick hack to bypass whatever check the DSi firmware uses, like we do for the region check, or actually installing the provided DSiware into the NAND. The latter implies dealing with an encryption layer and a FAT filesystem, which I can't wrap my head around. We'd need to get a good lil' FAT library, but then this would open more possibilities regarding DSi emulation.

Then there are the remaining popular-request items, and the big pile of issues.

For example, a looooot of the issues are with the OpenGL renderer. This is why I stand for emulating things accurately: you are far less likely to run into constant issues and get yourself caught into a game of whack-a-mole perpetually hacking around issues. While things like the OpenGL renderer are creative and cool, we have seen countless times that the DS GPU is a pile of quirks, and that emulating it correctly is only possible with somethings like our software renderer. We can keep coming up with creative solutions to try and fix OpenGL issues, but at some point there is only so much we can do when using a fundamentally inadequate tool.

An alternative may be unearthing my old 'shaderzorz' experiment: that was an attempt at a compute-shader rasterizer that worked similarly to that of the DS. Such a renderer, implemented either in compute shaders or in fragment shaders, may be able to get around the shortcomings of the current OpenGL renderer, and maybe also support higher-resolution rendering without too much of a performance penalty. Back then, I ended up ditching it in favor of a classical polygon-based renderer because I wasn't positive about the performance. However, the current renderer is far from optimal too, due to how rendering has to be done.

So, we might offer such a renderer for platforms that support it, and keep the classical renderer for the remaining users, but we would have to accept that the latter will remain imperfect.

There are also the timing issues. The holy grail of DS emulation, I guess. This, like several of the other things I have in mind (hi pixel-perfection), is pretty much a high-effort low-reward item.

No hacking around timings will get us really far if we don't have the logic down. Thus, we would need to work out the CPU timings, how memory waitstates for code and data regions interact for each instruction, and so on. Only once we have the general logic down, could we try implementing a model efficiently, and then seeing whether such a model can work with estimated cache timings, or whether we need actual cache emulation. Until then, no real point attempting to emulate the ARM9 caches if our base timing logic is off.

Another thing that would definitely be good for user-friendliness, would be making melonDS plug-and-play: basically, not requiring original BIOS and firmware.

As far as DS mode is concerned, it's possible to use DraStic's alternate BIOS (even though I would like to make my own eventually). Building a basic firmware image would also be doable, obviously it wouldn't come with the DS menu, but it would be enough to run games. We would just need to provide an interface for changing the firmware config.

DSi mode would definitely be trickier. It requires a NAND dump, and I haven't looked into how feasible it would be to craft a working basic NAND. We haven't even looked into DSi-mode direct boot yet, and that would definitely be a requirement.

Then there is the good ol' wifi quest. Not sure how far we can get there...


I want to be there for melonDS 1.0. That's going to be one big release :)

Maybe I originally wanted to write about more things? My brain is running out of fuel. Oh well.]]>
Update on donations -- by Arisotura Wed, 13 Jan 2021 17:34:31 +0000
* Patreon for monthly donations
* Paypal for one-time donations

I will add a donation page with these links and extra info.

Also, while I'm at it, some notes on these donation links:

Since these go to accounts that are mine, I was worrying that some people would think I spend the donation money on drugs and hookers, or whatever else. That ain't the case.

The donations mainly go towards the hosting costs, and other expenses related to the melonDS project (acquiring oddball addons to emulate, dumping the DSi bootrom, ...).

The domain name costs about 20€/year. The server itself costs $5/month, plus extra bandwidth usage; the server plan might have to be upgraded in the future as melonDS gets more popular.

The current influx of donations is already covering that, so the extra money is there for the melonDS team members to use if they face any emergency. For example, back in 2018 I had to cover transition-related expenses while having no income and trying to survive, so the patreon helped a bit with that, thank you folks. Currently things are going better for me, but we never know when one of us find themselves facing precarity, especially within the current context.

So I hope this clears up any doubt over the donations.

And of course, I want to remind that while donating is a nice gesture, it doesn't entitle you to anything in return, and conversely, you don't miss out on anything if you're not donating. You do as you wish.


I am also updating this site, mainly adding a dynamic page system to replace the old hardcoded pages (the howto/FAQ page has been ported to that). Let me know if anything is broken or missing.]]>
Merry Christmas from the melonDS team! -- by Arisotura Fri, 25 Dec 2020 15:19:08 +0000
melonDS 0.9.1

There are several changes since melonDS 0.9.

First, you may notice that we removed the nonfunctional vsync option from the video settings dialog. Admittedly, that setting was functional in the 0.8 versions. However, with Qt and the new multi-context OpenGL rendering we do, implementing vsync will take a bit more effort, and we haven't figured it out yet.

However, Generic implemented a new framerate limiter, based on that of Citra. This should help a lot with frame pacing issues.

I removed the hardcoded debug hotkey which had been accidentally left into the 0.9 release (oops).

Speaking of which, we now have a proper fullscreen hotkey. People were trying to use F11 as a fullscreen hotkey before, which not only was not implemented, but was actually triggering the hardcoded debug hotkey, freezing melonDS for a while. Now you can actually use F11 (or any key of your liking) for fullscreen.

On the DSi side, it is now possible to run unlaunch'd NANDs in melonDS. It may not yet be possible to hack melonDS and install unlaunch on it, though. We also added preliminary camera support, for now it feeds a fixed stripe pattern, but atleast the bases are there so games do better than just crashing.

We also now have a Mac build, courtesy WaluigiWare64. Speaking of builds, these release builds are pulled straight from our Github CI instead of being compiled on my computer. Let us know if there are any issues with them.
You can easily install melonDS and it's dependencies on macOS by running:
brew --cask install melonds

On the subject of package managers, melonDS is now also available as a flatpak package on flatpak, providing a simple, unified way to install melonDS on all Linux systems. First, install and setup the flatpak package manager, then install melonDS by running this in a shell.
flatpak install flathub net.kuribo64.melonDS

And, as usual, we have a bunch of little fixes and tweaks, which you can discover in our changelog or in the Github commit list.


melonDS 0.9.1, Windows 64-bit
melonDS 0.9.1, Linux 64-bit
melonDS 0.9.1, Linux ARM64
melonDS 0.9.1, MacOS 64-bit

If you're feeling generous: here's our Patreon]]>