This version has the following fixes and improvements:
  • Improved keyboard emulation (fixes Little Big Adventure hang after key press).
  • Improved SVGA mode scaling quality.
  • Fixed SoundBlaster DMA channel masking (fixes Mortal Kombat sound effects).
  • Implemented opcode AAM in protected mode (Warcraft 2 Setup - System info).
  • Fixed a BSOD problem when moving mouse in Warcraft 2 and Command & Conquer.
  • Improved BSOD error reporting, no more partial exception messages.
  • Implemented support for 80x50 text mode (Little Big Adventure Setup).
  • Implemented mouse function INT 33 AX=00A1 (Knights of Xentar).
  • Fixed a problem in AdLib hardware detection (Warcraft 2).
After I got the DSx86 version 0.41 released last weekend, I continued improving DS2x86. I had already managed to fix the keyboard emulation for LBA and the SB effects for Mortal Kombat, so I focused on the weird partial BSOD error message that happened in Warcraft 2 after moving a mouse. Before I could test that, I needed to use the setup program to disable audio, and while doing that I noticed that the setup program crashed due to an unsupported AAM opcode. This opcode behaves the same in real and protected mode, I had just forgotten to add it to the protected mode opcode pointer table, so that was an easy fix. However, finding the cause for the BSOD was considerably harder.
It took me three days to work on the BSOD problem. It seemed I got nowhere during the first two days, so on Wednesday I then decided to rewrite the whole BSOD system. Ever since I originally coded the BSOD system it has been the MIPS side that generates the full exception string and sends the whole screen back to the NDS side. Now I thought that perhaps with the new transfer system it would be better to transfer just the raw data from the MIPS side, and then build the string on the NDS side. After I did that, I got some proper-looking addresses on the BSOD screen. However, the exception cause was weird, it was 0x1F which is not mentioned in any MIPS reference material I have. Also, the crash address was in the middle of a page table clearing routine, which did not make much sense. If there was something wrong at that point, the code should have crashed on the first of the 16 similar opcodes, not on the 10th!
My exception handler walks the stack and looks for values that are in the range 0x80000000 .. 0x801DAFD0 (or where ever the first symbol from the library file is located). These numbers are between -2147483648 and -2145538096 in decimal notation, and such values are rarely used as parameters to functions, so this will usually give a proper list of function return addresses. The first eight of these values have been shown in the BSOD crash dump ever since I originally coded it, but this time the values it printed did not make much sense in relation to the crash location. Thus, the next step was that I added full register dump into my BSOD crash printout, hoping that that would give some more info about what exactly caused the crash. This is what the new BSOD crash dump displayed:
Now I finally had enough information to help me find the crash cause. The registers could not possibly have such values at the crash location 0x801B5C14, so it seemed that the crash location was reported wrong. However, the stack and register values very clearly pointed to my MouseEvent() routine which was called from the MouseMoved() routine. Since the crash happened after moving a mouse, these seemed to be correct values. But the crash address still pointed to within the PageTable clearing routine... And at that point I finally figured out the cause of the crash! The MouseEvent() routine gets called inside an interrupt generated originally from the NDS side data transfer request. The crash location points inside the PageTable clearing routine, probably because that was what the code was doing when the interrupt occurred! And my MouseEvent() routine uses the PageTable and does not expect it to be clear!
I changed the MouseEvent() routine not to use the PageTable (as it did not actually need to use it, it was just a convenient way to determine the location of some memory variables), and that got rid of the BSOD crash! I also some time later found out why the original message was cut after 4 characters: I overwrote the string in the new transfer system. This also caused the exception cause to show 0x1F instead the correct 0x03 "TLB miss on store" it should have displayed in the rewritten BSOD handling. This is also fixed now.
After that fix I then did some other minor fixes, for example I added a 80x50 character text mode handling, which was used by the Little Big Adventure setup program. I also found that WarCraft 2 sometimes detected AdLib hardware and sometimes not, so I spent some time debugging that problem and noticed that my handling of the detection routine was very poor and unreliable. I improved that routine so that now both WarCraft 2 and Little Big Adventure seem to play both FM music and SoundBlaster digital effects fine. There is still a potential problem where some SB IRQs might get missed when paging is on, which may cause SB digital audio to stop working after a while. This needs some better IRQ handling in general, so fixing this is on hold until I can figure out some improved ideas for that.
Anyways, this version should now have some worthwhile improvements, let me know of the problems you encounter, and again crash logs and BSOD error info is very welcome! Thanks again for your interest in DS2x86 and DSx86!