RIO passthrough: solve analog-poll latency (core=dynamic + cycles=max)

The RIO drops comms if the analog-reply ACK is late by more than a few ms.
Empirically a slower CPU failed sooner, so the latency was dominated by how
fast the game processes the RIO packet and ACKs -- core=dynamic (recompiler)
+ cycles=max keeps the board in sync (user-confirmed). game_rio.conf passes
the real RIO through serial1=directserial realport:COM1.

With real control input the sim advances and then faults (null-ptr deref at
BTL4OPT.EXE CODE+0x123B) -- downstream of the minimal test.egg not setting the
arena objectpath, so VIDEO/GEO/ARENA/thr_tshd.bgf isn't found. That is content
config, separate from the now-working VPX protocol / renderer / RIO. Details
in RIO-NOTES.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-03 15:08:39 -05:00
co-authored by Claude Opus 4.8
parent 57524d4a68
commit 833fe85d63
2 changed files with 104 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
# 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/<ARENA>` subdir). That is
content/mission configuration, separate from the VPX protocol, the renderer,
and the RIO — all of which now work.
+32
View File
@@ -0,0 +1,32 @@
[sdl]
output=opengl
[dosbox]
memsize=32
machine=svga_s3
[cpu]
# The RIO drops comms if an ACK is late by more than a few ms. Empirically
# (2026-07-03) a SLOWER CPU makes it fail SOONER -> the ACK latency is
# dominated by how fast the game processes the RIO packet and replies, so we
# run the CPU as fast as possible:
# - core=dynamic: recompiler, many x faster than the 'normal' interpreter.
# - cycles=max: full host speed.
core=dynamic
cputype=pentium
cycles=max
# RIO cockpit controls on COM1 (Phase 5 passthrough), plasma COM2 later.
[serial]
serial1=directserial realport:COM1
serial2=disabled
[autoexec]
mount c "C:\VWE\TeslaRel410\ALPHA_1"
c:
cd \REL410\BT
set VIDEOFORMAT=svga
set BLASTER=A220 I5 D1 H5 P330 T6
set TEMP=c:\
call setenv.bat r s n n
32rtm.exe -x
btl4opt.exe -egg test.egg
32rtm.exe -u
echo ALPHA1-RUN-DONE
pause