Posted By: wraggster
Pate has posted more news of his Dos Emulator for the DS:
DS2x86 has now progressed so far that I have managed to show the first title screens from my Trekmo demo! That is good progress, especially as I fought with a weird problem for the whole Sunday evening and Monday of the past week. Observant readers of my blog might have noticed something strange in the screen copy of my previous blog post. I myself only noticed the weirdness several hours after I had posted the blog post, when I was just proof reading the blog post again. The amount of EMS memory that 4DOS uses for swapping displayed 8197K! Normally it shows 224K, and there was no reason why it would suddenly start taking that much EMS (especially since I still only provide 1.5MB of EMS in DS2x86)! I looked at my latest changes in the code but did not see anything that would cause such a change, so I ran my opcode tester program, but that did not find anything wrong in any of the opcodes. I usually try to solve such weird issues before going to bed, as otherwise I just keep thinking about the problem and can not easily fall to sleep. This time it was already late Sunday evening so I had to leave the code like that.
On Monday after work I then began to really look into this problem. Luckily I had a working version in my backup directory, so I was able to run file compares between the source codes. The strange thing was that the real-mode opcode sources did not show any changes between the versions, while the problem was obviously in the real mode handling, as 4DOS stays in real mode all the time. After several hours of head scratching I finally figured out what the problem was. I had added a call to one of the real-mode opcode handlers from the protected-mode code, but had forgotten to make the required change into the real-mode handler that would allow it to be called from both real and protected mode. I had changed the main framework for this, though, which is why also the real-mode handling got broken. The file compare did not show this as the problem was that I had not changed the code where I should have, and the opcode tester did not find the problematic opcode because it was one of the simplest opcodes which I thought did not require a unit test! Argh! Well, several lessons learned again:
If you use unit tests to test your code, make sure the unit tests test everything!
No code is simple enough to not possibly get broken because of changes outside of the code.
When you change existing code because of global framework changes, make sure you change every code affected by this, not just the code you are currently working on!
Anyways, after fixing that problem I managed to add the protected mode IRQ handling during the week. By Friday I had reached the location in Trekmo code that switches to graphics mode (Trekmo uses triple-buffered Mode-X 320x240 graphics mode). On Saturday morning I added the Mode-X blitting routine, which I ported directly from the DSx86 ARM ASM code into DS2x86 MIPS ASM, I just needed to add on-the-fly conversion from palettized 256-color graphics to 16-bit graphics (which is the only supported graphics mode in DSTwo SDK). Surprisingly, my new blitting code only had a single mistake. I had accidentally used sw (store word) where I meant sh (store halfword), which caused an unaligned crash, but after fixing that the blitting routine worked fine! I got the initial title pages (two simple PCX images) to display fine, and then I again kept running into various as of yet unsupported 32-bit opcodes and modrm variations.
Now I am working on the missing 32-bit opcodes. I finally figured out a way to use the GCC ASM macro syntax to embed register names into the branch target labels, so I am currently creating a new and improved macro system that would allow me to add several modrm bytes for several opcodes with just tiny additions to a single macro. This would speed up my opcode implementation quite a lot, and also remove one potential source of bugs caused by typos. I found out that if you add \() at the end of the parameter name, the parameter will work even within a word, so that a macro call like this :
#define eax s0
.macro modrm_3_help oper jump reg
\oper\()_\reg\()_SIB:
b \jump\()_\reg
.endm
modrm_3_help mov mov_r32_t0 eax
Generates code like this (as the symbolic register name s0 means register number 16):
mov_$16_SIB:
b mov_r32_t0_$16
So, I think I'll get back to improving the macro system now instead of making this blog post longer. :-)
http://dsx86.patrickaalto.com/DSblog.html