It is not based on cgen. The core interpreter is generated by gencode.c and is specific to HC11 (the implementation is much much more efficient than what you would get with cgen).

The simulator is based on the GNU gdb sim core. This core implements the memory as well as an abstraction to represent the hardware (hw-*.c files). It implements a lot of useful functions to write a simulator and have it integrated in gdb. Unfortunately, I've never found some clear documentation about all that.

The HC11 simulator implements its own interpreter whose single entry point is cpu_interp_m6811() or cpu_interp_m6812(). This is generated by gencode.c. The interpretor is a large switch (256 entries) and dispatches one insn at a time. Simple instructions are inline while complex ones are implemented by functions in m68hc11_sim.c.

The sim_cpu struct is the main data structure that holds simulator info (registers and others). The SIM_DESC is the data structure managed by the sim core. It holds a sim_cpu and all hardware devices created for the simulator. (It can hold several cpus but I didn't tried).

A simulator must implement a number of entry points. They are prefixed with sim_.

sim_open() is called first to allocate a SIM_DESC, initialize the simulator, parse options, ...

sim_engine_run() is called to run the simulator. When it is called, the simulator must process instructions until some signal is received (ie, it stops, decide to stop or hits some breakpoints).

sim_resume() is the entry point for gdb to run the simulator and do single stepping (in case of single step, it sets an event that tells the simulator to stop quite immediately).

sim_fetch_register() is called by gdb to get the registers. sim_store_register() is similar for setting them.

sim_close() is called to release the memory (delete simulator).

The hardware devices are based on the GDB sim new hardware API (This API has a first implementation in the PPC simulator). Devices are implemented by dv-m68hc11* files. A device must simulate the real hardware and must do so by catching read/write to either I/O space or memory. The driver implements read/write handlers and installs a map that tells at which address the driver is mapped (in I/O or in memory space).

When the HC11 simulator reads memory, it uses the sim common API: sim_core_read_buffer() and sim_core_write_buffer(). This function looks in the map to identify the memory or the driver. Once the driver is found, it calls the read/write handler of that driver. (this falls you in m68hc11cpu_io_read_buffer() for example).

Each driver is described by a hw_descriptor structure that gives the name of the driver and a handler to initialize an instance of it. The existing devices are registered in a table.

For a given simulator run, when the simulator is created, we must create its associated hardware devices. This is done by calling sim_hw_parse () with a string giving the hardware description and parameters. The following:

sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");

Tells to create a SIO device and map 5 registers are logical base address 0x2B (which is first register of the SIO). In this case, the SIO device is integrated by the "m68hc11" device which represents the CPU. When a read to SIO is made, we first enter in the read_buffer() of the cpu which handles the read of the SIO by calling sim_core_read_buffer() again (but using the IO map so we change of space). (see dv-m68hc11.c).

Another important part of the sim common hardware is that it has an input/output event mechanism. A given hardware can export a number of output and can have some inputs. The outputs of a hw device can be connected to the input of another. This is made with some strange syntax in sim_hw_parse:

sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");

Here, this tells that the CPU output 'capture' is connected to the timer device input CAPTURE.

There are a lot of details that I can't explain. Reading the code several times really helps. (at least, it helped me a lot). If you want to understand more, I suggest to use gdb and do some stepping/breakpoint in the simulator itself.