Do you like my hacking? If so, please consider leaving something in the
Fediverse (Mastodon etc): @Sprite_tm@social. spritesmods.com
I ported Doom to an ESP32 chip before. That was a bit of a hassle, mostly because of memory requirements: the chip had to be an ESP32 with external PSRAM, and even then porting was a bit of a pain, specifically because PSRAM was necessary to satisfy the memory requirements that Doom has. I released that source a while ago now.
In the mean time, someone under the 'doomhack' moniker on Github decided that the Game Boy Advance also needed a Doom port. Actually, they more like decided that the Game Boy Advance needed a proper port of Doom. There actually was a commercial version of Doom, but it was a bit lackluster: it was based on the Jaguar port of Doom which had simplified levels with less complex geometry, fewer textures, and some areas removed. Additionally, some features, like enemies hearing your shots, got cut. It's also censored: blood is green or absent, monster corpses vanish quickly, and gib deaths are absent.
'Doomhack' sought to correct this by taking PrBoom (which in effect is a polished and cleaned up version of the original Id Doom source code) and chiseling away at it until it would fit into the Game Boy Advance hardware. This would be quite a feat: while program space wouldn't be an issue (GBA cartridges allow access to up to 32MiB of ROM), RAM would be: the GBA only has 288 Kbytes of (non-video) RAM, and while cartridges could also contain some RAM, that was mostly intended for savegames and was slow and only 64KiB max. 'Doomhack's version does not use this RAM. Instead, the main trick it uses is re-writing the WAD-file, the file where most assets are. Normally, Doom loads these assets into memory and does some small conversions from the on-disk format to a format it can use for the engine. 'Doomhack' decided that much RAM can be saved by doing the conversion beforehand, on a PC, and letting the engine use that modified WAD-file. That increases the size of the assets a bit, but it means that they can stay on the cartridge (which is memory mapped) rather than being loaded in RAM first.
Why am I telling you this? Well, this set the requirements for any chip I wanted to run Doom on if I wanted to use this port: It required ROM (or flash) that can memory map the entire re-written Doom WAD-file. Additionally, it needs somewhere around 300K of RAM. It also needed to be at least as fast as a GBA, but given that that beast ran at 16.8MHz, that shouldn't be a big issue.
All in all, I went for an ESP32C3. It's a RiscV-based SOC that runs at 160MHz, so a fluid Doom experience shouldn't be an issue. It has 400K of SRAM as well, so the GBA version of Doom should fit nicely, with room to spare for other things. Unlike the older ESP32 (which is limited to 4MiB), the ESP32C3 can map 8MiB of flash directly into its address space, which is enough for the Doom WADfile. It also has WiFi and, more importantly, BLE; this means I have a chance of wirelessly hooking up a controller to it to actually play Doom. Also not unimportant in these chip-shortage time: not only are they pretty widely available, as I work for Espressif I can take some home for free.
The schematic is pretty trivial. I decided to use an ESP32-C3-Wroom-02 module, because I don't trust myself to get the RF bits right on the first try. Aside from that, there's an LCD and a speaker. The speaker is directly connected to the GPIOs of the ESP32C3. This is bad practice as the speaker is an inductance, but given I'm using a tiny speaker and I'm not overly concerned about the long-term statistical reliability of this thing, I'm OK with the risk of breaking something. The LCD is actually a 0.96" rectangular TFT screen, as that was the smallest color display I could get at a reasonable price. (You can actually get displays that are smaller, intended for viewfinders, but they're ridiculously expensive and the supporting electronics wouldn't fit anyway.)
One thing about the ESP32-C3-Wrover-02 modules is that they only come with up to 4MiB of flash. I needed at least 8, because otherwise the Doom level data wouldn't fit. I solved that by desoldering the metal cap of the module and replacing the flash. I made a little video on how to do that if you want to know more.
I wanted the bauble to run off a LiIon cell, so it needed charging logic for that. There's an extra diode/mosfet circuit: if you're charging a LiIon cell, you shouldn't also draw power from it as that tricks the charging IC into thinking the LiIon still isn't done charging yet, which will over-charge the cell. As such, the extra components let the ESP32C3 run directly off USB power if it's applied. Either the 4.2V from a fully-charged LiIon cell or the 5V from USB are too much for the ESP32C3 to run off, so there's also a HT7833 3.3V LDO to tone that down to the 3.3V the ESP32C3 likes.
I designed a small PCB for the components, intended to sit on the back of the Wroom-02 module. The components all only just fit, and KiCad will throw up a gazillion DRC issues when you ask it to check for them. Regardless, the PCB works; the only issue I had with it is that when JLC manufactured it, they pulled back the pads the Wroom module mounted on a bit. That does not make it impossible to solder the module on top, but it does make it very hard to optically check if there is a connection. I worked around that by simply using lots of flux while soldering and afterwards checking for continuity using my multimeter, reflowing the joint when there was none.