Files
libretro/emulators/x1-box.yml
T
Abdessamad Derraz ea0b7536bb feat: profile x1-box 1.3.2
The default core is now hakuX, an HLE kernel that needs no firmware, so the MCPX, flash and disk images are only required by the xemu core. The Chihiro driver is now built: Chihiro BIOS, media board flash and the three baseboard EEPROMs are read beside the flash image. SDL3 replaces SDL2, so the user mapping file is gamepad_map.txt.
2026-10-26 23:20:44 +01:00

391 lines
22 KiB
YAML

emulator: X1 BOX
type: standalone
core_classification: community_fork
source: "https://github.com/izzy2lost/xemu"
upstream: "https://github.com/xemu-project/xemu"
author: "izzy2lost"
profiled_date: "2026-10-26"
source_commit: "e092175b9196438ee2712bf6f45398fe2970b5fe"
upstream_commit: "26fcbe54f17e496bdf530dad9f237e74e2f943fc"
core_version: "1.3.2"
display_name: "Microsoft - Xbox (X1 BOX)"
cores:
- "x1-box"
- "x1box"
systems:
- microsoft-xbox
- sega-chihiro
mode: standalone
notes: |
Original Xbox emulator for Android, package com.izzy2lost.x1box, arm64-v8a.
A Kotlin front end carries the launcher, setup wizard, game library, settings
and per-title overrides, and runs a game in one of two cores. The xemu core
is a whole xemu tree built through CMake against SDL3 3.4.14 and QEMU
10.2.0, its imgui interface, monitor and snapshot entry points stubbed. The
hakuX core, built from android/hakux, runs the game on FEX with an HLE Xbox
kernel and an HLE GPU, and is the global default. A game can override the
choice. .LauncherActivity answers VIEW with a content or file URI, and that
URI becomes the disc slot before emulation opens.
ref: QEMU_VERSION,
android/app/build.gradle.kts:49-54, 98, 104, 117,
android/app/src/main/AndroidManifest.xml:15-31,
android/app/src/main/cpp/CMakeLists.txt:79-80, 902, 911-912,
android/app/src/main/java/com/izzy2lost/x1box/HakuxLaunch.kt:25-34,
android/app/src/main/java/com/izzy2lost/x1box/LauncherActivity.kt:41,
99-130
The hakuX core needs no firmware. It boots the disc's default.xbe under its
own kernel, creates its 256-byte console EEPROM as eeprom.bin in its own
disk folder when none is there, and keeps saves in that folder when no disk
image is set.
ref: android/hakux/core/native/kernel/ex.c:172-225,
android/app/src/main/java/com/izzy2lost/x1box/HakuxLaunch.kt:36-41
The wizard walks four steps: the MCPX boot ROM, the flash ROM, the disk
image and a games folder. With the xemu core chosen globally each Next stays
disabled until its own step resolves. With hakuX the three firmware steps
can be skipped, and only the games folder is required. The two ROM pickers
keep .bin, .rom and .img, the disk picker .qcow2 and .img. A pick is
fingerprinted before anything is written, and only a file that passes is
copied into x1box under the external files directory as mcpx.bin, flash.bin
or hdd.img. A file chosen as a path in place is kept as that path instead.
Those names, the eeprom the wizard never asks for and the disc are written
to x1box/xemu.toml under sys.files. The disc is handed to QEMU as a file
descriptor through -add-fd and only copied to x1box/dvd.iso when that fails.
ref: android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:66-147,
173-176, 281-303, 436-484,
android/app/src/main/cpp/xemu_android.cpp:866-870, 949-1082, 1660-1673
The launcher sends the user back through the wizard whenever the games
folder stops resolving, and, when the global core is xemu, whenever the
MCPX, the flash or the disk does. A frontend intent for a game that runs in
hakuX starts it directly, one for xemu only once the three images resolve.
The xemu core underneath is looser: an MCPX path that is empty or not 512
bytes leaves the machine property off, an empty disk path attaches no drive
at index 0, and only the flash clears autostart on its own.
ref: android/app/src/main/java/com/izzy2lost/x1box/LauncherActivity.kt:49-50,
129-168,
system/vl.c:3074-3099, 3133-3149, 3160-3174
The xemu core also emulates the Sega Chihiro arcade board when Chihiro mode
is on, which forces 128 MiB of RAM and keeps the console EEPROM apart as
eeprom_chihiro.bin. The Chihiro BIOS then takes the flash slot, and the
MCPX ROM is not overlaid on it. The media board flash and the baseboard
EEPROMs are looked up by name beside that BIOS, since the Android build
leaves every chihiro.roms path empty. The network board firmware is read
only for a cabinet link, which this build never enables. A Chihiro game is a
netboot image or an extracted folder holding boot.id, both content.
ref: hw/xbox/chihiro/chihiro.c:58-61, hw/xbox/xbox.c:166-176,
hw/xbox/xbox.c:416-450, system/vl.c:2922-2944, system/vl.c:3152-3156,
hw/xbox/chihiro/chihiro.c:546-559,
android/app/src/main/cpp/xemu_settings_android.cc:116-139,
android/app/src/main/res/values/strings.xml:157,
android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:3063-3090
Settings imports a dashboard tree from a ZIP or a folder into the FATX
partitions of the configured disk image, C at 0x8CA80000 and E at 0xABE80000,
keeping what it overwrites in a dated backup folder. The tree is searched for
a boot XBE beforehand and the best candidate is copied to C/xboxdash.xbe when
that name is missing, xboxdash.xbe, default.xbe, evoxdash.xbe, avalaunch.xbe,
unleashx.xbe, xbmc.xbe and nexgen.xbe scoring in that order, with a name
carrying dash and a path under dashboard scoring above one under apps or
games. The status line probes C for xboxdash.xbe, msdash.xbe, xbox.xtf and
the directories xodash, audio, fonts and xboxdashdata.*, and calls the
install complete when the boot XBE sits beside at least one of the others.
ref: android/app/src/main/cpp/xemu_fatx_import.c:51-54, 1838-1853, 1897-1902,
1919-1966,
android/app/src/main/java/com/izzy2lost/x1box/XboxInsigniaHelper.kt:10-53,
android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2608-2683
Preparing Insignia turns the NAT backend on and writes the DNS 46.101.64.175
into the config sector of the disk image and into the EEPROM at 0xAC.
Registration boots a Setup Assistant image the user picks, which goes in the
disc slot like any other game. The disk tools format an image that already
exists and never create one: a retail layout needs at least 0x1DD156000
bytes and the extended F and G layouts need room past that boundary. The
EEPROM editor rewrites language, video standard, resolution flags, aspect
ratio and refresh rate in place and recomputes both checksums. The five
managed files travel together through an x1box-files-*.zip archive that
settings both writes and reads back.
ref: android/app/src/main/java/com/izzy2lost/x1box/XboxInsigniaHelper.kt:7-8,
62-77,
android/app/src/main/java/com/izzy2lost/x1box/XboxEepromEditor.kt:18,
164-218,
android/app/src/main/java/com/izzy2lost/x1box/XboxHddFormatter.kt:7-16,
46-50,
android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:51-79,
1138-1194, 1670-1683
files:
- name: mcpx_1.0.bin
required: false
path: "x1box/mcpx.bin"
config_key: "sys.files.bootrom_path"
size: 512
md5: "d49c52a4102f6df7bcf8d0617ac475ed"
validation: [size, md5]
description: "MCPX southbridge boot ROM"
note: >-
Booted by the xemu core only, so the wizard asks for it only when that
core is the global choice. The only file the app verifies by content. A
pick is accepted just when
its MD5 equals the value hardcoded in the wizard, which is the v1.0 boot
ROM. Anything else is refused with the expected hash quoted, and the
512-byte dump whose MD5 is 196a5f59a13382c185636e691d6c323d is named
separately as a known bad dump to re-dump. The check runs again over the
stored copy every time the wizard opens, so a file that stops matching
is dropped. The loader then checks the size a second time and ends the
process when it is not 512 bytes. The bytes are read over the last 512
of the flash image and the region stays writable so early retail kernels
keep their cache quirk. In Chihiro mode the image is left as it is, the
Chihiro BIOS carrying its own boot code.
source_ref: "source android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:23-25, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:75-99, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:436-484, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:23, source android/app/src/main/res/values/strings.xml:21-23, source system/vl.c:3075-3099, source hw/xbox/xbox.c:151-193"
- name: Complex_4627.bin
required: false
path: "x1box/flash.bin"
config_key: "sys.files.flashrom_path"
size: [262144, 524288, 1048576]
size_note: "The picker takes these three sizes. The loader takes any non-zero multiple of 65536 and assumes 256 KB filled with 0xFF otherwise."
validation: [size]
description: "Xbox flash ROM"
note: >-
Booted by the xemu core only. Passed as -bios, and the one image whose
absence stops an xemu run on its own: a path that cannot be opened
queues an error and clears autostart. The picker refuses what looks like
the boot ROM, a 512-byte file or either MCPX hash, then any size other
than 256 KB, 512 KB or 1 MB. There is no positive hash to match. The image is mapped at 0xFF000000 and mirrored to the top of
the address space. A size that is zero or not a multiple of 64 KB, or a
short read, falls back to 256 KB filled with 0xFF. A retail image cannot
launch unsigned code, so a debug or modified image is what boots a title.
source_ref: "source system/vl.c:3134-3149, source hw/xbox/xbox.c:72-110, source android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:72, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:101-124, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:512-531"
- name: xbox_hdd.qcow2
required: false
path: "x1box/hdd.img"
config_key: "sys.files.hdd_path"
description: "Xbox hard disk image"
note: >-
Taken in qcow2 or raw form and attached as index 0 with locked=on and
cache=writethrough. An empty setting attaches no drive at all and an
unopenable one only queues a message, but with the xemu core as the
global choice the launcher refuses to leave the wizard until the file
resolves. A hakuX run's saves are copied into it before xemu opens it. The formatter builds FATX partitions
inside an image that already exists and needs at least 0x1DD156000 bytes
for the retail layout. It never creates the image. Partitions C and E of
this image are what the dashboard import writes into.
source_ref: "source system/vl.c:3160-3174, source android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:73, android/app/src/main/java/com/izzy2lost/x1box/SetupWizardActivity.kt:126-147, source android/app/src/main/java/com/izzy2lost/x1box/XboxHddFormatter.kt:7-16, 46-50, source android/app/src/main/cpp/xemu_android.cpp:1016-1037, source android/app/src/main/java/com/izzy2lost/x1box/LauncherActivity.kt:146-153"
- name: eeprom.bin
required: false
path: "x1box/eeprom.bin"
config_key: "sys.files.eeprom_path"
size: 256
validation: [size]
description: "Xbox EEPROM image"
note: >-
Always pointed at x1box/eeprom.bin, a path the wizard never asks for.
Generated as XBOX_EEPROM_VERSION_R1 when it does not exist. A file whose
checksum matches another key version, R2 and R3 dumps included, is
deleted and generated again, so only an R1 dump carries a console
serial, region or HDD key over. A video standard the kernel rejects is
reset to NTSC-M in place. It is attached through the smbus-storage
device. A size other than 256 bytes,
or a generation that fails, clears autostart. Preparing Insignia and the
EEPROM editor write to it in place.
source_ref: "source system/vl.c:2946-3041, system/vl.c:3122-3132, source android/app/src/main/cpp/xemu_android.cpp:949-951, android/app/src/main/cpp/xemu_android.cpp:868, source android/app/src/main/cpp/xemu_settings_android.cc:274-313, source android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2986-2989"
- name: eeprom_chihiro.bin
system: sega-chihiro
required: false
path: "x1box/eeprom_chihiro.bin"
size: 256
validation: [size]
description: "Chihiro console EEPROM image"
note: >-
The EEPROM a Chihiro session opens instead of eeprom.bin, the configured
name with _chihiro before its extension. Generated as
XBOX_EEPROM_VERSION_D, the debug key the Chihiro BIOS expects, when it
does not exist, and deleted and generated again when it carries another
key version.
source_ref: "source system/vl.c:2922-2944, system/vl.c:2950-2995, system/vl.c:3007-3018"
- name: chihiro_xbox_bios.bin
system: sega-chihiro
required: false
path: "x1box/flash.bin"
config_key: "sys.files.flashrom_path"
size: 524288
sha1: "b700b0041af8f84835e45d1d1250247bf7077188"
description: "Chihiro BIOS"
note: >-
Takes the flash slot in Chihiro mode and is passed as -bios like a
retail image, through the same picker. chihiro_bios_known names this
512 KB image by its SHA-1, but nothing in this build calls it, so the
hash is not checked. The media board files are then looked up in the
folder of this file.
source_ref: "source hw/xbox/chihiro/chihiro.c:2326-2338, source system/vl.c:3133-3149, source hw/xbox/xbox.c:166-176, source android/app/src/main/res/values/strings.xml:157"
- name: fpr21042_m29w160et.bin
system: sega-chihiro
required: false
path: "x1box/fpr21042_m29w160et.bin"
max_size: 4194304
validation: [size]
description: "Media board flash ROM (SEGABOOT)"
note: >-
The first of three names tried beside the BIOS, then in its parent
folder. Read whole when it is not empty and at most 4 MB. Settings
installs a picked file into x1box under the matching name, or under this
one when the picked name matches none. Without it an error is logged and
the media board IDE serves no SEGABOOT. The board serial comes from the
MBDT header at 0xFFE00.
source_ref: "source hw/xbox/chihiro/chihiro.c:2305-2324, source hw/xbox/chihiro/chihiro.c:2342-2380, source hw/xbox/chihiro/chihiro.c:537-541, source hw/xbox/xbox.c:423-429, source android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:3003-3056"
- name: fpr-23887_29lv160te.ic4
system: sega-chihiro
required: false
path: "x1box/fpr-23887_29lv160te.ic4"
aliases: [fpr-23887.bin]
max_size: 4194304
validation: [size]
description: "Media board flash ROM, later revision"
note: "Read in place of fpr21042_m29w160et.bin when that one is absent, under either name."
source_ref: "source hw/xbox/chihiro/chihiro.c:2366-2380"
- name: ic10_g24lc64.bin
system: sega-chihiro
required: false
hle_fallback: true
path: "x1box/ic10_g24lc64.bin"
size: 8192
validation: [size]
description: "Base board QC EEPROM"
note: "Read beside the BIOS only at exactly 8192 bytes. Otherwise the House of the Dead 3 dump compiled into chihiro-firmware.h stands in."
source_ref: "source hw/xbox/chihiro/chihiro.c:2382-2451, source hw/xbox/xbox.c:433-438, source hw/xbox/chihiro/chihiro-firmware.h:24-25"
- name: pc20_g24lc64.bin
system: sega-chihiro
required: false
hle_fallback: true
path: "x1box/pc20_g24lc64.bin"
size: 8192
validation: [size]
description: "Base board SC EEPROM"
note: "Read beside the BIOS only at exactly 8192 bytes. Otherwise the House of the Dead 3 dump compiled into chihiro-firmware.h stands in."
source_ref: "source hw/xbox/chihiro/chihiro.c:2382-2451, source hw/xbox/xbox.c:439-444, source hw/xbox/chihiro/chihiro-firmware.h:540-541"
- name: ic11_24lc024.bin
system: sega-chihiro
required: false
hle_fallback: true
path: "x1box/ic11_24lc024.bin"
size: 128
validation: [size]
description: "Base board configuration EEPROM"
note: "Read beside the BIOS only at exactly 128 bytes. Otherwise the House of the Dead 3 dump compiled into chihiro-firmware.h stands in."
source_ref: "source hw/xbox/chihiro/chihiro.c:2382-2451, source hw/xbox/xbox.c:445-450, source hw/xbox/chihiro/chihiro-firmware.h:1056-1057"
- name: xboxdash.xbe
required: false
load_from: hdd_image
path: "C/xboxdash.xbe"
description: "Retail dashboard boot executable"
note: >-
Imported to the root of partition C from the C directory of a user
dashboard tree. The import treats this name as the boot entry: when it is
absent the best scoring .xbe of the tree is copied to it, and the retail
boot counts as ready only once the name exists. The start path of the
emulator never reads partition C, and preparing Insignia finishes with a
warning when the name is missing.
source_ref: "source android/app/src/main/cpp/xemu_fatx_import.c:1848-1849, android/app/src/main/cpp/xemu_fatx_import.c:1897-1898, android/app/src/main/cpp/xemu_fatx_import.c:1919-1966, source android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2608-2639, android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2674-2683, android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2756, android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2774-2776"
- name: msdash.xbe
required: false
load_from: hdd_image
path: "C/msdash.xbe"
description: "Retail dashboard executable kept beside the boot copy"
note: >-
Probed at the root of partition C and imported with the rest of the tree.
Its presence beside the boot XBE is one of the marks the status line
reads to call a dashboard install complete, and it is one of the names
that decide which directory of a picked tree is taken as the source root.
source_ref: "source android/app/src/main/cpp/xemu_fatx_import.c:1850-1851, android/app/src/main/cpp/xemu_fatx_import.c:1899-1900, source android/app/src/main/java/com/izzy2lost/x1box/XboxInsigniaHelper.kt:13, 42-50, source android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2756, android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2777-2779"
- name: xbox.xtf
required: false
load_from: hdd_image
path: "C/xbox.xtf"
description: "Dashboard typeface"
note: >-
Probed at the root of partition C and imported with the rest of the tree,
alongside the xodash, audio, fonts and xboxdashdata.* directories the
root scan looks for.
source_ref: "source android/app/src/main/cpp/xemu_fatx_import.c:1838-1846, android/app/src/main/cpp/xemu_fatx_import.c:1852-1853, android/app/src/main/cpp/xemu_fatx_import.c:1901-1902, source android/app/src/main/java/com/izzy2lost/x1box/XboxInsigniaHelper.kt:12, 14-16, source android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2756, android/app/src/main/java/com/izzy2lost/x1box/SettingsActivity.kt:2780-2781"
- name: "<driver>.zip"
required: false
unsourceable: "third-party Vulkan driver built for one GPU family, not an emulator artefact"
description: "Replacement Vulkan driver package"
note: >-
Imported through a picker into gpu_drivers under the external files
directory, renamed after the name field of the meta.json it carries, then
unpacked whole into gpu_driver in internal storage, entries that would
escape that directory being refused. The minApi field is compared against
the device before the archive is kept. Loading is offered only when
/dev/kgsl-3d0 exists, and clearing the install directory returns the app
to the system driver.
source_ref: "source android/app/src/main/java/com/izzy2lost/x1box/GpuDriverHelper.kt:15, 19-35, 41-89, 91-131, 133-136, 170-197"
- name: gamecontrollerdb.txt
required: false
bundled: true
size: 589031
sha1: "b194b556763146786b994f606c8697ab8f1b5f47"
description: "SDL controller mapping database"
note: >-
Read from the assets of the package as the game controller subsystem
comes up and handed to SDL as a memory stream. The asset manager reads
inside the archive and the path is a constant, so there is no search
order and nothing outside the package replaces this copy. An added pad
mapping goes in through controller_map.txt instead. The revision shipped
here is 589031 bytes and is not the one other releases carry under this
name.
source_ref: "source android/app/src/main/cpp/xemu_android.cpp:252-253, android/app/src/main/cpp/xemu_android.cpp:283-322, android/app/src/main/cpp/xemu_android.cpp:1529-1534"
- name: X1_Covers.txt
required: false
bundled: true
description: "Cover art index for the game library"
note: >-
Read from the assets and turned into a lookup from normalised game name
to a URL under the X1_Covers repository, which the library fetches and
caches per title. Only lines ending in .png are kept.
source_ref: "source android/app/src/main/java/com/izzy2lost/x1box/GameLibraryActivity.kt:136, android/app/src/main/java/com/izzy2lost/x1box/GameLibraryActivity.kt:1494-1540"
- name: gamepad_map.txt
required: false
load_from: internal_storage
description: "Extra SDL gamepad mappings"
note: >-
SDL 3.4.14, which CMake downloads as a release archive when
thirdparty/SDL3 is absent, builds this path from the internal storage
directory of the package when SDL_GAMECONTROLLERCONFIG_FILE is unset,
which it is here, and reads it while the gamepad subsystem starts, after
the mappings compiled in. It is the one mapping file a user can add
without rebuilding the package.
source_ref: "SDL src/joystick/SDL_gamepad.c:2972-2984, SDL src/joystick/SDL_gamepad.c:3007-3009, source android/app/src/main/cpp/CMakeLists.txt:79-84, source android/app/src/main/cpp/CMakeLists.txt:104-112"
exclusion_note: >
Two file loads present in the tree are not reached by this build and are not
listed. The Chihiro network board firmware, ver1305.bin, is read only from
chihiro.roms.net_firmware_path and only when a cabinet link is enabled, and
the Android settings neither set the path nor enable the link.
X1_Covers.xml ships in the assets and no code opens it, the library reading
X1_Covers.txt instead.
ref: hw/xbox/chihiro/chihiro.c:546-559,
android/app/src/main/cpp/xemu_settings_android.cc:124-139,
android/app/src/main/assets/X1_Covers.xml,
android/app/src/main/java/com/izzy2lost/x1box/GameLibraryActivity.kt:1500