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>
84 lines
3.4 KiB
Markdown
84 lines
3.4 KiB
Markdown
# i860 instruction encoding — validated against our own object files
|
||
|
||
Every fact here is cross-checked against the AS860 `*.S` (PGI/AS860 assembly) ↔
|
||
`*.O` (COFF machine code) pairs in `sda4/DPL3/VRENDER/AS860/`, using
|
||
`derive860.py`. Method: reproduce every `.text` byte offset from the assembly and
|
||
confirm each computed label offset equals its COFF symbol value; only then is the
|
||
`op6 → mnemonic` harvest trusted. 3 pairs align perfectly (CONTROL 2/2, TRISTRIP
|
||
4/4, XFLGHTPR 20/20 labels).
|
||
|
||
## Word format (little-endian, 32-bit) — CONFIRMED
|
||
|
||
REG-format:
|
||
|
||
```
|
||
31 26 25 21 20 16 15 11 10 0
|
||
+--------+-------+-------+-------+-----------+
|
||
| opcode | src2 | dest | src1 | (unused) | register src1
|
||
+--------+-------+-------+-------+-----------+
|
||
| opcode | src2 | dest | imm16 | 16-bit immediate
|
||
+--------+-------+-------+-------------------+
|
||
```
|
||
|
||
CTRL-format (br/call/bc/bnc/bt/bnt): `opcode[31:26] | disp26` (sign-extended,
|
||
word-scaled, PC-relative to the *next* instruction; i860 has one delay slot).
|
||
|
||
Verified from `CONTROL.O` (4 instrs, exact):
|
||
- `bri r1` = `0x40000800` → op `0x10`, src1(15:11)=1 ✓
|
||
- `ld.c fsr,r16` = `0x30900000` → op `0x0c`, src2(25:21)=4=fsr, dest(20:16)=16 ✓
|
||
- `st.c r16,fsr` = `0x38808000` → op `0x0e`, src2=4=fsr, src1(15:11)=16 ✓
|
||
|
||
Control registers: `fir=0 psr=1 dirbase=2 db=3 fsr=4 epsr=5` (fsr=4 confirmed).
|
||
|
||
## Primary opcode map (bits 31:26)
|
||
|
||
CONFIRMED = dominant mnemonic seen in cleanly-aligned ground-truth data;
|
||
otherwise from the published i860 ISA and consistent with what we saw.
|
||
|
||
| op6 | mnemonic | src | notes |
|
||
|----|----|----|----|
|
||
| 0x02 | ixfr | | integer→FP reg transfer (CONFIRMED) |
|
||
| 0x08/09 | fld.{l,d,q} | | FP load (+auto-inc); 0x09 CONFIRMED |
|
||
| 0x0a/0b | fst / pst | | FP store; 0x0b fst CONFIRMED |
|
||
| 0x0c | ld.c | | load control reg (CONFIRMED) |
|
||
| 0x0e | st.c | | store control reg (CONFIRMED) |
|
||
| 0x10 | bri | | branch indirect (CONFIRMED) |
|
||
| 0x11 | trap | | |
|
||
| 0x12 | **FP escape** | | fadd/fmul/fsub/pf*/fxfr/frcp/… sub-op in low bits (CONFIRMED) |
|
||
| 0x13 | core escape | | calli, etc. (calli CONFIRMED) |
|
||
| 0x14/15 | btne | imm/reg | 0x15 CONFIRMED |
|
||
| 0x16/17 | bte | imm/reg | 0x17 CONFIRMED |
|
||
| 0x18/19 | pfld.{l,d,q} | | pipelined FP load |
|
||
| 0x1a | br | | CTRL (CONFIRMED) |
|
||
| 0x1b | call | | CTRL (CONFIRMED) |
|
||
| 0x1c | bc | | branch on CC (CONFIRMED) |
|
||
| 0x1d | bc.t | | + taken hint (CONFIRMED) |
|
||
| 0x1e | bnc | | branch on !CC (CONFIRMED) |
|
||
| 0x1f | bnc.t | | + taken hint (CONFIRMED) |
|
||
| 0x20/21 | addu | imm/reg | |
|
||
| 0x22/23 | subu | imm/reg | |
|
||
| 0x24/25 | adds | reg/imm | CONFIRMED |
|
||
| 0x26/27 | subs | reg/imm | CONFIRMED |
|
||
| 0x28/29 | shl | | shift left |
|
||
| 0x2a/2b | shr | | shift right |
|
||
| 0x2c | shrd | | |
|
||
| 0x2d | bla | | |
|
||
| 0x2e/2f | shra | | 0x2f CONFIRMED |
|
||
| 0x30/31 | and | reg/imm | |
|
||
| 0x32/33 | andh | | high half |
|
||
| 0x34/35 | andnot | | |
|
||
| 0x36/37 | andnoth | | |
|
||
| 0x38/39 | or | | |
|
||
| 0x3a/3b | orh | | 0x3b CONFIRMED |
|
||
| 0x3c/3d | xor | | 0x3c CONFIRMED |
|
||
| 0x3e/3f | xorh | | |
|
||
|
||
Loads/stores `ld.{b,s,l}` / `st.{b,s,l}` sit in the low opcodes (0x00–0x07);
|
||
exact split (size/sign bits) to be pinned when the full decoder byte-exactly
|
||
reproduces the aligned pairs. Pseudo-ops seen in source: `mov` (= `or`/`shl`
|
||
with r0), `nop`, `fnop`.
|
||
|
||
## Tools
|
||
- `coff860.py` — COFF reader (symbols/sections).
|
||
- `derive860.py` — the .S↔.O aligner that produced/validates the above.
|