| Previous | Table of Contents | Next |
After its PS/2 product line introduction, the IBM VGA BIOS and display controller quickly became PC graphics de facto standards. Subsequently, numerous OEM VGA products appeared, each providing IBM VGA BIOS and/or register compatibility by preserving the original VGA I/O mapped registers, CPU address space video buffer location, DAC register I/O address locations and functions, etc. For product differentiation, these products also often implemented VGA extensions, including higher screen resolutions and enhanced color support. However, OEM vendors used different hardware approaches for these extensions and exploiting these various display controller extensions proved formidable.
Typically, only after successful video board identification could software exploit specific VGA extensions. Because no standard mechanism existed to identify video boards, software developers usually resorted to arcane, oblique tests such as reading and testing registers found at unique OEM-specified I/O addresses. Because foolproof testing proved technically difficult, if not impossible, for most application developers, they often abandoned VGA extension exploitation, resorting to lowest-common-denominator VGA services. Consequently, end users purchased Super VGA display controller cards and software that exhibited no capabilities beyond standard VGA capabilities.
VESAs VBE standard directly addresses this situation. It provides a single uniform software interface to Super VGA display controllers even when they have vastly different extension designs. Hiding these hardware differences allows software to exploit varying VGA extensions using a well-defined, single, uniform approach. Meanwhile, for OEM vendors, the VBE preserves maximum standard VGA compatibility and minimizes existing VGA BIOS changes and allows RAM as well as ROM-based implementations.
Specifically, the VBE addresses:
VBE functions return system level information as well as specific video mode details.
VBE provides several functions to exploit varying Super VGA hardware implementations.
Finally, VBE is fully upwards compatible so specific VBE version features are guaranteed to work in future versions. Hence, VBE provides a much needed stable video application programming interface (API).
Standard VGA video boards provide up to 256 KBytes of frame buffer memory and well-defined frame buffer access mechanisms. Several VBE modes require additional memory but compatibility necessarily restricts frame buffer memory CPU visibility to the standard VGA address range. Frame buffer bank switching provides a mechanism for CPUs to access extended frame buffer memory within standard VGA address space range constraints.
Specifically, software invokes VBE frame buffer bank switching functions to swap (map) video memory granules into the narrow VGA address range for frame buffer memory read and write operations. Software determines the precise way to accomplish this by examining the information VBE Function 0x01 (Return Super VGA Mode Information) returns. Readers not wanting to understand the precise mechanics should note the sample programs contain functions that accomplish this manipulation.
The standard CPU memory address range typically allotted to VGA display cards is 64 or 128 Kbytes, beginning at CPU memory segment 0xA000. This designated area, reserved for software VGA adapter frame buffer access operations, is referred to as the CPU video memory window. Mapping VGA frame buffer memory portions into the standard CPU video memory window using standard VGA program calls gives access to the entire standard VGAs frame buffer memory which can be up to 256 KBytes in size.
Standard VGA BIOS functions allow software to specify the frame buffer memory address range to appear in the CPU address space range for subsequent software memory read and write activities. The trick then is to swap (map) a given scan line into the CPU address space subject to display adapter hardware constraints so software can read/write all or part of the scan line as necessary. A VBE display adapter achieves this by dividing up frame buffer memory into fixed size granules. A granule contains multiple display adapter scan lines and, depending on the CPU video memory window size, a window may display more than one granule.
Different VBE display adapters may have different-sized granules, but a given adapter has only one size referred to as the window mapping function granularity. Some adapters have 4 KByte granules while others have up to 64 KByte granules. The essential concept is that VBE Function 0x05, CPU Video Memory Window Control, makes desired frame buffer memory granules appear in the CPUs 64 or 128 KByte VGA adapter address range under software control. This books sample programs only access one scan line at a time, greatly simplifying the code in exchange for performance penalties. Unfortunately, in some instances, scan lines may span two adjacent granules, requiring software bounds testing for proper scan-line access in those situations where only a scan-line portion is visible in the CPU video memory window.
VBE allows adapters to divide the CPU video memory into two separate windows referred to as Window A and Window B. When a display adapter supports two VBE windows, this guarantees two different granules can simultaneously appear within the CPUs video memory window. VBE Function 0x01 (Return Super VGA Mode Information) returns indicators for each windows CPU video memory window starting address and whether CPU software can read or write to each window.
When CPU software can only read one VBE window and write to the other, the software can copy from one window into another without repeated VBE Function 0x05 (CPU Video Memory Window Control) calls. In such instances, software repetitively reads scan-line data from one granule in one VBE window and writes scan-line data into the other VBE windows granule. Otherwise, software would swap in the read granule, read data from it into main memory, swap in the write granule, and copy the data from main memory. This constant swapping and double data movement imposes significant performance penalties.
Finally, both VBE windows always appear in different CPU video memory window areas because each VBE window has its own starting memory segment address. When software swaps a granule into a window, video controller hardware aligns the granules first byte at the windows starting segment address.
Independent of granule size differences, VBE supports three basic hardware windowing implementation types:
VBE Function 0x05 (CPU Video Memory Window Control) provides the information necessary for applications to detect the specific hardware implementation type an adapter provides and the read/write characteristics of each VBE window in dual window systems.
Standard VGA mode numbers reserve seven bit positions and range in value from 0x00 to 0x13. OEMs extend video mode range values from 0x14 to 0x7F. Because the standard VGA BIOS Function 0x00 (Set Video Mode) interprets bit 7 as a clear/dont clear video memory flag, values ranging from 0x80 to 0xFF are not available to VBE. Therefore, VBE video mode numbers are 15 bits wide, beginning at 0x0100.
This mode numbering scheme incorporates standard VGA mode numbers and OEM-defined mode numbers as VESA mode-number subsets, allowing programs to initialize regular VGA modes using VBE Function 0x02 (Set Super VGA mode).
| Bit Range | Meaning | Comment |
| D8-D0 | VBE Mode Indicator and Mode Value | D8 == 1 indicates this is a VESA defined mode
D8 == 0 indicates this is not a VBE defined mode |
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 X X X X X X X X . X X X X X X X X
| D15-D9 | Reserved | Reserved |
where D0 is the low-order bit and D15 is the high-order bit as illustrated:
VBE defines the following packed pixel modes that allow 256 maximum on-screen colors:
| VBE Packed Pixel Mode Number | Resolution (Cols x Rows) |
| 0x100 | 640x400 |
| 0x101 | 640x480 |
| 0x103 | 800x600 |
| 0x105 | 1024x768 |
| 0x107 | 1280x1024 |
VBE supports five direct color screen resolutions:
VBE defines three pixel bit assignments for each of the five resolutions, for a total of 15 different modes. This allows each resolution to potentially provide the following different numbers of simultaneous colors:
Display adapters must have enough memory to support the given modes. The pixel bit assignments for each of the three VBE defined direct color modes are:
| Total # Colors | # Rsvd Bits | # Red Bits | # Green Bits | # Blue Bits | Bit Assgt. Notation | Total Color Bits | Comment |
| 32K | 1 | 5 | 5 | 5 | (1:5:5:5) | 15 | 15-bit color |
| 64K | 0 | 5 | 6 | 5 | (5:6:5) | 16 | 16-bit color |
| 16M | 0 | 8 | 8 | 8 | (8:8:8) | 24 | 24-bit color |
The following table specifies the 15 VBE direct color modes and their resolutions and bit assignments:
| VBE Direct Color Mode Number | Resolution (Cols x Rows) | Bit Assignment | Number of Colors |
| 0x10D | 320x200 | (1:5:5:5) | 32K |
| 0x10E | 320x200 | (5:6:5) | 64K |
| 0x10F | 320x200 | (8:8:8) | 16.8M |
| 0x110 | 640x480 | (1:5:5:5) | 32K |
| 0x111 | 640x480 | (5:6:5) | 64K |
| 0x112 | 640x480 | (8:8:8) | 16.8M |
| 0x113 | 800x600 | (1:5:5:5) | 32K |
| 0x114 | 800x600 | (5:6:5) | 64K |
| 0x115 | 800x600 | (8:8:8) | 16.8M |
| 0x116 | 1024x768 | (1:5:5:5) | 32K |
| 0x117 | 1024x768 | (5:6:5) | 64K |
| 0x118 | 1024x768 | (8:8:8) | 16.8M |
| 0x119 | 1280x1024 | (1:5:5:5) | 32K |
| 0x11A | 1280x1024 | (5:6:5) | 64K |
| 0x11B | 1280x1024 | (8:8:8) | 16.8M |
Finally, VBE provides a very flexible way for software to determine other direct color operating modes by using the RedMaskSize, RedFieldPosition, GreenMaskSize, GreenFieldPosition, BlueMaskSize, and BlueFieldPosition values VBE Function 0x01 (Return Super VGA Mode Information) returns.
VBE defines several new video function calls. For maximum standard VGA BIOS compatibility, these calls are grouped under one function number. The AH register passes this number, 0x4F, to the video int 10h handler. Standard VGA BIOSs do not recognize this value and ignore these calls.
The AX register returns status information for every VBE function call. The status word format follows:
| Register Value | Value Meaning |
| AH == 0x00 | Function call successful |
| AH == 0x01 | Function call failed |
| AL == 0x4F | VBE function is supported |
| AL != 0x4F | VBE function is not supported |
Treat non-zero AH register values as general failure conditions, rather than testing for the specific 0x01 value.
This function returns Super VGA capability information by completing a 256-byte structure located at a caller specified address.
Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x00 | Return Super VGA information |
| ES:DI | ES:DI | Pointer to information structure |
| Output: | AX: VBE status value |
| Comment: | Preserves all other registers |
The information structure follows:
#define USGI unsigned int
#define USGC unsigned char
#define USGL unsigned long
struct VesaInfoBlock
{
USGC VesaSignature[4]; /* 'VESA' */
USGI VesaVersion; /* e.g. 0x0102 == 1.2 */
char far *OemStringPtr; /* who dat? */
USGC Capabilities[4];
USGI far *VideoModePtr;
USGI Total64kMemoryBlocks;
char Reserved[256]; /* more than enough space */
};
After successful completion:
VESASignature contains the characters V, E, S, and A for valid blocks.
VESAVersion specifies the VBE support level provided. The high-order byte specifies the major version number, and the low-order byte specifies the minor version number. Thus a 0x0102 value specifies VBE version 1.2.
OEMStringPtr is a far pointer to a null-terminated OEM-provided string. The string may identify the video chip, video board, memory configuration, etc. The strings format has no restrictions.
Capabilities describes what features the video adapter supports. The bit definition follows:
| Bit Position | Meaning | Comment |
| D0 | Is DAC switchable? | D0 == 1 indicates the DAC width is switchable
D0 == 0 indicates the DAC width is fixed to 6 bits per primary colorx |
| D31-D1 | Reserved | Reserved |
VideoModePtr points to a Super VGA (VESA-defined and OEM-specific) supported mode list placed within ROM or RAM. A 1 (0xFFFF) terminates the mode number list and each enumerated mode number occupies one word (16 bits). Either the list is a static ROM string, or the list is generated and placed at run time in the RAM information block (see above). Software must verify the display adapter supports given modes using VBE Function 0x01 Return Super VGA Mode Information. Some enumerated modes may not be available because of video board frame buffer memory limitations and monitor characteristics.
TotalMemory returns the display adapter frame buffer size expressed in 64 KByte blocks. Multiplying this value by 65,536 yields the frame buffer size in bytes.
This function returns information about specific Super VGA video modes, including OEM-unique, non-VESA video modes, returned by VBE Function 0x00 (Return Super VGA Information). This function returns information by completing a 256-byte maximum-size mode information structure located at a caller-specified address. To provide mode access, this function also returns additional mode information. Finally, pre-initialize the 256-byte buffer to zero before invoking Return Super VGA Mode Information.
Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x01 | Return Super VGA mode information |
| CX | Mode Value | Must be returned by VBE Function 0x00 |
| ES:DI | ES:DI | Pointer to 256-byte structure |
| Output: | AX: VBE status value |
| Comment: | Preserves all other registers |
The mode information block has the following structure:
#define USGI unsigned int
#define USGC unsigned char
#define USGL unsigned long
struct VesaModeInfoBlock
{
USGI ModeAttributes;
USGC WinAAttributes;
USGC WinBAttributes;
USGI WinGranularity;
USGI WinSize;
USGI WinASegment;
USGI WinBSegment;
void ((far *WinFuncPtr)());
USGI BytesPerScanLine;
USGI XResolution;
USGI YResolution;
USGC XCharSize;
USGC YCharSize;
USGC NumberOfPlanes;
USGC BitsPerPixel;
USGC NumberOfBanks;
USGC MemoryModel;
USGC BankSize;
USGC NumberOfImagePages;
USGC ReservedForPageFunction;
USGC RedMaskSize;
USGC RedFieldPosition;
USGC GreenMaskSize;
USGC GreenFieldPosition;
USGC BlueMaskSize;
USGC BlueFieldPosition;
USGC RsvdMaskSize;
USGC RsvdFieldPosition;
USGC DirectColorModeInfo;
char Reserved[256]; /* more than enough space */
};
ModeAttributes describes important video mode characteristics:
| Bit Position | Meaning | Values | Comment |
| D0 | Mode available in present video configuration? | 0= Mode not supported 1=Mode supported | Blocks video mode access when required hardware is not available (frame buffer memory, monitor types, etc.) |
| D1 | Reserved. | Must be set to 1. | Must be set to 1. |
| D2 | BIOS output functions availability indicator (TTY output, screen scroll, pixel output). | 0= Output functions not supported 1=Output functions supported | If D2 is 1 then the BIOS supports all standard output functions in this mode |
| D3 | Monochrome or color mode? | 0= Monochrome mode 1=Color mode | |
| D4 | Mode type? | 0= Text mode 1=Graphics mode | |
| D15-D5 | Reserved | Reserved | Reserved |
WinAAttributes and WinBAttributes describe the CPU windowing scheme characteristics, indicating whether windows exist and whether they are individually readable and writeable. The field format for both window A and window B follows:
| Bit Position | Meaning | Values | Comment |
| D0 | Window supported? | 0= Window not supported 1=Window is supported | Indicates whether a window (A or B) is available. |
| D1 | Window readable? | 0= Window not readable 1=Window is readable | Indicates whether a window (A or B) is readable. |
| D2 | Window writeable? | 0= Window not writeable 1=Window is writable | Indicates whether a window (A or B) is writeable. |
| D7-D3 | Reserved | Reserved | Reserved |
If bit D0 = 0 for both Window A and Window B (windowing not supported), assume the frame buffer memory completely resides at the standard CPU address appropriate for the modes MemoryModel.
WinGranularity specifies the smallest boundary, in KBytes, on which the window can align in video memory. The fields value is undefined when the appropriate WinAttributes field bit D0 has a zero value.
WinSize specifies the window size in KBytes.
WinASegment and WinBSegment specify CPU memory segment address window origins. When swapped in, granules align on these memory segment addresses.
WinFuncPtr specifies the CPUs video memory windowing function address. VBE Function 0x05 (CPU Video Memory Window Control) or direct function calls can invoke windowing support. Direct calls provide faster hardware paging register access than VBE function 0x05, and are intended for high performance application use. When this field has a zero value (Null), use VBE Function 0x05 to set the memory window when paging is supported.
BytesPerScanline specifies the logical scan-line length in bytes. The logical scan lines length is equal to or larger than the displayed scan line. When the logical scan line is longer than the displays scan line, software can use VBE Function 0x07 (Set/Get Display Start) to pan left and right smoothly.
XResolution and YResolution specify video graphics mode width and height in pixels per visible scan line and total visible scan lines, respectively.
XCharCellSize and YCharCellSize specify character cell dimensions in pixels.
NumberOfPlanes specifies the number of available memory planes for the mode. For standard packed pixel and direct color modes, this is 1.
BitsPerPixel specifies the total number of bits defining one pixel. For example, packed pixel 256-color graphics mode specifies 8.
NumberOfBanks indicates the number of banks holding scan-line groups. When dividing a screen scan-line number by NumberOfBanks, the remainder is the bank number containing the screen scan line and the quotient is the scan-line number within the bank. For modes that dont have scan-line banks, this field should contain one.
MemoryModel specifies the modes memory organization. MemoryModel values follow:
| Value | Value Meaning |
| 0x00 | Text mode |
| 0x01 | CGA graphics |
| 0x02 | Hercules graphics |
| 0x03 | 4-plane planar |
| 0x04 | Packed pixel |
| 0x05 | Non-chain 4, 256 color |
| 0x06 | Direct Color |
| 0x07 | YUV |
| 0x08-0x0F | VESA reserved |
| 0x10-0xFF | OEM defined |
Direct color modes should use the ModeInfoBlock MaskSize and FieldPosition fields to describe pixel formats. BitsPerPixelis always defined to be the total pixel memory size expressed in bits.
BankSize specifies the bank size in 1 KByte units. For modes that dont have scan-line banks, this field should contain zero.
NumberOfImagePages specifies the number of complete display images that simultaneously fit into the VGAs memory in this mode. The application may load more than one image into the VGAs memory if this field is non-zero, and rapidly flip the display between them.
Reserved supports future VBE extension features and always contains one in VBE 1.2.
RedMaskSize, GreenMaskSize, BlueMaskSize, and RsvdMaskSize (collectively referred to as MaskSize) define direct color pixel red, green, blue, and reserved component sizes in bits. Simple shift arithmetic using MaskSize field information provides pixel bit masks. MaskSize values for direct color (5:6:5) modes are 5, 6, 5, and 0, for the red, green, blue, and reserved fields, respectively. When MemoryModel contains the YUV value, the Y field uses the green value, the U field uses the blue value, and the V field uses the red value. The MaskSize field values are 0 for MemoryModel modes not having component field pixels.
RedFieldPosition , GreenFieldPosition, BlueFieldPosition , and RsvdFieldPosition (collectively referred to as FieldPosition) define respective color component least-significant-bit positions within direct color or YUV pixels. Color values are properly aligned with pixels by shifting component values left by component FieldPosition values. FieldPosition values for Direct Color (5:6:5) modes would be 11, 5, 0, and 0, for the red, green, blue, and reserved fields, respectively. When MemoryModel contains the YUV value, the Y field uses the green value, the U field uses the blue value, and the V field uses the red value. The FieldPosition field values are 0 for MemoryModel modes not having component field pixels.
DirectColorModeInfo describes direct color (not packed pixel) mode characteristics. Bit D0 specifies whether the DAC color ramp is fixed or programmable. If the color ramp is fixed, then it cannot be changed. If the color ramp is programmable, standard VGA DAC color registers BIOS call (AX=0x1012) loads red, green, and blue look-up tables. Bit D1 specifies whether applications can use direct color pixel Rsvd field bits or whether they are reserved, hence unusable.
| Bit Position | Meaning | Values |
| D0 | Fixed color ramp? | 0 == Color ramp is fixed Color ramp is programmable |
| D1 | Rsvd field bits usable? | 0= Rsvd field bits not usable 1=Bits in Rsvd field usable |
| D7-D2 | Reserved | Reserved |
This function initializes the video mode the BX register specifies. If the video BIOS cannot set the mode, the video BIOS leaves the video environment unchanged, returning a failure error code.
Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x02 | Set Super VGA video mode |
BX | Mode Value D0-D14=VBE Video mode D15=Clear memory flag | Only modes returned by VBE Function 0x00. If D15==0, frame buffer is cleared to zeros. If D15==1, frame buffer is not cleared. |
| Output: | AX: VBE status value |
| Comment: | Preserves all other registers |
This function returns the current video mode in BX.
Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x03 | Return current video mode |
| Output: | AX: VBE Status Value |
| BX: Current video mode | |
| Comment: | Preserves all other register |
These functions save and restore Super VGA video states and are a super-set of three standard VGA BIOS Function 0x1C (Save/Restore Video State) subfunctions. All Super VGA video states (except video memory) should be saveable/restorable by setting the requested states mask (in the CX register) to 0x000F. Software:
Save State(s) Buffer Requirement Determination Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x04 | Save/Restore Super VGA Video state request |
| DL | 0x00 | Return Save/Restore state buffer size |
| CX | Requested State(s) Save Buffer Size | D0= Save video hardware state
D1= Save/Restore video BIOS data state D2= Save/Restore video DAC state D3= Save/Restore Super VGA state |
| Output: | AX: VBE status value |
| BX: Number of 64-byte blocks to hold the state buffer | |
| Comment: | Preserves all other registers |
Save State Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x04 | Save/Restore Super VGA Video state(s) |
| DL | 0x01 | Save state(s) |
| CX | Requested State(s) To Save | D0= Save video hardware state D1= Save video BIOS data state D2= Save video DAC state D3= Save Super VGA state |
| ES:BX | Buffer Pointer |
| Output: | AX: VBE status value |
| Comment: | Preserves all other registers |
Restore State Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x04 | Save/Restore Super VGA Video state(s) |
| DL | 0x02 | Restore state(s) |
| CX | Requested State(s) to Restore | D0= Restore video hardware state
D1= Restore video BIOS data state D2= Restore video DAC state D3= Restore Super VGA state |
| ES:BX | Buffer Pointer |
| Output: | AX: VBE status value |
| Comment: | Preserves all other registers |
This function allows direct access to the hardware paging register and sets or gets the specified window position in video memory. VBE Function 0x01 (Return Super VGA Mode Information) provides window size, location, and granularity information essential to use this function properly.
For improved performance, software can access this function directly using far calls to the ModeInfoBlock WinFuncPtr address VBE Function 0x01 (Return Super VGA Mode Information) returns. When using far calls:
Select Window Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x05 | Super VGA video memory window control |
| BH | 0x00 | Select super VGA video memory window |
| BL | Window Number | 0= Window A
1= Window B |
| DX | Video Memory Window Position | Specified in window granularity units |
| Output: | AX: VBE status value |
| DX: Window position in video memory (in window granularity units) | |
| Comment: | Preserves all other registers |
Return Window Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x05 | Super VGA video memory window control |
| BH | 0x01 | Return super VGA video memory window |
| BL | Window Number | 0= Window A
1= Window B |
| DX | Video Memory Window Position | Specified in window granularity units |
| Output: | AX: VBE status value |
| DX: Window position in video memory (in window granularity units) | |
| Comment: | Preserves all other registers |
This function sets or gets the current logical scan-line length. Setting a logical video memory buffer wider than the display scan-line length allows applications to smoothly pan horizontally and possibly vertically using VBE Function 0x07 (Set/Get Display Start) which allows applications to set the starting display position at and within logical scan lines.
Set Scan Line Length Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x06 | Logical scan-line length |
| BL | 0x00 | Set scan-line length |
| CX | Desired Length | Expressed in pixels |
| Output: | AX: VBE status value |
| BX: Bytes per scan line | |
| CX: Actual pixels per scan line | |
| DX: Maximum number of scan lines |
| Comment: | Preserves all other registers |
Return Scan-Line Length Input:
| Register | Value | Comment |
| AH | 0x4 | FVBE request indicator |
| AL | 0x06 | Logical scan-line length |
| BL | 0x01 | Return scan-line length |
| Output: | AX: VBE status value |
| BX: Bytes per scan line | |
| CX: Actual pixels per scan line | |
| DX: Maximum number of scan lines | |
| Comment: | Preserves all other registers |
When VGA hardware considerations preclude setting a requested scan-line length, the next larger scan-line length that accommodates the desired scan-line length is provided, and:
Software can use VBE function 0x07 (Set/Get Display Start) to smoothly pan vertically within these available scan lines.
This function selects the pixel from the current logical page the display presents in its upper left corner. This function allows applications to pan and scroll around logical screens larger than the display screen resolution. This function allows rapid switching between different frame buffer areas for double-buffered animation effects.
Select Display Start Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x07 | Super VGA video memory window control |
| BH | 0x00 | Reserved and must be 0 |
| BL | 0x00 | Select Display Start |
| CX | Pixel Number | First displayed frame buffer scan-line pixel |
| DX | Scan Line Number | First displayed frame buffer scan line |
| Output: | AX: VBE status value |
| DX: Window position in video memory (in window granularity units) | |
| Comment: | Preserves all other registers |
Return Display Start Input:
| AH | 0x4 | FVBE request indicator |
| AL | 0x07 | Super VGA video memory window control |
| BL | 0x01 | Return Display Start |
| CX | Pixel Number | First displayed frame buffer scan-line pixel |
| DX | Scan Line Number | First displayed frame buffer scan line |
| Output: | AX: VBE status value |
| BH: 0x00 reserved and will be 0 | |
| CX: First displayed pixel in scan line | |
| DX: First displayed scan line | |
| Comment: | Preserves all other registers |
This function queries and selects the DAC width. The DAC palette width is always the standard VGA 6 bits per primary color after standard VGA or VBE Function 0x02 (Set Super VGA Mode) calls. Some DACs provide 6 bits, 8 bits, or more for primary colors.
Set DAC Width Input:
| Register | Value | Comment |
| AH | 0x4 | FVBE request indicator |
| AL | 0x08 | Set/Get DAC palette control |
| BL | 0x00 | Set DAC palette width |
| BH | DAC Width | Desired number of bits per primary color (Standard VGA = 6) |
| Output: | AX: VBE status value |
| BH: Current number of bits per primary color (Standard VGA = 6) | |
| Comment: | Preserves all other registers |
Get DAC Width Input:
| Register | Value | Comment |
| AH | 0x4F | VBE request indicator |
| AL | 0x08 | Set/Get DAC palette control |
| BL | 0x01 | Get DAC palette width |
| Output: | AX: VBE status value |
| BH: Current number of bits per primary color (Standard VGA = 6) | |
| Comment: | Preserves all other registers |
Applications can determine DAC width switching capability by querying the Capabilities fields bit D0 in the VgaInfoBlock structure VBE Function 0x00 (Return Super VGA Information) returns. If DAC switching is supported, the application can then attempt to set the DAC palette width to a desired value. If the DAC cannot support the requested width, the next lower value the DAC supports is selected. BH returns the resulting palette width.
The VESAEXAM.C program provides the logic necessary to query for, and determine the extent of, VBE support. Appendix D lists the VESA.H and PCX.H headers.
/*
Copyright (C) 1995, W. David Schwaderer
Some rights reserved - see WdsLogo() for details
Function: This program interrogates and documents VESA capabilities
for a single user-specified video mode or all available
video modes. Redirect the output to a file for hard copy.
See the text description in:
Digital Imaging in C and the World Wide Web
W. David Schwaderer
Wordware Publishing, Inc., 1997
Compiler: Borland C++ 3.1
Compile command: bcc -ml VesaExam.C
Call to programmers...
If you are interested enough to read this code, your name
probably should be in it. I will place contributing programmer's
names in source code when their suggestion(s) results in bug fixes
or program enhancements. Contributions must be new. Send written
suggestions on paper to W. David Schwaderer via Wordware Publishing,
Inc.
Complete or massive rewrites are not helpful (though possibly
warranted!). Contributions become the property of W. David
Schwaderer who reserves suggestion final disposition determination.
Thanks in advance for the consideration.
W. David Schwaderer
Version 1.0 3/15/93
Contributor Enhancement
--------------------------------
----------------------------------------------------------
Your name here... Your edited suggestion here...
Hometown, country Your edited suggestion here...
*/
#include <mem.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#define USGI unsigned int
#define USGC unsigned char
#define USGL unsigned long
#include "vesa.h"
int main(int argc, char *argv[]);
int WdsLogo(void);
int VesaNotPresent(void);
int DisplayVesaInfo(void);
int FillVesaModeBlock(struct VesaModeInfoBlock *VesaModeInfoBlockPtr,
USGI ModeNumber);
int DisplayVesaModeAttributes(USGI VesaModeAttributes);
int DisplayVesaWindowAttributes(USGC VesaWindowAttributes);
int DisplayVesaModeInfo(USGI ModeNumber, USGI VesaModesOnlyFlag);
int ExitLogo(void);
struct VesaInfoBlock VesaInfo;
USGI ModeValue;
int main(int argc, char *argv[])
{
if(VesaNotPresent())
{
printf("\nmain: VESA support not detected, exiting...");
ExitLogo();
}
printf("\nmain: VESA support detected...");
if (argc > 1)
sscanf(argv[1], "%x", &ModeValue);
DisplayVesaInfo();
WdsLogo();
printf("\nmain: Returning...\n");
return 0;
}
int WdsLogo(void)
{
printf("\n");
printf("\nCopyright (C) 1993 W. David Schwaderer, some rights reserved");
printf("\nThis program uses source code from W. David Schwaderer's");
printf("\n 'Digital Imaging in C and the World Wide Web");
printf("\n Wordware Publishing, Inc., 1997");
printf("\nW. David Schwaderer grants an unrestricted executable
program");
printf("\nuse-license for unmodified executable programs he releases.");
printf("\nNon-commercial source code use-licenses are also granted to:");
printf("\n - individuals for their non-commercial private use (enjoy!)");
printf("\n - educational institutions for teaching materials (learn!)");
printf("\nprovided the WdsLogo() function is compiled (execution not");
printf("\nrequired) without modification into derived executable");
printf("\nmodules. Other source code uses, including 'shareware',");
printf("\nare encouraged but strictly prohibited without W. David");
printf("\nSchwaderer's explicit written permission, easily obtained");
printf("\nwith appropriate book credit. Please contact David via");
printf("\Wordware Publishing, Inc. for written permission requests.");
printf("\nDeepest thanks for your cooperation.");
printf("\n W. David Schwaderer");
printf("\n");
return 0;
}
int VesaNotPresent()
{
struct SREGS SegReg;
union REGS OutReg, InReg;
InReg.h.ah = VESA_FUNCTION;
InReg.h.al = VESA_RETURN_INFO;
SegReg.es = FP_SEG(&VesaInfo);
InReg.x.di = FP_OFF(&VesaInfo);
int86x(VIDEO_INT, &InReg, &OutReg, &SegReg);
if(OutReg.h.ah != VESA_CALL_SUCCESSFUL)
return 1;
if(OutReg.h.al != VESA_FUNCTION_SUPPORTED)
{
printf("\nVesaNotPresent: VESA Presence test not supported");
return 1;
}
return 0;
}
int DisplayVesaInfo()
{
USGI far *FarIntPtr, *NearIntPtr, Index1, Index2, Mask;
char far *FarCharPtr, *NearCharPtr, LocalOemString[256];
/*------------------- signature ------------------*/
printf("\n\nDisplayVesaInfo: VesaSignature (hex) ==>");
for (Index1 = 0;
Index1 < sizeof(VesaInfo.VesaSignature);
Index1++)
{
printf("%02X", VesaInfo.VesaSignature[Index1]);
if (Index1 < (sizeof(VesaInfo.VesaSignature) - 1))
putchar('.');
}
printf("<== ('");
for (Index1 = 0;
Index1 < sizeof(VesaInfo.VesaSignature);
Index1++)
printf("%c", VesaInfo.VesaSignature[Index1]);
printf("')");
/*------------------- version -------------------*/
printf("\nDisplayVesaInfo: VesaVersion == VBE %u.%u",
((VesaInfo.VesaVersion >> 8) & 0x00FF),
(VesaInfo.VesaVersion) & 0x00FF);
/*------------------- OEM string -------------------*/
printf("\nDisplayVesaInfo: OemString ==>");
FarCharPtr = VesaInfo.OemStringPtr;
while(*FarCharPtr)
putchar(*FarCharPtr++);
printf("<==");
/*----------------- capabilities -----------------*/
printf("\nDisplayVesaInfo: Capabilities ==>");
for (Index1 = 0;
Index1 < sizeof(VesaInfo.Capabilities);
Index1++)
{
for ( Index2 = 0, Mask = 0x0080;
Index2 < 8;
Index2++, Mask >>= 1)
if (VesaInfo.Capabilities[Index1] & Mask)
putchar('1');
else
putchar('0');
if (Index1 != 3)
putchar('.');
}
printf("<==");
printf("\n - %s DAC width...",
(VesaInfo.Capabilities[3] & VESA_DAC_WIDTH_TEST_BIT) ?
"Switchable" : "Fixed (6 bits/primary color)");
/*------------------- total memory -------------------*/
printf("\nDisplayVesaInfo: Total64kMemoryBlocks == %u (%uKb total)...",
VesaInfo.Total64kMemoryBlocks,
VesaInfo.Total64kMemoryBlocks * 64);
/*------------------- video modes -------------------*/
FarIntPtr = VesaInfo.VideoModePtr;
if (!ModeValue)
{
while(*FarIntPtr != 0xFFFF)
{
if (*FarIntPtr & VESA_VIDEO_MODE_TEST_BIT)
DisplayVesaModeInfo(*FarIntPtr, !VESA_MODES_ONLY);
FarIntPtr++;
}
} else
DisplayVesaModeInfo(ModeValue, !VESA_MODES_ONLY);
return 0;
}
int FillVesaModeBlock(struct VesaModeInfoBlock *VesaModeInfoBlockPtr,
USGI ModeNumber)
{
struct SREGS SegReg;
union REGS OutReg, InReg;
InReg.h.ah = VESA_FUNCTION;
InReg.h.al = VESA_RETURN_MODE_INFO;
InReg.x.cx = ModeNumber;
SegReg.es = FP_SEG(VesaModeInfoBlockPtr);
InReg.x.di = FP_OFF(VesaModeInfoBlockPtr);
int86x(VIDEO_INT, &InReg, &OutReg, &SegReg);
if(OutReg.h.ah != VESA_CALL_SUCCESSFUL)
return 0;
if(OutReg.h.al != VESA_FUNCTION_SUPPORTED)
{
printf("\n\nFillVesaModeBlock: VESA mode info request not
supported");
return 0;
}
return 1;
}
int DisplayVesaModeAttributes(USGI VesaModeAttributes)
{
printf("\n -Your hardware does%s support it...",
(VesaModeAttributes & VESA_MODE_AVAILABLE_TEST_BIT) ?
"" : "n't");
if (!(VesaModeAttributes & VESA_MODE_AVAILABLE_TEST_BIT))
return 0;
printf("\n -Extended mode info is%s available...",
(VesaModeAttributes & VESA_MODE_EXTENDED_INFO_AVAIL_TEST_BIT) ?
"" : "n't");
printf("\n -BIOS output functions are%s supported...",
(VesaModeAttributes & VESA_MODE_OUTPUT_FUN_TEST_BIT) ?
"" : "n't");
printf("\n -%s mode...",
(VesaModeAttributes & VESA_MODE_MONO_COLOR_TEST_BIT) ?
"Color" : "Monochrome");
printf("\n -%s mode type...",
(VesaModeAttributes & VESA_MODE_MONO_TYPE_TEST_BIT) ?
"Graphics" : "Text");
return 0;
}
int DisplayVesaWindowAttributes(USGC VesaWindowAttributes)
{
printf("\n - Window is%s supported...",
(VesaWindowAttributes & VESA_WINDOW_SUPPORTED_TEST_BIT) ?
"" : "n't");
if (!(VesaWindowAttributes & VESA_WINDOW_SUPPORTED_TEST_BIT))
return 0;
printf("\n - Window is%s readable...",
(VesaWindowAttributes & VESA_WINDOW_READABLE_TEST_BIT) ?
"" : "n't");
printf("\n - Window is%s writable...",
(VesaWindowAttributes & VESA_WINDOW_WRITABLE_TEST_BIT) ?
"" : "n't");
return 1;
}
int DisplayVesaModeInfo(USGI ModeNumber, USGI VesaModesOnlyFlag)
{
struct VesaModeInfoBlock VesaModeInfo;
memset(&VesaModeInfo, '\x00', sizeof(VesaModeInfo));
if (VesaModesOnlyFlag)
{
if (!(ModeNumber & VESA_VIDEO_MODE_TEST_BIT))
{
printf("\nDisplayVesaModeInfo: Mode %04X is not a VESA mode...",
ModeNumber);
return 1;
}
}
FillVesaModeBlock(&VesaModeInfo, ModeNumber);
printf("\n\nDisplayVesaModeInfo: *---------- Mode == 0x%04X ----------*",
ModeNumber);
DisplayVesaModeAttributes(VesaModeInfo.ModeAttributes);
printf("\nDisplayVesaModeInfo: Bytes per scan line == %u",
VesaModeInfo.BytesPerScanLine);
/*------------------ general window information ------------------*/
printf("\nDisplayVesaModeInfo: Window Size == %uKb, Granularity == %uKb",
VesaModeInfo.WinSize,
VesaModeInfo.WinGranularity);
printf("\nDisplayVesaModeInfo: Window function pointer == %04X:%04X",
FP_SEG(VesaModeInfo.WinFuncPtr),
FP_OFF(VesaModeInfo.WinFuncPtr));
/*----------------- window A -----------------*/
printf("\nDisplayVesaModeInfo: Window A segment == 0x%04X",
VesaModeInfo.WinASegment);
DisplayVesaWindowAttributes(VesaModeInfo.WinAAttributes);
/*------------------ window B -----------------*/
printf("\nDisplayVesaModeInfo: Window B segment == 0x%04X",
VesaModeInfo.WinBSegment);
DisplayVesaWindowAttributes(VesaModeInfo.WinBAttributes);
/*------------------- extended mode information (preVBE 1.2) ------------------*/
if (!(VesaModeInfo.ModeAttributes &
VESA_MODE_EXTENDED_INFO_AVAIL_TEST_BIT))
return 0;
printf("\nDisplayVesaModeInfo: Resolutions X == %u, Y == %u",
VesaModeInfo.XResolution,
VesaModeInfo.YResolution);
printf("\nDisplayVesaModeInfo: Character cell Width == %u, Height == %u",
VesaModeInfo.XCharSize,
VesaModeInfo.YCharSize);
printf("\nDisplayVesaModeInfo: Number of planes == %u",
VesaModeInfo.NumberOfPlanes);
printf("\nDisplayVesaModeInfo: Bits per pixel == %u",
VesaModeInfo.BitsPerPixel);
printf("\nDisplayVesaModeInfo: Number of banks == %u",
VesaModeInfo.NumberOfBanks);
printf("\nDisplayVesaModeInfo: Memory model == %u ",
VesaModeInfo.MemoryModel);
switch(VesaModeInfo.MemoryModel)
{
case VESA_MODE_TEXT :
printf("(Text mode)");
break;
case VESA_MODE_CGA_GRAPHICS :
printf("(CGA graphics)");
break;
case VESA_MODE_HERCULES_GRAPHICS :
printf("(Hercules graphics)");
break;
case VESA_MODE_4_PLANE_PLANAR :
printf("(4-plane planar)");
break;
case VESA_MODE_PACKED_PIXEL :
printf("(Packed pixel)");
break;
case VESA_MODE_NON_CHAIN_4_256_COLOR :
printf("(Non-chain 4, 256 color)");
break;
case VESA_MODE_DIRECT_COLOR :
printf("(Direct color)");
break;
case VESA_MODE_YCbCr :
printf("(YCbCr)");
break;
default :
if (VesaModeInfo.MemoryModel < 0x10)
printf("(VESA reserved)");
else
printf("(OEM defined)");
}
printf("\nDisplayVesaModeInfo: Bank size == %u",
VesaModeInfo.BankSize);
printf("\nDisplayVesaModeInfo: Number of image pages == %u",
VesaModeInfo.NumberOfImagePages);
if (VesaModeInfo.MemoryModel == VESA_MODE_DIRECT_COLOR)
{
printf("\nDisplayVesaModeInfo: Mask sizes Red(%u), Green(%u)",
VesaModeInfo.RedMaskSize,
VesaModeInfo.GreenMaskSize);
printf("\nDisplayVesaModeInfo: Mask sizes Blue(%u), Rsvd(%u)",
VesaModeInfo.BlueMaskSize,
VesaModeInfo.RsvdMaskSize);
printf("\nDisplayVesaModeInfo: Field lsb position Red(%u), Green(%u)",
VesaModeInfo.RedFieldPosition,
VesaModeInfo.GreenFieldPosition);
printf("\nDisplayVesaModeInfo: Field lsb position Blue(%u), Rsvd(%u)",
VesaModeInfo.BlueFieldPosition,
VesaModeInfo.RsvdFieldPosition);
printf("\nDisplayVesaModeInfo: DirectColorModeInfo");
if (VesaModeInfo.DirectColorModeInfo &
VESA_PROGRAMMABLE_DIRECT_COLOR_RAMP_TEST_BIT)
printf("\nDisplayVesaModeInfo: - Color ramp is programmable");
else
printf("\nDisplayVesaModeInfo: - Color ramp is fixed");
if (VesaModeInfo.DirectColorModeInfo &
VESA_RESERVED_BITS_ARE_USABLE_TEST_BIT)
printf("\nDisplayVesaModeInfo: - Reserved bits are usable");
else
printf("\nDisplayVesaModeInfo: - Do not use reserved bits");
}
if (VesaModeInfo.MemoryModel == VESA_MODE_YCbCr)
{
printf("\nDisplayVesaModeInfo: Mask sizes Y(%u), U(%u)",
VesaModeInfo.GreenMaskSize,
VesaModeInfo.BlueMaskSize);
printf("\nDisplayVesaModeInfo: Mask sizes V(%u), Rsvd(%u)",
VesaModeInfo.RedMaskSize,
VesaModeInfo.RsvdMaskSize);
printf("\nDisplayVesaModeInfo: Field lsb position Y(%u), U(%u)",
VesaModeInfo.GreenFieldPosition,
VesaModeInfo.BlueFieldPosition);
printf("\nDisplayVesaModeInfo: Field lsb position V(%u), Rsvd(%u)",
VesaModeInfo.RedFieldPosition,
VesaModeInfo.RsvdFieldPosition);
}
return 0;
}
int ExitLogo(void)
{
WdsLogo();
exit(1);
return 0;
}
/*======================== End of File ========================*/
| Previous | Table of Contents | Next |