# SpinalVoodoo **Repository Path**: tangdk/SpinalVoodoo ## Basic Information - **Project Name**: SpinalVoodoo - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-30 - **Last Updated**: 2026-03-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpinalVoodoo SpinalHDL implementation of the 3dfx Voodoo Graphics GPU. ## Simulation Gallery
3dfx logo trace
Logo
Screamer 2 trace
Screamer 2
Quake trace
Quake
Valley of Ra trace
Valley of Ra
## Implementation Status ### FBI (Frame Buffer Interface) - Rasterization - [x] Triangle setup (bounding-box scan + edge function testing) - [x] Span generation (serpentine scan) - [x] Scissor clipping (clipLeftRight, clipLowYHighY) - [x] Y-origin transform (fbzMode bit 17, fbiInit3[31:22]) - [ ] Stipple patterns - Gradient Interpolation - [x] Color (R, G, B, A) - 12.12 fixed-point - [x] Depth (Z) - 20.12 fixed-point - [x] Texture coordinates (S, T, W) - 14.18 / 2.30 fixed-point - [x] Parameter adjustment for sub-pixel vertices (fbzColorPath bit 26) - Color Combine Unit (CCU) - [x] c_other source selection (iterated, texture, color1, LFB) - [x] c_local source selection (iterated, color0) - [x] cc_localselect_override (texture alpha bit 7 selects color0) - [x] zero_other, sub_clocal - [x] All mselect modes (ZERO, CLOCAL, AOTHER, ALOCAL, TEXTURE_ALPHA, TEXTURE_RGB) - [x] reverse_blend (factor inversion) - [x] Add modes (NONE, CLOCAL, ALOCAL) - [x] Invert output - Alpha Combine Unit (ACU) - [x] a_other source selection (iterated, texture, color1, LFB) - [x] a_local source selection (iterated, color0, iterated_z) - [x] alpha_zero_other, alpha_sub_clocal - [x] All alpha mselect modes - [x] alpha_reverse_blend, alpha_add, alpha_invert_output - Fog - [x] W-based fog table lookup - [x] Iterated fog (alpha/Z based) - [x] Fog color blending - Alpha Test - [x] Comparison functions (never, <, ==, <=, >, !=, >=, always) - [x] Reference alpha - Depth Buffer - [x] Z-buffer read/compare - [x] Depth function selection - [x] Z-buffer write - [x] W-buffer mode - [x] Depth bias - [x] Depth source select (iterated Z or W) - Alpha Blending - [x] Source blend factors (10 modes) - [x] Destination blend factors (10 modes) - [x] Framebuffer read for blending (fork-queue-join BMB pattern) - Chroma Key - [x] Color key comparison (post color-combine, matching real hardware) - [ ] Chroma range - Dithering - [x] 4x4 ordered dither (86Box ground-truth LUTs) - [x] 2x2 ordered dither (86Box ground-truth LUTs) - Framebuffer Write - [x] 16-bit RGB565 output - [x] Draw buffer selection - [x] Depth/alpha planes selection (fbzMode bit 18) - [x] RGB write mask - [x] Aux write mask - Linear Frame Buffer (LFB) - [x] Direct CPU writes (bypass mode, all write formats) - [x] Pixel format conversion (RGB565, RGB555, ARGB1555, XRGB8888, ARGB8888, Depth+color, Depth-only) - [x] Dual-pixel (16-bit formats) and single-pixel (32-bit formats) modes - [x] RGBA lane swizzle (ARGB, ABGR, RGBA, BGRA) - [x] Word swap and byte swizzle - [x] Dithering support - [x] Pipeline routing option (pixelPipelineEnable=1) - [x] LFB reads - Commands - [x] triangleCMD / ftriangleCMD - [x] fastfillCMD (screen clear via clip rectangle, color1/zaColor, with dithering) - [x] nopCMD - [x] swapbufferCMD (immediate + vsync-synchronized, swapsPending tracking) ### TMU (Texture Mapping Unit) - Texture Coordinates - [x] S/T/W interpolation - [x] Perspective correction (S/W, T/W division via 257-entry reciprocal LUT) - LOD (Level of Detail) - [x] LOD calculation from gradients (max gradient MSB position) - [x] Mipmap base offset calculation (per-LOD cumulative sizes) - [x] LOD bias (tLOD bits 17:12) - [x] LOD clamping (lodmin, lodmax) - [x] Per-pixel LOD adjustment (perspective-corrected W) - [x] Aspect ratio / non-square textures (tLOD lodAspect + lodSIsWider) - [ ] Trilinear blending (lod_frac) - Texture Address - [x] texBaseAddr register - [x] Texel address generation (row-major, 8/16-bit stride) - [x] Clamp and wrap modes (per-axis, textureMode bits 6-7) - [x] Clamp W (negative W forces S=T=0, textureMode bit 3) - [ ] texBaseAddr_1/2/3_8 (per-LOD base addresses) - Texture Filtering - [x] Point sampling (nearest) - [x] Bilinear filtering (min/mag) - Texture Formats (decode logic) - [x] RGB332 (8-bit) - [x] A8 (8-bit, alpha only) - [x] I8 (8-bit, intensity) - [x] AI44 (8-bit, alpha + intensity) - [x] ARGB8332 (16-bit) - [x] RGB565 (16-bit) - [x] ARGB1555 (16-bit) - [x] ARGB4444 (16-bit) - [x] AI88 (16-bit, alpha + intensity) - [x] YIQ422 / AYIQ8422 (NCC compressed) - [x] P8 / AP88 (palettized) - Texture Combine - [x] Texture output to color combine unit - [ ] Multi-texture (TMU chaining) - [x] NCC table decode - [x] Palette RAM (256-entry, loaded via NCC table 0 I/Q registers) - [ ] LOD dither - [ ] Data swizzle/swap ### Bus Interface / Register System - [x] BMB bus adapter (BmbBusInterface) - [x] 64-entry PCI FIFO with categorized routing (fifoBypass / syncRequired) - [x] Pipeline drain blocking for sync registers (triangleCMD, swapbufferCMD, etc.) - [x] Address remapping (fbiInit3 bit 0, external bit 21) - [x] CPU bus address decode (PCI BAR regions: registers, LFB, texture) - [x] texBaseAddr write relocation (SST-1 spec 5.53) - [ ] PCI configuration space (initEnable, busSnoop) - [ ] Memory FIFO (off-screen framebuffer extension) ### Display Controller - [ ] Video timing generator (hSync, vSync, backPorch, videoDimensions) - [ ] Framebuffer scan-out - [ ] Gamma correction CLUT (clutData) - [ ] DAC programming (dacData) - vRetrace is currently an external input (no internal generation) ## Scala CLI Commands ```bash # Run tests scala-cli test . # Format code scalafmt # Compile scala-cli compile . ``` ## Glide Simulation Tests Run the Glide2x test suite against the Verilator model: ```bash make native/sim/run/test00 # single test make native/sim/run-all # all screenshot tests TRACE=1 make native/sim/run/test00 # with FST waveform dump ``` Screenshots are saved to `output//screenshot.png`. **Environment variables** (set at runtime): | Variable | Description | |---|---| | `SIM_FST` | Path for FST waveform output (requires `TRACE=1` build) | | `SIM_CYCLE_LIMIT` | Max simulation ticks before clean exit (0 = unlimited) | | `SIM_FBWRITE_LOG` | Path to log framebuffer writes | | `SIM_TMU_LOG` | Path to log TMU/rasterizer activity | ## DOSBox-X (32-bit Glide Path) The sim backend builds a **32-bit** `libglide2x`, so DOSBox-X must also be 32-bit to `dlopen()` it. ```bash # Linux-hosted sim test make native/sim/run/test00 # Linux-hosted trace capture make native/trace/run/df00sim # Build and run a DOS guest binary inside DOSBox-X through its built-in GLIDE2X.OVL make dos/sim/run/df00sdk # Headless DOS guest variant make dos/sim/headless/df00sdk # DOS guest with trace backend make dos/trace/run/df00sdk # Launch a raw DOSBox-X session with the sim Glide backend injected make dos/dosbox ``` Common top-level commands: - `make native/help` prints the Linux-hosted and trace command surface. - `make native/sim/build` builds all Linux-hosted Glide test binaries. - `make native/sim/build/` builds one Linux-hosted test binary. - `make native/sim/run/` runs one Linux-hosted test and writes screenshot output under `output/`. - `make native/trace/run/` rebuilds the host Glide runtime with the trace harness and captures `traces/.bin`. - `make native/sim/check/` replays an existing trace through the check pipeline. - `make native/sim/test/` captures and checks in one step. - `make native/sim/check-all` replays every existing trace under `traces/`. - `make dos/help` prints the DOS and Tomb command surface. - `make dos/sim/build` builds all DOS SDK-style test binaries from `emu/glide/glide2x/sst1/glide/tests/Makefile.sdkwat`. - `make dos/sim/build/` builds one DOS SDK-style binary, for example `make dos/sim/build/df00sdk`. - `make dos/sim/run/` mounts `emu/glide/glide2x/sst1/glide/tests` as `C:` in DOSBox-X and runs `.exe` with the sim backend. - `make dos/sim/headless/` does the same with `DOSBOXX32_HEADLESS=1`. - `make dos/trace/run/` runs a DOS guest against the trace-capture Glide runtime and writes `traces/dos/.bin`. - `make dos/trace/headless/` does the same headlessly. - `make dos/dosbox ARGS='...'` launches DOSBox-X with the sim Glide backend and forwards extra DOSBox-X arguments. - `make tomb/help` prints the Tomb Raider setup requirements. - `make tomb/prepare ARGS='--game-dir ... --patch ... --iso ...'` prepares a reusable Tomb Raider source tree from your game files and 3dfx patch assets. - `make tomb/sim/run`, `make tomb/sim/headless`, and `make tomb/sim/capture` run Tomb Raider against the sim backend. - `make tomb/sim/trace` runs Tomb Raider against the live sim runtime and also dumps a trace to `traces/tomb_live/trace.bin`. - `make tomb/sim/trace/check` replays `traces/tomb_live/trace.bin` into `output/tomb/trace_replay_live/`. - `make tomb/trace/run` and `make tomb/trace/headless` run Tomb Raider against the trace runtime and write `traces/tomb/trace.bin` automatically. - `make tomb/trace/check` replays `traces/tomb/trace.bin` directly into `output/tomb/trace_replay/` without pulling in any stale `state.bin` from an old trace directory. The hierarchy is intentional: - `native//[/]` is for Linux-hosted test binaries. - `dos//[/]` is for DOS guest binaries inside DOSBox-X. - `tomb//` is for Tomb Raider convenience flows. - `de10/` is for board-oriented workflows using the `de10` runtime. Runtimes are explicit and non-stateful: - `sim` means the normal in-process Verilator-backed Glide runtime. - `trace` means the trace-capture Glide runtime. - `de10` means the board/MMIO-backed Glide runtime. In practice: - `native/...` and `dos/...` currently expose `sim` and `trace` directly in the command path. - `de10/...` keeps the runtime implicit in the namespace because every `de10` command already targets the board runtime. - `SIM_INTERFACE=de10` is the closest host-side reproduction of the board interface: it still uses the `sim` runtime, but swaps the Verilated top-level from `CoreSim` to `CoreDe10` and drives the DE10-style MMIO plus Avalon memory ports from the host harness. Examples: ```bash make native/sim/run/test00 SIM_INTERFACE=de10 make dos/sim/run/df00sdk SIM_INTERFACE=de10 ``` ### Tomb Raider Setup The Tomb helper scripts expect a prepared source tree at `DOSBOX_TOMB_SRC`. By default that is `/tmp/tr1-3dfx`. The easiest way to create it is: ```bash make tomb/prepare ARGS='--game-dir /path/to/TOMBRAID --patch /path/to/3dfx-patch.zip --iso /path/to/tr1disc01.iso' ``` That helper: - copies your source game directory into `DOSBOX_TOMB_SRC/TOMBRAID` - copies the ISO into `DOSBOX_TOMB_SRC/tr1disc01.iso` if provided - overlays the supplied 3dfx patch directory or archive onto the game directory It accepts either a patch directory or a `.zip`/tar archive. Add `--output /path/to/tree` to prepare somewhere other than `DOSBOX_TOMB_SRC`, and `--force` to replace an existing tree. Expected layout by default: ```text /tmp/tr1-3dfx/ tr1disc01.iso TOMBRAID/ TOMB.EXE ... game files ... ``` Typical flow: - Prepare the tree with `make tomb/prepare ...`, or assemble the layout manually. - Run `make tomb/help` to print the current assumptions. - Run `make tomb/sim/run` or `make tomb/sim/headless`. At launch time the helper scripts copy the source tree into `DOSBOX_TOMB_STAGE_ROOT` (default `/tmp/tr1-run`) and automatically rename any bundled `glide2x.ovl` so that DOSBox-X's built-in `GLIDE2X.OVL` guest bridge is used instead. You can override the defaults with these environment variables: - `DOSBOX_TOMB_SRC` - `DOSBOX_TOMB_STAGE_ROOT` - `DOSBOX_TOMB_GAME_DIR` - `DOSBOX_TOMB_ISO` - `DOSBOX_TOMB_EXE` Notes: - `scripts/run-dosboxx32-glide` prefers `DOSBOXX32_BIN` if set. - If `dosbox-x` on `PATH` is already 32-bit, it uses that. - Otherwise it auto-resolves Nix `pkgsi686Linux.dosbox-x`. - The script appends `scripts/dosboxx32-glide.conf` (enables `glide=true`, `voodoo_card=false`, `lfb=full_noaux`). - For low-level manual control you can still use `scripts/run-dosboxx32-glide` directly. ## Trace-Based Testing Glide trace files (`.bin`) capture PCI bus operations for offline replay against both the RTL simulation and a software reference model: ```bash # Capture a trace from a Linux-hosted test make native/trace/run/test_alphabet # Replay one trace through the reference model and RTL simulator make native/sim/check/test_alphabet # Capture and replay in one step make native/sim/test/test_alphabet # Replay every existing trace make native/sim/check-all ``` Replay outputs are written to `test-output//` as `_ref.png`, `_sim.png`, and `_diff.png`. Trace files are stored in `traces/` and compared pixel-by-pixel against a reference model. ## DE10-Nano The DE10-Nano flow is meant for three practical tasks: - generate FPGA-ready RTL and bitstreams - program or deploy a board - run workloads on real hardware Common commands: ```bash make de10/help # Generate RTL / FPGA build inputs make de10/rtl make de10/qsys make de10/bitstream # Program or deploy to the default board (fpga@debian-fpga.local) make de10/setup/program make de10/setup/deploy # Basic board validation make de10/check/mmio # Run workloads on hardware make de10/run/dos/df00sdk make de10/run/tomb ``` Useful defaults and assumptions: - Default board target is `fpga@debian-fpga.local` unless `DE10_HOST` or `DE10_USER` override it. - Default deployed runtime prefix is `/home/fpga/spinalvoodoo` unless `DE10_REMOTE_PREFIX` overrides it. - `make de10/run/dos/` uses the deployed launcher on the board and mounts `DE10_RUNTIME_DIR` (default `/home/fpga/de10-cross`) as `C:`. - `make de10/run/tomb` expects a prepared remote Tomb tree at `DE10_TOMB_SRC` (default `/home/fpga/tr1-3dfx`) containing the game directory and ISO. Extra DE10 helpers live in `scripts/` and `tools/` for board capture, replay, and bring-up.