# RIO cockpit controls — passthrough tuning (Phase 5+) The RIO (Remote Input/Output) is the cockpit control board on **COM1** (the plasma display is COM2, handled later). DOSBox-X talks to a real RIO through `serial1=directserial realport:COM1` (`game_rio.conf`). On this host the RIO is a **Prolific USB-to-Serial adapter enumerated as COM1**. ## The analog-poll latency problem (solved) The initial RIO *check* request tolerates latency and passed easily. But the runtime control loop ([L4CTRL.CPP:1145](../CODE/RP/MUNGA_L4/L4CTRL.CPP)) sends an **analog request** every cycle and, if the reply doesn't return inside its window, logs `LBE4ControlsManager::Execute, lost RIO analog request` and re-requests. The board itself refuses/drops comms if the ACK is late by more than a few milliseconds — a hard real-time deadline. Empirical result (2026-07-03): a **slower** CPU made the RIO fail **sooner**. So the dominant latency was how fast the game processes the RIO packet and emits the ACK, not the serial wiring. The fix: ``` [cpu] core=dynamic ; recompiler — many x faster than the 'normal' interpreter cputype=pentium cycles=max ; full host speed ``` With `core=dynamic + cycles=max` the RIO **stays in sync** (the user confirmed "the rio behaved"). Notes: - `cycles=fixed 20000` / `150000` and `core=normal` were all too slow — the RIO dropped comms, faster at lower speeds. - The DOSBox-X serial path is already low-latency on **transmit** (`directserial.cpp` `transmitByte` calls `SERIAL_sendchar` immediately). The one remaining emulator-side latency is the **1 ms receive poll** (`directserial.cpp:68`), reducible to ~0.25 ms if a future board needs it. - Prolific PL2303 has no adjustable `LatencyTimer` registry value (unlike FTDI); an FTDI adapter set to 1 ms latency would be the lowest-latency host option if ever needed. ## Next wall: mission content (a game-data issue, not protocol/RIO) With the RIO feeding real input, the simulation advances — and then the game faults: ``` 32loader runtime error: Unhandled exception Exception 0E at 00FF:0040223B Module 'BTL4OPT.EXE' section 'CODE' offset 0000123B [..] 8B 4D 0C (mov ecx,[ebp+0C]) 8B 11 (mov edx,[ecx]) ECX=2 The instruction referenced illegal address 00000002 ``` A near-null pointer (`2`) dereference: a function got `2` where an object pointer was expected. This is downstream of the failed content load logged just before it: ``` Entity -1:63 class:42 couldn't figure out how to MakeEntityRenderables L4VIDEO.cpp couldn't load object thr_tshd.bgf ``` `thr_tshd.bgf` exists in `VIDEO/GEO/ARENA/` and `VIDEO/GEO/POLAR/`, but not the top `VIDEO/GEO/`. The game builds its object search path from **`objectpath` entries in the mission notation file** ([L4VIDEO.CPP:1852](../CODE/RP/MUNGA_L4/L4VIDEO.CPP)), i.e. from the `.egg`. The shipped `test.egg` is only mission parameters and does not set up the arena object path, so arena-specific objects aren't found; the entity gets a broken renderable and the sim eventually dereferences it. **To progress past this needs a real mission/arena `.egg`** (or an object path manually pointed at the selected arena's `VIDEO/GEO/` subdir). That is content/mission configuration, separate from the VPX protocol, the renderer, and the RIO — all of which now work.