PDA

View Full Version : rpix86 v0.07 released! - Dos(PC) Emulator for RaspBerry Pi Released



wraggster
April 28th, 2013, 21:35
via http://rpix86.patrickaalto.com/rblog.html

Improvements in the new version
This version does not have any new features, it has just various small fixes and improvements, mainly affecting certain games. Here is a list of the changes:

Fixed a potential crash when a game moves the cursor far outside the screen area.
Implemented a dummy OUT 82,AL operation (Alone In The Dark).
Improved SB IRQ behaviour for short DMA buffers (Alone in the Dark).
Implemented a missing REP MOVSW Mode-X to RAM operation (Ween - The Prophecy).
Fixed a bug in REP MOVSW RAM to Mode-X operation (Ween - The Prophecy).
Implemented reading from DMA page register (Super Frog).
Implemented USE16 version of Mode-X REP STOSD opcode (Super Frog).
Implemented USE32 version of REP INSB opcode (Super Frog).
Implemented USE32 version of REP OUTSB opcode (Super Frog).
Added JPE special handling for "Super Frog".

Further detail about the changes
In the beginning of last week I got some error logs from rpix86 forum user Vanfanel, containing problems in games Alone in the Dark, Ween - The Prophecy and Super Frog. I began by troubleshooting Alone in the Dark, as I already had that game and it works fine in DSx86. However, as soon as I started it in rpix86, the whole rpix86 crashed with a segmentation fault. I could not even get an error debug log, which I thought was a bit strange.


Being able to run my emulator on top of a real operating system has the advantage that I can attach the GDB debugger to it from a different shell session, and I can then have GDB tell me exactly where the program crashes. With DSx86 and DS2x86 these problems have been much harder to track down, as they will simply hang the whole system in similar situations. In this case the debugger showed that rpix86 tried to draw the text mode blinking cursor outside of the memory block I had allocated for the text mode screen. I calculate the cursor position based on the row and column values, but had not limited those in any way. So if a game decides to hide the cursor by moving it to row 255 for example, my code simply tried to draw it there, even though the text mode only has at most 50 rows, and normally only 25. I added an out of bounds check and skipped the cursor drawing if the address is out of bounds, and this got rid of the crash.

After this small fix I got the exact same rpix86dbg.log error report from Alone in the Dark as what Vanfanel had reported to me. This was caused by the game trying to setup Sound Blaster with DMA channel 3 instead of the DMA channel 1 (which it actually uses in rpix86). I added a dummy handler for that DMA channel, but this only caused rpix86 to crash again with a segmentation fault. I again debugged this problem, and found out that the game executed code at the end of the RAM area (which was full of zeroes) and continued beyond the end of the RAM area! Obviously something much more serious was going on.

I do have various conditional debug defines in my cpu emulation sources, just for these kinds of problems. I enabled the "do not run zero code" and the "trace all opcodes" flags, and ran the game again. I found out that the game attempted to execute code at address FFEF:0008 forwards, and there it ran into zero code. After some more debugging I noticed that it jumps to that address when it tries to call the DOS INT 21h interrupt, and sure enough, some code had overwritten the int 21h vector to point to that invalid address!

I also have a memory watch feature built into rpix86, so I added a watch for the int21h vector address, and found out the code where it gets overwritten. It took me quite a while longer to understand what was going on, as I noticed that the root cause for the memory overwrite problems was that the game first allocates all available DOS memory, loads and executes another program, and after it exits the game again tries to allocate all available memory (of which there is none at this point), does not check whether the allocation succeeds and then proceeds to loading another program into memory that has not been allocated! This loading then obviously corrupts memory from all sorts of locations, including that int 21h address.

Since the game does work in DSx86, I began debugging it there and comparing the behaviour with what happens in rpix86. After considerable time I noticed that the first program that gets loaded is actually a Sound Blaster driver, and it exits with an error code if it can not determine the IRQ number for the Sound Blaster. It occurred to me that I had not run the Alone in the Dark hardware configuration option in rpix86. When I ran that, it detected only "Sound Blaster (no DMA)", even though it should have also detected "Sound Blaster (DMA)". Using the no DMA configuration allowed the game to start, though, but the audio was very bad.

So, obviously the problem was related to the game not detecting the SB IRQ number. After some more debugging I realized that the game does not set the playing frequency at all, and in rpix86 it gets left at zero, which will then never cause an IRQ to happen. In DSx86 I had (by chance) handled this situation better, and I copied the same handling to rpix86. This finally allowed the game to detect the proper Sound Blaster (DMA) audio device. The game does still not run very well, though. It has some weird slowdowns, so that it actually runs faster in DSx86! I have not yet managed to determine what causes these slowdowns, it looks like some sort of a timing issue.

The next game I debugged was the Ween - The Prophecy. It used a couple of somewhat more rare VGA Mode-X block moves, which I had not yet implemented in the code I had ported over from DSx86 and converted to be compatible with protected mode. I implemented these operations, and this allowed Ween to start up and proceed to the actual game fine.

Next I downloaded and tested Super Frog. The first problem was simple, it attempted to read from the Sound Blaster DMA page register, which I just had not implemented yet. After I implemented this, it proceeded to the next problem, where it attempted to clear the Mode-X graphics screen using a 16-bit REP MOVSD block operation. I had only implemented the 32-bit version which is usually used by protected mode games, but for some reason Super Frog wanted to use the 16-bit version even when it ran in 32-bit protected mode. This was pretty easy to implement, though.

After that problem Super Frog stopped into protected mode REP INSB port operation, which it used to read the VGA palette register values, and immediately after that into the corresponding REP OUTSB operation used to set the VGA palette register values. These were also easy to implement.

Finally the game stopped into a JPE opcode, in a code that was exactly like the routine mentioned in the Simply FPU tutorial for reducing an angle within the allowable range of ±263 radians. That is, the game obviously uses a lot of floating point operations, which are currently simply handled as a no operation in rpix86. At this point I assumed that this game can not be made to run in current rpix86, but I decided to code support for this specific algorithm anyways.

After this fix, to my surprise, the game did start up and did seem to work. I don't know how to play that game so I don't know whether it uses floating point operations during the game so that it will be unplayable, but I will leave that to you to test. :-)

I also spent a little time testing X-Wing, which seemed to work without problems, and also the horizontal pan jitter problem in Commander Keen 1. This jitter problem is difficult to solve, and I could not figure out a way to improve it in this version yet.

New web site features
Last week I also got a request to add a donate button to my rpix86 pages. Thus, I added one at the bottom of the main page. This is not a request for you to donate anything, but there is now a button for that purpose if for some reason you absolutely want to donate. :-)

Also, big thanks to Ben Garrett, who created a very informative tutorial for rpix86 installation and usage. The tutorial also gives a short history lesson about what DOS is, so check it out! I added a link to the tutorial also to my FAQ page.

In other news...
Last week I also got contacted by the people behind the new gaming console Game Consoles Worldwide Zero, or GCW-Zero for short. They would like me to port my x86 emulator also to their new device, and this is something that I find quite interesting. The device is powered by an Ingenic JZ4770 CPU running at 1GHz, so it is quite a bit more powerful than the 360MHz JZ4740 that is in the DSTwo flash cart for which I developed the DS2x86 version of my emulator. However, both of those processors use the MIPS32 architecture, so it should be relatively easy for me to port my DS2x86 code (which is 95% MIPS32 ASM) over to work on GCW-Zero.

I have already done some preliminary porting tests, and there are some issues that I need to solve to be able to run my emulator under an operating system, but these issues are reasonably similar to what I had to do when porting DSx86 over to rpix86. What this means, though, is that it looks like my finishing my Android port will get pushed back, as I am currently more interested in working on GCW-Zero than on my continuing the ax86 version. But who knows, possibly I can use some new features (that are coded in C language) in both of them!

Anyways, thanks again for your interest in my emulators! Have a nice 1st of May!

Download Attached