VGL_LABS cockpit test suite as pod-launch 'test' mode
The WC hang, root-caused in three layers (each necessary):
1. WC was rendered-samples + 100ms-capped interpolation; AWEUTIL's poll
storm (~550k port-ops/s) starved the render thread of awe_lock, so the
clock crawled ~90x slow. Fixed: free-running host-clock derivation +
a fairness gate so the render thread can always take the lock.
2. Free-running at true 44.1kHz still failed: trapped port reads cost
~30us -- MORE than one 22.7us tick -- so consecutive reads skipped
counter values, and AWEUTIL's WaitUntilWC (decoded at COM offset
0x5F42) exits only on EQUALITY with a target tick: skipped value =
missed target = 1.49s wrap penalty, or forever.
3. Advancing +1 per read still failed: WaitUntilWC reads WC TWICE per
iteration, so its equality sample saw only every 2nd value -- wrong
parity = infinite loop. Final semantics: during a poll storm the
counter advances once per FOUR reads (every value observable by all
of AWEUTIL's loop shapes; its 8192-unchanged-reads dead-clock bailout
never trips), and resyncs to true wall time after any 50ms idle gap.
Result: the full stock TEST.BAT (DIAGNOSE + AWEUTIL /S on both cards)
completes in seconds.
Also: pod-launch 'test' mode -> vwetest.conf (stock TEST.BAT -> TSTALL),
DOSBox window defaults to 900,600 in test mode (the DOS screen is the
suite's UI), VWE_AWE_LOG gains storm bursts with guest cs:ip + caller and
rare-read tracing (the instrumentation that cracked this).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Device raycast/scene parser (vpxlog.cpp):
- Connection lists: accumulate the WHOLE batch before slicing (records
straddling burst boundaries were dropped + misaligned the rest), do
not wipe polys per batch header (floor ships tri batch + quad batch;
only the last survived), keep every loop index (closing-dup drop
halved each quad). Together these were the "holey ground" the
range-finder fell through.
- Own-mech exclusion by minimum pick range (15) instead of the
dcs_parent ancestry walk: sibling link edges made the FLOOR and SKY
read as the player's subtree, so ground/sky aims never resolved.
Measured: own barrels/flash live within ~8 of the eye; sky/ground
are real pickable entities (sky.mod, afloor) -- firing into them
fires and misses, per the operator's arcade experience.
EMU8000 core (emu8k.cpp): clamp the oscillator output after cubic
interpolation. Crest overshoot on UNFILTERED voices overflowed int32
in the volume multiply and wrapped the crest negative for 1-3 samples
-- the speech/effects crackle (recorded signature: +0.7 flipping to
-0.7 at crests, random phase vs the chunk grid). Filter paths already
clamped; the bypass path now matches.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Vendored 86Box EMU8000 core (GPL-2, emu8k.cpp/.h + shim) plus vweawe.cpp:
two cards at the production addresses (0x620/0x640 register triplets),
rear-card DSP/mixer stub at 0x240, synthesis on an autonomous render
thread with direct winmm output so sustained voices ride through
emulation-thread stalls (RIO staging retries) like the real silicon did.
WC sample-counter interpolation between render chunks keeps HMI SOS
busy-waits fast. VWE_AWE32/VWE_AWE_ROM/VWE_AWE_RAM_KB/VWE_AWE_SHIFT/
VWE_AWE_LEAD_MS/VWE_AWE_DUMP/VWE_AWE_LOG env knobs.
emulator/roms: the AWE32 1MGM GM ROM dumped from our own pod card (SF2)
plus the reconstructed raw image the emulated EMU8000 loads. The HMI
driver refuses the AUDIO*.RES SoundFont upload without it (banks declare
irom=1MGM) -- that was the root cause of the first silent runs; full
debug chain in SOUND-NOTES.md. Repo serves the pod-owner community only.
.gitignore: drop the ROM excludes and un-ignore ALPHA_1/ and sda4/
(committed separately).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>