FX-CG[UI] is a piece of software designed to be a common interface for Prizm programs executing on non-Prizm platforms. It is implemented in Python and communicates with backend software (such as an emulator) via a shared memory mapping.
The shared memory mapping is implemented as a named mapping on Windows (via [http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx CreateFileMapping]), and is file-backed via mmap() on UNIX systems. The name or path of the mapping is passed to the UI as the first command line argument. The name should not contain any backslashes on Windows.
When file-backed, the file must be the requisite size. Until the UI is capable of automatically creating a file of the correct size, it must be created manually. The exact size necessary depends on your platform, and may be obtained by checking the value stored to SHM_SIZE in the UI’s createSharedMapping function (fx_cg_ui/core.py). Once that value is known, dd may be used to create a file of the requisite size:
$ dd if=/dev/zero of=mymapping bs=1 count=$SHM_SIZE
Mapping format #
The actual shared mapping is rather simple. The canonical definition is provided by the ipc_interface struct in FX-CG[CL] (interface.h). It has the following memebers.
Eight 16-bit values mimicking the Prizm’s keyboard registers. Various bits in the register are set when keys are depressed, and cleared when released. A function such as PRGM_GetKey can be used to convert values from these registers to KEY_PRGM_* values.
A simple 384 by 216 row-major array of 16-bit values representing the current display contents. 565 RGB, same as VRAM on the device. The contents of this array are displayed at regular intervals.
Mutex protecting the contents of vram during updates, used to prevent display tearing. If the UI updates the display from vram while a program is writing to VRAM (typically via a Bdisp_* syscall), it may display a partially-updated screen. Simply put, any function that reads or writes directly to the shared VRAM mapping should lock this mutex while accessing the mapping, in order to prevent partial updates.
Exact semantics of the mutex are platform-dependent (refer to the platform_mutex_acquire and platform_mutex_release functions in FX-CG[CL]), but current implementations use a value of 0 to indicate unlocked, and 1 to indicate locked.