Ok guys, more emulator goodness coming your way. This time, it’s for our DS homebrew community. Homebrew coder Pate has released a new version of DSx86, a DOS emulator for the Nintendo DS. Check out what’s new in the latest release after the jump.
Download: DSx86 v0.05
Ok guys, more emulator goodness coming your way. This time, it’s for our DS homebrew community. Homebrew coder Pate has released a new version ofDSx86, a DOS emulator for the Nintendo DS.
Finally I got version 0.05 released! The biggest changes since 0.04 are the improved EGA support (so that Commander Keen 4 runs), and I also added the blitted screen update mode for CGA graphics mode. In earlier version only the Direct mode was supported, now you can select whether you want to use blitted (60 FPS, 30 FPS or 15 FPS) or direct screen update.
Speaking of screen update modes, I don’t think I have properly described what the differences between those direct and blitted modes are, and how they relate to the different graphics modes that DSx86 supports, so I think it is time I do that. First, the difference:
- Direct mode writes directly to the Nintendo DS display memory (VRAM) at physical memory address 0x06000000. The way this works is that I detect whether the ES segment address points to the emulated x86 display memory (addresses between 0xA000-0xBFFF), and if it does, the segment prefix (or MOVS/STOS opcode) switches to use a different (duplicated) set of opcodes that do not store data to the emulated x86 RAM but instead write directly to the corresponding pixel(s) of the physical NDS VRAM. How the written data is converted to pixels is different in each graphics mode, so this mode needs as many different handlers for the same opcode as there are supported graphics modes.
The advantage of this mode is that it is generally much faster than the blitted mode, as the pixels are written only once, and only the actually changed pixels are handled. The drawback is that it needs duplicate versions of all the opcodes that can write to memory (and in the x86 architecture most of the opcodes can!) and it only detects screen address by ES segment. If the display memory is addressed by the DS segment it won’t be detected (except in MOVS opcode) and thus the game won’t work properly. In practice it is almost always the ES segment that is used to point to graphics memory (as it is the only generally unassigned “free” segment register) and the number of opcodes actually used is very limited. However, when using direct mode, I can never be sure that the next game won’t use some new opcode I haven’t yet handled in direct mode.
- Blitted mode in turn uses the emulated x86 display memory at 0xA000-0xBFFF just like any other memory, so that all the normal memory operations are supported. It needs no special opcodes, and all segment registers can be used to access the display memory, so this mode will not cause “unsupported opcode” errors, nor should the game behave strangely.
Depending on the selected blitting speed (60 FPS, 30 FPS or 15 FPS) the emulated display memory is scanned every, every other, or every forth frame in full, and all the pixels are copied to the actual Nintendo DS hardware VRAM. This process is as slow as it sounds like, as all the pixels are copied even if nothing has changed on the screen. Every pixel is in fact written to twice, first into the emulated memory and then again when it is copied to the actual hardware display memory. Thus this mode is generally much slower than the direct mode.
Next, let’s look at the different graphics modes supported by DSx86, and how they use those screen update modes:
- Text modes (80×25 and 40×25) currently only support Direct mode (regardless of what you select as Screen Update method). That is because I thought the text mode displays would become annoyingly sluggish if the display memory (which only contains the character code and attribute per each byte pair) is scanned and converted to bitmapped 6×8 pixel characters per each frame. With direct mode the data is written both to the emulated VRAM at x86 segment 0xB800 (so that the character code is easily accessible) and also directly to the NDS VRAM as a 6×8 pixel font.
- CGA mode 320x200x4 supports both Direct and Blitted modes (starting from version 0.05). Earlier only the Direct mode was supported. If I need to decrease the memory usage of DSx86 code at some point I might actually remove the CGA direct mode support, as I believe the games that use CGA mode will probably run fast enough also using the blitted mode, and keeping the direct mode creates quite a bit of code bloat.
- EGA modes actually use a combination of Direct and Blitted mode (again regardless of what is selected as Screen Update method), which is a bit sad as it brings the drawbacks of both of the modes, and none of the advantages can be used. This is because of the complexity of the EGA graphics modes; they do not write directly to the display memory even on the x86 architecture, instead they use the EGA graphics registers to modify and expand the written byte to the 32-bit output value, as I explained below in the Jan 17th blog entry. This also means that EGA supports needs a lot of duplicated opcodes, many of which are still missing. Also not nearly all the EGA register fatures are yet supported, and I’m actually thinking of refactoring much of the current EGA code to be able to support the features in the next version.
- MCGA mode supports both direct and blitted mode, so you can try with the the direct mode first, and if you get unsupported opcode errors, fall back to the blitted mode. Some games (like Solar Winds) use the DS segment register to write to the graphics memory, so they will always need to use the blitted mode.
In the future I will continue working on the EGA mode, and at some point I’ll expand this to the VGA Mode-X style graphics modes (as used by Wolfenstein 3D and Master of Orion, for example). Those modes also need a combination of direct and blitted mode, as they use the VGA registers and the full 256KB of VGA VRAM. They are faster to blit to the screen though, as they use the same 8-bit pixels as the Nintendo DS VRAM, so no conversion is needed. I’m also thinking of switching to a “dirty buffer” approach with the text mode support, so that I could drop the direct mode support and switch to blitted mode, without killing all the performance.
Anyways, hope you like the new version, and sorry I haven’t had time to go through all the debug logs you have sent me. I’ll continue working on those reports for the 0.06 version, and please keep on sending the log files from 0.05!
Download: DSx86 v0.05