Aeon Emulator Blog

April 21, 2011

All about the Game Port

Filed under: Aeon, Hardware — Greg Divis @ 2:00 pm

Probably the biggest noticeable feature of Aeon 0.63 is support for emulating joysticks/gamepads through the PC game port. This was a pretty easy device to emulate, but hasn’t really been a priority for me since I basically never use game controllers on my PC. Turns out other people do though… Go figure :)

Anyway, the game port interface is actually pretty interesting in that it provides essentially no abstraction from the hardware. Learning how it worked made me finally understand what the deal was with every game needing calibration to work properly, and those weird dials on analog joysticks that I always had to fiddle with to keep the controls from drifting. If you already know how this works or don’t care, you won’t find this article very interesting, so you should probably stop now. Otherwise, read on…

Using a Joystick in DOS

DOS provides essentially no abstraction on anything except the disk (I guess that’s why it’s the Disk Operating System), so to work with the joystick, games would have to read a byte from the game port. Four of the bits of this byte are used to indicate the status of the first four buttons (or the first two buttons of each joystick if two are attached). The other four bits are used to indicate the position of the first four analog axes (again, or the first two of each joystick if two are attached).

Reading button status is easy enough: just look for whether the appropriate bit is cleared, which indicates that the button is pressed. Getting the position of an axis is another story.

You might wonder how an analog value can be transmitted using a single bit. The answer is: time. A DOS program first writes a value to the joystick port (any value will do), then immediately goes into a loop continuously reading the status byte. The axis bits will all start out at 1, and eventually will all drop to 0. The amount of time it takes for this to happen is proportional to the joystick’s position in that axis. The amount of time this takes is device dependent and can be measured in microseconds, so a game would count the number of iterations it takes for the value to drop to 0, rather than using timers or anything sophisticated like that.

Weird, isn’t it? Well, it turns out this makes a lot of sense.

The Hardware

I mentioned before how DOS provides no abstraction for most hardware devices, so you are left communicating with them directly most of the time. Most devices have some degrees of abstraction themselves, so this isn’t a huge problem, but the game port has essentially none. The classic joystick design that it works with was little more than a couple potentiometers (basically adjustable resistors if you are unfamiliar with circuits). Writing a value to the port causes some capacitors in the device to become charged. The speed this charge is lost depends on how much resistance is in the potentiometers (which is controlled by the joystick position and those crazy dials).

So that’s really all there is to it. A charge is placed on a circuit and the program waits for it to go away.


For me, it was important to understand how programs would use the game port for me to emulate it properly. Fortunately, modern API’s make it a lot easier to read a joystick position, so it was trivial to query DirectInput for this. That means I just had to translate this value into something resembling a decaying voltage.

Fortunately, I knew that this charge decayed so quickly that DOS programs would generally just count iterations in a tight loop that looks something like this:

          mov cx, 0        ; initialize cx to 0 for a counter
          mov dx, 201h     ; set game port 201h to the dx register
          out dx,al        ; write any value to the port
start:    inc cx,1         ; increment cx register by 1
          in al,dx         ; read current status of the game port
          test al,1        ; check whether the joystick 1 x-axis 1 bit is set
          jnz start        ; go to start if the bit is still set

So at the end of this loop, the CX register will contain the number of iterations it took for the bit to drop to 0. Knowing this, I can “cheat,” and just use a counter myself instead of doing any complicated high-resolution timing. All I have to do is scale the position of the joystick and decrement this value every time a program reads from the game port. When the value is greater than 0, Aeon returns a 1 for that axis; otherwise it returns a 0. This approach has worked perfectly in every game I’ve tried so far, and it was really easy.

Modern Controllers

Modern game controllers are more sophisticated than this – they are designed to communicate using USB or some other proprietary digital protocol and contain all of the logic needed to convert an analog position into a digital value, so fortunately modern game developers don’t have to be aware of the hardware implementation of how their input devices operate anymore. That’s fine with me. I for one have no desire to go back to the days of calibration and fidgeting with dials.

April 20, 2011


Filed under: Aeon, Fun & Games — Greg Divis @ 10:46 pm

I’ve always been a fan of computer RPG’s, and usually the bigger the better. I first heard about the game Daggerfall years after its release and had a lot of trouble tracking it down, but had tons of fun with it once I did.


To be honest, I didn’t play the game so much as I played with it. The scope is huge, and the dungeons were randomly generated and extremely annoying (in my opinion). Also, it was a pretty buggy game – I remember an odd glitch that seemed to be unique to my computer at the time where my character was utterly incapable of falling; I would just glide in the air if I walked off an edge. Regardless of its problems, it’s still a fun sandbox to play in for a little while.


Bethesda (the company that made Daggerfall), released the game as freeware. You can download it from here. It runs pretty well in Aeon, provided you have a pretty fast machine.

Aeon Version 0.63

Filed under: Aeon, New Version — Greg Divis @ 9:31 pm

Finally a new build! I guess I should really stop saying I’m going to update this blog more often. I’d like to… Well, I’m sure you’ve heard all of the standard excuses already, so on to the change list:

  • Added game port emulation for joystick support
  • Fixed bug allowing an interrupt window after some pop ss instructions which caused random crashing
  • Fixed bug preventing SVGA from being detected in some programs
  • CD-ROM emulation is much more accurate when mounting a host drive or an iso
  • Host CD drive can now be captured
  • Minor performance improvements to a large number of instructions
  • Major performance increase for 4-plane video modes (EGA, Mode X)
  • Added support for launching commands with /c
  • Fixed memory corruption issue when too many files were opened at once
  • Added "Check for Updates" option to Help menu

I finally added joystick support! It’s not very configurable yet – just giving you access to two axes and the first 4 buttons on any standard gamepad/controller/joystick. A more sophisticated button/key mapper will be added in a future version.

As usual, the download is here. I’ve redone the website as well. Hopefully most will consider this an improvement :)

Update: There is a bug in the installer that will report the incorrect version when upgrading. You’ll have to uninstall the old version first, then the install will run correctly.

Create a free website or blog at