Conversation
|
Based |
|
@CE1CECL This needs updated to current codebase |
|
was that formatted using (Also, you should be using clang-format, not clang-format-16) |
It was with |
|
I dunno, but yeah, that's not our code style, also the clang-format off markers got removed. At this point, I advise starting again, but from our current code base, this currently doesn't compile, and even headers are reordered. |
03fe2bf to
e18b8f9
Compare
Signed-off-by: Christopher Lentocha <christopherericlentocha@gmail.com>
|
Ok, I ended up redoing the entire file from scratch, due to compiler errors and it was too hard to diff from the original commit by this point, while undoing the ordering of headers fixed it, I had to take the time to do it. |
There was a problem hiding this comment.
Pull request overview
This PR adds initial support for VirtualBox's legacy VBoxVGA emulation to 86Box by extending the existing Bochs VBE SVGA driver. The implementation introduces VirtualBox-specific VBE Display Interface (VBE_DISPI) IDs and a new configuration register interface (VBE_DISPI_INDEX_CFG) that allows guest software to query device capabilities such as VRAM size and 3D support.
Key changes include:
- Addition of VirtualBox-specific VBE_DISPI ID constants (VBE_DISPI_ID_VBOX_VIDEO, VBE_DISPI_ID_HGSMI, VBE_DISPI_ID_ANYX, VBE_DISPI_ID_CFG) for device identification
- Implementation of a configuration interface register (VBE_DISPI_INDEX_CFG) with read handlers for querying version, VRAM size, 3D support, and VMSVGA capabilities
- Expansion of memory configuration options from 4-16 MB to 1-512 MB to match VirtualBox's flexibility
- Extensive code reformatting to improve consistency and readability
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ret = 0x000f; | ||
| break; | ||
| case VBE_DISPI_INDEX_CFG: | ||
| switch (dev->vbe_regs[dev->vbe_index] & 0x1000) { |
There was a problem hiding this comment.
The mask 0x1000 is incorrect for matching VBE_DISPI_CFG_ID values. The VBE_DISPI_CFG_ID constants range from 0x0000 to 0x0004, so masking with 0x1000 will always result in 0x0000 or 0x1000, never matching cases VBE_DISPI_CFG_ID_VRAM_SIZE (0x0001), VBE_DISPI_CFG_ID_3D (0x0002), VBE_DISPI_CFG_ID_VMSVGA (0x0003), or VBE_DISPI_CFG_ID_VMSVGA_DX (0x0004).
The mask should likely be 0xFFFF or a value that preserves the lower bits. Looking at VirtualBox's implementation, this should read the value without masking, or mask with 0xFFFF to get the full 16-bit value.
| switch (dev->vbe_regs[dev->vbe_index] & 0x1000) { | |
| switch (dev->vbe_regs[dev->vbe_index] & 0xFFFF) { |
There was a problem hiding this comment.
This 0x1000 comes from VBE_DISPI_CFG_MASK_ID as is defined here in the VBox source. It isn't correct, either way, it should be 0x0FFF (I got 0x1000 from
#define VBE_DISPI_CFG_MASK_SUPPORT 0x1000 /* Query whether the identifier is supported. */
By mistake)
| ret = 1; | ||
| break; | ||
| case VBE_DISPI_CFG_ID_VRAM_SIZE: | ||
| ret = dev->vram_size; |
There was a problem hiding this comment.
The return value should be cast to uint16_t or the function should handle potential overflow. The dev->vram_size is a uint32_t (can be up to 512 MB based on config options), but ret is a uint16_t. This will truncate the value, returning incorrect VRAM size information.
For example, 512 MB (0x20000000) truncated to uint16_t becomes 0x0000. The correct approach would be to either:
- Return the full 32-bit value if the protocol supports it, or
- Return VRAM size in a different unit (e.g., MB or 64K blocks) that fits in 16 bits
| ret = dev->vram_size; | |
| ret = dev->vram_size >> 16; |
There was a problem hiding this comment.
VBox Doesn't do this in this register.
There was a problem hiding this comment.
Then either VBox has a bug or there's some other difference going on here.
There was a problem hiding this comment.
VirtualBox does VRAM size return in the dword handler, so you need an inl() handler in 86Box - 86Box uses separate handlers for byte, word, and dword.
There was a problem hiding this comment.
Indeed I did overlook what Copilot said before,
ret in 86Box is uint16_t, while val in VBox is uint32_t
Both of the ->vram_size in both of VBox & 86Box are both uint32_t
Will fix as soon as I can.
| default: | ||
| break; | ||
| case VBE_DISPI_INDEX_ID: | ||
| if ((val == VBE_DISPI_ID0) || (val == VBE_DISPI_ID1) || (val == VBE_DISPI_ID2) || (val == VBE_DISPI_ID3) || (val == VBE_DISPI_ID4) || (val == VBE_DISPI_ID_VBOX_VIDEO) || (val == VBE_DISPI_ID_ANYX) || (val == VBE_DISPI_ID_CFG)) |
There was a problem hiding this comment.
The VBE_DISPI_ID_HGSMI (0xBE01) constant is defined at line 77 but is missing from the ID validation check. The condition checks for VBE_DISPI_ID_VBOX_VIDEO (0xBE00), VBE_DISPI_ID_ANYX (0xBE02), and VBE_DISPI_ID_CFG (0xBE03), but omits VBE_DISPI_ID_HGSMI which is part of the VirtualBox VGA device ID sequence.
Add || (val == VBE_DISPI_ID_HGSMI) to the condition to allow this ID to be set.
| if ((val == VBE_DISPI_ID0) || (val == VBE_DISPI_ID1) || (val == VBE_DISPI_ID2) || (val == VBE_DISPI_ID3) || (val == VBE_DISPI_ID4) || (val == VBE_DISPI_ID_VBOX_VIDEO) || (val == VBE_DISPI_ID_ANYX) || (val == VBE_DISPI_ID_CFG)) | |
| if ((val == VBE_DISPI_ID0) || (val == VBE_DISPI_ID1) || (val == VBE_DISPI_ID2) || (val == VBE_DISPI_ID3) || (val == VBE_DISPI_ID4) || (val == VBE_DISPI_ID_VBOX_VIDEO) || (val == VBE_DISPI_ID_HGSMI) || (val == VBE_DISPI_ID_ANYX) || (val == VBE_DISPI_ID_CFG)) |
There was a problem hiding this comment.
Not implemented, adding it for XP makes it BSOD.
| (val == VBE_DISPI_ID4)) | ||
| else if ((addr == 0x1cf) || (addr == 0x1d0)) | ||
| switch (dev->vbe_index) { | ||
| default: |
There was a problem hiding this comment.
The VBE_DISPI_INDEX_CFG register needs a write handler to store the configuration ID value. Currently, writes to this register fall through to the default case which does nothing. The guest driver writes the config ID (e.g., VBE_DISPI_CFG_ID_VRAM_SIZE) to this register, then reads it back to get the corresponding value.
Add a case handler:
case VBE_DISPI_INDEX_CFG:
dev->vbe_regs[dev->vbe_index] = val;
break;There was a problem hiding this comment.
Fixed it by adding all registers to the write list:
default:
dev->vbe_regs[dev->vbe_index] = val;
break;
| #define CVT_MIN_VSYNC_BP 550.0 | ||
|
|
||
| /* 3) Nominal HSync width (% of line period) - default 8 */ | ||
| /* 3) Nominal HSync width (% of line period) - default 8 */ |
There was a problem hiding this comment.
[nitpick] These comments have extra indentation that is inconsistent with the rest of the code. The comments should be aligned with the code at the same level (no leading spaces before the /*). This appears to be a formatting error introduced during the refactor.
| /* 3) Nominal HSync width (% of line period) - default 8 */ | |
| /* 3) Nominal HSync width (% of line period) - default 8 */ |
| ret = (dev->id5_val == VBE_DISPI_ID5) ? 0x11 : 0xbe; | ||
| break; | ||
| case 0x04: | ||
| ret = (dev->pci_conf_status & 0b11100011) | 0x80; |
There was a problem hiding this comment.
[nitpick] Binary literal 0b11100011 should be written as 0xE3 for consistency. Binary literals are not commonly used in this codebase, and using hexadecimal notation is more conventional for bit masks in hardware emulation code.
| ret = (dev->pci_conf_status & 0b11100011) | 0x80; | |
| ret = (dev->pci_conf_status & 0xE3) | 0x80; |
| #define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 | ||
| #define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ | ||
| CVT_J_FACTOR | ||
| #define CVT_M_PRIME CVT_M_FACTOR *CVT_K_FACTOR / 256 |
There was a problem hiding this comment.
[nitpick] Missing space around the * operator. Should be CVT_M_FACTOR * CVT_K_FACTOR / 256 for consistency with the spacing in the line below and general C style conventions.
| #define CVT_M_PRIME CVT_M_FACTOR *CVT_K_FACTOR / 256 | |
| #define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 |
Signed-off-by: Christopher Lentocha <christopherericlentocha@gmail.com>
|
What's the current status of the code? |


Summary
This Adds support for VirtualBox's older VGA Card that used to be emulated with 3D support until v6.1 of VirtualBox
Currently the code is a clang-format-16 mess, because this PR was actually started about a year ago by myself.(Update: 12/07/2025: I redid the whole thing to do what must be done to work in 86Box's current state, the rewrite from VBox's Code wasn't needed, and broke Bochs's version more than anything)As of 09-17-2025, VBox Additions MUST be older than 4.0.0 due to SSE[?] not implemented yet.
VBoxGuestAdditions_3.2.28.iso work the best!
Checklist
References
This is the commit & file I used the most which helped me out with this a lot.