PDA

View Full Version : DS2x86 is starting up!



wraggster
September 26th, 2010, 18:50
News from Pate concerning his Dos Emulator for DS:

Okay, now I finally got some proper progress done with DS2x86! Yesterday I still fought with the screen update problem, and also had problems with the key input. Late yesterday I finally got the screen update to work without hanging, and also found the solution the the key input problem. I am using a couple of techniques that are unsupported by the current SDK, so I have had to come up with some hacks to work around the limitations of the SDK.

The first big issue was that the SDK only has one function to refresh the NDS screen, called ds2_flipScreen as it flips the two internal screen buffers. Using this function the current buffer gets sent to NDS and you can then start writing to the other buffer. I need to build the 16-bit 256x192 screen buffer from the emulated PC screen data, so I already have a sort of internal double-buffering. The screen contents that are being written to by the running software is separate to the buffer that gets sent to the NDS. I did not want to add another double-buffering layer and copy all the data for every single frame, but instead use only one buffer and (in text modes) only build the characters that have changed since the last frame.

Looking into the SDK dump files I found out that ds2_flipScreen calls a function called update_buf, that simply sends the current buffer to the NDS side, and luckily that function was not static so I could call it directly from my screen update code. However, it gets a handle variable up_screen_handle as it's parameter, and that is static to the SDK library, so I needed to add an ugly hack to find out the address of this variable from the original function, and then give this address as a parameter to the buffer update function. I added a call to this function to the timer interrupt handler, as the DSx86 architecture does not have a "main loop" that would refresh the screen contents once per frame. The underlying x86 code runs as fast as it can, and I just sample the screen contents using the timer interrupt several times a second.

I first tried to use this new method only for the upper screen and use the original SDK console functions for the lower screen, but that kept hanging the system constantly. I thought that perhaps the internal functions are not interrupt-safe, so that when the lower screen is in the process of updating the NDS side, and my timer interrupt happens in the middle of this and starts sending the upper screen data, this might be the cause for the hangs. So, I coded my own console functions for the lower debug screen and used the interrupt routine to update also the lower screen, and then finally I got the screen update system to work without hangs. This also had the advantage of increasing my debug screen from 32x24 characters to 42x24 characters. The bottom row commands got even harder to hit accurately with the stylus, though.

The next problem I had was that the SDK ds2_getrawInput function did not seem to report any key releases. Whenever a key was pressed, it stayed pressed until another key was pressed. This turned out to be caused by not calling the regist_escape_key SDK function to register a key to use for escaping to the console (or something, I am not quite clear about the use of the escape key). Why I need to register an escape key to get the keyboard input working properly is beyond me, and is probably a bug in the SDK, but in any case after calling that function I got the key input working for the debug screen. The default console in the SDK calls this function during InitConsole, so the key input works fine when using the default console.

After that it was just a matter of porting the DOS functions so that I could try actually starting up 4DOS. This morning I then finally found and fixed the most serious problems in my ported DOS functions, and got 4DOS to progress up to the command prompt! I haven't yet checked where the "Unknown command" error message comes from, so there is probably still something wrong in my routines, but I was quite pleasantly surprised that my actual x86 CPU core emulation (which was completely written from scratch for the MIPS assembler) is already robust enough to run the 4DOS kernel!


This is about as far as I can get at the moment, as there are still a lot of stuff missing before I can even give any commands to the 4DOS prompt. I haven't coded any IRQ handling stuff yet (which is needed for the x86 code to read the keyboard I/O ports), all I/O port handling is still missing (so even when I get the IRQ handling done the IRQ has nothing to read yet), and all the bottom screen keyboard graphics are still missing (as the DSx86 keyboard graphics are 16-color and the DS2x86 graphics need to be 16-bit coloured). These should all be resonably straightforward, unless I run into some unforeseen obstacles when porting them from the current DSx86 code. But, in any case, I am pretty happy with the progress I have been able to achieve during the last week. Currently it looks like DS2x86 might actually be a reality one day. :-)

http://dsx86.patrickaalto.com/DSblog.html