PDA

View Full Version : DSx86 News - Dos Emulator for DS - Happy New Year!



wraggster
January 3rd, 2010, 17:39
Pate has posted some more great WIP News about his Dos Emulator for DS:


Alpha version 0.01 feedback
Big thanks to everyone of you who tested the 0.01 alpha version and reported the problems you found, either by sending me the full DSx86dbg.log files or by posting on the GBADEV forum thread! The logs showed pretty clearly that DSx86 is still missing too many opcodes for it to support other games besides those I have specifically supported. Sorry about that, I thought it might be able to run some other simple games already. Also, the logs showed that quite many games want to use the graphics mode 0x0D (320x200 16-color EGA mode). I guess this should be the next graphics mode DSx86 will support.

Opcode tester program progress
Pretty soon after I released the 0.01 version, I noticed some serious problems with Leisure Suit Larry 3. After I fixed the missing opcode in 0.01, it still would not recognize any user input, instead it always said "Bad Said Spec" whatever I tried to type. I could not find the problem by debugging the code (and I tried for hours), so I then decided that now would be a good time to finally improve my opcode tester program. Until now the program had only tested for typos in the memory access, so that my opcode handlers don't change the wrong memory location (addressing with [SI] instead of [DI], for example).

I worked on the tester program for two full days, and added pretty complete tests for all arithmetic, logical, and move opcodes. It tests all modrm byte variations that DSx86 supports, and is smart enough to skip the variations I haven't yet coded. It checks for the correct result of the operation, and also for correct CPU flag changes.

When running the improved tester program I found about half a dozen bugs in my opcode handlers, including bugs in "TEST" opcode, which the original tester program had skipped completely, as it doesn't change any memory.

Now I feel much more confident that the new opcodes and modrm byte variations I add will work properly even when I don't currently know of a game that would use them. Thus, I have been adding quite a few new opcodes these past days since the 0.01 release, for example all "INC", "DEC" and "LEA" variations are now fully supported, same as all arithmetic 16-bit operations with immediate values, and most of the "MOV" opcodes as well. Still a lot of work to do with the remaining missing opcodes, but it is much nicer to keep adding them now when I can test the new variations immediately.

Auxiliary Carry and Parity flags
One big difference between the ARM and x86 processors is that ARM does not have the Auxiliary Carry (which works like the normal Carry flag, but for the bottom 4 bits of a byte) nor the Parity flag (which tells whether the least significant byte of the last arithmetic operation has an even number of set bits). I had hoped that games would not use these flags, but now I have noticed them both being used in games.

The AC flag is used in Leisure Suit Larry 3. When drawing data to the screen, LSL3 uses both the Carry flag (for the upper 4 bits) and the AC flag (for the lower 4 bits) to determine whether the new data is in front of or behind whatever is currently on the screen. It uses code like this:

CMP BL,[DI+7FF0]
LAHF
TEST AH,10

That is, it compares the current value in BL with the value in memory, then loads the AH register with the resulting flags, and then tests for the bit in AH that has received the AC flag. A somewhat complex method, but since the x86 instruction set does not contain a conditional jump that would check the AC flag, this is the most straightforward method available.

Since the ARM processor does not have anything similar, I had to code a game-specific special case to handle this. I added some code to the LAHF opcode (which is quite rare) handler, so that it checks whether the next opcode is "TEST AH,10" (which could have no other purpose but to test the AC flag), and if so, it determines if the previous opcode is "CMP BL,[DI+7FF0]", and if so, it performs the compare again, but this time by shifting the values 4 bits left, so the resulting real carry will get the value that the AC flag would get in x86. This new carry is then stored into the AH register bit 0x10, so the following test will give the correct result. This seemed to solve the problem completely for Leisure Suit Larry 3.

Based on a log file I received, The Incredible Machine uses the parity flag. However, on closer examination of the code I believe this is actually a bug in the game. The game has code like this:

1E30:60EB 83F90A cmp cx,000A
1E30:60EE 7C0C jl 60FC ($+c)
1E30:60F0 0BFF or di,di
1E30:60F2 7A02 jpe 60F6 ($+2)
1E30:60F4 AA stosb
1E30:60F5 49 dec cx
1E30:60F6 D1E9 shr cx,1
1E30:60F8 F3AB repe stosw
1E30:60FA D0D1 rcl cl,1
1E30:60FC F3AA repe stosb

The way I interpret that is, that it first check if it has less than 10 bytes to move. If so, it jumps to simply moving them byte-by-byte. If there are more bytes, it first checks whether the low byte of the target address has an even number of bits set (?!), and if so, it jumps to moving the data by word access, else it first moves the leading byte, and then the remaining bytes using word access.

What the author probably meant, was to check whether the target address is even, and jump to word access if so. That would have been done by a code somewhat like this:

test di,0001
jz 60F6

That is, by testing whether the lowest bit of the address is set or not. Luckily for the author, x86 works fine with unaligned word access (unlike ARM), so this is a benign bug that causes no ill effects. What is annoying, though, is that I need to add a special case into DSx86 to handle a code that shouldn't be there in the first place!

SB ADPCM support
I also added the 4-bit ADPCM and 2.6-bit ADPCM audio support to DSx86 SoundBlaster emulation, both of which are needed by Solar Winds. It was reasonably easy to do, again using the DOSBox sources as a reference. My version does not sound quite similar yet, though, so perhaps I still have something wrong in my implementation. At least it does not crash, which is always the main thing when coding for ARM7. :-)

Annoying save game bug
I have been testing Leisure Suit Larry 3 pretty extensively, as it used to be one of my favourite games back in the early 90's. That was mostly because I had a Roland LAPC sound card (basically an MT-32 synth built into a PC ISA card), which the game supported perfectly. It even loaded new patches to the synth to make the music sound really really good (much much better than what the music sounded on any General Midi synth, for example, not to mention AdLib/SoundBlaster cards). I think the music plays surprisingly well even on my poor AdLib emulation in DSx86. It obviously does not sound great, like with the LAPC card, but it is close enough that it brings back memories. :-)

Currently there is a really annoying problem with save games of LSL3. For some strange reason DSx86 occasionally corrupts the save game directory file "LSL3sg.dir". This is pretty much the worst file to get corrupted, as losing it means you lose all of the possible several save games.

What is curious is that usually when this corruption happens, I can see the save game names at the top row of the DSx86dbg.log file, and the LSL3sg.dir file contains only "---------------", which should be at the start of the DSx86dbg.log file! I don't see how it could swap the file pointers, especially as the DSx86dbg.log file had not been open when I saved the game! This still needs a lot of looking into.

Future plans
Well, today my two-week Christmas vacation ends, so tomorrow I need to again start working "for real". I would like to release version 0.02 with a lot of added opcodes reasonably soon, but I don't yet know when that might be. Probably in a week or two. The next big thing to add would then be the support for the 320x200 EGA 16-color mode, but that will be for version 0.03 at the earliest.

http://dsx86.patrickaalto.com/