Update: Since we wrote this story, the original link on Next-Hack and the associated video have both vanished. We’ve left the link to Next-Hack up in case the story returns, but removed the video link to avoid having a dead embed for no reason. There’s no given reason for why the project was taken down. A link to the original page, with some of the visual assets, is available from the Internet Archive. Original story below:
A group of hackers has gotten Doom up and running on an unusual platform: an Ikea smart bulb. The group wrote up its project on Next-Hack and shared details of the implementation.
This group decided to get Doom running on a low-end platform and set specific rules for themselves in what would and would not be acceptable. The device must have reasonable computing power relative to Doom’s original requirements. The team references a 486-33, though I can tell you from personal experience you could play it with a modest viewing frustum on hardware as weak as an 80386SX-16. Only the microcontroller inside the chosen device could be used to run the game. Adding a small color display and additional flash memory to store files were both acceptable. The minimum goal was to play E1M1, otherwise known as the first level of “Knee-Deep in the Dead.”
The team originally planned to deploy an Ikea Trådefri lamp. While the modest 40MHz Cortex M4 was plenty powerful, the chip only had 32KB of RAM. This was deemed impossible. Then, some months later, Ikea updated with a new model. These new lamps featured an 80MHz Cortex-M33 and 108KB of RAM in total with 1MB of NAND flash. The team also attached an additional 8MB of NAND flash.
Development was handled on a comparatively powerful Cortex-M7. The STM chip they used, an STM32H743, features a memory-mapped QSPI (quad serial parallel interface) NAND flash chip, allowing the team to treat it as memory-mapped flash.
The team steps through the optimizations it made to get Doom running in under 108KB of RAM as opposed to the 160KB+ they estimate it requires by default. They saved a substantial amount of memory by converting data types — Doom used 32-bit integers in some cases, where only 8 or 16-bits were required. In several cases, they took data that was originally stored in RAM and moved it to NAND flash to free enough capacity to let the game run in the first place. They even optimized the memory buffer to save 5KB of RAM. One interesting thing their testing revealed: Performance, even on a smart bulb, is determined more by the speed of flash memory accesses than by the speed of the CPU.
But even after all of this, the team had a problem: Data transfer speeds on the STM32H743 were fast enough, but the EFR32MG21 they were working with inside the Ikea smart bulb didn’t support the same high-speed (relatively) interface. Their initial storage bandwidth was limited to 2.5MB/s until they overclocked the chip to 80MHz. That improved bandwidth up to 5MB/s. I’ll let them explain how they doubled it again:
The EFR32MG21 has three USARTs. One o tem is used for printing debug messages and downloading the WAD file to the external flash. We have two USART left… and the peripheral reflex system! With these two, we can synchronize the two USARTs (working in SPI mode) so that they read data at the same time, actually creating a double SPI (DSPI). Luckily, the QSPI memory also supports dual read, and in this way, we can reach 10MB/s!
The story goes on to describe how they kept the two SPIs synchronized and the additional work the team did to get audio working and play the game at Ultra Violence difficulty without running out of RAM. There are also step-by-step instructions for how to build the device. Overall performance and image quality are better than the GBA version. The group points out that the GBA’s 16.7MHz ARM7TDMI was only capable of 0.9 DMIPS/MHz, while the CM33 achieves ~1.5DMIPS/MHz and runs at 80MHz. The team isn’t done optimizing Doom for their diminutive platform and they plan to improve both performance and RAM usage in the coming days.