Doom for siglent 1xx4X series scopes
  • C 92%
  • Makefile 8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
GameTec_live a6fffe384c scope doom
2026-07-24 09:28:35 +02:00
assets scope doom 2026-07-24 09:27:15 +02:00
docs scope doom 2026-07-24 09:27:15 +02:00
reference/button-monitor scope doom 2026-07-24 09:27:15 +02:00
runtime scope doom 2026-07-24 09:27:15 +02:00
src scope doom 2026-07-24 09:27:15 +02:00
usb-root scope doom 2026-07-24 09:27:15 +02:00
vendor scope doom 2026-07-24 09:27:15 +02:00
.gitignore scope doom 2026-07-24 09:27:15 +02:00
Dockerfile.build scope doom 2026-07-24 09:27:15 +02:00
Makefile scope doom 2026-07-24 09:27:15 +02:00
README.md scope doom 2026-07-24 09:28:35 +02:00
SHA256SUMS.txt scope doom 2026-07-24 09:27:15 +02:00
THIRD_PARTY_LICENSES.md scope doom 2026-07-24 09:27:15 +02:00
USB_README.md scope doom 2026-07-24 09:27:15 +02:00

Doom for the Siglent SDS1000X-E

This is a standalone, reproducible project for booting Doom directly from an ordinary MBR/FAT32 USB stick on a Siglent SDS1000X-E. The complete path—from stock U-Boot through a USB-root Linux userspace, FPGA/display/button initialization, and Doom—has been confirmed on the physical scope.

Project layout

Path Contents
src/ Siglent Doomgeneric framebuffer/input platform
runtime/ Static FAT-root PID 1 and temporary U-Boot environment
vendor/doomgeneric/doomgeneric/ Pinned Doomgeneric engine sources
assets/ Recovered kernel, original DTB, FPGA bitstream, modules, WAD
docs/ Reconstructed architecture, DT source, kernel config, provenance
reference/button-monitor/ Button/encoder investigation tool and capture
dist/ Final directly-extractable USB ZIP
usb-root/ Staging tree used to create the ZIP

Why the USB itself is the root filesystem

The recovered kernel has CONFIG_BLK_DEV_INITRD disabled. U-Boot can load and pass a legacy ramdisk, but Linux ignores it. The kernel does have USB storage, SCSI disk, DOS partition, VFAT, rootwait, and devtmpfs support built in. The working boot command therefore uses:

root=/dev/sda1 rootfstype=vfat rw rootwait init=/linuxrc

FAT32 cannot represent a conventional Linux root with symlinks and Unix mode bits, so /linuxrc and Doom are statically linked and the root is deliberately flat. Devtmpfs supplies device nodes. The recovered kernel modules, runtime FPGA image, Doom executable, and WAD are ordinary FAT files.

Runtime sequence

  1. U-Boot reads the kernel, DTB, and environment from FAT32.
  2. The copied DTB disables the NAND/SMC controller.
  3. Linux mounts the USB FAT partition as / and runs /linuxrc.
  4. PID 1 mounts devtmpfs/proc/sysfs/tmpfs and holds GPIO 933 low.
  5. It writes fpga.bit to /dev/xdevcfg.
  6. It loads the recovered AXI DMA/CDMA/VDMA and Siglent DMA/VDMA/keyboard modules in the stock order.
  7. It programs the menu VDMA at 0x43000000, raises GPIOs 933/959, and enables the backlight register at 0x40610380.
  8. It reproduces the stock dedicated power-button path on GPIOs 922-924.
  9. It launches Doom, which renders through /dev/fb0, reads /dev/siglent_kb, and plays monophonic MUS music through the TTC-driven piezo beeper.

The runtime does not create persistent boot logs. Diagnostics remain visible on ttyPS0 at 115200-8-N-1.

Build

From this directory:

docker build -t siglent-doom -f Dockerfile.build .
docker run --rm -v "$PWD:/src" siglent-doom

The container rebuilds both static ARM executables, creates usb-root/, validates the kernel header, DTB, module formats, NAND-disabled status, and PID 1 under QEMU user emulation, then produces:

dist/siglent-sds1000xe-doom-usb.zip

That ZIP is the only final file in dist/. Its contents begin directly with boot_uImage, linuxrc, doom.wad, and the other USB-root entries—there is no enclosing project directory. The Doom executable inside it is byte-for-byte identical to the executable used in the successful physical-scope test.

On PowerShell:

docker run --rm -v "${PWD}:/src" siglent-doom

Deploy

Use a USB stick with an MBR partition table and one FAT32 partition. Remove any old contents, then extract dist/siglent-sds1000xe-doom-usb.zip directly to the partition root. The ZIP contains the required empty dev, proc, sys, and tmp directories.

Insert the stick before power-on. Remove it and power-cycle to return to the stock firmware.

Controls

Scope control Doom action
Vertical or Horizontal encoder Move forward/backward
Vertical Position or Horizontal Position encoder Turn left/right
Vertical or Horizontal encoder push Use / menu select
Vertical Position or Horizontal Position encoder push Fire / menu select
Soft keys 1–6 Escape, Enter, fire, use, map, run
Math / Ref / Roll / Search Fire / use / map / run
Left / Stop / Right / Display-Persist Turn left / backward / turn right / forward
Run/Stop Fire
Power button Sync the USB filesystem and power off

The port accepts -invertmove, -invertturn, -swapencoders, and -pulsems N. See docs/DOOM_PORT.md for details.

The power key is reported by the separate MSP430 supervisor on GPIO 924, not as a Siglent keyboard event. Its recovered circuit and shutdown sequence are documented in docs/POWER_BUTTON.md.

The beeper is a single square-wave voice rather than a PCM audio device. Doom maps the recovered Zynq TTC0 registers and reduces its MUS scores to one stable melodic voice. Percussion and sound effects are disabled. The implementation, limitations, and register-level evidence are documented in docs/BEEPER_SOUND.md.

Flash safety

usb-root/boot_devicetree.dtb is generated from the recovered DTB with /amba/memory-controller@e000e000 set to status = "disabled". PID 1 contains no UBI, MTD, or NAND operation. U-Boot itself necessarily originates from the scope's internal boot storage before it switches to USB.