Skip to content

xinpian-tech/DOOM

 
 

Repository files navigation

DOOM Baremetal RISC-V

Run the original 1993 DOOM on bare metal RISC-V hardware with no operating system.

This port runs on QEMU's virt machine with the ramfb framebuffer device, targeting the RV32IMACV architecture (32-bit RISC-V with Vector extension).

Features

  • No OS required - Runs directly on hardware/emulator
  • Full game support - Uses registered DOOM WAD (embedded in binary)
  • Graphics - 320x200 resolution via QEMU ramfb device
  • Input - UART keyboard input with arrow key support
  • Portable - Built with Nix for reproducible builds

Quick Start

Prerequisites

Build

nix build

This produces result/bin/doom.elf.

Run with QEMU

qemu-system-riscv32 -M virt -cpu max -m 32M -device ramfb \
    -bios none -kernel result/bin/doom.elf

Or enter the development shell and run:

nix develop
qemu-system-riscv32 -M virt -cpu max -m 32M -device ramfb \
    -bios none -kernel result/bin/doom.elf

Run Screenshot Test

The test navigates through menus, starts a game, and captures screenshots:

nix develop
python3 test/screenshot.py result/bin/doom.elf

Screenshots are saved to build/test-output/.

Controls

Input is via UART serial console. When running QEMU with -nographic, type directly into the terminal.

Key Action
Arrow keys Move/Turn
Enter Select/Confirm
Escape Menu
Space Use/Open doors
Ctrl+A Fire weapon
1-7 Select weapon

Arrow keys use ANSI escape sequences (ESC [ A/B/C/D).

Project Structure

baremetal/
  crt0.S              - Startup code (stack, BSS, main)
  i_main_baremetal.c  - Entry point
  i_system_baremetal.c - System functions (timing, memory)
  i_video_stub.c      - Video output and keyboard input
  ramfb.c             - QEMU ramfb framebuffer driver
  w_wad_embedded.c    - Embedded WAD file support
  linker.ld           - Memory layout (14MB ROM, 14MB RAM)
  platform.h          - Platform compatibility definitions

linuxdoom-1.10/       - Original DOOM source code

test/
  screenshot.py       - Automated test with screenshots

nix/
  doom.nix            - Nix build configuration
  newlib.nix          - C library for baremetal

Memory Layout

For QEMU virt machine with 32MB RAM:

Region Address Size Contents
ROM 0x80000000 14MB Code, rodata, embedded WAD
RAM 0x80E00000 14MB Data, BSS, stack, heap
ramfb 0x81C00000 ~250KB Framebuffer

Technical Details

Graphics

Uses QEMU's ramfb device configured via fw_cfg DMA interface:

  • Resolution: 320x200
  • Format: XRGB8888 (32-bit)
  • Base address discovered at runtime

Input

Reads from NS16550A UART at 0x10000000:

  • Polls receive buffer in game loop
  • Handles ANSI escape sequences for arrow keys
  • Keys auto-release after ~1 second for smooth movement

Timing

Uses RISC-V rdtime instruction reading from CLINT mtime register. Provides millisecond-precision timing for game logic (35 Hz tick rate).

Original README

See README.TXT for John Carmack's original release notes from 1997.

License

Original DOOM source code is released under the GNU General Public License 2.0. Copyright (c) ZeniMax Media Inc.

Baremetal port additions are also GPL-2.0.

About

DOOM In RV32

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 96.0%
  • C 3.8%
  • Makefile 0.2%