![]() |
Home | Downloads | Screenshots | Forums | Source code | RSS | Donate |
Register | Log in |
< Proper melonDS 1.0 release "soon"Windows OpenGL issues fixed, finally! > |
DSi bugfixes Jun 24th 2025, by Arisotura |
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. However, two issues: 1) the camera preview was rolling (as shown above), and 2) when trying to take a picture, it would just freeze. Third issue is that it runs at like 4 FPS, but that's common to anything DSP-related for now, and we'll address it later. I decided to first try and fix the camera rolling issue, because I thought that maybe the second issue was linked. So I first logged what was going on with the camera. What settings are used on the camera, on the interface, and on the associated DMA channel. cam1: start, width=256 height=192 read=0024 format=0002
CAM TRANSFER: CNT=EE06 CROP=00180038/00A700C6 ARM9 NDMA1 START MODE 0B, 04004204->0221E0E0 LEN=10368 BLK=504 CNT=CB044000 So what does this all mean? The camera is set to 256x192, nothing special there. However, the settings used on the camera interface enable cropping, which is interesting. Basically, it only retains a 144x144 section of the camera frame. Which is confirmed by the DMA parameters. The total length is 10368 words, which is the length of a 144x144 frame. The block length is 504 words, which corresponds to 7 scanlines of said frame. This matches the DMA interval setting on the camera interface, too. So what's the issue there? If you happen to remember, I've discussed the camera interface before. Long story short, it has a FIFO buffer that holds 512 words worth of picture data, and it triggers a DMA transfer every N scanlines, with N=1..16. When modelling this system in melonDS, I had assumed that this N would be a multiple of the frame height. But the issue became apparent after I looked at my logs: 144 is not a multiple of 7. Which meant that it was discarding the last 4 scanlines of each camera frame. Hence the rolling. So I decided to force a final DMA transfer at the end of each camera frame if there's anything left in the FIFO, which seems to be what the hardware does. Either way, this fixed the rolling issue entirely. But it didn't fix the second issue, which turned out to be unrelated. Another apparent issue is that the camera input looks very squished in melonDS. It might be good to add a "preserve aspect ratio" scaling mode to avoid that. So I had to dig deeper, once again. When trying to take a picture, the game would send a command to the DSP to tell it to scale the picture to a different size, then send it a bunch of parameters via PDATA, then... get stuck. This one proved to be tricky to figure out. I had no real idea what was going wrong... did a lot of logging and tracing, but couldn't really figure it out. Eventually, CasualPokePlayer enlightened me about what was being sent to the DSP. The mechanism used to transfer command parameters is what they call the pipe. It's a simple FIFO buffer: the ARM9 writes data into the buffer, then updates the buffer write position, and does all that by using PDATA. In this situation, the parameters that were being sent for the scaling command looked correct, but the pipe write position was zero, which, according to CasualPokePlayer, was suspicious. He was on to something. Looking at the code that was determining that value, I found that it was broken because for some reason the pipe length was zero. So I traced writes to that variable. I found that it was part of a bunch of variables that were initialized from DSP memory, through a PDATA read. Looking closer, there was another bug with PDATA reads, that caused them to be one off. When I fixed that, the freeze was fixed entirely. Finally, we get to play golf with a goofy face in melonDS. What's not to love! The game also runs quite well past the profile selfie part. Yep, it uses the DSP just to scale a picture. Also, looking at the game's DSP binary, I had an idea. This binary only supports two commands: scaling and yuv2rgb. There's also a separate command channel, and it has one command, for playing sound effects (presumably, the camera shutter sound). It would be totally feasible to HLE this shit. According to CasualPokePlayer, most of the games/apps that use the DSP seem to use one or another variant of this binary, with extra features, but same basic idea. The only exception is the DSi sound app, which uses the DSP for AAC decoding. Obviously, it would still be worth it to pursue a DSP JIT, atleast for the sake of homebrew. But the HLE route seems to also be viable, and it's piquing my interest now. Maybe not for 1.0, but I want to give it a try. |
6 comments have been posted. |
< Proper melonDS 1.0 release "soon"Windows OpenGL issues fixed, finally! > |
Rndm3 says: Jun 24th 2025 |
Thanks for all your hard work and for these high quality in-depth blog posts, what would we do without you? But don't be overwhelmed, rest when you need to. Thank you for everything. |
User29128 says: Jun 24th 2025 |
it's nice that you are making the dsi games that require the camera work on the system!, i really hope you get it to work on warioware snapped since that game has had that issue for so long (it crashes on startup) |
AsPika says: Jun 26th 2025 |
Nice face! Smile!!! 😆📸 Enjoy the golf! 🏌️ |
jonarbuckle0 says: Jun 27th 2025 |
I noticed something in melonDS 1.0 RC: If the emulator is sped up (unlimited frame rate), the clock is also sped up, making it desynchronized from the computer time. It didn't happen in 0.95, so is it a bug or a feature to take care of multiplayer breaking? |
LEGO_Vince says: Jun 27th 2025 |
I'm sorry if this is off topic, but I can never read DSP as anything but DarkSydePhil. What does DSP actually mean ? |
Arisotura says: Jun 27th 2025 |
LEGO_Vince: Digital Signal Processor. it's a type of processor that is specially made to process signals, like for example audio data... jonarbuckle0: yeah, melonDS 1.0RC keeps the RTC in sync to the emulated game, so from the point of view of the game, it's accurate. I thought of adding some hotkey or whatever to resync the time, but idk how the games would appreciate it... |