Dumpbin for S3 stuff.
S3 has a series of SVGA graphics cards, of which the Trio64 is the most common, having had a very significant market share in the pre-3D era. I don't have 86c8xx or 86c9xx, nor ViRGE chipsets to check for compatibility, but they should work with similar code. Also, Microsoft's Microsoft Virtual PC emulates a Trio64V to a good extent, allowing you to test parts of your code without touching real hardware.
The Trio64 and compatible chipsets:
|Chip name||PCI id||chipset signature||tested|
|Trio32/64/64V+||0x5333 : 0x8811||No||Yes|
|VirtualPC Trio64||0x5333 : 0x8811||E1 - 10 - 00||Yes|
|Trio64V2/DX||0x5333 : 0x8900||No||No|
|Trio64V2 DX/GX||0x5333 : 0x8901||E1 - 01 - 04||Fail|
VGA mode, VESA mode
The Trio64 is a typical SVGA card, adding more registers to the VGA standard. Most registers are available via port 3D4/3D5. It also supports a linear framebuffer. The location of which you can determine by looking at the first BAR in the PCI configuration space. In addition, the hardware acceleration part uses a sparse register set, starting at port 42E8, and taking steps of 400 hex. This is a remnant of the ISA time. You can't change the location of these ports, yet they may interfere with other port placements if you (or the bios) are unaware of it.
Since there were many SVGA cards, S3 decided to protect several registers from accidental use. Hence, we first have to unlock them.
Write3C4(0x08, 0x06); // Unlock the PLL (clock) controls Write3D4(0x38, 0x48); // Unlock the control registers #1 Write3D4(0x39, 0xA5); // Unlock the control registers #2 Write3D4(0x33, Read3D4(0x33) & 0xAD); // Unlock compatibility mode registers
Once that is done, we have free access over the video card's operation. Like several video cards, there is a VGA mode and there is an "extended" mode. Usually with some form of intermixing. In our case, the display signal will still be formed using the VGA registers. We will still need to access the accellerator and enable "extended" mode
outportw(&H4AE8, 1); // Enable the accellerator and extended mode
This puts us in limbo. There are a few things left to do to get access to the framebuffer.
Write3D4(0x31, Read3D4(0x31) | 0x09); // Unfold VGA planes, enable memory > 265k Write3D4(0x58, Read3D4(0x58) | 0x13); // Switch to LFB mode, disable VGA memory accesses Write3D4(0x13, 80); // Set virtual width to something sensible
Now we're getting somewhere. Since we are still using the VGA registers, we're still using a valid set of timing registers. The net result is that we have a 640x400 timing left over from text mode, however the accellerator put us in 8-bit graphics mode. By loading the VGA portion with a 16-color mode, you get the corresponding 8-bit mode due to the accellerator being enabled. Note that due to changing the bitdepth, the amount of bytes on a scanline changed as well. Hence we need to update the virtual width register. For a single mode:
// For 640x???: Write3D4(0x13, 80); int pitch = horizontal_resolution * bytes_per_pixel; Write3D4(0x13, pitch / 8); // VGA thinks in characters, divide by 8
... to be continued ...
Memory Mapped I/O
Setting bit 4 in CR53 (I/O port 0x03D4, index 0x53) enables memory mapped I/O mode, where the extended registers become memory mapped like this:
- I/O port 0x8?E8 accessable via. memory address 0x000A8?E8
- I/O port 0x9?E8 accessable via. memory address 0x000A9?E8
- I/O port 0xA?E8 accessable via. memory address 0x000AA?E8
- I/O port 0xB?E8 accessable via. memory address 0x000AB?E8
These addresses are write-only
In addition, pixel data can be written to the memory area from 0x0000A0000 to 0x0000A7FFF (instead of using the "Pixel Data Transfer Registers" - I/O ports 0xE2E8 and 0xE2EA)
There have been reports that some Trio64s don't actually reconfigure themselves properly upon reboot.