Getting DOOM to run on something is an old challenge in hardware hacking. This version is worth a closer look because of what had to be built first. Andrew Spode picked a cheap, unbranded children's camera sold as the X9S. Its SoC, the HX-Tech HX3302B, has no public documentation. In his write-up dated November 01, 2026, he describes dumping the firmware, working out the instruction set and memory map, and building a C compiler, an SDK and an emulator from scratch. He then ported doomgeneric, and the result runs at around 30fps with sound, music and save/load. Hackaday covered the project. According to the author's write-up, the camera still works as a camera with the port installed.
The hardware, as measured
The camera's box and interface name no manufacturer, so every figure below comes from Spode's own measurements in his write-up. None of them is a manufacturer specification.
- SoC: HX-Tech HX3302B, an OpenRISC-derived core (the project's toolchain targets it as little-endian with no delay slot)
- CPU throughput: about 120 MIPS in the best case, falling to about 82 MIPS in code with frequent branches
- Cache: 8KB instruction cache plus 8KB data cache
- RAM: 2MB, of which only 891K is free under the stock firmware
- Flash: 4MB, with reads measured at about 4.4MB/s. Code that misses the cache and runs from flash is about 18x slower than code in RAM.
- Display: 320x240, 256 colours
Spode says the result comes out similar to a 486 DX4/100, while noting it is not directly comparable. That is his own estimate, not a benchmark result, but it fits: DOOM was designed for 486-class PCs.
Getting in: flash dumps, EXIF and an unchecked checksum
The first step was physical. Spode read the camera's 8-pin flash chip with an XGecu T48 programmer. The CPU identification came from earlier work. Jeroen Domburg (Sprite_tm) had modded a cheap toddler camera built on a related HX-Tech SoC, and his write-up supplied the CPU to expect and a Ghidra processor definition (derived from OpenRISC) that the new work builds on. Hackaday also notes that Sprite_tm had done work on the HX3302B before.
The firmware update path, which Hackaday calls the "Achilles' heel" of this camera, turned out to be easy to exploit. The camera loads firmware updates from an SD card. According to Spode's write-up, it never checks that the header checksum is correct, and an update can write just part of the flash. With that path open, he could load his own code without a programmer. For debugging, he used an EXIF trick from Sprite_tm's earlier work: the camera's photo-metadata code is changed to write a slice of the camera's memory into the photo, which is then read back off the SD card. Hackaday also highlights this technique. The camera's normal output files became the debug channel.
Building a toolchain for a chip nobody documents
The HX3302B core is OpenRISC-like, but standard OpenRISC tools don't target it as-is. The project repository includes patch scripts that turn stock binutils 2.43.1 and GCC 14.2 into a little-endian OpenRISC compiler with no delay slot. On top of that, Spode wrote his own SDK and an emulator, so code could be tested on a PC instead of being flashed to the camera for every change.
The repository splits its contents by licence:
- Documentation under CC BY 4.0
- A USB firmware dumper,
tools/usb_flash_read.py, under MIT. It dumps the firmware over USB, so no programmer is needed. - Compiler patch scripts under GPL-3.0-or-later
- The SDK and emulator under MIT
- The DOOM port, a patch against doomgeneric, under GPL-2.0-or-later
The repository leaves two things out on purpose. Firmware dumps are not included. The game data is not included either: you supply the DOOM1.WAD v1.9 shareware file yourself.
The repository credits also say that AI models, specifically Claude and Kimi, did much of the heavy lifting, including reading the disassembly and writing the tools. That is useful context for anyone judging the project or building on it.
Fitting DOOM into 891K
The hardest constraint was memory. With 891K free out of 2MB, DOOM does not fit. Spode's write-up says the game could use up to about 1.4MB in total, in fragments, by borrowing memory the stock firmware never touched. The camera firmware stays in place, which is how it can still take photos.
Code placement was the second problem. Flash reads run at about 4.4MB/s, and code that misses the cache runs about 18x slower than code in RAM. Spode found that about 99% of the time was spent in roughly 29KB of DOOM's 260KB of code, so he put that small hot core in RAM and left the rest, such as start-up code, menus and the automap, in flash. Hackaday summarises it as keeping only the most-used DOOM code in memory and the rest in flash.
Audio needed its own work. Hackaday says Spode wrote a custom synthesizer for the music, and his write-up describes the output as chiptune music. Sound effects and save/load also work. Hackaday's verdict is that the controls have "a few quirks" but the result is a playable DOOM console. That is reasonable for a game built for a keyboard and now played on a children's camera's buttons.
What It Means for Makers
This is a reverse-engineering project, not a product. Nothing is for sale, and none of the sources give a price for the X9S camera itself. What is available now is the published code: the GitHub repository is public, with documentation, a USB firmware dumper, a compiler toolchain, an SDK, an emulator and the DOOM patch.
The project is most useful to three groups:
- Reverse engineers and firmware hackers. The write-up shows a complete workflow on an undocumented SoC: identify the core, dump the flash, find an update path that skips the checksum check, then build tools.
- Embedded developers. The patch scripts for binutils 2.43.1 and GCC 14.2 show how to adapt mainstream compilers to a nonstandard core variant, here a little-endian OpenRISC with no delay slot.
- Owners of the same or similar cameras. Because the dumper works over USB, you can try it without buying a programmer like the T48 Spode used for his first read. The repository does not ship stock firmware, so you need to dump your own device, and you must supply the shareware WAD yourself. The repository was tested on one camera, an X9S on one firmware version, and warns that a bad flash can brick the camera.
The broader point is about cheap consumer hardware. An unbranded toy turned out to contain a chip that Spode compares to a 486 DX4/100, along with a firmware updater that doesn't check its header checksum. Sprite_tm showed that a related camera could be modded, and this project takes the same chip family much further, from firmware mods to a working SDK.
Anyone planning to build on this code should keep two things in mind. Each component carries its own licence, from MIT to GPL. And by the repository's own account, much of the code and analysis came from AI models.