Files
TeslaRel410/emulator/PHASE2-PROGRESS.md
T
CydandClaude Fable 5 e13575d3ac Phase 2: FIFO transport working + RIO validated on real hardware
RIO (Phase 5) validated with real hardware: with a physical RIO on
COM1 and serial1=directserial realport:COM1, the game's 1996 RIO
driver talks to the board — the 'RIO never came back' error is gone
and expected activity was seen on the RIO board.

VPX FIFO fast path decoded (OUTSW.ASM + capture): after i860 boot the
render protocol pumps 16-bit words to a FIFO data port seen as
0x154/0x155 byte writes, payload starting with the 4-byte action. The
device now extracts FIFO message actions (confirmed vr_init=0 with the
args string, vr_create=1 with node type 0x2D) and echoes replies with
handler-specific overrides from board source VR_REMOT.C (init/statistics
reply action = 1).

Blocked on one unknown: velocirender_sync checks the init reply against
a constant that is neither 0 nor 1, so the Rel 4.10 board differs from
the DPL3 dev source. Needs the Rel 4.10 LIBDPL source or disassembly of
BTL4OPT.EXE at the format string (file offset 0x107772). Device has a
VPX_INIT_REPLY experiment hook for candidate values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 23:41:49 -05:00

7.0 KiB
Raw Blame History

Phase 2 — Boot Protocol Emulation: Progress

Status: boot handshake + i860 download + FIFO transport solved; blocked on one unknown constant in velocirender_sync. Phase 5 (RIO) validated on real hardware.

Update 2 (2026-07-02): FIFO transport working; RIO validated

  • Phase 5 — RIO passthrough validated with real hardware. A physical RIO was attached to the host's COM1 (Prolific USB-serial). With serial1=directserial realport:COM1 (see rio.conf) and L4CONTROLS=RIO, the game's 1996 RIO driver (L4RIO.CPP, 9600 baud) talks to the real board: the RIO never came back from check request? error disappears, and the expected activity was observed on the RIO board. The cockpit control path works end-to-end, unmodified, through DOSBox-X serial passthrough.

  • FIFO fast path decoded and implemented (send side). The board is dual-register: the render protocol switches to a FIFO channel after the i860 boots. From OUTSW.ASM + the capture: each message writes an outsw tag byte to outputData, then pumps the payload as 16-bit words to the FIFO data port, which DOSBox-X sees as byte writes to 0x154 (low) / 0x155 (high). The payload begins with the 4-byte action. The device now parses this and extracts the action of each FIFO message (confirmed: vr_init=0 with the /device~… args string, then vr_create=1 with node-type 0x2D).

  • Handler-specific reply actions (from board source). velocirender_receive reads replies on the slow path (already served); the device echoes the sent action, with per-handler exceptions found in VRENDER/VR_REMOT.C: velocirender_init and velocirender_statistics do *data = 1, so their reply action is 1, not the sent action. The device implements this map.

  • Remaining blocker — one constant. The game reaches velocirender_sync, which sends vr_init (action 0) and checks the reply action against a specific value that is neither 0 (echo) nor 1 (the DPL3 board's init return) — so the Rel 4.10 board returns a different value than the DPL3 dev-tree source. Determining it needs the Rel 4.10 LIBDPL/VRENDER source or a disassembly of BTL4OPT.EXE around the format string at file offset 0x107772 ("unexpected action %d returned in velocirender_sync"). The device has an experiment hook (VPX_INIT_REPLY=<n>) to try candidate values.

Original Update 1 analysis (handshake + i860 download) follows.


Status: substantial progress; boot handshake + i860 download solved; render transport (FIFO fast path) identified as the remaining sub-protocol.

The VPX device (vpx-device/vpxlog.cpp, env VPX_RESPOND=1) now drives the production BattleTech v4.10 (ALPHA_1 image) through the entire transputer/i860 boot sequence — far past the Phase 1 wall — and reaches the live renderer protocol. Each layer below was solved by reading the normative sources on the drive (sda4/DPL3/VR_COMMS.C, DPL_HOST.C, VRENDER/VR_REMOT.C, LINKIO.C, OUTSW.ASM) and iterating against the running binary.

Solved

1. iserver boot handshake

After the monitor (VRENDMON.BTL) download, boot_xputer() calls startup_handshake(), which does 3 iserver transactions (Phil's comment in VR_COMMS.C: "the C run-time boots up and does 3 iserver transactions"). Each is a receive_protocol() read of a 4-byte little-endian length/route word (bit31=iserver, low16=payload length) + payload, answered by iserver_action(); only success is checked. The device feeds 3 well-formed iserver "version" requests (tag 42, no request-content dependency) and the handshake completes.

2. i860 renderer download

boot_860() then streams the i860 image (VRNOSTEX.MNG) as framed renderer messages on the slow byte path: vr_860args (21), vr_860code (18, ×118), vr_860data (19, ×37), vr_860bss (20, ×9). The device parses the outbound frame stream ([length_word:4][action:4][data], nb = length_word & 0xffff) and absorbs them, staying byte-aligned throughout.

3. The echo-action reply model (validated against board source)

Renderer request/reply calls (velocirender_create/delete/flush/sync in DPL_HOST.C) send an action and require the same action echoed back. The board side confirms this exactly: VRENDER/VR_REMOT.C remote_velocirender() replies with its data buffer whose first word is still the received action (reply()dN_send). The device tracks the last outbound action and echoes it; this is the general model for every render call, not a one-off.

The remaining sub-protocol: the FIFO fast path

After the i860 boots, the host stops using the slow byte path and switches to a FIFO fast path for the render protocol. This is why the current build still stops at velocirender_sync — the device only implements the slow path (0x1500x153).

Discovered mechanics (from the capture + OUTSW.ASM + LINKIO.C):

  • The VPX board is dual-register: beyond the C012 slow link (0x150 inputData / 0x151 outputData / 0x152 inputStatus / 0x153 outputStatus), there is a FIFO data port reached at 0x154/0x155 (observed) and an ok_to_fifo status at 0x160.
  • send_FIFO_protocol() / velocirender_transmit() (when use_fifo) call the assembly outsw() (OUTSW.ASM): it writes a 0x40 "use fifo" tag byte, then add dx,3 and REP OUTSW — pumping the message as 16-bit words into the FIFO port. In the capture these land as alternating byte writes to 0x154/0x155 and decode to the init/args string (e.g. /device~0x150~/video~svga~…).
  • The host switches to use_fifo once the board asserts ok_to_fifo (fifo_ok_status() reads 0x160 bit0); see the commented wait loop in boot_xputer().

Next step (concrete)

Extend the device to implement the FIFO transport:

  1. Answer ok_to_fifo (0x160 bit0) at the right time so the host enables use_fifo.
  2. Accept FIFO writes: the 0x40 tag, then word-stream data at the FIFO port (0x154/0x155). Reassemble into [length_word][action][data] messages (same framing as the slow path).
  3. Serve FIFO reads for replies: velocirender_receive() in FIFO mode reads the reply (length_word + [action][node]) from the FIFO/status ports. Echo the sent action (model already validated), returning meaningful node handles for vr_create so later vr_delete/geometry ops have valid remotes.
  4. Then the render loop (vr_draw_scene + frame-ack, velocirender_frameack()) — the Phase 3 boundary, where geometry/material/texture commands can be decoded into the OpenGL backend (formats already implemented in restoration/divformats.py).

Reproduce

set VPXLOG=C:\VWE\TeslaRel410\emulator\vpxresp.txt
set VPX_RESPOND=1
emulator\src\src\dosbox-x.exe -conf emulator\respond.conf

Console progression now: BattleTech v4.10BTL4Application → RIO check → (handshake, i860 download succeed) → unexpected action N in velocirender_sync (the FIFO-path render handshake, the next target). The log's # note lines trace the device's decisions (handshake requests fed, frames parsed, actions echoed, mystery ports resolved to 0x154/0x155).