Predator/IR vision: reverse-engineered from the original firmware and
confirmed by the build team -- it is the Division board's TEXTURE-VALUE RAMP
mode (a "check your texture maps" diagnostic the devs hijacked), NOT a
grayscale squash or a false-colour palette. Located in VREND.MNG (effect
handler @0xe6c0, wire action 0x1b, type -1 ON / -2 OFF); ramp colours from
VR_DRAW.C. Renderer reworked to match: vrview_gl now does the 4-ramp
lerp(color0,color1,luminance(texel)) in the mesh pass (grayscale+defog
removed). Live-rendered on a new night-clear arena egg; crew A/B verdict
pending.
Firmware-decomp toolchain (emulator/firmware-decomp/), all built from the
project's own artifacts and validated:
- coff860.py i860 COFF reader (symbols/sections), names match AS860 source
- derive860.py derives the i860 opcode map from matched .S<->.O pairs
- dis860.py i860 disassembler (98% on clean ground truth; proven on
VREND.MNG -- velocirender_statistics decodes correctly)
- sigmatch860.py reloc-invariant signature matcher onto the stripped image
- i860-encoding.md / FIRMWARE-SYMBOLS.txt / README.md
PVISION-IMPLEMENTATION-GUIDE.md: self-contained hand-off for the BT411 team.
HARDWARE-ARCHITECTURE.md + hardware-photos/ (15 board shots): the Division
VelociRender card is a 2-board stack driving a 3-processor pipeline --
INMOS IMS T425-J25S (comms/control, runs vrendmon.btl) + Intel i860 XP-50 (FP
geometry, runs vrender.mng) + Division PXPL IGC 5.2 ASIC with ~48x PXPL EMC
5.1 (UNC Pixel-Planes-5 SIMD array; "EMC" = the firmware's configEMCs) +
Analog Devices ADV7150 RAMDAC + NTSC. Plus the VWE Video Distribution Board
(P/N 1404: AMD MACH130 + 3x Brooktree Bt477) for the 3-VGA-head cockpit split.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
227 lines
14 KiB
Markdown
227 lines
14 KiB
Markdown
# Division VelociRender card — hardware architecture (for emulation)
|
||
|
||
Reconstructed from the firmware (`VREND.MNG`), the DPL3/VRENDER board source, and
|
||
Division's own design docs (`VWE.DOC`, `PXPL5001.DOC`, `CM200IO.H`, `DMA.TXT`).
|
||
**Physical component tables at the bottom are placeholders to fill from the
|
||
photos.** This documents what the software *proves* must be on the board, so the
|
||
photos only need to pin part numbers and quantities.
|
||
|
||
## Form factor
|
||
|
||
Full-length, full-height, **double-stacked EISA** card pair (operator-described):
|
||
|
||
- **Bottom board:** the i860 front-end processor + its DRAM + the host/link
|
||
interface.
|
||
- **Top board:** the **Division PXPL IGC 5.2** rasterizer + supporting logic
|
||
(VRAM, RAMDAC, video out).
|
||
|
||
## The pipeline (three stages)
|
||
|
||
```
|
||
Host PC (EISA) Card, bottom board Card, top board
|
||
┌───────────────┐ link/CCB ┌────────────────────┐ FIFO/ ┌──────────────────┐
|
||
│ BTL4OPT.EXE │ ─────────► │ i860 front-end │ coeff │ PXPL IGC 5.2 │
|
||
│ VelociRender │ (transputer│ (VREND.MNG): │ stream │ (Pixel-Planes 5) │
|
||
│ wire: draw_ │ link, │ traverse, TRANSFORM│ ─────► │ tiled SIMD │
|
||
│ scene, DCS, │ C011-style│ LIGHT, planarize, │ "down │ rasteriser: │
|
||
│ materials …) │ 0x150) │ binitize, emit │ the │ edge/plane eval, │
|
||
└───────────────┘ │ pxpl5 coefficients │ wire" │ Z-buffer,texture │
|
||
└────────────────────┘ │ → VRAM tiles │
|
||
└───────┬──────────┘
|
||
VRAM→FrameStore│→ RAMDAC → 3 VGA heads
|
||
```
|
||
|
||
1. **Host (EISA PC)** runs the game; sends the VelociRender command wire (scene
|
||
graph: create/DCS/draw_scene/materials/effects — *not* transformed geometry).
|
||
2. **i860 front-end** (bottom board, runs `VREND.MNG`): scene traversal,
|
||
per-frame **transform / lighting / planarization / "binitize"**, and
|
||
generation of the per-primitive **coefficient words** the rasterizer consumes.
|
||
Feeds them to the back-end via a FIFO/DMA. (`VWE.DOC`: "push a ton of
|
||
triangles down the wire into the pxpl5 back-end"; a z-buffered flat-shaded
|
||
textured quad = **48 32-bit words**, a triangle ~24.)
|
||
3. **PXPL IGC 5.2 back-end** (top board): Division's implementation of **UNC
|
||
Chapel Hill Pixel-Planes 5** — a *tiled SIMD pixel-processor array*. Per tile
|
||
it evaluates edges/planes, does Z-buffering and texturing, into VRAM tile
|
||
buffers, then VRAM→FrameStore (`DMA.TXT`: tile loop, "wait for 2 interrupts
|
||
from DMA engine (scan-converter + end-of-texture)", `VRAMwritetoFrameStore`).
|
||
4. **Video out:** FrameStore → RAMDAC → **3 VGA heads** (the octopus cable; 5
|
||
mono MFDs + colour radar packed in one framebuffer — see the VDB decode note),
|
||
NTSC timing (`TESTVR.BAT /video NTSC`).
|
||
|
||
## Register / command interfaces (what an emulator must model)
|
||
|
||
**Host ↔ i860 — transputer link + CCB** (`CM200IO.H`, Division project "BLASTER",
|
||
CM100/CM200 lineage):
|
||
- "860 ↔ transputer io control register", `INPUT_CCB 0xFFFFF000` / `OUTPUT_CCB
|
||
0xFFFFF300` (256-byte Command Control Blocks), `CLEAR_INT`/`INT_CLEARED`.
|
||
- IO opcodes: `IO_LINK_OUT`, `IO_LINK_RAST_OUT`, `IO_DIVNET_IN/OUT/NODE`
|
||
(DIVNET = Division's transputer-link network — this is also the pod-to-pod
|
||
mesh path), `IO_BLOCK_IN/OUT`, `IO_MATHADV_REQ`, `IO_TIMER`.
|
||
- The host side pumps the link via a **C011/C012-style link adapter at EISA I/O
|
||
0x150** (`outveryfast` REP OUTSW); boot resets via port 0x160.
|
||
|
||
**i860 → PXPL IGC — coefficient stream** (`DMA.TXT`, `EOF.C` `IGC_*` macros):
|
||
- `IGC_SETENABS`, `IGC_MEMeqSCA_S1`, `IGC_MEMeqZERO`, `IGC_MEMgeSCA_S1`,
|
||
`IGC_CLEAR`, `IGC_CPY`, `send_em(&DMAptr,&coeffptr,…)` — the ops that build the
|
||
per-tile coefficient blocks the IGC executes.
|
||
- IGC per-primitive/per-pixel registers (`dvpx_*`): `dvpx_zbuf`, `dvpx_texid`,
|
||
`dvpx_texsize`, **`dvpx_texmode`**, **`dvpx_texrampsel`** (the material's ramp
|
||
index at the hardware level), `dvpx_diffuse`, `dvpx_specular`, `dvpx_scalar`.
|
||
- **Texture display modes** (`dvpx_eoftexmode`, `EOF.C`): **0 = texture RAMP**
|
||
(texel value → colour ramp — this is where IR/"predator" vision lives; see
|
||
PVISION-IMPLEMENTATION-GUIDE.md), 0x4 = 8-bit mono, 0x6/0x7 = full colour
|
||
(3-3-2 / 4-4-4). The 4 ramps (`texture_ramps[MAX_TEX_RAMPS=4]`) live in IGC
|
||
memory, selected per primitive by `dvpx_texrampsel`.
|
||
|
||
## Boot (both processors, every cold start, blind — see board-boot note)
|
||
|
||
- **`/tranny vrendmon.btl`** = the **transputer** boot image (INMOS boot-from-
|
||
link; ~85 KB). Loaded first over the link while the transputer is held reset.
|
||
- **`/i860 vrender.mng`** = the **i860** application (~380 KB; disassembles
|
||
cleanly as i860 — confirmed). The renderer logic (incl. pvision) is here.
|
||
- No version handshake possible pre-boot; both are streamed unconditionally.
|
||
|
||
## Lineage & external references (for the emulator author)
|
||
|
||
- **Division Ltd** (UK), project "BLASTER"; chip generations CM100 → CM200 →
|
||
**PXPL IGC 5.2** (the VWE board).
|
||
- **Rasterizer = UNC Pixel-Planes 5** (Fuchs, Poulton et al., UNC Chapel Hill,
|
||
~1989-92): tiled, SIMD pixel-processor array, "renderer" bin architecture,
|
||
quadratic expression evaluation. Well-documented in the graphics literature —
|
||
the authoritative model for the back-end.
|
||
- **Intel i860 (XR/XP)** front-end — documented ISA; our `dis860.py` disassembler
|
||
reads `VREND.MNG` directly.
|
||
- **INMOS transputer** (T-series) + **C011/C012 link adapters** — documented; the
|
||
host-comms and DIVNET/mesh layer.
|
||
|
||
## Emulation implications
|
||
|
||
- It's a **3-processor system**: transputer (comms/link/DIVNET), i860
|
||
(geometry/coefficient generation — already disassemblable), PXPL IGC (SIMD
|
||
rasterizer). A bit-exact renderer = run `VREND.MNG` on an i860 core + model the
|
||
IGC's coefficient interpreter (edge/plane eval, Z, texture modes incl. the
|
||
ramp) + the CCB/link glue. The transputer layer can likely be *stubbed* at the
|
||
CCB boundary (as our GL bridge already stubs the link) unless DIVNET/mesh
|
||
behaviour is needed.
|
||
- The IGC is the hard part (custom SIMD ASIC) — but its *programming model* is
|
||
fully visible in `EOF.C`/`PP5REND.C`/the `dvpx_*` set + the PXPL5 docs, and the
|
||
Pixel-Planes 5 literature describes the microarchitecture.
|
||
- Priorities: (1) i860 core + coefficient emit is enough to *drive* a
|
||
functional-accurate rasterizer we write to spec; (2) modeling the IGC exactly
|
||
buys true bit-exactness; (3) transputer only if mesh/DIVNET timing matters.
|
||
|
||
---
|
||
|
||
## Physical component inventory — IDENTIFIED FROM PHOTOS (2026-07-14, 13 photos)
|
||
|
||
Photos in `hardware-photos/` (`01`-`08` close-ups, `09`-`13` the assembly + module
|
||
shots). **Corrected topology (operator + edge-on/separated shots): it is a
|
||
TWO-BOARD stack**, each board covered front and back — the several `DBxxxx`
|
||
silkscreens (all "(C) Division Ltd. 1994") are functional areas/sub-modules of
|
||
the two boards, not separate cards.
|
||
|
||
### Board 1 — i860 geometry board (bottom)
|
||
| area | key silicon (as marked) | photos |
|
||
|---|---|---|
|
||
| CPU | **Intel `A80860XP-50`** — i860 **XP, 50 MHz** (heatsinked) | 04, 10-left |
|
||
| coeff FIFO path | **IDT `72510`** FIFOs · grid of Cypress `CY7C451-20` | 04 |
|
||
| working RAM | **2× RAM SIMM** = `DBIO151/03`, **Hitachi `HM624256AJP-25`** DRAM ×6/SIMM | 12-left, 09 |
|
||
| soldered memory | **16× Ramtron `DM2202J-15` EDRAM** | 03, 10-left |
|
||
| I/O / data-mux (other side) | `DBIO152/03` (SN 630254): large `QS74FCT153/158` mux array · Lattice ispLSI 1032/1016 · IDT `16Z646` · `QS338450` bus switches | 01, 11-left |
|
||
| host bus | **gold EISA edge** · IDT `74FCT16292/16841` transceivers ("pma") | 02 |
|
||
| glue/clock | Lattice ispLSI · GAL22V10 · Cypress `CY7B991` RoboClocks | all |
|
||
|
||
### Board 2 — PXPL rasterizer board (top)
|
||
| area | key silicon (as marked) | photos |
|
||
|---|---|---|
|
||
| rasterizer control | **`DIVISION PXPL IGC 5.2`** custom ASIC (gold ceramic PGA, date 9447) | 07, 08, 10-right |
|
||
| scan-conversion | **3× Xilinx `XC3090-100`** FPGAs (+ a 4th on the video side) | 07, 08, 10-right |
|
||
| **SIMD pixel array** | **`DBIO153/02` daughter cards: 4 sets of 3 = 12 cards, EACH with 4× `DIVISION PXPL EMC 5.1`** custom chips ⇒ **~48 EMC chips**. (These "look like 12 RAM SIMMs" but are the pixel-plane modules.) Back side: `QS74FCT2821` regd transceivers + `74F08`. | 12-mid/right, 13, 07 |
|
||
| VRAM | ~10-16× Micron `MT42C8256` VRAM | 08, 10-right |
|
||
| RAMDAC | **Analog Devices `ADV7150`** (programmable gamma/palette) | 08 |
|
||
| clocks | ICS `2572` synth · Cypress `CY7B991` | 08 |
|
||
| video out (other side) | `DBE0151 Pixel Planes rev/02` (SN 120227): VGA heads · **Maxim `MAX440/442`** amps · **`LM1882` + `74ACT715` + 14.318 MHz** (NTSC) · Lattice ispLSI 1048 ×2 | 05, 06, 11-right |
|
||
|
||
### The big reconciliation: PXPL IGC + PXPL EMC = the rasterizer
|
||
|
||
The daughter cards carry **`DIVISION PXPL EMC 5.1`** chips — and **`EMC` is exactly
|
||
the `_configEMCs` / `configEMCs_hi` the firmware programs** (`EOF.C`). So:
|
||
|
||
- **`PXPL IGC 5.2`** (1 ASIC on Board 2) = the **I**mage **G**eneration
|
||
**C**ontroller — the master rasterizer that runs the coefficient stream and
|
||
drives the array.
|
||
- **`PXPL EMC 5.1`** (~48 chips on the 12 daughter cards) = the **E**nhanced
|
||
**M**emory **C**ontroller — the **UNC Pixel-Planes-5 SIMD pixel-processor/memory
|
||
array** ("the planes"). Organized 4 banks × 3 cards × 4 chips.
|
||
|
||
Together, IGC + EMC array = the complete Division Pixel-Planes 5 rasterizer. The
|
||
texture-mode/ramp work (incl. pvision) is IGC-programmed and executed across the
|
||
EMC array.
|
||
|
||
### What the photos pin for emulation
|
||
|
||
- **i860 = XP @ 50 MHz** — set the emulated core exactly.
|
||
- **Rasterizer = 1× `PXPL IGC 5.2` + ~48× `PXPL EMC 5.1`** (SIMD array), no public
|
||
datasheet — model from the `dvpx_*`/`IGC_*`/`configEMCs` firmware interface +
|
||
the Pixel-Planes 5 literature. This is the hard part but the programming model
|
||
is fully in-source.
|
||
- **RAMDAC = ADV7150** (documented) — pins the colour/gamma back-end (supersedes
|
||
the guessed `pow(1/1.25)`; read its real config from the firmware).
|
||
- **Video = NTSC** (`LM1882`+`74ACT715`+14.318 MHz, `MAX440/442` amps → VGA heads).
|
||
- **Memory:** i860 = 2× Hitachi-DRAM SIMM + 16× Ramtron `DM2202` EDRAM;
|
||
rasterizer = Micron `MT42C8256` VRAM + the EMC on-chip pixel memory.
|
||
|
||
### The transputer — CONFIRMED: INMOS IMS T425-J25S (2026-07-14)
|
||
|
||
Firmware proved it first: **`VRENDMON.BTL` is transputer code, not i860** (as i860
|
||
it's garbage; it opens `0xF0`=240 = INMOS **boot-from-link** length byte, then the
|
||
textbook prologue `ajw 4; stl 1; stl 1; stl 1` + coherent `ldl/stnl/ldc/opr`).
|
||
Operator then located the chip on the i860 board (dust-covered, lower-centre-right
|
||
PLCC):
|
||
|
||
- **`INMOS IMS T425-J25S`, date 9335 (wk35 1993):** the **32-bit integer
|
||
transputer** — 4 KB on-chip SRAM, 4 serial links, **no FPU** — `J` = 84-pin
|
||
PLCC, `25` = **25 MHz**.
|
||
- The **no-FPU** point confirms the labour split: **T425 = comms/control/boot**
|
||
(runs `vrendmon.btl`; host link + the `CM200IO.H` CCB to the i860 + DIVNET
|
||
pod-mesh over its 4 links, no FP needed); **i860 XP = FP geometry** (runs
|
||
`vrender.mng`). Exactly the 1990 CM200 "860 ↔ transputer" pairing carried into
|
||
the 1994 board.
|
||
- **Emulation impact:** the system is **T425 + i860 XP + IGC/EMC**. `VREND.MNG`
|
||
(i860, disassembles clean via `dis860.py`) and `VRENDMON.BTL` (T425 bytecode)
|
||
are DIFFERENT ISAs — don't run `dis860` on the `.BTL`. For a functional renderer
|
||
the T425 can be stubbed at the CCB/link boundary (as the GL bridge does); for
|
||
bit-exact/timing it must be modelled (INMOS T4-series ISA is well documented —
|
||
the boot image already decodes cleanly).
|
||
|
||
## Downstream: the VWE Video Distribution Board (VDB) — photos 14/15
|
||
|
||
A **separate board, VWE's own** (not Division): silkscreen **"VIDEO DISTRIBUTION
|
||
BOARD, (C) 1994 V.W.E. Inc., Design by A.G./M.C., P/N 1404 REV.1"**. ISA form
|
||
factor; receives the rendered framebuffer from the Division card and fans it out
|
||
to the cockpit displays — the physical realization of the **3-VGA-head decode**
|
||
(5 mono MFDs + colour radar packed in one 16bpp framebuffer → 3 heads → octopus).
|
||
|
||
- **AMD `MACH130-18JC` CPLD** — the pixel routing / region-decode / timing (splits
|
||
the packed framebuffer into per-display regions).
|
||
- **3× Brooktree `Bt477KPJ80`** — 256×24 palette **RAMDACs**, one per VGA head
|
||
(the heads' final DAC is here, distinct from the Division card's `ADV7150`).
|
||
- Support: `74F245`/`74LS125`/`SN74LS541` buffers, `MAD1103` delay lines, an HP
|
||
part, fuse + analog output driver/filter array → D-sub outputs on the bracket.
|
||
- Back = solder-side only, one hand-added **bodge wire** (a Rev.1 fix).
|
||
- **Emulation note:** a display-fanout stage; render-accuracy needs only the
|
||
framebuffer→region mapping (the bridge already models the 3-head split). The
|
||
`Bt477` palettes / `MACH130` matter only for exact per-head colour/timing.
|
||
- **MACH130 "firmware":** no `.JED`/PAL source in the software dump (checked), and
|
||
its FUNCTION is already RE'd in `VDB-NOTES.md` from the MUNGA_L4 driver, so a
|
||
chip dump isn't needed for emulation. It IS **socketed** (84-pin PLCC — easy to
|
||
pull), so a hardware read is possible with a universal programmer that lists
|
||
MACH130 — the only catch is the MACH1xx **security bit** (if set, typical for
|
||
production, readback is blocked). Low priority.
|
||
|
||
### Still open (for the hardware owner)
|
||
2. **Exact EMC-array geometry** — confirm 4×3×4 = 48 `PXPL EMC 5.1`, and how the
|
||
4 banks map to screen tiles / the Pixel-Planes bin structure.
|
||
3. **VRAM/EDRAM totals** (count × size) for the frame/Z/texture split.
|
||
4. **`ADV7150` exact variant** + any genlock on the video side.
|