Pate has posted some WIP News concerning his Dos Emulator for DS:
Today I got fed up with the Packed File Corrupt problem, and decided to see if I could handle the required "LOADFIX" functionality automatically within DSx86. I looked at a couple of games that cause this behaviour, and used a hex editor and debugger to see if I can find a pattern in their header that would detect the use of the buggy /EXEPACK linker switch that cause this problem. I found the following things in common with the EXE headers of the problem games:
RelocationItems is zero.
HeaderSize is 0x20 (512 bytes) even though the actual header is only 28 bytes.
Initial SP is 0x0080.
Initial IP is either 0x0010 or 0x0012.
Practically all EXE packers have zero RelocationItems, so that alone is not a sufficient indicator of a buggy EXEPACK code, but I didn't find all of the above header settings in any packed EXE file that don't have the "Packed File Corrupt" problem.
I made a small code change into DSx86 where it detects the above EXE header signature, and allocates 64KB of RAM before allocating the memory for the program and running it. I also added new code to the FreeProcessMemory() code so that when the process exits it checks whether an extra block of memory was allocated and frees that as well when freeing the actual memory of the process. The end result was that the programs that have that EXE header signature only get 580KB of RAM, and don't give the "Packed File Corrupt" message any more.
I might need to adjust this detection algorithm in the future, to check also the start of the actual code (which seems to always be nearly identical to this):
1C59:0012 8CC0 MOV AX,ES
1C59:0014 051000 ADD AX,0010
1C59:0017 0E PUSH CS
1C59:0018 1F POP DS
1C59:0019 A30400 MOV [0004],AX
1C59:001C 03060C00 ADD AX,[000C]
1C59:0020 8EC0 MOV ES,AX
1C59:0022 8B0E0600 MOV CX,[0006]
1C59:0026 8BF9 MOV DI,CX
1C59:0028 4F DEC DI
1C59:0029 8BF7 MOV SI,DI
1C59:002B FD STD
1C59:002C F3 REPZ
1C59:002D A4 MOVSB
1C59:002E 8B160E00 MOV DX,[000E]
1C59:0032 50 PUSH AX
1C59:0033 B83800 MOV AX,0038
1C59:0036 50 PUSH AX
1C59:0037 CB RETF
Detecting this code before actually loading the EXE into memory is slightly more difficult than just looking at the EXE header, so I hope the current change will fix at least most of the problems.
Galactic Battle
I had a plan to work this weekend on adding support for EGA, specifically mode 0x0D (320x200 with 16 colors). Last week I searched for a small game that would use that mode, and I downloaded a couple of games that weren't suitable (had a lot of extra files) until I found Galactic Battle which seemed to be just what I was looking for. It is a small Space Invaders clone that uses mode 0x0D and PC Speaker sounds.
It did have the "Packed File Corrupt" problem, and I didn't have the above fix in the code at that time, but that was easy to work around by starting 4DOS without swapping. Anyways, this Friday I then began working on emulating the 16-color mode. During the last week I had been thinking about ways to emulate this mode, and I did come up with a solution that I thought might work, so I began coding it. I managed to get the code working pretty well already on Saturday, and I took the screen copy above from the Galactic Battle running in DSx86. It was quite playable, perhaps just a little bit slow.
EGA emulation
The 16-color modes are a lot more complex than any graphics mode I have so far supported. MCGA 320x200 with 256 colors is the easiest, as each pixel is simply a byte that is an index to a palette, exactly like the bitmapped background modes in Nintendo DS. The CGA mode was a little bit more complex, as it has 2 bits per pixel, but that was easily handled via a look-up table (LUT).
However, EGA and VGA 16-color modes are a different beast entirely. They use four separate memory planes, a byte in each plane has 8 neighbouring pixels, and each plane contains one bit of the 4-bit color. All these four planes share the same memory address (in segment 0xA000), and the plane that is being read/written is determined by writing a certain mask to a certain EGA/VGA I/O register. Thus, writing for example 4 neighbouring pixels of different colors might need 4 writes to the same memory position, and most likely also four reads and some bit masking so that the other 4 pixels in the same bytes don't get overwritten. A pretty complex scenario to emulate (and especially to do it fast!).
The real EGA has 4 times 64KB planes totalling 256KB of RAM, and I didn't want to spend more than this 256KB of RAM in my emulator. I also didn't want to assign less than this amount of RAM to the EGA/VGA memory, as many games use page flipping and assume that this much memory is available. So, I needed some way to make the memory behave like four different planes of 64KB each, but I also needed a way to blit this fast into the Nintendo DS VRAM, which is organized as 8 bits per pixel (that is, each byte is a separate pixel).
The straightforward method to emulate this might have been to allocate 64KB of RAM for each of the four planes, and use these planes like the original EGA/VGA
...
Catherine: Full Body’s English translation for the Vita