Gauges: fix bank-switching (window-granularity mismatch)
The garbled top-strip render was a paging bug, not the video mode. The
pageFcnPtr in L4GAUGE.INI (C000:2616) is a red herring -- the driver's direct-
pointer path is commented out ("THIS DOES NOT WORK"); it pages via portable
VESA int 10h/4F05, which our S3 handles.
Real cause: window granularity. SVGASetPage passes the bank in granularity
units; the blit advances by pageDelta = pageSize/granularity per 64KB window
crossed. The INI's granularityInKB=4 is the Cirrus CL-GD5434's 4KB window
granularity (the pod's actual video card; the "STB Horizon+" board was
Cirrus-based). Our emulated S3 uses 64KB banks, so pageDelta=16 -> every bank
landed 16x too far -> the smear.
Fix (config only): L4GAUGE.INI [640x480x16] granularityInKB=64 (=sizeInKB, so
pageDelta=1, matching the S3's 64KB banks). Full framebuffer now pages
correctly -- 315+ frames, VDB splitter stays ON, display renders as expected
(blank between missions; user confirmed "that is the screen I expect").
ALPHA_1 is git-ignored so the INI edit isn't committed; reproduction + backup
(L4GAUGE.INI.orig) documented in GAUGE-NOTES.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+28
-25
@@ -39,33 +39,36 @@ Separately, `patch_btl4opt.py` now also neutralizes the general `Verify_Failed`
|
|||||||
debug-assertion crash (this is a `DEBUG_LEVEL 1` build); not required for the
|
debug-assertion crash (this is a `DEBUG_LEVEL 1` build); not required for the
|
||||||
heap fix but makes the debug build behave like release under emulation.
|
heap fix but makes the debug build behave like release under emulation.
|
||||||
|
|
||||||
## Open: bank-switching garbles the framebuffer
|
## Fixed: bank-switching (window-granularity mismatch)
|
||||||
|
|
||||||
The gauge framebuffer currently renders **only a top strip, garbled** — the
|
Symptom: the gauge framebuffer first rendered **only a top strip, garbled**.
|
||||||
rest black. 640×480×16 is 600 KB accessed through a 64 KB window; the game
|
Not the video mode (that works) — a paging error. 640×480×16 is 600 KB
|
||||||
pages it by **calling a hardcoded far pointer** from `L4GAUGE.INI`:
|
accessed through a 64 KB window, so the game pages video memory as it blits.
|
||||||
|
|
||||||
```
|
`L4GAUGE.INI`'s `pageFcnPtr` (`C000:2616`, the pod card's VESA `WinFuncPtr`)
|
||||||
[640x480x16]
|
is a **red herring** — the direct-pointer path is commented out in the driver
|
||||||
mode=273 ;0111h
|
(`L4SVGA16.ASM` `SVGASetPage`: *"THIS DOES NOT WORK … must use a DPMI call"*).
|
||||||
pageFcnPtr=796182 ;C000:2616 <- STB Horizon+ VESA bank-switch routine
|
The live code pages via **portable VESA int 10h / AX=4F05h**, which our S3
|
||||||
```
|
handles fine.
|
||||||
|
|
||||||
`C000:2616` is the STB card's VESA `WinFuncPtr`. On our emulated S3 that
|
The real bug was **window granularity**. `SVGASetPage` passes the bank in
|
||||||
address is not the bank-switch function, so paging fails and only the first
|
*granularity units*; the blit advances the bank by
|
||||||
bank(s) (~top 50–100 lines) render. Until this is fixed there is no complete
|
`pageDelta = pageSize / granularity` each time it crosses a 64 KB window
|
||||||
framebuffer to divide into the six displays.
|
(`L4VB16.CPP` ~3947). The INI carried `granularityInKB=4` — the **Cirrus
|
||||||
|
CL-GD5434**'s 4 KB window granularity (the pod's video card; the "STB
|
||||||
|
Horizon+" board was Cirrus-based). Our emulated **S3 uses 64 KB banks** (its
|
||||||
|
CR6A bank register selects 64 KB pages, and DOSBox-X's default VBE granularity
|
||||||
|
for S3 is 64 KB). So `pageDelta = 64/4 = 16` and every bank landed 16× too
|
||||||
|
far → the smear.
|
||||||
|
|
||||||
Fix options (next):
|
**Fix (config, no binary patch):** in `ALPHA_1/REL410/BT/GAUGE/L4GAUGE.INI`,
|
||||||
1. **Point `pageFcnPtr` at our card's real `WinFuncPtr`** — query VESA
|
`[640x480x16]` set `granularityInKB=64` (= `sizeInKB`, so `pageDelta=1`,
|
||||||
GetModeInfo (int 10h/4F01) for mode 0x111 under our S3 and put that far
|
matching the S3's 64 KB banks). Backup: `L4GAUGE.INI.orig`. After the change
|
||||||
pointer in `L4GAUGE.INI` (`special`/`pageFcnPtr` fields), or force the
|
the full framebuffer pages correctly (315+ frames, VDB splitter stays ON, no
|
||||||
game to use the queried pointer instead of the baked-in one.
|
tear-down); the display renders as expected (blank between missions; the
|
||||||
2. **Use a linear-framebuffer (LFB) mode** (VESA 2.0, mode 0x111|0x4000) so
|
active-mission instruments draw once the sim runs).
|
||||||
no bank switching is needed — requires the SVGA16 paging path to target
|
(Alternative, untried: `machine=svga_paradise`, whose DOSBox-X default VBE
|
||||||
the LFB.
|
granularity is 4 KB — would match the stock INI without editing it.)
|
||||||
3. **Route bank switches through int 10h/4F05** (portable VESA windowing)
|
|
||||||
instead of the direct pointer — a small game patch.
|
|
||||||
|
|
||||||
Once the full 640×480 buffer renders, splitting it into the six VDB display
|
Next: with the full 640×480 buffer rendering correctly, split it into the six
|
||||||
regions is straightforward (the VDB device already models the splitter).
|
VDB display regions (the VDB device already models the splitter).
|
||||||
|
|||||||
Reference in New Issue
Block a user