Weekly post assuring you guys the corgi is still alive. 🙂
I fixed a problem with the ADC/SBC instructions (add/subtract with carry) relating to how the carry and overflow flags were updated – this allows Harvest Moon DS to boot, but it soon crashes afterwards due to unimplemented graphics registers. I’m trying to test other games as well, but many of them get stuck on a “save data error” screen. Which makes sense, as I’ve yet to implement that.
The way CorgiDS handles drawing to the screen is also funky:
As you can see, the Digimon aren’t looking too well. What’s happening is that the sprites are being overwritten by other sprite tiles with a “transparent” color, or more specifically, a color with 0 alpha. In the process of trying to fix this issue, I think it’s a good idea to rewrite the 2D graphics engines to take into account background and sprite priority. Currently CorgiDS uses hardcoded priorities based upon background/sprite number – which is normally accurate – but both can have custom priorities that supersede this rule. Even if it’s not super important now, the rewrite will allow for more flexibility with future graphical effects.
After the rewrite, my next task will be to handle rotscaling as well as windows (which should function like their Game Boy analog). Maybe engage in some bughunting as well. Plenty of work to do on the corgi!
Two months of work have certainly paid off. While I haven’t gotten the firmware completely under control, I have accomplished something equally exciting: getting to the title screen of my first commercial game.
Digimon World Dusk: a childhood game of mine. Perhaps not the highest quality title for the DS, but it’s pretty decent. I chose this game (as well as a couple of others) due to its relative simplicity, in that it doesn’t use 3D graphics or any stupid tricks in order to play correctly; it just so happened that this was the first to boot successfully.
Make no mistake, however: CorgiDS is in no condition to be released in the foreseeable future. The emulation speed is horrible, only a small subset of the graphical features are in place, and certain bugs are still lingering about. For instance, Harvest Moon DS refuses to boot at all, and the firmware immediately skips to the boot menu without displaying the health and safety screen.
So, where to go from here? First I want to fix the remaining bugs so that my sizable game/homebrew library will be completely functional. Next I’ll work on implementing rotation and scaling for the 2D engine, and maybe along the way adding some much needed optimization. There’s some other 2D features I’ll need to add, but I’ll just implement those as needed.
After that, however? It’ll be time to start work on the 3D GPU, probably the most difficult part to get working. If you follow melonDS, you already know that this is also the weirdest part of the DS. Even now no emulator handles all of its edge cases correctly, and some of its more obscure features still need to be reverse-engineered. It should be a lot of fun. 🙂
Unfortunately I don’t have any visual results. The firmware almost reaches the starting screen (giving you health and safety information), and a single frame of it can be seen before the graphics become garbage. I implemented some very basic stubs for the sound and WiFi that don’t do anything, and I also fixed a pretty bad DMA bug that resulted in only one half or one fourth of the operation being completed. Most of the homebrew, as well as the few commercial games I’ve tested, fail to display anything at all – the ROMs affected seem to get stuck in an infinite loop before they reach the main game loop.
Most of my work now consists of comparing the results of no$gba to my emulator and trying to fix any differences. Tedious stuff, but I’m close to a breakthrough I feel…
After working on the GUI and fixing several mysterious bugs that only appeared after the migration (in particular a nasty buffer overflow), I can say that CorgiDS is growing at a nice rate. Check it out:
Before you ask, no, CorgiDS isn’t magical enough to render this in 0 ms. The “time taken” works on DeSmuME, so I have no idea why it doesn’t on CorgiDS. Issues with the Real Time Clock might be a possibility, but it’s not exactly concerning me right now.
While the bottom screen in this demo only uses the simple “frame buffer” mode, the top screen makes use of one of the tiled background modes based upon the GBA hardware. If you’re aware of how the Game Boy draws things, the way the DS/GBA handles this is surprisingly similar. Unfortunately this is one of the simpler modes that commercial games and more sophisticated homebrew don’t make use of; I’ve yet to get into affine backgrounds or sprites, and all sorts of crazy things like rotation and scaling can be applied to those.
The GUI is much more advanced now and despite not having many options, feels almost complete. You can load a ROM, choose where the emulator looks for the BIOS and firmware images, and even save a screenshot; in fact I used that last feature for the above image. The best part is thanks to Qt, everything should not only be cross-platform, but also have a native appearance. I’ve kept my GUI code as separate as possible from the emulator code so adding new frontends, if needed, will be pretty painless. This may all seem like small stuff to be writing about, but a large number of emulators – not necessarily in the DS scene – have obtuse and complicated interfaces that scare away beginners, and it’s one of my goals to have an intuitive, easy to use GUI for CorgiDS.
My next big goal, assuming no major setbacks, will be to load the firmware and get the graphics from that displaying. This makes use of the aforementioned affine backgrounds and sprites, so this ought to keep me occupied for a while. Until next time!
Homebrew location: http://www.gamebrew.org/wiki/Mandelbrot_Fractal
My original code used SDL, which would be okay except it’s quite difficult to create useful GUIs with it. Thus, I installed Qt so that I could create a proper intuitive interface from the start. Unfortunately, this means all the SDL related code is nonfunctional for the moment; furthermore I’m not entirely familiar with Qt, so progress will be slow for now as I read tutorials and watch some videos to get me up to speed. This is meant to be a long-term project however, so by spending extra time now, CorgiDS will benefit all the more.
As for the bug: I noticed that certain homebrew that I tested would jump to uninitialized or zeroed-out memory; in either case, nothing with valid code to execute. I suspected this to be a problem with the CPU for a while, but as it turns out, this was a red herring. I pinpointed the exact location where the emulator messed up, and I fired up the nocash debugger. The code that I tested (dslinux) would jump to invalid memory if a certain part of memory was set to zero – nocash gave a non-zero value and worked fine. I looked up the memory address on GBAtek and found it had something to do with the firmware user settings.
There it was!
I had overlooked the firmware when writing my direct boot function. The firmware writes to memory the user settings, which contains useful data such as touchscreen calibration points and the user’s language. Without including this, the memory supposed to hold these values would always be zero, and as GBAtek specifies, some of these values are never supposed to be zero. Why the ROMs decided to shit themselves because of this I’m not entirely sure, but regardless, now that I’ve added this functionality, everything seems to work as it should.
My next goal will be to get CorgiDS to its former state before the Qt migration. This will take some time, and of course I’ll be adding more GUI specifics beyond that. Stay tuned!