RP2040 Doom
kilograham.github.io
kilograham.github.io
I did some playing around with VGA graphics from the Pico when it first came out (wrote a simple library to produce SNES like graphics, wrote it all up on my blog https://gregchadwick.co.uk/blog/playing-with-the-pico-pt6/). It felt like Doom should be doable but I figured you'd need an off chip RAM expansion interfaced via the PIO. Clearly not.
The Pico really is a very fun board to play around with. Could be a great target for a retro style mini console thing.
I've been playing with this thing. It's quite neat: https://shop.pimoroni.com/products/picosystem?variant=323695...
(Note that it's a dev board; if you just want to play AAA games, not the thing to buy. If you want to program a game and show it off, it's what you want.)
question is, how would one go about compiling Doom for the Picosystem? that would be so cool…
One thing I really like about it is the super quick boot compared to all normal devices that need to boot an operating system first.
Highly recommended.
https://codetiger.github.io/blog/building-a-retro-style-game...
Carmack would be proud!
MCUs can have on chip RAM/ROM and off chip [quad] serial RAM/ROM, and even parallel access RAM/ROM like FRAM. Several ways to skin the cat. Or cut the pie, as it were.
The SNES ran Doom with two 64k RAM banks (albeit with textures and data such as level geometry running directly from ROM.)
https://doom.fandom.com/wiki/Super_NES
While this port makes it a point to port everything accurately, including multiplayer.
SNES Doom - 128KB RAM, I think a 2MByte ROM, CPU is 65816 at 3Mhz + SuperFX RISC CPU at 21Mhz, which also had its own 64KB of RAM.
PSX Doom - 2MB RAM + 1KB fast scratchpad, able to load from a standard 650MB CD, CPU is a MIPS R3051 at 33Mhz + the PSX accelerated graphics, not used except to draw strips
So doing this in a device that has not too much more RAM than the SNES and also has to livestream the VGA signal Atari 2600 style is exceedingly impressive. It's a dual CPU unit but basically having to spend a core manually bit banging the VGA signal like that is what fascinated me the most.
Edit: yes, see https://kilograham.github.io/rp2040-doom/rendering.html
Also if the RP2040 is just $1, does this mean we should be able to get e.g. Doom on cheap handheld single-game devices like the old Game & Watch and similar machines? I remember spending hours on these "racing games" or 12-in-1 Tetris LCD machines from the toy shop. How much does a small (2-4") color OLED or backlit LCD cost these days? Actually, what is the cheap handheld market looking like these days? I had a boggle at the local toy shop's website, VTech is still going for it but mainly with baby toys it seems, and those Tetris handhelds are still the same from 20-30 years ago, they cost just €3,99 these days. I'm also seeing some products from a company called Wonky Toys, and miniature Atari arcade cabinets.
QT Py ESP32 Pico: https://blog.adafruit.com/2022/01/24/is-this-one-of-the-smal...
Doom Boy ESP32: https://habr.com/ru/post/512130/
LilyGo FabGL VGA32: https://m.aliexpress.com/item/33014937190.html
ESPlay Micro V2: https://www.makerfabs.com/esplay-micro-v2.html
How far did you get with it? Any video of the end result?
I'm wondering about a few things:
- "I decided to leave the XIP cache to do its thing, and select a few small areas of hot code or data to promote to RAM manually"[1]: I understood this as you leaving the XIP cache activated. But this seems at odds with "16K of flash XIP cache, that we’ve talked about, but decided not to use."[also 1], which I'm interpreting as "decided not to make use of the XIP cache (i.e. turn it off)" (maybe I'm misreading).
- I thought ARM32 has 12(-14) usable registers (compared to 14-15 in x86-64), so why these mentions of "scarce Cortex-M0+ registers"? (Does FIQ mode reduce the number of usable registers?)
- "not good on a Cortex M0+ where the overhead of a function call is generally 30-40 cycles, with the corresponding loss of most of your precious “in-register” state": are function calls disproportionally slower on Cortex M0+? (Certainly 30-40 cycles seems high.) Why is that? (Registers r4-r11 are callee-saved[2], thus not lost; mutable data might have to be re-read from memory, though--just like on other architectures, but maybe CPU caches are faster on those.)
- "These OR values can be stored in a lookup table indexed by higher bits in the sample position, and thus the 8x space savings can be realized without needing any branches in the code!"[3]: Cortex-M0+ has a 2-stage pipeline[4], I'd hence expect the cost of a jump to be just 1 additional cycle, for the re-processing of the 1st stage for the next instruction (maybe I'm wrong), which would be the same as a memory access. (Maybe multiple jumps can be saved this way, though.) Did measurements show the lookup table to be faster?
[1] https://kilograham.github.io/rp2040-doom/speed_and_ram.html [2] https://en.wikipedia.org/wiki/Calling_convention#ARM_(A32) [3] https://kilograham.github.io/rp2040-doom/sound.html [4] https://en.wikipedia.org/wiki/Cortex-M0%2B#Cortex-M0+
The way I'm reading it, you can disable the XIP cache and use that 16KB of RAM for anything else you want. But the author "decided not to use" it for something else, that is, the 16KB are still being used as cache.
Cortex-M0+ is thumb-only (compressed 16bit instruction encoding). "In Thumb state, the high registers, r8-r15, are not part of the standard register set. The assembly language programmer has limited access to them, but can use them for fast temporary storage."
> (Does FIQ mode reduce the number of usable registers?)
There is no FIQ mode in Cortex-M. Instead you usually have the nifty Nested Vectored Interrupt Controller (NVIC) and it is designed so your interrupt handlers can be regular C functions, with no special handling needed (no special interrupt return instruction) needed.
I just HAVE to nitpick on Fandom/Wikia search term squatting. There is a real Doom Wiki at doomwiki.org.
These newer compatible boards being released are awesome.
The RP2040 is more powerful than an 80286. The PC/AT which was hugely more powerful than the original IBM PC (on which DOOM also ran). Put a keyboard, mouse, and an frame buffer on an STM32F4 or F7 and you've got the computational and capability equivalent of the PC's that powered the world in 1985. People did accounting, CAD, spreadsheets, email, all sorts of things on them. Amazing I know, but here we are.
If you want something that doesn't use any dedicated hardware, interfacing with analog displays (e.g. NTSC/PAL/VGA) can be done with a handful of resistors on GPIO pins. Conceptually, it is easier but actually dealing with timing is a pain. Again, libraries that deal with the grunt work are available.
Additionally, some "control registers" are being implemented in the FPGA that can do certain actions. At a minimum they are "clear to one color", "copy region", "scroll region", and "copy glyph". The STM32 has the DMA2 peripheral that does a lot of cool bitblt type functions but these can be nominally slowed down by not synchronizing with the FPGA's schedule for displaying things.
The STM32 is running micropython. The "plan", such as it is, is to let the REPL run using the display as its terminal, and a "graphics mode" to reserve parts of the screen for graphics. The small goal is to re-create sort of the VIC-20/C64/ZX Spectrum kind of "vibe" (interpreted language easy access to the graphics) and then build from there. Clearly the basic frame buffer is like 20% of the FPGA so there is lots of room to do other stuff in there.
[1] https://www.kickstarter.com/projects/1812459948/minispartan6...
Plus some of the early 8 bit machines drove a display with minimal extra hardware - eg the ZX80 / ZX81 although it was very very slow as a result!
Wolfenstein worked on 286.
But i found DOS4GW command line option to "emulate" ram with swap file on DOS. I make virtual memory like 4MB and run game. It took 15 minutes to start game and show main menu, another 5 mins to navigate on menu and 15 to run game. Frame rate was some like frame PER minute.
I don't think PC/AT was sub $1 either :)
It required a 386 with 4MB of RAM. It would not run on a 286, much less the original 4.77mhz IBM PC.
source: https://www.mobygames.com/game/dos/doom/techinfo
IIRC, Doom was very playable, but not exactly smooth on my cheap 386SX which was... 20mhz? But it ran like butter on the 66MHZ 486's in the school's computer lab.
OTOH they are actually overclocking the RP2040 at 270Mhz.
How does one even get these ideas?
> For RP2040 Doom, whilst I thought I might need to build my own single pin PIO networking with some sort of token passing, it turned out I had 2 GPIO pins free that could be configured for I2C, so I decided to just use that instead.
...what am I doing with my life
It has two buttons built-in and support for LiPo batteries. It might be possible to make this a teeny-tiny handheld device.
I can't wait to see what kind of a chip they make after the RP2040.
The original game ran (if you had a fast enough PC) at 35 FPS on a 70 Hz display.
I thought I had done something worthwhile with I2C.
I was wrong, and I am a bad person.
Edit: typo
I've got some Raspberry Pi Picos, and would like to try it out.
Any tips on how to get WiFi working on Pico?
It is basically an Arduino on steroids. It cannot run cron jobs. It has no network stack, kernel or operating system, and cannot run any software not specifically written for it.
I have heard that it's possible to run some form of Unix: https://www.zdnet.com/article/now-you-can-run-unix-on-the-ti...
Wanted to hear from my homies here for any ideas.