First off, I just yesterday noticed that I had made a mistake when I prepared version 0.05 for release: I had forgotten to disable the conditionally included Memory Watch code from the CPU emulator! I had used the Memory Watch code to break into the debugger if an opcode writes to the BIOS F000:0000 address (which my buggy EGA code did at some point), but then forgot to turn the feature back off after I fixed the EGA code. This Memory Watch code causes a noticeable slowdown to the whole emulation, as it checks a memory address after every single opcode is executed! So, if you are wondering why 0.05 feels slower than 0.04, this is the cause. Sorry about that, I'll try to be more careful in the future. Oh, and another thing, it seems Commander Keen 4 has an unsupported EGA opcode in the actual game. I only tested the demo, and it does not have this issue, so I did not notice it. This should be fixed in the next release, though.
During the past week I did not have time to work on DSx86 at all, as we got about 30cm more snow here, and all my free time went to shoveling snow from my yard! I only got to working on DSx86 this Friday, and immediately began a complete rewrite of the EGA graphics code. I decided to code proper EGA read and write subroutines, which handle all the various read/write modes, functions, and Set/Reset features of the EGA hardware. The separate EGA opcodes then call these subroutines as needed. This code will run somewhat slower than the previous EGA code that had everything inlined to each of the opcodes, but now the subroutines are in ITCM so perhaps the difference is not all that great. And adding all the features to all the separate opcodes would have made the code quite huge. This improved EGA implementation now finally got rid of the graphics glitches in Duke Nukem 2.
I used DOSBox sources as a reference, and noticed that DOSBox actually has a buggy implementation of Write Mode 3: It should rotate the host byte before all the other operations, but DOSBox does not have the rotate code in the Write Mode 3 handler. It is possible that no game ever uses Write Mode 3, so this bug might never actually manifest itself. In fact, I decided to copy the bug into DSx86, as that saves a reasonable amount of code. :-)
I have now added pretty much all of the unsupported EGA opcodes from the debug logs I have received for versions 0.04 and 0.05. I also debugged the game Swap, in which the cursor left a trail of corrupt graphics when it was moved. I found out that the game used opcode mov al,[si] to read the original data below the cursor from the EGA memory. This was a problem as I have only supported EGA memory access with the ES segment (or with the DS segment in the string opcodes). I coded a special case to the mov reg8,r/m8 opcode for when the DS segment points to the graphics memory, and that fixed the problem in Swap. However, I'll need to rethink my whole approach to graphics memory handling in the future, as there will surely be many more cases where the DS segment is used with various opcodes to access the graphics memory.
I also downloaded Street Fighter II and SimCity demo, which both have graphics issues, and will continue debugging them to see what causes these problems.
Currently I am working on the INT 03 problem that happens in games like Castle Master. Simply supporting that opcode did not fix the issue in Castle Master, so I am investigating this further. It looks to me like the INT 03 (which is the debugger breakpoint interrupt) is used in the game to detect whether it is running inside a debugger, which in turn is most likely some sort of anti-hacking feature in the game.
I'll continue working on these issues for the next week, and hopefully get 0.06 ready for release then next weekend. Thanks again to all of you who keep testing DSx86 and sending me the debug logs!