rpix86 - Blog

Apr 6th, 2014 - rpix86 version 0.17 released!

Here is the latest version of rpix86! Not a lot of changes, as I still have not had all that much time to work on rpix86, but there are a couple of changes that you might find useful.


Sorry I have not had time to work on more enhancements. I hope you enjoy this version, and let me know of any bugs you encounter!

Mar 9th, 2014 - rpix86 version 0.16 released!

Okay, after a bit of a hiatus on the rpix86 front, here finally is a new version of rpix86! I have ported a few features over from my other project, and also managed to spend a couple of days fixing some minor bugs for this version. Here are the most notable changes:

1. Implemented new experimental CD-ROM support

You can now give a new -c (as in CD-ROM) command line parameter to rpix86. This parameter gives the directory on your Raspberry Pi that should be used as the root directory of D: drive. This D: drive is emulated as a CD-ROM drive (when a DOS program queries the type of the drive). For example, if your game is located in /home/pi/rpix86/Games/MYGAME and you have a subdirectory CDROOT under that directory that contains all the files from the CD of the game, you can give a parameter -c/home/pi/rpix86/Games/MYGAME/CDROOT to have rpix86 use the contents of that directory as a D: drive.

Note that ISO images (or any other similar CD images) are not supported, you need to extract all the files from the image to a directory on your Raspberry Pi. I am looking into a possibility of adding ISO image support in the future.

2. Fixed the rpix86 screen copy feature

I had broken the screen copy feature in rpix86 several versions ago, but I had not had much need for that feature myself so I had not bothered to fix it. Now I finally decided to look into this problem. It turned out that I had accidentally moved the screen copy routine to a location in the code after the screen was cleared, which is why all the screen copies had just a black screen. In this version you can again take a screen shot by pressing the PrintScreen button on your keyboard. The screen copies are written into SCR??.BMP files, with the ?? being an incremental number.

3. Ignore the "drop-to-debugger" key press if debugger is not available

I added code to detect whether the current screen size allows running the inbuilt debugger, and if the debugger is not activated, the "drop-to-debugger" key (right Windows key) will not do anything. The built in debugger is meant for my own debugging use, so you can freely ignore this information completely. :-)

4. Improved previous fix for writing to unmapped EMS page

The fix I made in version 0.15 for the Aces Over Europe bug was not a very good one, so I made a better fix in this version. Now writing to an unmapped EMS page writes to normal low memory, just like it works on a real PC.

5. Improved mouse initialization (fixes crash in Fragile Alliance)

There was a minor problem in the mouse initialization routine which left some mouse scaling variables uninitialized. This could cause a division by zero problem in some games that tried to change the mouse scaling immediately after initializing the mouse. This problem is now fixed.

6. Added support for HLT opcode in protected mode (Fragile Allegiance)

Another minor problem was that the game "Fragile Allegiance" used the HLT (Halt) opcode from protected mode, and I had not yet implemented that yet. Implementing it was quite easy, and that fix allowed Fragile Allegiance to run.

7. Implemented a missing EGA opcode (Spacewrecked)

The game "Spacewrecked" failed to run because I had not implemented a rare EGA mode opcode it used. After implementing that the game began to run fine.

Thanks for your continued interest in rpix86, and let me know of any bugs you find in this version! My time to work on a new rpix86 version continues to be somewhat limited, but I will try to work on it at least every now and then.

Feb 23rd, 2014 - Lack of rpix86 progress

First off, sorry for my lack of blog updates for the recent weeks. I have not had time to work on rpix86 for a few weeks now, as I have been busy working on stuff relating to my license agreement with Retro Infinity. I am currently porting my x86 emulation core to a new platform, but this work falls under a NDA so I can not tell you more about it. This work has a deadline, and I prefer to get all stuff that has a deadline done sooner rather than later. Thus, rpix86 is on hold until this work is done.

I can however tell you about one enhancement that will be in the next version of rpix86. I will add a simple CD-ROM support to the next version. This means that you can give a second file folder parameter to rpix86, and this will be used as a D: drive and will show up as a CD-ROM to the DOS programs. This will allow you to run some programs that expect the CD to be present, and will also help installing some DOS programs distributed on a CD. This is also a small step towards ISO image support, which I hope to eventually have in rpix86.

In any case, thanks again for your continued interest in rpix86, and I hope to be able to get back to working on it within a few weeks or so.

Jan 5th, 2014 - rpix86 version 0.15 released!

Happy New Year! I decided to start a new blog page now that the year has changed, so that the single blog page does not grow too big. You can find the previous blog entries using the link at the bottom of this page.

This version has mostly game-specific fixes, but also a new somewhat experimental -f2 filtering option which may improve performance in some games. Here are the details of the fixes:

1. Fixed Crystal Caves hang on title screen

I got a test report asking if the Crystal Caves hang could be fixed, and I was somewhat surprised to hear that rpix86 had such a problem. This game has been working in DSx86 for ages, so it should work fine in rpix86 as well. I began to debug the problem, and noticed that indeed it hangs completely on the title screen. After some digging I found out that the reason it hangs is that the Interrupt Enable CPU flag is not set while the game waits for either timer interrupt or keyboard interrupt. So it never gets either of those interrupts and thus hangs.

The question was then to find out what code clears the Interrupt Enable flag. I added some debug logging to all the code that clears the flag, but that produced tons of output as every interrupt clears the flag for the duration of handling the interrupt. In the end I almost accidentally noticed that the game uses INT 03 (opcode 0xCC) which is a debugger breakpoint interrupt. This has some special handling in my code, and when looking at that code (and comparing it with older code from DSx86) I finally found the problem. In my rpix86 code I pushed the CPU flags with the interrupt flag already cleared, while I should have pushed the flags BEFORE clearing the interrupt flag. Fixing that bug allowed Crystal Caves to run normally. It uses similar code to Commander Keen 1 for horizontal smooth scrolling, though, so the scrolling may be somewhat jittery.

2. Removed unnecessary delay loop from default BIOS keyboard IRQ handler

While debugging Crystal Caves, I noticed that it overrides the BIOS INT 9 keyboard interrupt and checks for the pressed key using input from port 0x60 (the Keyboard Data Port). Input from that port clears the Output Buffer Full bit in the Keyboard Status Port 0x64. However, the game then calls the original BIOS INT 9 handler, which first loops up to 65536 times waiting for the Keyboard Status Port to report that the keyboard buffer is full, before proceding to read the key from port 0x60. This code is based on the actual BIOS of a PC clone, and I hadn't bothered to change that behaviour. (As a curious side note, one of my first PC clones (from around 1985 or so) contained the full printed BIOS source code as an appendix of its manual. That was quite helpful when I coded my own emulated BIOS routines originally for DSx86.)

This waiting for the keyboard status meant that when playing Crystal Caves (and possibly other similar games) there was an unnecessary delay loop of 65536 cycles that happened after every key press. Since I know that the keyboard interrupt in rpix86 only happens after a key is pressed, I removed that delay loop from my emulated BIOS routines.

3. Added experimental -f2 filtering option, for hardware dispmanx scaling

Next I looked into a strange problem in Lemmings where the game runs at more or less normal speed when I run it in a 640x480 window (which I usually do when debugging games in rpix86), but has bad stuttering when it is run full-screen (on my full-HD display). Since nothing in my code except the OpenGL ES drawing routines behave in any way differently depending on the screen size, this seemed quite strange. The OpenGL ES routines should handle all scaling in hardware (or so I thought), but just to be sure I added some timing code around the glTexSubImage2D() call I use to copy the emulated graphics memory to an OpenGL texture. This was the result:

Screen size and filteringTimeMax theoretical framerate
640x400 -f01.5 ms667 fps
640x400 -f11.5 ms667 fps
1920x1080 -f015 ms66 fps
1920x1080 -f125 ms40 fps

To my big surprise, this single call took a lot more time when the screen size increased! With texture filtering on (-f1 parameter) it caused rpix86 to not even reach 60fps emulation speed, and even with no texture filtering (-f0) it only left very little time for the actual CPU emulation!

So, it occurred to me that perhaps I should check what happens if I do the size scaling using the dispmanx call instead of OpenGL ES, so that OpenGL can always draw into 640x480 (the maximum VGA resolution that rpix86 supports) screen size. This produced the following timings, so I decided to include this feature as a -f2 filtering mode. Feel free to experiment with this parameter, it may help performance in some situations. The scaling is not as smooth as with the -f1 parameter, though.

Screen size and filteringTimeMax theoretical framerate
640x400 -f01.5 ms667 fps
640x400 -f11.5 ms667 fps
640x400 -f21.6 ms625 fps
1920x1080 -f015 ms66 fps
1920x1080 -f125 ms40 fps
1920x1080 -f21.6 ms625 fps

4. Implemented missing CD-ROM call INT2F AH=1501 (X-Wing INSTALL.EXE)

Next I checked why the INSTALL.EXE of X-Wing caused a soft crash in rpix86. I noticed that the game uses a CD-ROM detection method that I had not implemented yet, so I added that code (as a dummy routine, so that the game sees there is no CD-ROM device). This allowed the INSTALL.EXE to show the main selection screen.

5. Fixed DOS Get STDIN Status call to handle enhanced keyboard correctly

However, after getting the INSTALL.EXE main selection screen to show, I could not actually change the selection, as the cursor keys did not seem to work! This also needed some more debugging, until I found out that the game uses the DOS INT21 AH=0B GET STDIN STATUS call to check if a key is available. I had support for that call, but looking at that description I realized that I did not handle the enhanced keys properly. I originally emulated the old 83-key cursor keys in DSx86, and only later switched to enhanced 101/102-key DOS keyboard emulation. At that point I did not fix that DOS call to also handle enhanced key codes correctly. The fix was quite minor, and it made the INSTALL.EXE work properly.

6. Implemented several missing Mode-X opcodes (Aces Over Europe)

Next I tested Aces Over Europe, which had a soft crash when the actual flying should start. There were several VGA Mode-X opcodes that this game uses that have not been used by any other game. It looks like the game actually stores data (like pointers and such) into the VGA graphics memory, and then uses those later when drawing the screen. This is probably some sort of a speed trick, although it actually only slows things down in rpix86 as the graphics memory is slower to handle than normal RAM. In any case, after adding several such new Mode-X opcode handlers the game progressed to the actual flying quite fine.

7. Fixed writing to non-mapped EMS page (bug in Aces Over Europe)

However, after exiting the game back to 4DOS prompt, giving any command in 4DOS caused a soft crash. Obviously something in Aces Over Europe had corrupted memory that belonged to 4DOS.

I used my inbuilt memory watch routine to detect when the 4DOS memory gets corrupt, and noticed that the memory is already corrupt when 4DOS loads the code back from EMS memory. So, I changed the watch address to be inside the physical memory that 4DOS maps into EMS, and then caught the code in Aces Over Europe that writes to this memory. I confirmed in DOSBox that this seems to be a bug in the game, it writes into unmapped EMS memory page. I had been lazy in rpix86 and left unmapped EMS pages to point to the beginning of my EMS memory area, and in this case it meant that the game wrote to memory that belonged to 4DOS.

I did a quick fix to this problem by reserving one EMS page to be the "unmapped" page, so that any game that tries to write to an unmapped page writes safely to this reserved area. This fixed the crash in 4DOS after exiting Aces Over Europe.

Thanks again for your interest in rpix86, let me know of any new bugs you find in this version!

Previous blog entries