Cxbx Reloaded overview - Cxbx-Reloaded/Cxbx-Reloaded GitHub Wiki

Here's some technical details on how Cxbx-Reloaded works.

Executable launch modes

Cxbx-Reloaded is a single executable which operates in two different modes:

  1. If launched normally (without any command-line arguments), it will show a user-interface then wait for user inputs.
    • However, if you drag and drop an xbe file on top of the executable, it will automatic run said xbe file.
  2. To emulate Xbox software, Cxbx-Reloaded relaunches itself (with the path to the Xbox executable to run on the command-line). The emulated Xbox screen is then put over the user-interface. At the end of emulation, the second instance terminates and the user-interface reappears.
    • If you want to start standalone emulation, than the following argument should be input cxbxr-ldr.exe /load "path to xbe" via command prompt.

If another process launches Cxbx-Reloaded (for instance, a user starts a shortcut via Windows Explorer) with a command-line argument, there's no parent process, so when emulation ends in this scenario, the Cxbx-Reloaded process terminates entirely.

Emulation aspects

Operating System

Cxbx-Reloaded currently runs on 64-bit Windows 7 and up.

(More on this later, under Xbox Kernel)

CPU 'emulation'

Cxbx-Reloaded emulates the Xbox using direct code execution.

This means most of the CPU instructions the Xbox would execute are executed directly on the host machine without any modification or interpretation.

This restricts running Cxbx-Reloaded to CPU's that are compatible with the Xbox Pentium 3 Coppermine CPU!

The advantage of this approach is that Cxbx doesn't need to emulate the CPU at all, and offers native, 'faster-than-real-hardware' emulation speeds.

Admittedly, executing Xbox code as-is does bring with it a few complexities:

  • Some opcodes are prohibited to be executed in user-mode on Windows
  • IN/OUT opcodes must be emulated
  • CPU-specific opcodes (like CPUID) still need to be emulated
  • The FS segment layout differs between Xbox and Windows
  • Mapping physical to virtual addresses using the MMU isn't allowed (More on this later, under Hardware accesses and Contiguous memory.)

Xbox Kernel (BIOS)

Cxbx-Reloaded contains it's own implementation of the Xbox kernel, which means there's no need to acquire a dump from your Xbox.

In it's current form, the Cxbx-Reloaded kernel forwards many of the 378 kernel APIs towards the host Windows kernel APIs.

This restricts running Cxbx-Reloaded to operating systems that contain the Win32 APIs, so far Windows only!

Because many of the kernel API's are just forwards, some aspects of the Xbox kernel are not emulated well enough.

Timings will differ, thread switching works differently, thread local storage must be patched, etc. etc.

In the future, more APIs will be replaced with an implementation that doesn't rely on Windows anymore, and will be built on top of an abstraction-layer, removing much of the dependency on Windows.

High Level Emulation (HLE) vs Low Level Emulation (LLE)

Cxbx-Reloaded historically emulates Xbox software by patching a huge set of functions present in the Xbox executable, and replacing these with an implementation that can run on the host.

This process is called 'High Level Emulation', or HLE for short.

To be able to do this reliably, the functions that need to be replaced have to be pin-pointed accurately.

For this, caustik (the initial developer of Cxbx, the parent project of which Cxbx-Reloaded is a fork), introduced a data structure (called OOVPA tables) and accompanying scanning code.

Read more on this elsewhere in the Wiki.

In contrast to this, another approach to emulate a machine like the Xbox is not to find and patch functions, but to emulate only the hardware that these functions access.

This is called 'Low Level Emulation', or LLE for short.

Cxbx-Reloaded in it's current form, is slowly migrating towards LLE, and offers an experimental flag to enable LLE of the GPU.

APU and JIT LLE are disabled due to being unimplemented.

For now, Cxbx-Reloaded only reliably supports HLE and LLE GPU.

Emulating Xbox memory layout

Cxbx-Reloaded emulates the Xbox memory layout using a trick that allows 'fast path' memory access by mimicking the memory layout of the Xbox on the host OS.

This involves the following steps:

First, we apply these linker options to the Cxbx-Reloaded executable:

  • ImageBase is set to memory address 0x00010000 (the lowest possible virtual memory address on both Xbox and Windows).
  • Relocation information is stripped, so Windows is forbidden to relocate Cxbx-Reloaded to another address.

Furthermore, to be able to run Xbox code on the same virtual addresses as on real hardware, we apply these tricks:

  • All emulation code is moved 64 MiB upwards, by reserving an empty-initialized virtual memory placeholder as the very first thing (before any code appears in the Cxbx-Reloaded .text section).
  • This placeholder is used for all Xbox virtual memory operations.

The downside to this is that the Cxbx-Reloaded is quite big (more than 67 MiB currently), but once compressed it's less than 3 MiB.

Since Cxbx-Reloaded launches itself a second time for actual emulation, memory-requirements on the host are doubled to at least 256 MiB of memory.

Hardware accesses

Most Xbox hardware is mapped from 0xF0000000 to 0xFFFFFFFF.

Cxbx-Reloaded reserves this memory-region using so-called 'guard-pages' which guarantees this memory range isn't used for anything else, and causes so-called access violations,or more accurately, guard-page exceptions.

When Cxbx-Reloaded emulates an Xbox instruction that accesses a hardware component (reading or writing to one of the MMIO memory-addresses), this access is trapped using an 'exception handler'.

This allows us to capture and emulate hardware accesses that aren't present on the host.

When Cxbx-Reloaded operates entirely in HLE mode which is the current default, most if not all hardware accesses are prevented entirely.

Normally, this is mostly a moot point, and you won't see slow-down in emulation because of this.

However, when it happens, exception handling is slow, as it incurs a context-switch (storing and restoring the entire state of a thread) and has to figure out which address needs which handling.

Therefore, there are plans to dynamically replace all Xbox instructions that access hardware registers with a small patch that will handle the hardware access directly.

(More on this later, under JIT.)

Contiguous memory

In addition to the hardware memory range, the Xbox has a memory range that's shared between the CPU and the GPU, called 'Contiguous memory.'

For the CPU, this memory is mapped to addresses 0x80000000 to 0x84000000.

For the GPU, this memory is addressable from 0x00000000 to 0x04000000.

Since we emulate the GPU, we can access this memory solely in the CPU memory-mapped space, which we reserve at startup.

Tiled memory

Tiled memory is not yet fully researched for Cxbx-Reloaded.

Currently, Cxbx-Reloaded just maps the same memory in use for 'Contiguous memory' towards the tiled memory region (0xF0000000 to 0xF4000000).

This is probably not sufficient and will need more research and emulation.

JIT

TODO

Rendering

Xbox renders using the Nvidia NV2A GPU.

Most software written for the Xbox was developed with some version of the official "Xbox Development Kit" (XDK for short), which offered Direct3D 8 like features.

Therefore, Cxbx-Reloaded uses Direct3D 9 as its rendering API.

Vulkan is currently not under consideration.

Some features the NV2A offered are unavailable on Direct3D 8 and 9; For those Cxbx-Reloaded tries to convert it to be host-compatible.

For example, some texture-formats like P8, R8B8 and others are not available on host Direct3D, and are thus converted into ARGB, the most widely supported texture format.

Vertex coordinates undergo a similar conversion.