February 20th, 2012, 00:11 Posted By: wraggster
[h=4]SoundBlaster transfer system improvements[/h]Okay, during the past week I finally managed to rewrite the SoundBlaster data transfer routines for the new DSTwo transfer system I am using. Now I am happy with the method, it is much cleaner than before, and it handles all the various types of playing (auto-init, 8-bit WAV, ADPCM) properly. It can also support Direct DAC output, but I think my actual SB emulation does not support that yet. There are also other problems in the actual emulation, as Warcraft digitized sounds are still not working, but I believe those problems are in the actual emulation running on the MIPS side, not in the transfer system.
[h=4]Bug fixing and VESA SVGA support[/h]After I got the SB audio working, I spent some time trying to get Command & Conquer running. I only got a black screen, with the HDD "led" blinking constantly. It took me quite a while to realize that the problem was not in the game looping, but instead I had broken the graphics blitting when paging is active in the 0.33 version! Sorry about that.. I broke it while moving the emulated VGA VRAM area into a physically different location on the DSTwo RAM (for the future SVGA support), and forgot that the paging routines still used the original memory address. Thus nothing was shown on the screen.
After fixing that, I began working on the VESA BIOS support. I again used my own old LineWars II game as a test bench, as it has the option to use VESA 640x480 mode with 256 colors. I did my first test after I had coded only a couple of the most essential VESA BIOS calls, enough to make LW2 think the VESA mode is available. The intro did run for a few seconds, and then the game crashed! That was rather unexpected, as I thought I had not changed anything that might have caused a crash.
So, I began debugging the reason for the weird crash. I found out that the game crashed because a jump table was overwritten with garbage. I have a memory watch feature in the DS2x86 inbuilt debugger, so I used that to find out the opcode that overwrites the jump table. The overwriting happened in a routine that draws the sun image to the offscreen buffer I use when blitting the 3D viewport to the actual SVGA VRAM. Having the source code of the misbehaving game was again very useful, as I could easily see what the misbehaving routine attempts to do and why it might fail. Since the offscreen buffer is 512x256 pixels (or 128KB) and LW2 is a real-mode game, it needs to access two 64KB segments while drawing the images to the screen buffer. I had used the shld r/m16, r16, imm8 opcode with the imm8 value of 21 to simultaneously copy and shift one register to another register, to help selecting the correct segment. Comparing my algorithm with the DOSBox algorithm made me realize that my version does not work properly when the shift count is more than 16, and thus the segment where the game draw the sun image was wrong and so it overwrote some code outside of the screen buffer. Seems like the DOSBox people had also had problems with that variation of the shld opcode, as the comment in the DOSBox source code says "let's hope bochs has it correct with the higher than 16 shifts" :-). Anyways, I copied the same algorithm (converted to ASM) into my shld implementation, and after that LineWars II stopped crashing.
The next problem was that the polygons that LineWars II draws to the viewport sometimes were not correct. Even though the ship was clearly in the middle of screen, some polygons were drawn all the way towards the left edge of the viewport. After some more debugging I found a bug in my idiv opcode handling. If the result was negative, the high 16 bits of the eax register got overwritten with 0xFFFF! LineWars II used the high 16 bits of eax as a temporary save for the polygon X coordinate, so occasionally the X coordinate became -1 and thus the polygon began from the left edge of the viewport. After I fixed that problem, LineWars II began to run fine in the SVGA 640x480 with 256 colors mode on DS2x86! (The screen copy below is from DOSBox, as I don't have screen copy feature in the current DS2x86.)
It's a bit unnerving having to fix such serious bugs in the core CPU emulation, it makes me wonder how serious problems there still are in the code! LineWars II only uses 386 features when using the VESA graphics mode, in the lesser graphics modes it runs using only 80186 opcodes. This is why I have not noticed these problems before, but I would have expected these to cause problems in other games as well. Perhaps games usually either use 80186 opcodes or fully 386 opcodes, and not a mixture of them as LW2 does. Both of these problems were caused by mixing 16-bit and 32-bit opcodes in the same routines. Anyways, the more bugs I find and fix, the fewer there are remaining!
Next I plan to continue improving the VESA graphics mode support (currently it only works in Zoom mode), and I think I will need to revisit the current scaling modes as well, they do not produce quite good enough quality in the higher resolution modes yet. Perhaps I need to reimplement the Smooth scaling mode for the higher resolution graphics modes after all.
For more information and downloads, click here!
There are 0 comments - Join In and Discuss Here