Commit Graph
6 Commits
Author SHA1 Message Date
CydandClaude Opus 4.8 6991b68685 emu_main: IGC drain-wait hook (0xf0421510): firmware polls [r16] until the rasterizer consumes the region queue; we consume instantly
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 16:21:01 -05:00
CydandClaude Opus 4.8 4f143e3a26 i860 emu: EXACT pipelined FP model (MAME-validated) -- N-R divide passes
unhooked; draw_scene #1 runs with 41K IGC board accesses

The functional pipe model is replaced with exact i860 semantics, validated
against MAME's i860 core (src_opers[] and insn_dualop/insn_fadd_sub verbatim):

- Precision bits: SOURCE = bit8, RESULT = bit7 (swapped from our old reading;
  .ds is invalid except famov). For DUAL ops: sp = multiplier source prec,
  rp = adder source prec AND all results.
- Dual ops (sub 0x00-0x1f): bit10 selects PFAM (fdest <- A-pipe retire) vs
  PFMAM (fdest <- M-pipe retire) -- NOT "pipelined". FLAGM operands (the
  A-pipe entries in the DPC table) read the M-pipe in the PFMAM family.
  T-loads on DPC 2,3,6,7,8,0xb,0xc; K-loads on DPC 1,3,5,7 (from fsrc1 at
  mul precision; T from the M-pipe last stage).
- fdest BYPASS: pipelined ops whose source register equals fdest read the
  retiring pipe value instead of the stale register (dual mul: op2 only;
  dual add + scalar pipelined fadd/fmul: both operands).
- Pipe stages carry (value, result-precision); push rounds to single when
  rp=0 (exact magic-constant float->int bit games); retire encodes with the
  pusher's precision. Adder = 3 stages; multiplier = 2 (double) / 3 (single);
  pfld = 3-stage load pipe; graphics fiadd/fisub = 1-stage pipe, 64-bit .dd.

ACCEPTANCE: (1) the firmware's own Newton-Raphson integer divide now computes
16/16 = 1 through the pipes -- the intdiv hook is retired (authentic
execution); (2) draw_scene #1 from the snapshot executes real render phases:
coefficient fld.d bursts, 0x800-byte queue-page initialization, tile enqueue,
and the first region flush -- 40,959 IGC/board MMIO accesses (previously 0).
Frame still running at the profiling time budget (~240M steps in).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 15:40:29 -05:00
CydandClaude Opus 4.8 58b9dcda2f emu_main: fix __init__ split by the intdiv-hook edit (self.heap was unreachable)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 14:01:41 -05:00
CydandClaude Opus 4.8 abd908a4e5 emu_main: hook the runtime integer-divide (0xf042ee00, r22=r22/r23) with exact host division -- the compiled Newton-Raphson needs exact dual-op pipe timing; geometry stream now consumes frames correctly (replay passes cmd 151 blocker, 387+ commands)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 14:00:44 -05:00
CydandClaude Opus 4.8 d9cfd74070 i860 emu: pipelined FP unit + dual-ops, adds CC sign rule, flush op;
version-matched capfw7 replay BUILDS THE SCENE

- Pipelined FP model: 3-stage adder / 2-stage(double) multiplier pipes with
  KR/KI/T registers; pfadd/pfsub/pfmul honor the P-bit; PFAM(0x00-0x0f)/
  PFSM(0x10-0x1f) dual-operations implemented from the validated mnemonic
  grammar (r2pt, ra1p2, m12apm, ...: M-unit/A-unit routing + K/T loading).
  Survives the capture build's Newton-Raphson boot math.
- adds CC = result-negative (sign rule); addu stays carry. Fixes printf's
  pad-to-width loops and the exit-walk's empty-table branch.
- op 0x0d = flush (cache-line flush, store-format split offset, bit0
  auto-increment): boot cache-flush loops.
- fix/ftrunc: NaN/inf/out-of-range -> IEEE indefinite instead of raising.
- emu_main: per-build address maps (sda4 + capfw7); capfw7 map fully derived
  (main 0xf0403f80, remote_velocirender 0xf040cee0, dN_receive 0xf04024c0,
  velocirender_init 0xf040c5d8, do_init 0xf0409440, reply 0xf0409320,
  alloc core 0xf042c628, v2p 0xf042c300, locks 0xf0423360/0xf04233b8).
  The 860-boot preamble is skipped for capfw7 (the monitor's job -- the app
  build rejects those actions); the capture build dispatches 42 actions,
  explaining the unknown actions 29/42 in cap7.
- run_to_draw: version-matched marathon from the TRUE ENTRY 0xf0400000 with
  the boot handshake ([0xfffff728]) satisfied -- crt0/pools/main are all the
  firmware's own startup, eliminating the seed-slot guesswork.

STATE: authentic boot + init (reply=4) + scene build running: 152 commands
(31 create, 59 flush, dcs_link, list_add, texmaps) processed and replied
before the time cap. First draw_scene sits ~1400 commands ahead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 13:20:35 -05:00
CydandClaude Opus 4.8 a688cc1c30 i860 emu: ISA round 2 (ground-truth encodings) + authentic-main runner; firmware
processes the full wire boot incl. the downloaded PAZ/sfx module

ISA fixes, all derived from the toolchain's own .S<->.O pairs (AS860.ZIP:
OPTFLOAT/TRISTRIP/ZBUF32, plus DNC.O) and the firmware's linked COFF header:

- DATA_BASE = 0x1000 DEFINITIVE: VREND.MNG carries its original COFF header in
  the file tail (.data vaddr 0x1000, .bss 0x1f940, entry 0xf0400000).
- Integer loads: even opcodes are register-indexed (EA = src2 + src1); op 4/5
  size flag = instr bit0 (0 = ld.s 16-bit, 1 = ld.l 32-bit); ld.b/ld.s
  sign-extend.
- Integer stores: st.s/st.l selected by offset bit0, same split-offset rule.
- FP loads/stores: FP register lives in the DEST field for both fld and fst
  (fst does NOT use the integer split-store encoding); flag bits: bit0 =
  auto-increment (base <- EA), bit1 1=.l/0=.d, bit2 = .q; .d/.q span register
  pairs/quads. ~450 fld.d + ~300 fst.d were previously read/written 32-bit.
- bla (op 0x2d, was misdecoded as shrd): branch-on-LCC-and-add with the
  sign-dependent LCC rule (src1<0 -> signed sum >= 0), so spent countdown
  loops terminate. 335 bla instructions in the firmware.
- CORE ESCAPE (op 0x13): sub-op 1 = lock, 2 = calli, 7 = unlock. Previously
  everything decoded as calli, so every spinlock acquire jumped to address 0 --
  this was the phantom "exit stub" behind most earlier derails.
- f2b: IEEE overflow -> +/-inf instead of raising.

emu_main.py (new): runs the firmware's OWN main() (0xf0403f10) and feeds real
wire captures through a hooked dN_receive, so init/do_init/dispatch/handlers
all execute authentically. Provides the transputer-monitor environment
(processor id, DRAM region descriptors in the shared control block, sbrk/
shared-block seed slots) and hooks only the link primitives (bla busy-wait,
dN_mynode/dN_nodes/dN_receive/dN_send, putchar path, spinlocks, page allocator
+ virt->phys translator pending Tier-2 VRENDMON).

KEY DISCOVERY: the capture's args860/code860/data860/bss860 preamble is the
host DOWNLOADING an additional i860 module (the PAZ/sfx renderer layer, banner
"i860 50MHz") which installs the runtime handler tables and system objects.
Feeding it through the firmware's own handlers, the module loads and makes the
first IGC board-register writes. State: 834+ wire commands processed (module
download + init + create); first draw_scene sits at command 1568.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:26:10 -05:00