Source code documentation

Back to the index.

Source code documentation


This is the automatically generated Doxygen documentation for GXemul, built from comments throughout the source code.

See the main documentation for more information about this version of GXemul.

See GXemul's home page for more information about GXemul in general:

(NOTE: There is a huge portion of code in GXemul which is legacy code. The documentation you will find on this page is only about the new framework, which is available from release 0.6.0.)

The main program creates a GXemul instance, and does one of two things:

After letting the GXemul instance load the files (or, in the more general case, attach the components), GXemul::Run() is called. This is the main loop. It doesn't really do much, it simply calls the UI's main loop, i.e. ConsoleUI::MainLoop().

Most of the source code in GXemul centers around a few core concepts. An overview of these concepts are given below. Anyone who wishes to delve into the source code should be familiar with them.

Core concepts

See the end-user description of the framework for information about how these concepts appear to the actual user. The sections below describe how those concepts are implemented in the code.


The most important core concept in GXemul is the Component. Examples of components are processors, networks interface cards, video displays, RAM memory, busses, interrupt controllers, and all other kinds of devices.

Each component has a parent, so the full set of components in an emulation are in fact a tree. A GXemul instance has one such tree. The root component is a special RootComponent, which holds some basic state about the emulation, such as the number of steps executed. It also contains zero or more sub-components.

Starting from the root node, each component has a path, e.g. root.machine1.mainbus0.ram0 for the RAM component in machine1 in the example above.

The state of each component is stored within that component. The state consists of a number of variables (see StateVariable) such as strings, integers, bools, and other more high-level types such as zero-filled memory arrays. Such memory arrays are used e.g. by the RAMComponent to emulate RAM, and can also be used to emulate video framebuffer memory.

Individual components are implemented in src/components/, with header files in src/include/components/. The configure script looks for the string COMPONENT(name) in the header files, and automagically adds those to the list of components that will be available at runtime. In addition, make documentation also builds HTML pages with lists of available components, and as a special case, a list of available template machines (because they have special meaning to the end-user).

Command interpreter

A GXemul instance has a CommandInterpreter, which is the part that parses a command line, figures out which Command is to be executed, and executes it. The CommandInterpreter can be given a complete command line as a string, or it can be given one character (or keypress) at a time. In the later case, the TAB key either completes the word currently being written, or writes out a list of possible completions.

The CommandInterpreter, via the ConsoleUI, is the user interface as seen by the user.

Unit tests

Wherever it makes sense, unit tests should be written to make sure that the code is correct, and stays correct. The UnitTest class contains static helper functions for writing unit tests, such as UnitTest::Assert. To add unit tests to a class, the class should be UnitTestable, and in particular, it should implement UnitTestable::RunUnitTests by using the UNITTESTS(className) macro. Individual test cases are then called, as static non-member functions, using the UNITTEST(testname) macro.

Since test cases are non-member functions, they need to create instances of the class they wish to test, and they can only call public member functions on those objects, not private ones. Thus, the unit tests only test the "public API" of all classes. (If the internal API needs to be tested, then a workaround can be to add a ConsistencyCheck member function which is public, but mentioning in the documentation for that function that it is only meant for internal use and debugging.)

Unit tests are normally executed by make test. This is implicitly done when doing make install as well.

It is recommended to run the configure script with the –debug option during development; among other things, this enables use of Wu Yongwei's new/debug memory leak detector (part of Stones of NVWA).

Generated on Sun Aug 17 2014 10:51:05 for GXemul by doxygen