XGS progress marches on

The blog may be quiet lately, but that doesn’t mean I’ve stopped making progress! The big reason for the silence since January is that work has kept me busier than expected, and XGS development was stalled while I was hunting down a very subtle bug in the CPU emulation. I finally squashed that bug yesterday, resulting in me finding and fixing even more bugs in a marathon session last night. The end result is that I think the new XGS is pretty close to being at parity with XGS 0.54 when it come to compatibility.

Here’s a run-down of what’s changed since my last update:

CPU Emulation Improvements

A bug was fixed in which the final address calculation was not crossing bank boundaries in some of the indexed addressing modes. This single bug took me two months to track down because the effects were subtle, usually resulting in cases where pieces of GS/OS applications did not get moved into the right spot in memory and leading to jumps into blank memory.

A bug with interrupt handling was also fixed, in which the status register value pushed onto the stack in emulation mode included the M and X bits (both forced to 1), which made the interrupt handler think the (B)reak bit was set and treat the interrupt as a BRK.

The IRQ emulation is now level-triggered signal like the real hardware, and not edge-triggered. Logic has been added to the System class to allow multiple interrupt sources to raise and lower their virtual interrupt lines, which are then presented as a single IRQ level to the actual CPU emulation.

General Emulation Fixes

I discovered a minor bug that skipped a single page of memory remapping (page 3, specifically) which caused some 8-bit programs that use AUXRD/AUXWR to crash.

A bug that did not properly turn off the emulated 5.25″ drive motor was fixed. The bug caused GS/OS to hang indefinitely waiting for the motor to turn off.

The VBL interrupt now works properly (and can be cleared again).

Input Handling

The input handling has been much improved; there is no longer any lag or missing key presses, and I’ve added all the missing mappings for shifted keys so you can now type pretty much anything into the emulation and have it come out as the proper key press.

I’ve added in most of the old special keys, and remapped some others:

  • The input grab toggle is now Right-Control (formerly F5) to match things like VirtualBox and VMware.
  • F11 toggles full screen mode
  • Pause toggle trace mode (if the debugger is compiled in)
  • Control-Home resets the emulator
  • SysReq sends an NMI


The trace output now shows the CPU register state as it is after the instruction, not before, which just makes more sense when you’re reading trace output.

The MVP instruction now actually shows up as MVP in trace outputs. Formerly it showed up as MVN.


The video emulation no longer renders whole frames; instead, each line is rendered at the time it should be rendered during the emulation. I’ve also remove the code that renders each line twice; instead I rely on SDL to stretch the frame to the proper aspect ratio. On most modern systems this means that the aspect ratio correction moves from software to hardware.

Virtual Disks

All eight SmartPort virtual disks can now be set from the command line using the –hd1 through –hd8 options. Note that the numbering now starts with “1” so the former –hd0 option is gone.

Next Steps

I’m now working on implementing some sort of GUI, both for the emulator itself and for the built-in debugger. Originally I had planned to use some sort of SDL GUI toolkit, but I can’t find one I really like, so I think I’m going to just implement the GUI as a separate window that can be toggled between visible and hidden. The choice now is between GTK+ and Qt; currently I am leaning towards the latter.