Aeon Emulator Blog

January 17, 2010

Aeon Version 0.55

Filed under: Aeon, New Version — Greg Divis @ 10:03 pm

Finally time for a new build! I’ve made a pretty good amount of progress. Most of the floating-point instructions are working, and I’ve implemented some of the actual protection mechanisms in protected mode, along with paging. Most of the 32-bit DOS extenders I’ve tried work at least somewhat now, with one notable exception being Borland’s DPMI.000 extender (which, in my humble opinion, is the most evil piece of code ever written). Some of the more advanced 32-bit games don’t work yet either, though some do (Daggerfall, for example, if you’re willing to jump through a few hoops). Here’s the change list:

  • Implemented about 90% of x87 floating point unit
  • Partially implemented CPU protection levels
  • Added support for paging
  • Fixed a few DOS memory allocation bugs
  • Minor Sound Blaster fixes
  • Fixed some protected mode instruction bugs
  • Added keystroke to release captured input (CTRL+F12)
  • Implemented a few more missing instructions
  • Better support for TSR’s

In order to support paging, I had to change a lot of code – unfortunately, Aeon may run a little slower as a result, though I haven’t noticed any change on my test system. Also, it’s possible that I’ve broken compatibility with something that used to work. Again, I haven’t seen anything in my regression tests, but my tests don’t include running every game in the world…

Download here.

Update: It seems that some of the changes I’ve made may have broken Aeon on 32-bit versions of Windows. I’m going fix this and repost a new version, then set up a proper 32-bit test system so this doesn’t happen again.

December 25, 2009

Merry Christmas

Filed under: Aeon, Fun & Games — Greg Divis @ 8:00 am

By 1990, the PC was becoming a viable platform for home gaming able to compete with the likes of Nintendo and Sega. To play to the PC’s strengths of a common mouse and keyboard input, some different genres of game took off in the PC market compared to the consoles, one such genre was the adventure game. Something of an evolution of the older text-parser adventure games, the point & click graphical adventure game was huge for several years. If you were into those games, one of the companies you paid attention to was Sierra On-Line. Now defunct, with most of their IP’s owned by EA, Sierra was a big deal. They made King’s Quest, Quest for Glory, Police Quest, Space Quest – and it seemed like they added a sequel to each of those series almost every year.

In the late 80’s and early 90’s, Sierra distributed electronic “Christmas cards.”  For some reason, I still have a copy of this one goofy Christmas cartoon they made using their SCI adventure game engine.

Title Screen

In The Seasoned Professional, an inept actor gets dressed up in all of the wrong holiday costumes, all the while being scolded by the director for screwing it up.

Groundhog Day No

I thought this was pretty funny when I was 9 years old or so – the kind of humor they were going for was definitely aimed at that younger age group, but looking at it again now the nostalgia is hard to beat on something like this.

Seasons Greetings

Hope everyone reading this has a happy new year. See you in 2010.

December 22, 2009

What’s next

Filed under: Aeon — Greg Divis @ 10:46 pm

I wanted to get a new version posted before the end of the year, but it’s looking like that isn’t going to happen. I’ve made significant progress with the x87 floating-point unit, and been able to get Duke Nukem 3D and a few other games at least somewhat working, but I’ve also broken compatibility with a few games that used to work. I figured it would be better just to keep working on it until I’m fairly sure I’ve got any new bugs I’ve introduced fixed.

Anyway, since it seems some people are actually attempting to use Aeon now, here’s a kind of road map for what I’d like to have ready at each “major” version, so you know what to expect:

  • 0.6
    • Protected mode complete enough to run most DOS games that don’t require SVGA
    • Functionally complete, but not necessarily exact, FPU emulation
  • 0.7
    • CD-ROM/MSCDEX emulation
    • Improve emulated DOS command prompt (more commands, multiple drives)
    • Simple batch file support
    • SVGA*
  • 0.8
    • SVGA*
    • Program usability, UI improvements
    • Performance improvements
  • 0.9
    • Improve performance
    • Improve compatibility
  • 1.0 – Stable

*SVGA is listed in two versions because I’m not sure exactly how much of this I’ll be doing. Unlike VGA, it was a while before there was any kind of an SVGA standard like VESA, so I need to do some more research and decide how best to approach this.

This is not an exhaustive list. For example, I haven’t listed additional features that will be needed to properly support some of these, like a user-interface for manual drive mounting to support removable media like CD’s. I’ve deliberately tried to get all of the actual hardware/software emulation that I want to have feature complete (but probably not bug-free) by 0.8, so I can work on improving the application UI and performance up until I’m ready to call it stable.

Everything up to 0.9 should be considered an unstable, experimental alpha. 0.9 will hopefully be beta quality, and 1.0 will be stable.

December 13, 2009

Aeon Version 0.52

Filed under: Aeon, New Version — Greg Divis @ 4:30 pm

This build includes fixes to things that were broken in 0.51, and also a few other general improvements:

  • Fixed crash on startup due to the icon (!) embedded in Aeon.exe on some systems
  • Fixed bug in file system redirection that could sometimes cause a crash with the change directory command (Master of Magic setup)
  • Fixed mouse coordinate input bug where clicks would sometimes not register at the right position
  • DMA controller improvements
  • Sound Blaster 16 DSP improvements, digitized sound should work a lot better
  • Changed default Sound Blaster IRQ to 7
  • Added some protected-mode-related instructions
  • Redesigned and streamlined operand decoder in preparation for FPU instructions

Download here.

December 12, 2009

Master of Magic

Filed under: Aeon, Fun & Games — Greg Divis @ 10:00 am

It’s been a while since I’ve posted about a specific game, and I’ve had this post written for quite a while so this seems like a good time for it. I’ve always been terrible at strategy games, but for some reason I’ve also always had a soft spot for them. The first turn-based strategy game I really got into was Master of Orion II – which came bundled with Master of Magic when I bought it back in 1996.

Title Screen

Master of Magic had a lot going for it – cool premise of conquering a randomly-generated fantasy realm, nice graphics, fairly intuitive control (for the time). The game also had its share of flaws – the AI opponents could show some odd behavior, and on a technical side, the game ran pretty slow. That being said, it’s still fun to play for a while, and I kind of like being able to mash that giant “Next Turn” button on my tablet PC.

Think I cheated a little?

Technically, the game is also pretty interesting. Despite its expansive, colorful look, it’s a regular 16-bit real-mode DOS program. It does, however, make extensive use of Expanded Memory, and so far it’s the only program I’ve run in Aeon that created multiple named expanded memory handles. If you aren’t familiar with expanded memory, basically a program would ask the memory manager for a handle, then allocate chunks of memory using that handle – the memory could then be mapped into real-mode conventional memory 16k at a time. Mainly for diagnostic purposes, a handle could be assigned a name. Master of Magic not only created a named handle, it created 22 of them.

YO MOMA

You can tell from this that they kind of divided up what they were storing in expanded memory using different handles. I’m not sure what the deal is with the “YO MOMA” handle, but I at least got a chuckle out of that when I first saw it. I’m sure the programmers didn’t expect anyone to see that, but being a developer myself I have an appreciation for that kind of thing :)

If you’re looking to play Master of Magic, it works fine in Aeon and DOSBox (though in either case I recommend turning the sound effects off, or your tactical battles will take forever). If you’re looking for a sequel or a more modern version of this game, you’re mostly out of luck, at least until Elemental: War of Magic is released.

Update:
This is what I get for publishing an old post like this. The setup program for Master of Magic has been broken for a few versions, and I never noticed this since it wasn’t part of my normal testing. It should be working again in 0.52. For reference, here’s the settings I used to run the game:

Music: General Midi (port 330)
Sound: No sound

November 24, 2009

Aeon Version 0.51

Filed under: Aeon, New Version — Greg Divis @ 3:41 pm

It’s been a while since I’ve posted a new build. A lot has changed in the code, but the single biggest visible change is the addition of protected mode emulation. It’s very far from complete. Right now, I’ve only gotten two protected mode games to work: Doom and Rise of the Triad – even so, those only work correctly if you disable Sound Blaster sound effects. Why those two games? I just happened to have them on my hard drive. Here’s the complete change list:

  • 16/32-bit protected mode support added (no actual paging or protection works yet though)
  • Fixed consistency issues with 16 vs. 32 bit stack and instruction pointers
  • Fixed 32-bit addressing modes
  • Small Sound Blaster DSP fixes, still lots of playback issues though
  • Added support for a few FPU instructions
  • Added extended memory support (XMS)
  • Most instructions now work with 16 or 32-bit operand sizes
  • Fixed a few issues that caused hardware interrupts to get disabled when they shouldn’t
  • Eliminated generation of multiple identical operand decoders (reduces memory usage, may increase performance somewhat)
  • Fixed an issue with unchained 256-color (mode X) display modes sometimes getting rendered incorrectly

If you’re expecting your favorite 32-bit DOS game to work now, you’ll probably be disappointed (unless, of course, you wanted to play Doom with no sound). Also, performance is not all that great for 32-bit programs, as I haven’t really optimized it for speed yet. I’m going to focus on improving protected mode compatibility up through version 0.6; expect all of these things to gradually improve from here.

Download here.

November 20, 2009

Success!

Filed under: Aeon, Protected Mode — Greg Divis @ 9:06 pm

“…the worst part of this implementation is over” – Me, one post ago

I regretted typing that almost immediately, because right after that I found an embarrassing number of bugs in my code and faced hours of very tedious troubleshooting figuring out what was wrong. The result, though, was worth it:

DMP

What, a 32-bit protected mode MOD player is not cool enough? Fine:

Doom

Ok, so two 32-bit programs working does not mean I’ve got good compatibility yet. I’ll probably be posting a build 0.51 or so after I’ve had a chance to do some regression testing to make sure I haven’t broken anything. Right now, my plan is for version 0.6 to have decent protected mode game compatibility, so you should be able to see some continuous improvement as I approach it. That should also mean more frequent builds (I hope).

But right now, it’s Friday night. I’m taking a break. :)

November 15, 2009

Protected Mode – Not quite there yet

Filed under: Aeon, Protected Mode — Greg Divis @ 6:20 pm

After doing my homework on x86 protected mode, I’ve been working on actually implementing it. As expected, it’s not easy and I’ve encountered lots of gotchas. Before I talk any more about this, here’s where I was at when I wrote this post:

image

Unfortunately it crashes right after displaying that message, but believe me, it’s better than it was. I certainly have a greater appreciation for the kind of nightmare the Intel engineers that designed the 386 had to deal with – grafting an entirely different mode of operation while maintaining compatibility with 16-bit code. DOS extenders really took advantage of this to allow a 32/16-bit protected mode application to run on top of 16-bit real-mode DOS – and DOS/4GW was possibly the most commonly used of these extenders.

(As an aside, many of the protected-mode-related instructions begin with the byte 0F, so if you’ve seen something like “Opcode blahblah0F not implemented.” from trying to run something in Aeon, that’s probably why.)

At this point, I’ve gotten a DOS/4GW game to at least get its protected mode environment set up. The good news it that I think the worst part of this implementation is over – the crash I’m getting now is due to a feature I haven’t implemented yet, rather that one that I’ve implemented wrong some time in the past. Way easier to debug.

Also, to properly support DOS extenders I had to get an extended memory manager working (among other things). All of that is done, so I’m hoping that soon I’ll have more to show for all of this work than a screenshot of DOS/4GW starting up.

November 10, 2009

Decoding and Decoupling

Filed under: Aeon, Performance — Greg Divis @ 2:16 am

In optimizing code for performance, it’s crucial to know the critical path. Once you know which part of your code is most impacting performance, you know where to spend most of your effort optimizing. In Aeon, this means focusing on the instruction decoding, since every instruction must be decoded before it can be emulated. The x86 instruction set is a CISC architecture, so this means there’s a lot of instructions and a lot of data is packed into a small number of bits. For example, most of the x86 instructions accept multiple operands, with the operands consisting of any combination of CPU register, memory address, or immediate value. Add to this the fact that memory addressing has implicit register-based offsets encoded in the operand, with two completely different meanings depending on whether the instruction uses 16 or 32-bit addressing, and you have a lot to decode on potentially every instruction.

The more I learned about the x86 machine code, the more I wanted to decouple it from the actual instruction implementation. In other words, I wanted to be able to write code that would emulate the function of an instruction without worrying about the form its operands are in, and I wanted this to be fast. Eventually, I did succeed in this…mostly. Here’s what my 16-bit MOV instruction emulator looks like:

[Opcode("89/r rmw,rw|8B/r rw,rmw|8C/r rmw,sreg|8E/r sreg,rmw|A1 ax,moffsw|A3 moffsw,ax|B8+ rw,iw|C7/0 rmw,iw", AddressSize = 16 | 32)]
public static void MoveWord(VirtualMachine vm, out ushort dest, ushort src)
{
    dest = src;
}

Before I get into that giant Opcode attribute on the method, let’s dissect the method itself. The first parameter is present on every instruction, and it contains a reference to the current emulated system – this is mainly used by instructions that need to cause certain side-effects, such as updating processor flags or accessing memory in a specific way; for the MOV instruction, it isn’t used, but is still required due to the way this method gets invoked. Following the VirtualMachine are the operands for the instruction; in this case, the first one is marked with the out keyword, meaning that the operand is only written-to by the method. The second operand is only read from, so it is passed by value. Both operands are 16-bit values, implying that this emulates the 16-bit operand-size version of MOV. Finally, the body of the method simply assigns the value of the second operand to the first operand. The dest and src parameters could be registers, values in emulated RAM, or immediates, but to MoveWord they are all the same.

One of the things I like about C# is that you can add custom metadata to things like methods and then inspect these at runtime using reflection. In this case, the custom OpcodeAttribute class specifies all of the opcodes and operand formats for each instruction implementation. The | symbol inside the long opcode string above basically means “or,” so all of the substrings between them specify the different MOV opcodes and their operands. Note that all of them take exactly two operands and all of them have a writable first operand (immediate values only ever show up as the second operand). I’ll break down the first form of MOV:

89 Specifies a 1-byte hexadecimal opcode
/r The byte following the opcode specifies at least one register
rmw The first operand is either a register or a value in memory of the current processor word-size (16-bit, in this case)
rw The second operand is a register of the current processor word-size (16-bit)

This information, along with the out keyword in the method signature, allows Aeon to generate code for decoding these operands, fetching initial values, and then writing any out or ref values back. Basically, when emulation begins for the first time, all of the opcode methods are enumerated and the OpcodeAttributes on them are parsed into more manageable objects. From this information, a small IL method is generated to decode, call the implementation method, and then write back values if necessary. Because the resulting generated method gets compiled by the JIT like everything else, simple instructions like MOV end up getting automatically inlined, despite the runtime binding.

Besides the speed, another benefit to this is that it’s really easy for me to add new instructions (provided they don’t encode some type of operand I haven’t dealt with yet). All I need to do is add a static method with the appropriate attribute and the runtime binding handles the rest. The downside is that writing this IL generator was a big pain, and it was very hard to test and nearly impossible to debug. Hmm… I guess it was worth it…

October 30, 2009

Planar Video Memory

Filed under: Aeon, Graphics — Greg Divis @ 3:19 pm

In a previous post, I gave a brief overview of the components of a VGA card, but I didn’t talk about the two components that most affect how data flows from the CPU to video RAM. Let’s start with some background information.

In the early days of computing, monochrome displays were pretty common. Video memory for such a simple system could require as little as 1 bit per pixel if only one color intensity is needed. This means that to fit a 1-bit color 320×200 pixel resolution image in video memory, you only needed about 8 KB of dedicated video memory. When the time came to introduce color displays and what would be called the Color Graphics Adapter (CGA), the design would grow from this.

CGA extended the monochrome video model by adding a second “plane” of bits to represent the same pixels as the first, monochrome plane. Now, there are two bits used for each pixel on the screen, and they are used as an index into a 4-color palette. Although two bits are used to form one index, the bits are not contiguous in memory because they are in separate planes.

Eventually, the Enhanced Graphics Adapter (EGA) came along, and another two planes were added. Now, one pixel consists of a 4-bit index with one bit taken from each of the four planes, so 16 simultaneous colors could be displayed.

The Video Graphics Array (VGA) is compatible with EGA and CGA, but adds higher resolution 4-bit video modes and a low-resolution 8-bit video mode, finally making more realistic graphics possible with the ability to show 256 colors at once. On a CGA, EGA, and VGA card the video memory is still planar, and accessing video RAM in 2 or 4-bit color modes is quite a headache as a result. For 8-bit, though, IBM decided to give developers a break and not add another 4 planes; in fact, the default 256-color display mode on VGA hardware sets up some control registers to make video memory for this mode appear linear. For the first time, instead of complex masking and shifting, all you had to do to write an 8-bit pixel to the screen was to calculate its address and write to it:

pixelAddress = 0xA0000 + (y * ScreenWidth) + x

There was a drawback to this 256-color mode, and that’s that it locked you into a low-resolution 320×200 (which has a weird-looking aspect ratio), and did not leave any off-screen video memory available for page-flipping or hardware scrolling. A number of games disabled this linear addressing, placing the card into “unchained 256-color mode.” It added the complexity of dealing with multiple planes again, but allowed a measure of hardware acceleration that was otherwise impossible, and with further tweaking could allow better resolutions.

Aeon currently handles most of the 16 and 256 color standard EGA/VGA resolutions.

« Newer PostsOlder Posts »

Create a free website or blog at WordPress.com.