Boot crash fix, CPU updates, and a new debugger

Lots of changes have been pushed into the XGS repository since my last post.

Boot crash fixed

The bug causing the emulation to crash into the system monitor at startup has been fixed. It was not, as I had originally suspected, a CPU emulation bug. Instead it was a bug in the Mega2::buildLanguageCard() method, and a fairly obvious one in retrospect. Turns out it was mapping all sixteen $DnXX logical pages to the same physical page; needless to say this resulted in severe memory corruption!

CPU emulation updates

The latest code makes two major changes to the CPU emulation, though not in any way visible outside the code.

First, there is now a LogicEngineBase class that defines the executeOpcode() method as a virtual method. The LogicEngine template class inherits from this, and so now the emulator just stores a pointer to the current logic engine and calls it directly, instead of using a large set of nested if statements to pick it manually for every opcode. This actually turned out to be just as fast as my original “no virtual functions” implementation, and the code is cleaner too.

Second, the cpuRead and cpuWrite methods now take an extra parameter of type mem_access_t (defined in the M65816/types.h file). This tells the rest of the emulator exactly what a particular memory access is for:

  • Instruction fetches
  • Opcode fetches
  • Stack operations
  • Generic data

This was done to facilitate the new debugger, which has been decoupled from the CPU emulation and moved to its own module.

The new debugger

As I mentioned above, the debugger is has been moved out of the M65816 emulation and into its own module. In the new implementation the debugger monitors all calls to cpuRead and cpuWrite, and using the memory access type provided by the CPU it can decode instructions as well as monitor (or even modify!) other memory accesses. I made this change for a couple of reasons:

  1. Some of the things i want the debugger to eventually do would have required putting a lot of hooks inside M65816. The new debugger design hooks into exactly two places, and since it’s sitting “above” the CPU emulation it has a lot more control.
  2. I want a graphical UI for the debugger, but I don’t want to make M65816 depend on any GUI libraries.

At the moment the debugger only implements the instruction disassembly from the old version. Additional features will get added once I implement the GUI.

 

 

A new year and a new XGS

Well, it took a lot longer than I thought, but I’ve finally managed to roll out my first alpha prerelease of the XGS rewrite. At the moment only text mode is implemented, and the boot sequence does not yet complete properly, but it dos start up. Since this is at such an early stage of development I am not making this available as a tarball release. Those interested in playing with it can download it directly from the GitHub page.

 

Changes in this Version

The entire code base has been converted from C to C++, and heavily refactored so that the individual code modules correspond more closely to the individual pieces of the IIGS’s hardware.

All of the platform-specific drivers have been removed; instead, the code uses SDL2 for most platform-specific functions.

The emulation timing has been rewritten to use Linux timer FDs. This is currently the dependency that makes the code non-portable.

The CPU emulation has been completely rewritten. The new version is significantly easier to understand and debug than the old version, as all of the cryptic and convoluted C macros are gone. The opcode execution logic is now implemented in a C++ template which is used to generates individual classes optimized for specific combinations of memory and index width.

What’s Next

At the moment all of my energy is focused on fixing whatever issue or issues are causing the boot sequence to crash. This involves running both old and new XGS in debug mode and comparing the resulting execution traces.

Once the boot issue is fixed the keyboard handling needs a lot of love. The current implementation is only partially usable, especially since it fails to properly handle applying modifiers (shift & control) to key presses before putting them into the input buffer. As a result you can’t even type many characters, making it difficult to investigate problems and run tests within the emulation.

 

XGS Lives

Believe it or not, XGS is now 20 years old! The project was started way back in 1996, when my fastest PC was still a 66 MHz Pentium. Sadly, for various reasons, development pretty much stalled in 1997. I briefly started tinkering with it again in 2002, but I got busy, and nothing came of it. The last released version is still from 1997…but that’s about to change.

Lately I’ve found myself in need of a good personal project to sink my teeth into, and so I’ve circled back around to XGS.  I have two goals in mind for the future of XGS:

  1. Finishing what I started 20 years ago.  I want to find and fix the bugs that keep some high-profile software from running (hi Diversi-Tune!), improve the emulation (3200-color support anyone?), and apply some spit and polish in the form of an actual GUI.
  2. Create a version of XGS that is geared towards running on a Raspberry Pi to create a teeny-tiny Apple IIGS. Part of this project would involve some actual hardware hacking to create interfaces to authentic Apple hardware. I for sure would like to implement ADB, so that a real IIGS keyboard and mouse can be used. I’m also considering trying to drive an actual 3.5″ 800k drive, which would be great if there’s anyone out there with some stuff on old IIGS disks.

With those goals mind, the first decision I’ve made is that I’m no longer going to go out of my way to make the code portable beyond Linux. I certainly won’t object if anyone wants to resurrect any of the other ports, and I will try to not make things hard on anyone who wants to do so, but if I can do something cleaner and/or easier by targeting just Linux that is the way I will go. Case in point: the current code base is using the Linux timerfd interface for timing, because it just works way better for me than straight POSIX timers (I did try them!)

Next, I’ve mostly finished up some work I started back in 2002 to replace all the individual video and audio drivers with a single set. Currently that’s SDL for video and PulseAudio for audio. I wanted to use SDL for both, but I so far I’ve been unable to get SDL audio that doesn’t have lots of skips and crackles. SDL does have the benefit of being multi-platform so at least here I hopefully made things easier for any would-be port maintainers.

I’m also looking at ways to simplify the code by removing some roundabout ways of doing things that were originally implemented to make the emulator actually usable on 1996-vintage PCs. The new low-end for acceptable performance is going to be a Raspberry Pi 2.

And finally, I’m considering changing the code base from C to C++ and implementing the various hardware chips as their own classes. This isn’t fundamentally different than what is there now, but the resulting code will be much cleaner, and the interfaces between the various emulated hardware bits will be well-defined. It will also aid in my long-term Raspberry Pi goals, because I’m going to need to be able to plug in different bits cleanly (e.g remove ADB emulation and replace with an interface to my yet-to-be-designed ADB hardware).

I’m really excited about all this, and I’m hoping to start pushing out some new development snapshots this month. Stay tuned!

Welcome

Since my old personal website was very, very out of date, I’ve decided to relaunch my page as a blog. Over the coming months I intend to post regularly regarding the status of my various personal projects, so stay tuned!