DDDR/2 - 16-Bit VGA Display Driver
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
16-Bit VGA Display Driver
The 16-bit VGA display driver provides hardware independence to the application code that performs I/O to a display device. An application program need not be concerned with the hardware-specific requirements of the adapter card.
The 16-bit VGA display driver is a set of special-purpose I/O routines, operating at privilege level 2 (Ring 2). This driver, along with other presentation drivers, provides the link between the internal interface to display devices and the OS/2* interfaces to the kernel device drivers at Ring 0 (the highest privilege level) and the screen.
When an application needs to perform I/O to the screen, it calls a system DLL, which in turn calls the Presentation Manager* (PM) graphics engine, contained in PMGRE.DLL. The graphics engine then calls the display driver, contained in DISPLAY.DLL. The display driver can then access the adapter hardware directly through memory-mapped I/O, or can call the OS/2 kernel by way of the standard driver mechanism to perform the I/O.
When the display driver is loaded, the graphics engine allocates an internal dispatch table to process the functions. The dispatch table is an array of pointers to function-handling routines. The low-order byte of the function number identifies the member of the array that contains the pointer for the function. The first time that the display driver is called at its OS2_PM_DRV_ENABLE entry point, it replaces the graphics engine pointers in the dispatch table with pointers to the corresponding functions supported by the display driver. Some of the pointer replacements are mandatory; others are optional.
The graphics engine pointer to the dispatch table is passed to the display driver by way of a FillLogicalDeviceBlock call.
16-Bit VGA Architecture
The 16-bit VGA display driver consists of one component (DISPLAY.DLL). DISPLAY.DLL contains all entry points-both device-dependent and device-independent functions (including seamless support) - that the graphics engine calls.
All the fonts, cursors, and bit maps are included in a binary resource file (.RES) that is built and added to the driver by the resource compiler.
The following is a list of the functions in the graphics engine that are hooked by the 16-bit VGA display driver.
- Graphics Engine Attribute Functions
- Graphics Engine AVIO Functions
- Graphics Engine Bit-Map Functions
- Graphics Engine Color Table Functions
- Graphics Engine Device Functions
- Graphics Engine Escape Functions
- Graphics Engine Line Functions
- Graphics Engine Marker Functions
- Graphics Engine Miscellaneous Device Functions
- Graphics Engine Miscellaneous Screen Functions
- Graphics Engine Query Functions
- Graphics Engine String Functions
For more information about these functions and their descriptions, see #Graphics Engine Functions.
Debugging support is provided through a macro, color_puts<>, contained in seamless.inc. This macro sends data through the kernel debugger port to a serial port. The kernel debugger and its related documentation is provided with the OS/2 2.X Toolkit. The input for the macro is foreground color, background color <string>, as follows:
ifdef FIREWALLS color_puts BLUE,BLACK,< This message will be output to the debugging terminal > endif ;FIREWALLS
Current debugging messages in the code are placed inside the conditional compilation ifdef FIREWALLS. This value is defined when compiling the debug version of the driver. Another example of this macro can be found in init.asm.
The BITBLT Function
One of the most important functions used in Presentation Manager is BITBLT (Bit Block Logical Transfer), which draws the rectangles that make up the PM Desktop, icons, and other bit maps. BITBLT is similar to a byte-block move operation except that blocks are moved on bit boundaries instead of byte boundaries. This could require that the bits of the source be aligned to the bits of the target (phase alignment). An example is moving all bits of a bit map left two pels. Once the bits are aligned, they are combined with an optional pattern and the target, as specified by the raster operation (ROP).
For arbitrary BLT processing, code is derived dynamically and written to a data segment. This segment is then aliased to a code segment, and executed. BITBLT functionality is the same for 16-bit VGA, 32-bit VGA, and 32-bit Super VGA.
For detailed information on BITBLT functionality, see VGA32\IBMDEV32\BITBLT.ASM and VGA32\IBMDEV32\CBLT.ASM.
The innermost functionality of BITBLT can be pictured as follows:
Bytes are fetched from a source. Color conversion is applied if the source and target are of different color formats. (See Color Conversion and XGA Support for Palette Management - Dithering and BITBLTing for detailed information about color conversion.) The source bits then are aligned with the target. Bits from a previous phase alignment and the current phase alignment are combined to form one byte's worth of data. The unused bits from the phase alignment are saved for the next phase alignment.
The ROP is applied against the source bits, pattern, and target, as needed; the result replaces the target byte.
The following illustrations show possible overlaps that can occur when a BLT is performed. Since the source and target can overlap, the order in which bytes are processed must be chosen with care. If the order is wrong, a byte of the source might be overwritten (as a target) before the byte is used as a source. (You might remember propagating spaces through a field on the IBM* 360s and 370s).
In the following figures, S is the source, D is the target, and x is the corner from where the first byte will be fetched. The comments (on the right) tell in which directions (X and Y) the BLT must be performed to prevent the overwriting of a source byte before it is used as a source. The possible cases of overlap are as follows:
- Disjointed (not special cased)
- Identical (not special cased)
The following four examples are degenerate cases (along with identical and disjoint) and the directions are as shown:
Phase Relationship Between Source and Target Bit Maps
Since BLTs are performed on bit boundaries instead of byte boundaries, rotations of the source bit map bytes might have to be performed. Source data is always rotated to align with the target. The following describes how the phase relationship is determined and how to start the BLT. (Some phase relationships require a different number of initial source bit map fetches to acquire enough bits to satisfy the first store.)
The number of bytes separating the source and target in the following examples is irrelevant; only the relationship of the bits within the bytes is important. Saved and used masks are applied after rotating the source byte.
|Saved bits mask||A mask that gives the bit that must be carried over to the next byte BLTed.|
|Used bits mask||A mask that gives the bits that are to be used for the current byte BLTed.|
|Old unused bits||Bits that were not used in the last byte BLTed and, therefore, bits that must be used for the current byte BLTed.|
|First byte mask||A mask that is used to mask the bits (of the very first byte BLTed) that are to be altered. The complement of this mask gives the bits of the target byte that are to remain unaltered.|
The BLT is started based on the cases of overlap as previously specified.
For box cases 3, 4, 5, 6, 8, disjoint, and same (as shown previously), BLTs start at the left, stepping right. Calculations are based on the left side of the source and target rectangles. The starting mask is based on the leftmost byte of the target; the ending mask is based on the rightmost byte of the target, as follows:
For box cases 1, 2, and 7, BLT starting at the right, stepping left. Calculations are performed on the right side of the source and target rectangles. The starting mask is based on the rightmost byte of the target , and the ending mask is based on the leftmost byte of the target.
Raster Operation Codes And Definitions
Each raster operation code represents a Boolean operation in which the source, currently selected brush, and target are combined.
The operands used in the operations are:
|S||Source bit map|
|P||Currently selected brush (also called pattern)|
|D||Target bit map|
The Boolean operators used in these operations are:
|x||Bitwise Exclusive OR|
|n||Bitwise NOT (inverse)|
All Boolean operations are presented in reverse Polish notation. For example, the operation:
replaces the target with a combination of the source and brush.
combines the source and brush with the target. Because there are alternate spellings of the same function, although a particular spelling might not be in the list, an equivalent form will be.
Each raster operation code is an 8-bit integer value that represents the result of the Boolean operation on predefined brush, source, and target values. For example, the operation indexes for the PSo and DPSoo operations are:
In this case, PSo has the operation index
00FC (read from the bottom up); DPSoo has the index
Color conversion applies when the source and target color formats are not the same. Color conversion takes place prior to any mix mode. For additional information, see XGA Support for Palette Management - Dithering and BITBLTing.
Mono Color Conversion
- Applied when the source is monochrome and the target is color.
- When going from monochrome to color, 1 bits are converted to the target image foreground color, and 0 bits are converted to the target image background color.
Color Mono Conversion
- Applied when the source is color and the target is monochrome.
- When going from color to monochrome, all pels that match the passed background IPC (obba_bgndIPC) are converted to the target image background color; all other pels are converted to the target image foreground color.