|
June 13th, 2010, 23:52 Posted By: wraggster
Pate has posted this news concerning his Dos Emulator for the DS:
The next version will have at least one major improvement: No need for the LOADFIX command any more! Or at least I hope it won't be needed. I'll still leave the command available in case some game works better with it, for some reason. This would be rather strange, though.
While debugging Moonstone a couple of weeks ago I noticed that the reason it hangs after the intro was that the MAIN.EXE it tries to run after the intro suffered from the "Packed file corrupt" problem. Usually running LOADFIX before running such a game will help, however with Moonstone it did not improve the situation, MAIN.EXE still did not launch but this time complained "Not enough memory". I stopped working on it for a while, but began thinking of ways to get rid of the need for the LOADFIX feature completely (see my Jan 17th, 2010 entry for more info about the LOADFIX problem, if you are interested).
The solution suddenly occurred to me last Friday, and yesterday I spent the whole morning reorganizing the internal memory emulation in DSx86 to use my new idea. Since the problem is caused by buggy EXEPACK decoders that wrap the segment address below zero (to 0xFFF0 and such), I thought that what about if I move the emulated BIOS segment (0xF000..0xFFFF) of DSx86 before the actual RAM memory area (0x0000..0x9FFF)! That way the segment wrap would not cause any problems, as addresses like 0xFFF0:0xFF00 will then automatically point to the correct place in the DOS RAM area without any need for a special handling for such a situation! Gotta love such sudden coding ideas that both make the code simpler than before and automatically handle difficult situations. :-)
I had earlier had the BIOS 0xF000 segment as a separate data block of exactly 64KB in size, with various BIOS tables and other static data already located in the "final" locations within the block. The DOS RAM in turn is a bss block of 640KB. So, implementing this new idea meant that I had to copy all the BIOS static data into the bss memory block after DSx86.nds has been loaded, and it also means that the memory footprint of DSx86 will increase somewhat (as the static data is in memory twice, once in the data area and once in the bss area). However, as I don't have the extra blank space in the 64KB data block taking space from the DSx86.nds file itself, the file size got smaller. This change also will improve the DSx86 internal reboot, as the BIOS area will be recreated during a soft reboot, so it won't get corrupted as easily.
This was a rather extensive and a little bit scary change, so there is a chance that some games that need something specific from the BIOS (that I had forgotten to copy to the new BIOS area) might not work in the upcoming version. I hope I remembered to copy everything (and did not make any typos!), though.
EGA smooth scrolling fixed
The EGA horizontal smooth scrolling issue will also be fixed in the upcoming version. Late last Sunday I already thought I got it fixed, after I changed my code so that the EGA starting address values that the game sets up will only get used after one full frame has passed. With that change both Supaplex and Heimdall scrolled very smoothly. However, on Monday I then tested Commander Keen 4, which had always scrolled smoothly (even though it does not sync to the vertical retrace signal), but it scrolled now so badly it was actually nauseating! So, back to the drawing board..
The actual problem is caused by the fact that on the real EGA/VGA card, the screen start position (which scrolls by 8 pixels at a time) can be setup whenever the display is active, and it will take effect after the next vertical retrace time. The pixelwise smooth scrolling register however takes effect immediately, so it needs to be set during the vertical retrace period. Both Supaplex and Heimdall used a system where they first wait for a vertical retrace period, then wait for the screen active period to start, then set the coarse start position, then wait for the screen retrace period to start, and then set the pixelwise scrolling register.
However, in DSx86 I need to use the current values of both of those registers when I start blitting the screen, and this happens during the vertical blank time of the NDS display. It finally occurred to me, that from the PC game's point of view, the vertical blank period when I blit the screen is actually the active display time! So, perhaps if I simply swap the VBlank bit of the NDS display status register when reporting the current status to the PC game... And voilĂ*, that fixed the scrolling in all the games! Ha, yet another simple and clean fix, I just needed to do some thinking to figure it out. :-)
Game-specific fixes
Here is a short list of games that should run in the next version, and a description of the fixes I have made to DSx86 to make them run properly.
Moonstone will start the actual game, thanks to the LOADFIX removal.
Wizardry games had a problem opening the *.dsk files. At least in Wizardry 1 this was caused by the game attempting to open file "WIZ1 .DSK", and my DOS file routines did not trim the blanks away from the file name as they should have. I fixed the file name routines, so Wizardry will load the file properly.
Uninvited needed the DOS FindFirst function to clear the AX register. This is an undocumented behaviour, even the Ralf Brown's Interrupt List has no mention of this. I found this behaviour from the DOSBox sources, though.
B.A.T. used a wrong palette. This was caused by the game first setting the VGA 256-color DAC registers, and then the EGA 16-color registers. I did not check the current video mode when setting the EGA palette registers, so they overwrote the 256-color palette with a 16-color palette. Now I ignore the EGA palette registers in 256-color mode, though this might not be a final solution.
Alone in the Dark had various problems. I have two versions of that game, one started but had a severely broken palette, and the other did not even start but crashed with a jump to address 0000:0000.
The palette problem turned out not to have anything to do with the palette routines. Instead it was a problem similar to the LOADFIX problem, it moved data (including the palette data) around in the EMS memory segment (at 0xE000) using an address like 0xDFFF:0x0010. Since the memory access method in DSx86 is based on the segment address, that address did not point to the EMS memory, and thus the palette had invalid values. The fix for this was similar to the new LOADFIX fix, I made the 0xDC00 segment (which does not contain any useful data) point to the memory immediately before the EMS memory, so this memory access will point to the EMS memory as required. After this fix the game began to look correct.
The next problem with the working version was that it crashed at exit. This was caused by DSx86 not saving DS and ES registers of the calling program when it executes another program. I fixed that, and now the game returns to DOS properly. Strange that this bug has not caused more problems.
After those fixes I debugged the other version of the game that crashed at the start. I found out when debugging that it crashes when it tries to return from a Terminate-and-Stay-Resident function. Immediately before this call the program had resized it's memory to 0 (a rather unsafe thing to do, practically freeing the memory block where the program itself is executing). When a memory block size is decreased, the DOS memory allocation functions split the memory block in two, and this causes a new memory block to be generated over the beginning of this program's Program Segment Prefix (which contains the return address of the calling program, among other things). I noticed that when my memory allocation routine clears the name field of the new memory block, it overwrites this return address with zeros. DOSBox does not clear the name of the new memory block in this situation, so I commented out that line of code, and that made this version of Alone in the Dark start properly.
I also fixed the "Unsupported Port I/O" problem in the setup program, so I could setup the game to use SB audio. Currently there is still a problem with the SB audio handling, it looks like the game wants to use DMA channel 0, even though the BLASTER variable says that SB uses DMA channel 1. This is what I am currently debugging.
Miscellaneous
I have also fixed various other issues mentioned in the debug logs I have received. Currently for example History Line 1914-1918 progresses further than before. I have also tested various other games but haven't yet figured out the problems in them. I should also soon look into the save game problem that affects several games, including Supaplex. The problem might have something to do with my using the Unix-style file function wrappers over the libFAT functions, which are not fully compatible with the way DOS file access is supposed to work. I guess I should at some point start accessing the libFAT functions directly (or just include a custom version of libFAT), but I really would rather not have to do that.
By the way, I yesterday downloaded the new version 1.0.3.6 of iDeaS, and have been using it to debug DSx86. The new version has fixed the problems I had with it in the previous version, so now I can use it fully to debug these badly behaving games. For example the problems in Alone in the Dark were reasonably easy to find using iDeaS. It is rather slow, but the cool feature of it is that it has DLDI support, so I can run and debug any game on my PC's hard disk with DSx86 running in iDeaS!
Big thanks again to all of you who have been sending me the debug logs, and updating the Compatibility Wiki with new information! It is very fun and encouraging to notice how DSx86 has created a community of people who test games and work on the wiki pages. I really did not anticipate anything like this when I started working on DSx86!
http://dsx86.patrickaalto.com/DSblog.html
For more information and downloads, click here!
There are 0 comments - Join In and Discuss Here
|
|