Exodus is a software program designed to allow real physical hardware to be emulated in software. This is not a revolutionary idea. There are many other emulators out there for a wide variety of tasks and systems. What makes Exodus a little different is what goals it tries to achieve, what it does that other emulators do not, and what it doesn't do that other emulators do. More detail is given about the goals of Exodus in the "Design Philosophy" section. In this section, you'll get a quick overview of what makes Exodus different.
So, what does make Exodus different from other emulators? There are a few key points:
- Plugin model, with XML-based system definitions
- Perfect timing synchronization
- Effective multithreading
- Debug and development focused
More detail about each of these items will be given below.
1. Plugin model, with XML-based system definitions:
The first and most significant thing to understand about Exodus, is that it is not actually an emulator. Exodus is a generic emulation platform, which allows systems to be assembled from individual components at runtime. Plugins are used to add actual emulation support for real devices. A device may be an individual discrete component, such as a processor, sound, or video chip. This plugin model itself isn't as interesting as how Exodus builds systems from these devices. With Exodus, nothing that makes up a "system" is hardcoded. Exodus uses XML files, called modules, to build an actual system from a set of discrete components. The current system is simply defined as the current set of loaded modules, and any selected settings for those modules.
Perhaps more significantly than the plugin model itself, Exodus completely handles all the communication and interaction between each device. Exodus emulates the idea of the "system bus", and supports mapping devices in almost any way imaginable. Devices themselves can be written to simply emulate themselves in isolation, without knowing or caring about the system they are used in, or how they are physically connected to that system. When devices are emulated in this manner, they are inherently reusable in any system, under any situation in which the real device could be placed. This means that you only have to emulate one device, once, and there are no system-specific hacks that have to be applied in order to make that device work in a given system. Support can be added for new systems simply by writing an XML file to describe the physical devices in that system and the connection between those devices, and loading the file in the Exodus platform, provided emulation cores exist for all the required devices.
With this plugin model, and the XML-based method of defining system components, Exodus is probably the most generic, flexible, and scalable emulation platform ever written. The long-term goal of Exodus is to provide support for as many systems as possible, even to rival other projects such as MESS and MAME. The project goals, architecture, and design philosophy are setup to attempt to make this emulator easier to maintain and more flexible over time than other large-scale emulation projects however, as well as providing several key advantages they currently do not offer.
2. Perfect timing synchronization:
So, apart from this modular architecture, what's interesting about Exodus? The most important thing is accuracy, in particular, timing accuracy. Most emulators are extremely inaccurate when it comes to timing. The reason for that is that there's often a huge performance tradeoff involved. In a real system, you might have half a dozen or more discrete devices all doing things at the same time. Each device might run at its own rate with its own performance characteristics. In a real system, those devices are not completely isolated, that wouldn't be a very useful system, those devices need to interact. When you're emulating that system, how do you ensure that every single device access occurs in the correct order though? The simple fact is, most emulators do not. Most emulators aim for a certain degree of timing accuracy, which is usually just enough to emulate some particular set of existing programs that run on that platform, and that's as accurate as they get. Timing related bugs often become the biggest roadblock to increasing emulation accuracy as an emulator advances, and increasingly become more and more difficult to solve. So, how do you solve timing problems with 100% accuracy? Well, the first, most obvious way, is to run every device in what's called "lock-step". This is simply to advance every device in the system one by one, advancing each device by a single "step", ensuring that no device gets ahead of another. This works with 100% reliability. It's also very, very, very slow. The biggest problem this approach has is that you reduce your emulator to a single-threaded model, because everything always has to wait for everything else, so you can't really do anything in parallel. Since we now live in the age of parallel computing, this effectively cripples the performance of your emulator now and into the future. That leads into the next topic.
3. Effective multithreading:
Exodus was built from the ground up to solve the unsolvable timing problems, and has a unique approach to timing accuracy. It adopts what I call the optimistic execution model. This idea isn't new either. The concept is simple, and it goes something like this: "Most of the time, a timing problem is not going to occur. Given that assumption, I want to execute my devices unsynchronized for as long as possible. If something ends up happening in the wrong order, I want to roll back to the previous point, and repeat the operation, this time with fore-knowledge about the timing requirements". This is the execution model Exodus uses. By executing in parallel for as long as possible, we can make use of multiple cores. The idea of state rollback is implemented as a core part of the platform itself, and is heavily optimized to be as fast as possible where a rollback is not required. Devices can assist the emulation by giving advance notice about significant events, such as interrupt generation, which are likely to affect other devices. System XML definitions can also give additional timing hints, such as forcing particular devices to always remain behind the current execution point of other devices. A combination of these techniques allows Exodus to achieve 100% timing accuracy, while making effective use of multiple cores to execute devices in parallel for as long as possible.
4. Debug and development focused:
Another key point that makes Exodus different is simply what kind of users it targets. Exodus is not designed to allow you to play commercial games for mainstream systems. That may be a side-effect of what it does, but that is not its focus. There are many other emulators out there for a large number of systems. If you simply want to play games, one of those may be more suitable. Exodus is aimed at users who have a technical interest in a particular platform. A large number of debugging and diagnostic features are provided to assist in better understanding the internals of the hardware, and to assist in debugging problems, and developing code, where it may be difficult to gather information on the real hardware. To this end, Exodus has a strong focus on accuracy in all areas, with the goal that any given piece of code will behave exactly the same way in Exodus as it would on the real hardware. Debugging features are exposed to provide as much transparency as possible, so that at any given point, it can be understood what state each device is in, and to allow that state to be modified in real time through the debugger.
These points summarise the main things that make Exodus a little different from other projects. Hopefully this is enough to spark your interest. For more detailed information about the design of Exodus, as well as the current level of support and future plans of Exodus, please refer to other sections of this website.