DDDR/2 - Virtual Video Device Drivers

This chapter describes the design, implementation, and interfaces of a virtual video device driver, including the virtualization and windowing of DOS session on an OS/2 platform. It is assumed that you are familiar with the terms and concepts in the OS/2 Virtual Device Driver Reference.

Overview
A virtual video device driver is used by the IBM Operating System/2 as a virtual display device for DOS applications executing in a DOS session by providing virtual hardware support. Virtual video device drivers are required when it is necessary for multiple DOS sessions to share one or more video devices.

The virtual video device driver manages access to video memory, video registers, and video adapter ROM BIOS. Special functions have been defined to permit other OS/2 Ring 3 components (such as the DOS Session Manager and the Presentation Manager display device driver) to obtain the vital video state information necessary to window a DOS session on the Presentation Manager Desktop.

For simplicity, a dedicated virtual video device driver should be targeted to a specific video device. This reference manual includes a set of virtual video device drivers that can be used as templates for enhancement modifications to any of the currently supported devices, or they can be used as samples to create a virtual device driver from scratch for a similar but compatible device. For example, the OS/2 virtual Super VGA device driver (VSVGA.SYS) is a derivative of the virtual VGA device driver (VVGA.SYS).

The following virtual video device drivers, which cover an extensive range of the most commonly used video devices, are included in this reference manual: The video devices for which OS/2 provides virtual video device drivers include:
 * Virtual CGA device driver VCGA
 * Virtual EGA device driver VEGA
 * Virtual MONO device driver VMONO
 * Virtual VGA device driver VVGA
 * Virtual XGA device driver VXGA
 * Virtual SVGA device driver SVGA
 * Virtual 8514/A device driver V8514A
 * Western Digital
 * ATI
 * Cirrus Logic
 * Headland
 * IBM Super VGA
 * Trident
 * TSENG
 * Video 7**
 * Note: Specific Super VGA chip revision/model support can be found in VVDP.H.

Installable Virtual Video Device Driver Architecture
The architecture of a virtual video device driver conforms to the architecture defined for all virtual device drivers. However, some parts of the multiple DOS session's architecture have been designed primarily for virtual video device drivers, as follows: A significant amount of the primary virtual video device driver code involves communication with the DOS Session Window Manager. A Remote Procedure Call (RPC) mechanism must be used to communicate between the DOS Session Window Manager and a virtual video device driver under the following conditions: For this purpose the DOS Session Window Manager creates a thread that calls the virtual video device driver to wait for a video event from any of the currently windowed DOS sessions.
 * Foreground and background notification hooks
 * Freeze and thaw services
 * Title change and code-page change notification hooks
 * The DOS Session Window Manager is a Ring 3 component (lowest privilege level);
 * Virtual device drivers run at Ring 0 (highest privilege level);
 * DOS sessions have no Local Descriptor Table (LDT) and therefore cannot attach to Dynamic Link Libraries (DLLs).

Design of Installable Virtual Video Device Drivers
A virtual video device driver is a base device driver, although a "DEVICE=" statement in the CONFIG.SYS file is used to specify one or more virtual video device drivers to load. The DOS Session Manager and DOS Session Window Manager identify a virtual video device driver by its registered name. For example, a virtual video device driver for the primary display would register as VVIDEO1$; a virtual video device driver for the secondary display device would register as VVIDEO2$; and so forth.


 * Note: Support of multiple DOS sessions is disabled if no virtual video device driver claims ownership of the primary display device after virtual video device driver loading and initialization is completed.

Supporting DOS-Standard Adapters and Modes
IBM-compatible CGA, EGA, VGA, XGA, and 8514/A adapters are supported as primary display devices; monochrome adapters are supported as secondary display devices. For these devices, the standard configurations (including the amount of video memory, type of monitor and so forth), are supported. However, there are a few exceptions. For example, support for other dual-adapter combinations, such as EGA/Monochrome with CGA/Color, or VGA/ Monochrome with CGA/Color, are not supported.

All EGA monitor combinations (RGB, ECD, and monochrome) and VGA, XGA, 8514/A monitor combinations (8512/8513, 8514, and 8515), as well as all EGA memory combinations (64KB, 128KB, 192KB, and 256KB) of the 8514/A monitor are supported. The type of monitor used with a monochrome or CGA adapter is immaterial; that is, the behavior of the adapter is not affected.

There are some limitations, however. For example, an EGA, VGA, or Super VGA with a 2xx port configuration, instead of the standard 3xx Also, an EGA display with only 64KB of display memory cannot support high-resolution graphic modes in a window, due, in part, to the video mode used concurrently by Presentation Manager (640 x 200, 16 colors), which consumes nearly all of the 64KB of on-board video memory. In addition, blinking attributes (whether in text or graphics modes) cannot be emulated in a DOS window.

A significant portion of the primary virtual video device driver involves communication with the DOS Session Window Manager. This includes providing a set of services to fully describe a DOS session's video state and a set of notifications to signal when the video state changes, so that a DOS session being windowed remains relatively synchronized with its associated DOS session that is executing in the background.

Because the DOS Session Window Manager, OS/2 Session Manager, and Presentation Manager display device driver execute in Ring 3, while the virtual video device driver runs in Ring 0, a system entry point is necessary for these Ring 3 components to communicate with the virtual video device driver. The virtual video device driver provides the following DosRequestVDD service to:
 * DOS Session Window Manager
 * -Set Access
 * -Set Focus
 * -Set Lock
 * -Query Mode Info
 * -Query Cursor Info
 * -Query Palette Info
 * -Copy LVB Content
 * -Copy Bit Map Content
 * -Wait for Video Event
 * -Control Event


 * PM Display Device Driver
 * -Set Display Requirements
 * -Request off-screen VRAM
 * -Free off-screen VRAM
 * -Request VGA Controller
 * -Free VGA Controller
 * -Query VRAM Status


 * Note: See DOS Session Window Manager Services and Presentation Manager Display Driver Services for a detailed explanation of the DosRequestVDD functions provided by the virtual video device driver.

There are two kinds of DOS session window support: The latter is a subset of the former. The virtual video device driver always attempts to provide support for displaying a running image and for standard text and CGA graphics modes this is always possible, but there are graphics modes cases where that is not possible. One example is the 64KB EGA mode; other examples are the XGA and 8514/A modes.
 * Displaying a running image in a window
 * Displaying a frozen image in a window

Support for the XGA or 8514/A graphics modes is not a matter of sufficient memory but of the sheer complexity of virtualizing the 8514/A hardware. In addition, if a DOS application uses VGA graphics modes on an 8514/A system, it will not be able to use the VGA memory if a monitor, being used as a secondary display by other tasks in the system, is connected to the VGA.

There is no known reliable method of determining whether a monitor is connected to the VGA or Super VGA. The 8514/A can detect a limited set of IBM-compatible, fixed-frequency monitors, whereas the XGA, using DMQS, has the potential of identifying all monitor types, including OEMs.

In an 8514/A system, there is no architected way for the virtual video device driver to determine whether the VGA is in use by another process or session. Conversely, there is no way for the virtual video device driver to claim the device and prevent other processes or sessions from later acquiring the device.

Note:

256-color modes will not be rendered accurately in a window even when the PM display driver supports 256 colors, because the DOS Session Window Manager does not provide Palette Manager support.

High-resolution graphics modes on a 64KB EGA currently will not be rendered properly in a DOS window because the memory organization is substantially different (planes 0 and 1 and planes 2 and 3 are chained together).

OS/2 provides a single, generic Super VGA virtual device driver that supports the majority of the Super VGA video adapters made with the above-mentioned Super VGA chip sets. However, there are a small number of adapters that cannot be reliably virtualized due to the way they are designed. An example of this category is an adapter that requires multiple OUTs to a specific port before permitting the extended clock bits to be programmed.

Of the 8514/A graphics modes, only the 1024 x 768 256-color mode has been tested for accurate rendering in a window.

Virtualization Support Strategy
The virtualization support required for these devices varies, depending on the complexity, capability, and operational characteristics of the device. However, the approach to develop a high-level design should always be the same, regardless of the device involved. To illustrate, we will use the 8514/A and XGA devices as examples in the following sections.

Virtualization Support Requirements for 8514/A and XGA
The following sections describe the device description, functional requirements, and design tradeoffs for the 8514/A and XGA devices.

8514/A Device Description

 * The majority of the I/O ports are either read-only or write-only.
 * There is a multi-function register that requires special considerations because the functionality characteristics are totally different from the other I/O registers.
 * The 8514/A internal RGB index of the DAC is not readable.
 * The VRAM cannot be accessed directly. (It is not a dumb frame device.)
 * Special consideration must be given to handling the passthrough-mode capability of this device.
 * Video memory size is assumed to be 1MB for the following reasons:
 * -The OS/2 PM Display Device Driver cannot function without it.
 * -It is not possible to configure a system with multiple 8514/A adapters.


 * The 8514/A is not a Direct Memory Access (DMA) device.

XGA Device Description

 * The I/O registers mostly are readable and writable, plus a few reserved registers.
 * It is a BusMaster device, capable of DMA operations.
 * DMA (co-processor) operations are initiated through memory-mapped I/O registers located in the adapter ROM area above C0000.
 * The device can operate in a virtual memory (that is, a 386 environment).
 * Video memory can be accessed by the DOS application through either an A0000 or B0000 aperture, without use of a co-processor.
 * Multiple XGA configuration is possible.
 * With built-in VGA hardware, the two operating environments are mutually exclusive even though they share the same DAC and VRAM.
 * Planar VGA is disabled on a single display system (the display is attached to the XGA adapter).
 * 132-column text mode is supported.
 * All graphics modes are packed-pel.

8514/A Functional Requirements

 * Determine the existence of the device and the type of display attached.
 * Trap all the write-only I/O ports, even if the DOS session executes in the foreground (full-screen); otherwise, the device cannot be saved or restored.
 * No page-fault hook is required because the 8514/A is not a memory-mapped device.
 * Establish a mechanism with the virtual VGA device driver to manage ownership of the shared device.
 * Enable the DOS application that is INT 2Fh-aware to save and restore its own video state.
 * Trap all I/O, whether or not I/O can be virtualized while the DOS session is executing in the background.

XGA Functional Requirements
Upon detection, the I/O handler can choose one of the following:
 * For every XGA configuration in the system, determine the physical location and size of VRAM, the type of display attached, and the location of the memory-mapped I/O registers.
 * A page fault hook is required to detect the memory-mapped I/O registers used, because the affected system memory must be locked down before any DMA operations can occur.
 * Notification of EMS, XMS, and DPMI memory allocations is required, so that the memory object can be locked down for DMA operations.
 * Page-fault handling of A0000 and B0000 is not required because an I/O trap handler can be installed to monitor usage of the Aperture Control register.
 * -When the DOS session is foreground, map the linear address to the physical location of the VRAM (that is, A000 or B000), giving a length of 64KB because that is the maximum size of the aperture.

This approach eliminates duplication of the page fault management logic of the virtual VGA device driver.
 * -When the DOS session is background, map the linear address to the appropriate location within the shadow buffer that was saved during the recent session switch. The displacement is 64KB-aligned, and it is computed using the content of the Aperture Index Register.


 * The XGA-specific registers must be saved/restored to provide 132-column text mode support. The virtual VGA device driver is expected to handle the others. Enable the DOS application that is INT 2Fh-aware to save and restore its own video state.

8514/A Design Tradeoffs
When save/restore of the complete video state is required, you have two choices for saving the 1MB VRAM:
 * -Allocate the 1MB shadow buffer during creation of the virtual DOS session, thus eliminating a potential problem with resource allocation during session switching.
 * -Delay allocation of the shadow buffer at the time of session switch, but risk the possibility of session termination because the required memory is not available.

Software emulation of any hardware-assist operations to the video memory probably is too complex to achieve successfully. The only alternative available is to freeze the DOS application whenever these I/O ports are accessed in the background. A frozen image can be presented in a window if the complete video state and VRAM were saved for the DOS window session.

XGA Design Tradeoffs
It is impossible to anticipate what the DOS application might do when the memory-mapped I/O register is touched; assume the worst. To preserve the integrity of the system by not permitting the DOS application to interfere with system operations, lock down the affected memory regions.

Although there are numerous ways to do this, there are penalties involved with each one. Some of the methods (and their possible drawbacks) are described following this table.

In a multiple XGA configuration system, saving and restoring every XGA probably is desirable. Instead, you can let the DOS application take care of it, or you can selectively save/restore only one XGA device.

Software emulating the XGA hardware operations is not desirable.

The only apparent alternative is to freeze the DOS application when the I/O ports are accessed in the background. A frozen image can be presented in a window if the complete video state and VRAM are saved for the DOS window session.

Methods of Locking Down Memory Regions

 * Assume each full-screen DOS session is started in physical memory below 1MB by OS/2. This has the advantage of not having to specifically lock down the 640KB DOS region, and the memory, by default, is continuous. This is ideal for any XGA-specific DOS applications that do not require any extended memory, while achieving performance equal to DOS. The drawback here is that this type of session is not supported by OS/2.
 * Assume each full-screen DOS session is started anywhere in system memory with the 640KB DOS region locked down discontiguously by OS/2. Here, the virtual memory mode of the XGA must be used. EMS, XMS, and DPMI memory allocation can be locked dynamically through the extended memory allocation notification interface. Putting the XGA in VM mode would result in a 10 to 15 per cent degradation in performance, depending on the type of operations involved. OS/2 does not support this type of session start.
 * Assume that XGA will be operating in VM mode. The 640KB DOS region gets locked down discontiguously only when access to the memory-mapped I/O register is detected. EMS, XMS, and DPMI memory allocation is handled as in the second case above.
 * While operating in VM mode, the XGA has the ability to generate an interrupt to the system processor whenever the memory object being referenced is not present. Assuming that the 640KB region can be selectively forced into a not-present state, a physical device driver can be written to avoid such interrupt and post the event. Although the event is posted at interrupt time, the actual lockdown of memory cannot take place until the virtual device driver gets a chance to execute at task time, when it can resume the XGA operation after successfully locking down the memory object.


 * Note: The second and third assumptions above require the generation of a Page Directory and Page Table in order for the XGA to access the DOS session's linear address space and VRAM.

Virtual and Non-Virtual (Full-Screen) Operations
For optimal performance and compatibility, the virtual video device drivers support full-screen operation. In this mode, there is no visual difference between DOS and DOS-session operation. For convenience, an option appears on the DOS session's system menu to convert the DOS session from windowed mode to full-screen mode and back again. Virtual video device drivers support full-screen by performing the following operations: When a DOS session does not own the physical display (that is, when it is in the background), the virtual video device drivers do the following:
 * Registering foreground and background VIDEO_SWITCH_NOTIFICATION hooks with the DOS Session Manager
 * Allocating a Save and Restore video buffer
 * Installing I/O hooks to shadow key video port accesses
 * Mapping physical video memory into the appropriate video address space
 * Coercing text-mode fonts to match the currently selected code page
 * Providing pointer drawing services to the virtual mouse device driver to define, draw, and erase pointer images
 * Install I/O hooks to track and emulate all video port accesses.
 * Map appropriate system memory to the active portions of the video address space.
 * Report video events to the DOS Session Window Manager (assuming the Presentation Manager is active and the DOS session is an unminimized window). Such reporting includes changes to:
 * -Mode
 * -Palette
 * -Cursor
 * -Video memory
 * -Input events
 * -Scroll or string events
 * -Paste continue or terminate (through the virtual keyboard device driver)
 * -Session title change
 * -Screen-switch or video memory allocation errors

At any time, the DOS Session Window Manager (or other processes that have access to a DOS session's process ID) can update a DOS session's window state, as follows: Any aspect of a DOS session's video state can be queried as follows:
 * Windowed or non-windowed
 * Focused or non-focused
 * Minimized or un-minimized
 * Locked or unlocked
 * Mode
 * Palette
 * Cursor
 * Video memory
 * Wait for video events
 * Cancel wait for video events

I/O Handler Installation
I/O port handlers are installed during the creation of a DOS session This is always required if the target device requires virtualization. The assembler-language hook interface is faster than its "C" language counterpart.

Whenever possible, avoid simulation by a lower-level I/O handler. For example, if the device is capable of word I/O, do not install just the byte I/O handlers, because your byte I/O handlers will be called twice for each word I/O issued by the DOS application.

I/O ports can be enabled or disabled dynamically on a per-DOS session basis except when the VDHIIH_ALWAYS_TRAP option is specified at port installation.

I/O trapping can be removed at any time, provided that it is called using the same port arguments passed to install the I/O ports.

Currently, I/O handlers may be preempted for the following reasons: There is a remote possibility that a DOS session screen-switch might occur while an I/O handler is blocked, meaning that there is a slight risk of a shadowed DOS session's I/O operation accessing the hardware when it is no longer owner of that hardware. At present, there is no satisfactory means of removing that possibility. Making all the necessary code and data resident-both in kernel and virtual device driver-is not acceptable, nor is the overhead of calling semaphore services in the I/O handlers.
 * The code is swappable.
 * The data referenced by the handlers is swappable.
 * The OS/2 kernel portions that route I/O traps, page faults, and so forth, are swappable as well.

Mouse-Independent Pointer Drawing Services
When the virtual video device driver creates a DOS session for the first time, it opens the virtual mouse device driver. If the OPEN is successful, it provides the virtual mouse device driver with the following entry points: Also, whenever the DOS session changes video modes (including the initial mode change during DOS-session creation), the virtual video device driver notifies the virtual mouse device driver of the new mode, screen dimensions, and so forth.
 * Show Pointer
 * Hide Pointer
 * Define Text Pointer
 * Define Graphics Pointer
 * Set Video Page
 * Set Light-Pen Emulation

Built-in Extended INT 10h and INT 2Fh Services
The EGA Register interface is integrated into the virtual video device driver as part of its INT 10h interception logic. This interface is a set of INT 10h services that are used by applications to make possible drawing operations and simultaneous use of the mouse pointer on EGA and VGA hardware. The virtual video device driver's pointer drawing services are intended to replace this interface, but existing graphical applications still use it (generally when mouse support is also present). The interface must be present or these applications will not function correctly.

The INT 2Fh services notify applications when they are about to be switched to full-screen or background mode. Applications can use this notification to stop accessing video memory if they are using a video memory not supported for background operation. This prevents them from freezing and redraws their screen in the event the virtual video device driver fails to fully restore it.

Virtual Video Device Driver Services
Multiple virtual device drivers can be installed for the same adapter. Usually, the second virtual device driver detects that the adapter's address space is already reserved, and so, fails to install. However, virtual video device drivers can be written to take control of a device from an owning virtual device driver when a certain event occurs and then to relinquish control later. This is accomplished by supporting the Release Device and Accept Device inter-virtual device driver requests in both virtual video device drivers. An owning virtual video device driver must unmap all video pages and uninstall all page-fault and I/O hooks upon receipt of a Release request, and later must reinstall all hooks upon receipt of an Accept request. VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_DEVACCEPT (5)            */       PVOID pReqIn,    /* Undefined.                         */       PVOID pReqOut    /* Undefined.                         */     );

VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_DEVRELEASE (6)           */       PVOID pReqIn,    /* Undefined.                         */       PVOID pReqOut    /* Undefined.                         */     ); This support is provided for multiple virtual video device drivers installed for the same device but virtualizing different aspects of the hardware (for example, VGA and Super VGA virtual video device drivers for a single Super VGA adapter). A virtual video device driver that is not currently the owner must silently pass on any DosRequestVDD and VDHRequestVDD requests that it receives to the next virtual video device driver in the chain, using the VDDREQ_PASS return code.

In cases where multiple video adapters use the same physical monitor (such as VGA with 8514/A), there is no need to issue the device requests described previously because the devices are separate. Coordination of which virtual video device driver is currently the display owner must be accomplished by way of a similar pair of inter-virtual device driver requests: Release Display and Accept Display. Virtual video device drivers generally need not act except to update their own display ownership settings. Only the virtual video device driver that is currently the display owner for a given DOS session should respond to requests from the DOS Session Window Manager for that DOS session. The same is true of virtual mouse device driver pointer requests. For example, on a VGA and 8514/A single display system, only the virtual video device driver with display ownership should respond to certain system requests (that is, QUERYMODE, QUERYCURSOR, QUERYPALETTE, COPYLVB, and COPYBITMAP). VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_DSPACCEPT (7)            */       PVOID pReqIn,    /* Undefined.                         */       PVOID pReqOut    /* Undefined.                         */     );

VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_RELEASE (8)              */       PVOID pReqIn,    /* Undefined.                         */       PVOID pReqOut    /* Undefined.                         */     ); For the VGA and 8514/A combination, the VGA virtual video device driver still manages all video event communication with the DOS Session Window Manager. This eliminates major duplicate functionality with the 8514/A. However, because the 8514/A virtual video device driver still must be able to post its own video events, a post event inter-virtual device driver request is supported by the VGA virtual video device driver. VDHRequestVDD(      HVDM hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_POSTEVENT (9)            */       PVVPOST pvvp,    /* Pointer to a VVPOST structure      */       PVOID pReqOut    /* Undefined.                         */     ); where VVPOST is a structure containing: typedef struct vvp_ { /* vvp (input for POSTEVENT request*/      LONG  iEvent;    /* See the VVDEVENT_* constants below */       PVOID pEvent;    /* Event data (varies by event type   */ ULONG flEvent;  /* See POSTEVENT_* constants below    */ }VVPOST;

#define VVDEVENT_NONE        0 /* No change             */ #define VVDEVENT_MODE        1 /* Change in DOS         */ /* session's mode       */ #define VVDEVENT_PALETTE     2 /* Change in DOS         */ /* session's palette    */ #define VVDEVENT_LVB         3 /* Change in DOS         */ /* session's LVB        */ #define VVDEVENT_SCROLL      4 /* Scroll of DOS         */ /* session's LVB        */ #define VVDEVENT_STRING      5 /* String output         */ #define VVDEVENT_CURSOR      6 /* Cursor position/type  */ /* change               */ #define VVDEVENT_INPUT       7 /* DOS session is check- */ /* ing for input data   */ #define VVDEVENT_ENDPASTE    8 /* DOS session has       */ /* cancelled pasting    */ #define VVDEVENT_PASTE       9 /* DOS session is ready  */ /* for additional pasting*/ #define VVDEVENT_SWITCHERROR 10 /* DOS session cannot be */ /* switched foreground  */ #define VVDEVENT_TITLECHANGE 11 /* DOS session title has */ changed              */ #define VVDEVENT_DDE        12 /* Set/Clear DDE flag    */ #define POSTEVENT_ADD   0x0001 /* Add given event. */    #define POSTEVENT_FLUSH  0x0002 /* Flush given or        */ existing event. */    #define POSTEVENT_DELETE 0x0004 /* Delete existing event.*/ The XGA device has VGA device capability built into the hardware, but it is physically impossible to activate the functionality of both devices at the same time without another VGA-capable device installed. The extra VGA device can come in a form of a planar VGA with a display monitor attached, a VGA adapter, or another XGA device. In the event that the XGA device being targeted for save/restore by the XGA virtual device driver is also the startup device (that is, it comes up in VGA mode on system startup), a fast path can be used to temporarily stop the VGA virtual device driver from doing the save/restore of the same device without going through the preferred way of Release and Accept device. In this case, the Save Restore request is supported by the VGA virtual video device driver. VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_SAVERESTORE (10)         */       PVOID (0 or 1),  /* 1=yes, 0=no                        */       PVOID pReqOut    /* Undefined.                         */     ); The Repaint request is used by other virtual video device drivers (8514/A and XGA) to indicate whether the PM Desktop's screen image has been damaged by the full-screen DOS session. The virtual video device driver accepting this request must notify the PM display device driver, using QUERYVRAMSTATUS, that repaint of the Desktop is required when the PM becomes foreground. VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_REPAINT (11)             */       PVOID(TRUE),     /* 1 = REPAINT required               */       PVOID pReqOut    /* Undefined.                         */     ); The Request Controller request is issued by the virtual Window device driver (VWIN.SYS) on behalf of the WIN-OS/2 display device driver to force the virtual video device driver to immediately release the VGA controller currently owned by a background or windowed DOS session. VDHRequestVDD(      HVDD hvddVideo   /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_REQCTRL (12)             */       PVOID PReqIn,    /* Undefined.                         */       PVOID PReqOut    /* Undefined.                         */     ); The Free Controller request is issued by the virtual Window device driver (VWIN.SYS) on behalf of the WIN-OS/2 display device driver to notify the virtual video device driver that the VGA controller is now available. This request is issued only when the virtual video device driver requests notification on completion of the current PM operation. VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT   Func,      /* VVDDEVREQ_FREECTRL (13)            */       PVOID   PReqIn,  /* Undefined.                         */       PVOID   pReqOut  /* Undefined.                         */     ); The Set PM Window request is issued by the virtual Window device driver (VWIN.SYS) to permit the specified windowed DOS session access to the video device. It is up to the virtual video device driver servicing this request to remove all I/O hooks, map VRAM to physical A0000H as needed, and remove all pending window events for the target DOS session. VDHRequestVDD(      HVDD hvddVideo,  /* Virtual video device driver handle */       HVDM hvdm,       /* Screen group ID of the DOS session */       INT  iFunc,      /* VVDDEVREQ_PM_WINDOW (14)           */       PVOID(TRUE),     /* 1 = Enable WIN-OS/2                */       PVOID pReqOut    /* Undefined.                         */     );

8514/A and XGA Virtual Device Drivers
DOS applications currently written to the 8514/A adapter interface, XGA adapter interface, or directly to the 8514/A and XGA display adapters can run in a full-screen DOS session. This is due to the ability of each adapter's virtual device driver to: A DOS application is permitted to run only in a full-screen foreground DOS session; it is frozen immediately if it attempts to access the hardware when switched to the background.
 * Grant I/O privilege
 * Save or restore the video state
 * Provide video bit-map images to the shield layer when the DOS session is being windowed.

The virtual 8514/A device driver statements, which are required in the CONFIG.SYS file, are added during installation when the presence of an 8514/A display adapter is detected: DEVICE=C:\OS2\MDOS\VVGA.SYS DEVICE=C:\OS2\MDOS\V8514A.SYS The virtual XGA device driver statements, which are required in the CONFIG.SYS file, are added during installation when the presence of an XGA adapter is detected: DEVICE=C:\OS2\MDOS\VVGA.SYS DEVICE=C:\OS2\MDOS\VXGA.SYS The following items should be set in DOS to enable a DOS session:
 * Enable I/O trapping to permit the virtual video device driver to save and restore the hardware instance used by a DOS application when the application switches away from the foreground DOS session. The virtual video device driver allocates a buffer to save the video image. The maximum size of this buffer is 1MB and is obtained each time a full-screen DOS session is created.

Enabling I/O trapping is the default. Although multiple instances of XGA can be present on a system, the virtual XGA device driver saves or restores only the state of the first instance used by a DOS application. It is the application's responsibility to save or restore the other XGA instances.


 * Register for screen switch notification. This implies that a DOS application has hooked INT 2Fh so as to be notified when it is to be switched to full-screen foreground or background. This notification informs the application that it must restore the screen when switched to full-screen foreground, and must stop accessing video memory (to avoid freezing) when switched to background.

An application that uses more than one instance of XGA must specify this option to save and restore the states of the other XGA adapters. The default is no VIDEO_SWITCH_NOTIFICATION.

Any DOS session that is not saved or restored by the virtual video device driver cannot be displayed in a window. DOS 8514/A and XGA applications are not interactive in a window; they can be viewed only.

Virtual Keyboard Device Driver Services
The virtual video device driver utilizes the Post Peek and Post Read requests from the virtual keyboard device driver to post events to the DOS Session Window Manager when the windowed DOS session video state changes. In addition to generating the VVDEVENT_INPUT event to the DOS Session Window Manager to adjust window orientation, these notifications also serve to suggest to the virtual video device driver when to check for palette and LVB changes, which generate VVDEVENT_PALETTE and VVDEVENT_LVB events.

The virtual keyboard device driver uses the Post Paste request to indicate whether paste operations can start or end. The virtual video device driver posts the VVDEVENT_PASTE or VVDEVENT_ENDPASTE event to the DOS Session Window Manager, based on the type of paste operation requested. The virtual video device driver provides the following VDHRequestVDD services for the virtual keyboard device driver: VDHRequestVDD (       HVDD hvddVideo,        HVDM hvdm,        INT  iFunc,     /* Virtual video device               */                        /* driverEVREQ_POSTPEEK (1)           */        BOOL fAvail,    /* TRUE if ROM BIOS buffer is not     */                        /* empty.                             */        PVOID pReqOut   /* Undefined.                         */     );                 /* Returns TRUE. */

VDHRequestVDD (       HVDD hvddVideo,        HVDM hvdm,        INT  iFunc,     /* Virtual video device               */                        /* driverEVREQ_POSTREAD (2)           */        BOOL fAvail,    /* TRUE if ROM BIOS buffer is not     */                        /* empty.                             */        PVOID pReqOut   /* Undefined.                         */     );                 /* Returns TRUE. */

VDHRequestVDD (       HVDD hvddVideo,        HVDM hvdm,        INT  iFunc,     /* Virtual video device               */                        /* driverEVREQ_POSTPASTE (3)          */        BOOL fContinue, /* TRUE to continue pasting,          */                        /* FALSE to end.                      */        PVOID pReqOut   /* Undefined.                         */     );                 /* Returns TRUE. */ The PEEK and READ notifications occur prior to the actual operation; fAvail is TRUE if the ROM BIOS input buffer contains data, and FALSE if empty. In addition to generating VVDEVENT_INPUT events for the DOS Session Window Manager to adjust window orientation, these notifications also serve to suggest to the virtual video device driver when to check for changes in video context.

For the PASTE notification, fContinue is TRUE if pasting can continue (that is, buffer space is now available), and FALSE if pasting should be terminated (that is, the user pressed ESC). In the first case, the virtual video device driver posts VVDEVENT_PASTE to the DOS Session Window Manager, and in the second case, VVDEVENT_ENDPASTE.

Virtual Mouse Device Driver Services
For the virtual mouse device driver, the virtual video device driver provides a VDHRequestVDD function, as well as several direct interfaces for pointer drawing operations.

The following VDHRequestVDD service is provided: VDHRequestVDD (       HVDD  hvddVideo,        HVDM  hvdm,        INT   iFunc,    /* Virtual video device               */                        /* driverEVREQ_POSTMOUSE (4)          */        PVOID pReqIn,   /* Undefined.                         */        PVOID pReqOut   /* Undefined.                         */     );                 /* Returns TRUE. */ The virtual mouse device driver must return the address of a function that permits the virtual video device driver to obtain mouse position and button status during processing of the INT 10h, Query Light Pen function, when light pen emulation is enabled for the active DOS session. Also, whenever the DOS session changes video modes (including the initial mode change that takes place during DOS-session creation), the virtual video device driver notifies the virtual mouse device driver driver of the new mode and screen dimensions.

The POSTMOUSE notification is intended to be called whenever the mouse is about to record a button transition event (that is, button going down or button coming up). Its purpose is to notify the virtual video device driver that a video event is likely to occur.

The direct-call interfaces are exported by way of the following VDHRequestVDD to the virtual mouse device driver during the creation of the first DOS session. (To avoid introducing a loading-order dependency, they are not exported during virtual device driver initialization.) VDHRequestVDD (       HVDD  hvddMouse,        HVDM  hvdm,        INT   iFunc,    /* iFunc = VMDEVREQ_REGISTER (1)      */        PVMREG pvmreg,  /* Pointer to VMREG structure         */        PVMFUNC pvmfunc /* Pointer to VMFUNC structure        */     );                 /* Returns TRUE                       */ where VMREG is a structure containing all the direct-call addresses: typedef struct vmreg_s {       ULONG     nb;              /* Size of structure, in   */ /* bytes (24)             */ PFNSHOWPTR pfnShowPtr;    /* Ptr to show pointer fn. */       PFNHIDEPTR  pfnHidePtr;    /* Ptr to hide pointer fn. */       PFNDEFTEXT  pfnDefTextPtr; /* Ptr to define text /* pointer fn. */       PFNDEFGRAPH pfnDefGraphPtr;/* Ptr to define graphics /* pointer fn. */       PFNSETPAGE  pfnSetPtrPage; /* Ptr to set pointer      */ /* page fn. */       PFNSETLPEN  pfnSetLPenEm;  /* Ptr to enable/disable   */ /* lpen fn. */    }  VMREG; and where VMFUNC is a structure in which the virtual mouse device driver must return the address of its own exported function to return mouse position and button status: typedef struct vmfunc_s {       ULONG      nb;               /* Size of structure,    */ /* in bytes (8)         */ PFNQUERYSTAT pfnQueryStatus; /* Ptr to query virtual */ /* status proc. */    }  VMFUNC; The virtual video device driver also uses VDHRequestVDD to notify the virtual mouse device driver of changes in video mode: VDHRequestVDD (       HVDD  hvddMouse,        HVDM  hvdm,        INT   iFunc,              /* VMDEVREQ_SETSIZE (2)      */        PVMSS pvmss,              /* Pointer to VMSS structure */        PVOID pReqOut             /* Undefined                 */     ); where VMSS is a structure containing the following information: typedef struct vmss_s {       ULONG nb;          /* Size of structure, in bytes (36)*/ LONG lMode;       /* Video mode (for example,        */                           /* 00h-13h, or -1)                 */ ULONG ulWidth;    /* Width of screen, in pels        */ ULONG ulHeight;   /* Height of screen, in pels       */ ULONG ulCellWidth; /* Width of screen cells, in pels */ ULONG ulCellHeight;/* Height of screen cells, in pels */ ULONG ulPtrWidth; /* Width of pointer drawing size,  */ /* in pels                        */ ULONG ulPtrHeight; /* Height of pointer drawing size, */ /* in pels                        */ ULONG ulUnitWidth; /* Width of pointer drawing unit, */ /* in pels                        */ } VMSS; The direct-call interfaces supplied by virtual video device drivers are defined as follows: BOOL FNSHOWPTR VVShowPtr (       HVDM hvdm,           /* DOS session handle,           */                             /* or CURRENT_VDM                */        ULONG xNew,          /* Horizontal pel (NOT cell)     */                             /* coordinate                    */        ULONG yNew           /* Vertical pel (NOT cell)       */                             /* coordinate                    */     );                      /* Returns TRUE unless ptr       */ /* drawing disabled             */

BOOL FNHIDEPTR VVHidePtr (       HVDM hvdm             /* DOS session handle, or       */                              /* CURRENT_VDM                  */     );                       /* Returns TRUE unless ptr      */ /* drawing disabled            */

BOOL FNDEFTEXT VVDefTextPtr (       HVDM hvdm,            /* DOS session handle, or       */                              /* CURRENT_VDM                  */        ULONG ulANDMask,      /* Screen mask                  */        ULONG ulXORMask,      /* Pointer mask                 */        BOOL fHW              /* TRUE to use hardware cursor  */     );                       /* Returns TRUE                 */

BOOL FNDEFGRAPH VVDefGraphPtr (       HVDM hvdm,            /* DOS session handle, or       */                              /* CURRENT_VDM                  */        USHORT ausMasks[],    /* Screen mask, followed by     */                              /* pointer mask                 */        ULONG xHot,           /* Relative horizontal hot-spot */                              /* coordinate                   */        ULONG yHot            /* Relative vertical hot-spot   */                              /* coordinate                   */     );                       /* Returns TRUE                 */

BOOL FNSETPAGE VVSetPtrPage (       HVDM hvdm,            /* DOS session handle, or       */                              /* CURRENT_VDM                  */        ULONG ulPage          /* Video page number            */     );                       /* Returns TRUE                 */

BOOL FNSETLPEN VVSetLPenEm (       HVDM hvdm,            /* DOS session handle, or       */                              /* CURRENT_VDM                  */        BOOL fEnable          /* TRUE to enable emulation     */     );                       /* Returns TRUE                 */ For reference, the function supplied by a virtual mouse device driver to a virtual video device driver is defined as follows: BOOL FNQUERYSTAT VMQueryStatus (       HVDM hvdm,       /* DOS session handle, or            */                         /* CURRENT_VDM                       */        PVMSTAT pvmstat  /* Pointer to VMSTAT info structure  */     );                  /* Returns TRUE                      */ where VMSTAT is a structure containing: typedef struct vmstat_s {       BOOL  fPtrHidden;    /* Visual pointer status         */ ULONG x;            /* Current virtual x position    */ ULONG y;            /* Current virtual y position    */ ULONG flButtons;    /* Current button status         */ } VMSTAT;

/*    ** Button status bit definitions */

#define BUTBIT_LEFT    0x0001 #define BUTBIT_RIGHT   0x0002 #define BUTBIT_CENTER  0x0004

Virtual Video Device Driver Services for OS/2 Applications (DosRequestVDD)
The following services are intended to provide a method for any OS/2 Ring 3 application to manage or obtain the video state of a DOS session.

DOS Session Window Manager Services
For the DOS Session Window Manager, the virtual video device driver provides the following DOSRequestVDD services: DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_SETACCESS (1)            */        ULONG cbInput,  /* See the ACCESS_ constants          */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Undefined                          */        PVOID pOutput   /* Undefined                          */     );
 * The Set Access request informs the virtual video device driver that the caller is interested in receiving video events for the requested DOS session, preventing future callers from obtaining the same privilege. It also declares the DOS session to be windowed. Under the cover, the virtual video device driver can initiate a global timer hook for the purpose of video event checking upon creation of the first DOS session. In addition, the same interface can be used by the OS/2 Session Window Manager to help the virtual video device driver track which sessions are being windowed by PM so that events are not reported when PM is not foreground. When PM returns to foreground, it is up to the virtual video device driver to post refreshed events so that all DOS-session windows are repainted.

#define ACCESS_RELEASE  0 /* Release access             */ #define ACCESS_REQUEST  1 /* Request access             */ #define ACCESS_PMREQUEST 2 /* Request access made by PM */

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_ACCESS_DENIED (Access already has been taken.) ERROR_INVALID_FUNCTION (iFunc invalid, or access        already set.) DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS Session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_SETFOCUS (2)             */        ULONG cbInput,  /* TRUE if gaining focus,             */                        /*   FALSE if losing                  */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Undefined                          */        PVOID pOutput   /* Undefined                          */     );
 * The Set Focus request records the current DOS session as having or not having focus. Unlike the foreground/background notification hooks provided by the DOS Session Manager (which are supported only by the Session Manager), this function is called by the DOS Session Window Manager as the user gives or takes focus to or from DOS sessions.

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION (iFunc is invalid)
 * The Set Lock request suspends and resumes the DOS session's video state. The virtual video device driver guarantees that the video state will not change following a LOCK until a corresponding UNLOCK is issued. Moreover, if a DOS session is locked multiple times, it must be unlocked an equivalent number of times before it is truly unlocked.

Implementation of this service currently is based on the VDHFreeze and VDHThaw services, instead of a lazy lock, to avoid additional overhead in the interrupt and I/O handlers, and to make the lock implementation simple for both background and foreground DOS sessions. Consequently, callers should use the lock service sparingly and for as brief a time as possible to avoid communication problems due to line drop. DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_SETLOCK (3)              */        ULONG cbInput,  /* TRUE if locking,                   */                        /*   FALSE if unlocking               */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Undefined                          */        PVOID pOutput   /* Undefined                          */     );

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION (iFunc is invalid) ERROR_BUFFER_OVERFLOW (Too many freezes       outstanding.) DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_QUERYMODE (4)            */        ULONG cbInput,  /* 0                                  */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Sizeof(VVMODE)                     */        PVOID pOutput   /* Pointer to a VVMODE structure      */     );
 * The Query Mode request returns current mode information for the DOS session, such as screen dimensions, whether or not the DOS session is suspended, code-page ID, and so forth.

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_INVALID_PARAMETER   (Pointers are invalid.) ERROR_NOT_READY           (VDM has no video state                                           yet.) ERROR_ACCESS_DENIED       (User buffer could not                                           be locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                           outstanding.) where VVMODE is a structure containing: /*    ** Output for MODE event */

typedef struct vvm_s {       ULONG ulAdapter;    /* See the ADAPTER_* constants. */       ULONG ulFormat;     /* See the FORMAT_* constants. */       ULONG ulDDFormat;   /* See the DDFORMAT_* constants. */       ULONG flMode;       /* Mode descriptors (See MODE_*   */                            /*  constants.)                   */ ULONG nRows;       /* Height of screen in rows       */ /* (or y pels)                   */ ULONG nCols;       /* Width of screen in columns     */ /* (or x pels)                   */ ULONG nPlanes;     /* Number of planes (Must be 1    */                            /*  for OS/2 2.0.)                */ ULONG nBitCount;   /* If TEXT, zero;  if BITMAP,     */ /* bits per pel).                */        ULONG ulCellWidth;  /* Width of cells (normally 8;    */ /* 1 for BITMAPs)                */        ULONG ulCellHeight; /* Height of cells (1 for         */ /* BITMAPs)                      */        ULONG fSuspended;   /* See the SUSPEND_* constants.   */        ULONG cpID;         /* Current code-page ID           */        ULONG FormatID;     /* Current format ID              */     }  VVMODE;     #define ADAPTER_MONO  0   /* Adapters supported          */     #define ADAPTER_CGA   1   /* (Same as VioGetConfig       */ /* constants)                 */     #define ADAPTER_EGA   2     #define ADAPTER_VGA   3     #define ADAPTER_8514A 7

#define FORMAT_CGA   2   /* LVB formats supported       */ #define FORMAT_4BYTE 4 #define FORMAT_BITMAP 0

#define DDFORMAT_4PLANE 1 /* Display driver formats     */ /* supported                  */

#define MODE_MONO       0x0001 /* Monochrome mode in    */ effect               */ #define MODE_UNDERLINE  0x0002 /* Underlining in effect */ #define MODE_SUP_XSCALE2 0x1000 /* X scaling supported  */ /* by factor of 2       */ #define MODE_SUP_YSCALE2 0x2000 /* Y scaling supported  */ /* by factor of 2       */ #define MODE_SUP_PARTIALSCAN 0x4000 /* Partial scan line */ /* copy requests supported */ #define SUSPEND_NONE            0 /* DOS session running*/ normally          */ #define SUSPEND_OUT_OF_MEMORY   1 /* DOS session sus-   */ pended due to low */ /* memory            */ #define SUSPEND_UNSUPPORTED_MODE 2 /* DOS session sus-  */ pended due to     */ /* unsupported mode  */ DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_QUERYCURSOR (5)          */        ULONG cbInput,  /* 0                                  */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Sizeof(VVCURSOR)                   */        PVOID pOutput   /* Pointer to a VVCURSOR structure    */     );
 * The Query Cursor request returns current cursor position and shape information for the DOS session:

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_INVALID_PARAMETER   (Pointers are invalid.) ERROR_NOT_READY           (VDM has no video state                                    yet.) ERROR_ACCESS_DENIED       (User buffer could not be                                    locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) where VVCURSOR is a structure containing: /*    ** Output for CURSOR event */

typedef struct vvc_s {       ULONG row;          /* Row (Y position) of DOS        */ /* session's cursor              */ ULONG col;         /* Column (X position) of DOS     */ /* session's cursor              */ ULONG ulScanStart; /* Starting scan line for DOS     */ /* session's cursor              */ ULONG ulScanEnd;   /* Ending scan line for DOS       */ /* session's cursor              */ ULONG fVisible;    /* TRUE if DOS session cursor     */ /* visible,                      */ /* FALSE if not                  */ } VVCURSOR; DosRequestVDD(       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_QUERYPALETTE (6)         */        ULONG cbInput,  /* 0                                  */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Size of RGB array, in bytes        */        PVOID pOutput   /* Pointer to RGB array               */     );
 * The Query Palette request returns the RGB array for the DOS session. The RGB array contains 16 RGB entries for text modes and (2(n) bits per pel) entries for graphics modes:

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_INVALID_PARAMETER   (Pointers are invalid.) ERROR_NOT_READY           (VDM has no video state                                    yet.) ERROR_ACCESS_DENIED       (User buffer could not be                                    locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) where the RGB array contains 16 RGB entries for text modes (FORMAT_CGA) and (2(n)BitCount) entries for graphics modes. RGB entries are packed on byte boundaries and have the following structure: typedef struct rgb_s {       BYTE bBlue; BYTE bGreen; BYTE bRed; } RGB; DosRequestVDD (       HVDD  hvddVideo /* virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_COPYLVB (7)              */        ULONG cbInput,  /*  Sizeof(RECTL)                     */        PVOID pInput,   /* Pointer to RECTL structure         */        ULONG cbOutput, /* Size of output LVB                 */        PVOID pOutput   /* Pointer to output LVB              */     );
 * The Copy LVB request copies a rectangular portion of the DOS session's logical video buffer (that is, text-based LVB) to the specified output LVB. Using this call, the DOS Session Window Manager can keep a private copy of the LVB in sync with the virtual video device driver's LVB for a given DOS session:

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_INVALID_PARAMETER   (Pointers are invalid.) ERROR_NOT_READY           (DOS session has no video                                    state yet.) ERROR_INVALID_DATA        (DOS session has changed                                    video modes.) ERROR_NOT_LOCKED          (Caller must lock DOS                                    session) ERROR_ACCESS_DENIED       (User buffer could not be                                    locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) where RECTL is a structure defining the region to be copied: typedef struct rcl_s {       LONG xLeft;     /* Left column (leftmost is 0)        */ LONG yBottom;  /* Bottom row                         */ LONG xRight;   /* Right column                       */ LONG yTop;     /* Top row (topmost is 0)             */ } RECTL; and where pOutput points to an output LVB. Using this call, the DOS Session Window Manager keeps a private LVB in sync with the virtual video device driver's LVB for a given DOS session. Arbitrary rectangles of the source LVB are copied to the same relative position in the target LVB.

ERROR_INVALID_DATA is returned to callers that have exclusive event access when a DOS session is in the process of changing video modes. It alleviates the need for a caller to constantly lock and unlock the DOS session to ensure a reliable transfer. Callers without exclusive event access have no alternative but to lock and unlock for each copy; otherwise, they run the risk of obtaining incorrect or obsolete information. The virtual video device driver enforces this, and will return ERROR_NOT_LOCKED if called without exclusive access and the DOS session unlocked.

DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_COPYBITMAP (8)           */        ULONG cbInput,  /* Sizeof(VVRECT)                     */        PVOID pInput,   /* Pointer to VVRECT structure        */        ULONG cbOutput, /* Size of output graphics buffer     */        PVOID pOutput   /* Pointer to output graphics buffer  */     );
 * The Copy Bit Map request copies a rectangular portion of the DOS session's graphics video buffer to the specified output buffer. The output buffer is interpreted either as a device-dependent bit map (DDB) into which the requested region is copied at the same relative position, or as a device-independent bit map (DIB) intermediate buffer into which the region always is copied, starting at offset 0.

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid) ERROR_INVALID_PARAMETER   (Pointers are invalid) ERROR_NOT_READY           (DOS session has no video                                    state yet) ERROR_INVALID_DATA        (DOS session has changed                                    video modes) ERROR_NOT_LOCKED          (Caller must lock DOS                                    session) ERROR_ACCESS_DENIED       (User buffer could not                                    be locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) where VVRECT is a structure defining the region to be copied and how it is to be copied: /*    ** Input for COPYBITMAP request */

typedef struct vvr_s {       ULONG  ulDDFormat;  /* Display driver format          */ /* (0 if DIB used)               */ ULONG cx;          /* Target bit map width           */ ULONG cy;          /* Target bit map height          */ RECTL rcl;         /* Rectangle being requested      */ PBYTE pbColorXlate;/* Display driver color           */ /* translation table             */ } VVRECT; and where pOutput points to an output graphics buffer. Using this call, the DOS Session Window Manager keeps a private bit map in sync with the virtual video device driver's graphics buffer for a given DOS session.

ulDDFormat in the VVRECT structure determines whether the request is a DIB transfer (zero) or a DDB transfer (nonzero). DIB transfers are supported for whole scan lines only (that is, xLeft and xRight are ignored). The first requested scan line must be copied to offset 0 of the bit-map buffer, and so on.

Only one DDB format, DDFORMAT_4PLANE (1), has been defined for the current release, but third parties that provide both new virtual video device drivers and new PM display drivers can define their own formats. The DOS Session Window Manager, in its capacity as mediator between the virtual video device driver and the Presentation Manager display driver, makes no interpretation of ulDDFormatin the VVMODE structure other than to initiate device-independent bit-map transfers for a zero format and device-dependent transfers for nonzero formats.

The DDFORMAT_4PLANE format requires a bit-map buffer that matches the dimensions of the DOS session's current graphics mode and has exactly four color planes (16 colors). The first scan line of the first plane is at offset 0, followed by the first scan line of the second plane at the next DWORD boundary, and so on. In addition, none of the four planes of data for a particular scan line can cross a 64KB boundary; instead, they must start at the next 64KB boundary.

For example, if the DOS session is in a 640 x 480 x 16 mode (that is, four planes of 480 80-byte scan lines), then only 204 complete scan lines will fit in each 64KB section of the buffer. The buffer must therefore be 128KB, plus 22.5KB for the 72 remaining scan lines, for a total of 150.5KB.

For this version of OS/2, DDFORMAT_4PLANE bit-map transfers are supported only for whole scan lines (vvr.rcl.xLeft and vvr.rcl.xRight are ignored). The buffer is assumed to be as large as the DOS session's current graphics screen dimensions, and the requested scan lines must be copied to the same relative position within the target buffer.

ERROR_INVALID_DATA is returned to callers that have exclusive event access when a DOS session is in the process of changing video modes. It alleviates the need to constantly lock and unlock the DOS session to ensure a reliable transfer. Callers without exclusive event access have no alternative but to lock and unlock for each copy; otherwise, they run the risk of obtaining incorrect or obsolete information. The virtual video device driver enforces this, and will return ERROR_NOT_LOCKED if called without exclusive access when the DOS session is unlocked.

?The Wait Event request returns the next windowed DOS session video event. The DOS Session Window Manager uses this interface to obtain video state changes for any unminimized windowed DOS sessions and calls the appropriate graphics engine or PM Window Manager interfaces to realize the changes: DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_WAITEVENT (9)            */        ULONG cbInput,  /* Size of buffer for event data      */        PVOID pInput,   /* Pointer to event buffer            */        ULONG cbOutput, /* Sizeof(VVEVENT)                    */        PVOID pOutput   /* Pointer to VVEVENT structure       */     );

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_INVALID_PARAMETER   (Pointers are invalid.) ERROR_ACCESS_DENIED       (User buffer could not be                                    locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) where VVEVENT is filled in with the following information: /*    ** Output for VVDSYSREQ_WAITEVENT */

typedef struct vve_s {       LONG  iEvent;  /* One of the VVDEVENT_constants       */ ULONG sgID;   /* Screen group ID of DOS session      */ ULONG nData;  /* # of entries of information returned*/ } VVEVENT;

/* Event IDs for VVDSYSREQ_WAITEVENT. */

#define VVDEVENT_NONE    0  /* No change                */ #define VVDEVENT_MODE    1  /* Mode change              */ #define VVDEVENT_PALETTE 2  /* Palette change           */ #define VVDEVENT_LVB     3  /* Text or graphics buffer change                  */ #define VVDEVENT_SCROLL  4  /* Scroll change            */ #define VVDEVENT_STRING  5  /* String output change     */ #define VVDEVENT_CURSOR  6  /* Cursor position/type change                  */ #define VVDEVENT_INPUT   7  /* DOS session is input ready */ #define VVDEVENT_ENDPASTE 8 /* Cancelled pasting        */ #define VVDEVENT_PASTE   9  /* Start pasting            */ #define VVDEVENT_SWITCHERROR 10 /* Session switch error */ #define VVDEVENT_TITLECHANGE 11 /* Session title change */ #define VVDEVENT_DDE        12  /* Set/Clear DDE flag */ and the buffer addressed by pInput is filled in with: VVMODE structure,      if (iEvent == VVDEVENT_MODE) VVLVB structure(s),    if (iEvent == VVDEVENT_LVB) VVSCROLL structure,    if (iEvent == VVDEVENT_SCROLL) VVSTRING structure,    if (iEvent == VVDEVENT_STRING) VVCURSOR structure,    if (iEvent == VVDEVENT_CURSOR or                                VVDEVENT_INPUT) null-terminated string, if (iEvent == VVDEVENT_TITLECHANGE) For all the above events, nData will equal 1 (with the exception of the LVB event, which will return the number of VVLVB structures provided). For those events not listed (PALETTE, PASTE, ENDPASTE, SWITCHERROR, and NONE), nData will equal 0, as no additional data is returned with those notifications.

DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* DOS session screen group ID        */        ULONG iFunc,    /* VVDSYSREQ_CONTROLEVENT (10)        */        ULONG cbInput,  /* See the CONTROL_constants          */        PVOID pInput,   /* Pointer to event buffer            */        ULONG cbOutput, /* Sizeof(VVEVENT)                    */        PVOID pOutput   /* Pointer to VVEVENT structure       */     );
 * The Control Event request provides several subfunctions that control the event thread (that is, any thread dedicated to the WAITEVENT request).

#define CONTROL_RELEASE        0 /* Release event thread */ #define CONTROL_VDMMINIMIZED   1 /* Disable video events */ /* for DOS session     */ #define CONTROL_VDMUNMINIMIZED 2 /* Enable video events  */ /* for DOS session     */

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION (iFunc is invalid) ERROR_INVALID_PARAMETER (parameter(s) are invalid) The RELEASE function is used to unblock any threads blocked in the WAITEVENT request. The resulting event is NONE. The VDMMINIMIZED and VDMUNMINIMIZED functions disable and enable event reporting for the DOS session, respectively.

Presentation Manager Display Driver Services
The virtual device driver provides the following DOSRequestVDD services for the PM display driver. DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* NULL (that is, none)               */        ULONG iFunc,    /* VVDSYSREQ_SETDRQ (11)              */        ULONG cbInput,  /* Sizeof(VVDRQ)                      */        PVOID pInput,   /* Pointer to VVDRQ structure         */        ULONG cbOutput, /* Undefined                          */        PVOID pOutput   /* Undefined                          */     );
 * The Set Display Requirements request is issued by a PM display driver whenever PM switches to or from full-screen operation (including the first time it initializes the display, during system initialization):

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_INVALID_PARAMETER   (Parameters are invalid.) ERROR_ACCESS_DENIED       (User buffer could not be                                    locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) where VVDRQ is a structure defining the region to be copied and how it is to be copied: /*    ** Structure for VVDSYSREQ_SETDRQ */

typedef struct vvdrq_s {       PBYTE  pPhysVRAM;   /* Physical address of VRAM       */ ULONG nbReserved;  /* Number of reserved bytes       */ ULONG offLatchByte;/* Offset of available latch /* storage                       */ PBYTE pfbDRQFlags; /* Pointer to flags (see DRQ_*    */                            /* constants)                     */ PBYTE pfCtrlOwned; /* Addr. of display.dll's        */ /* fCtrlOwned flag               */ PBYTE pfCtrlNotify;/* Addr. of display.dll's        */ /* fCtrlNotify flag              */ ULONG nShadowRegs; /* Number of registers to shadow  */ PVVREG pShadowData; /* Address of first entry in     */ /* shadow list                   */ } VVDRQ;

#define DRQ_DIRTYREGS 0x01 /* Video controller registers */ /* modified                  */ and in which the PVVREG pointer points to one or more structures (as indicated by nShadowRegs) containing: /*    ** Shadow entry for VVDSYSREQ_SETDRQ */

typedef struct vvreg_s {       USHORT port;    /* Port number                         */ CHAR  indx;    /* Register index # (-1 if index reg)  */ BYTE  value;   /* Last value written to register      */ /* by virtual video device driver     */ } VVREG; DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* NULL (that is, none)               */        ULONG iFunc,    /* VVDSYSREQ_REQMEM (12)              */        ULONG cbInput,  /* 1 implies WAIT, 0 implies NOWAIT   */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* # of bytes of off-screen memory    */                        /* needed                             */        PVOID pOutput   /* Address of DWORD to receive offset */     );
 * pPhysVRAM :indicates the starting physical address for VGA VRAM that the display driver will use (for example, A0000h).
 * nbReserved :is the number of bytes of display memory reserved exclusively for the PM display driver. It includes all the visible on-screen memory required, which must start at offset 0 from pPhysVRAM, as well as any off-screen memory needed for mouse pointer manipulation, latch storage, and so forth, immediately following. 64KB minus nbReserved yields the amount of off- screen memory to be managed by the virtual video device driver.
 * offLatchByte :is the offset (relative to pPhysVRAM) of a byte of video memory that the virtual video device driver can use at any (non-interrupt) time to temporarily save or restore VGA latches to and from system memory.
 * pfbDRQFlags :is a 16:16 pointer (Global Descriptor Table (GDT) alias selector:offset) to a byte of resident data containing inter-device driver communication bits. Currently, only one bit (bit 0) is defined, and it is set whenever the virtual video device driver has modified VGA Sequencer or Graphics Data Controller (GDC) registers. The PM display driver uses the bit to determine whether or not it must reinitialize any Sequencer or GDC registers it uses prior to the next PM drawing operation, after it has claimed ownership of the VGA controller.
 * pfCtrlOwned :Is another 16:16 pointer-to-byte flag that is 0 if the controller is currently unowned, or 1 if owned. When either party sets the flag, the test and set must be done atomically (for example, XCHG and CMP) to avoid race conditions. If the PM display driver cannot set the flag, it must issue the REQCTRL function to force the virtual video device driver to clear the flag immediately. Similarly, if the virtual video device driver cannot set the flag, it must set the CtrlNotify byte flag (the 16:16 address of which is in pfCtrlNotify) and wait for the PM display driver to finish the current drawing operation and issue the FREECTRL function.
 * pShadowData :is a 16:16 pointer to an array of entries specifying a VGA port (for example, 3C0H, 3CEH), a register index or -1 for the index itself, and a shadow byte in which any changes to that register or index must be stored. The virtual video device driver must update the shadow bytes in parallel with the actual OUT instructions, uninterrupted, so that interrupt-time PM pointer operations are not affected. The PM display driver also updates the shadow bytes, but it has no obligation to do so.
 * The Request Off-screen Memory request is issued by a PM display driver when it wants to use some of the non-reserved off-screen memory.

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_ACCESS_DENIED       (User buffer could not be                                    locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) ERROR_NOT_ENOUGH_MEMORY   (Off-screen memory                                    allocation failed.) On successful return, pOutput points to an offset (relative to pPhysVRAM) of one or more contiguous pages of off-screen VGA memory. In the current virtual video device driver implementation, the request always fails if any DOS sessions currently exist. This way, if any background or windowed DOS sessions switch to a planar graphics mode, they will not be starved for VGA memory due to indeterminate memory consumption by PM (for example, Task Manager popped up, pull-down menu active, and so forth). DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* NULL (that is, none)               */        ULONG iFunc,    /* VVDSYSREQ_FREEMEM (13)             */        ULONG cbInput,  /* Undefined                          */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* # of bytes of off-screen memory    */                        /*   freeing                          */        PVOID pOutput   /* Address of DWORD containing offset */     );
 * The Free Off-screen Memory request is issued by a PM display driver to free memory allocated by the above request. It should do so in a timely manner, particularly if the memory was allocated by way of a WAIT request.

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_ACCESS_DENIED       (User buffer could not                                    be locked.) ERROR_LOCK_FAILED         (Too many VDD locks                                    outstanding.) DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* NULL (that is, none)               */        ULONG iFunc,    /* VVDSYSREQ_REQCTRL (14)             */        ULONG cbInput,  /* Undefined                          */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Undefined                          */        PVOID pOutput   /* Undefined                          */     );
 * The Request VGA Controller request is issued by a PM display driver to force the virtual video device driver to immediately release ownership of the VGA controller. Ownership is indicated by the fCtrlOwned byte flag (see the VVDRQ data structure description in the section titled Presentation Manager Display Driver Services).

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION (iFunc is invalid.) DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* NULL (that is, none)               */        ULONG iFunc,    /* VVDSYSREQ_FREECTRL (15)            */        ULONG cbInput,  /* Undefined                          */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Undefined                          */        PVOID pOutput   /* Undefined                          */     );
 * The Free VGA Controller request is issued by a PM display driver to notify the virtual video device driver that the VGA controller is now available. This request is not issued every time the display driver completes an operation, but rather when the virtual video device driver has requested notification by setting the fCtrlNotify byte flag (see the VVDRQ data structure description in the section titled Presentation Manager Display Driver Services).

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) DosRequestVDD (       HVDD  hvddVideo,/* Virtual video device driver handle */        SGID  sgID,     /* NULL (that is, none)               */        ULONG iFunc,    /* VVDSYSREQ_QUERYVRAMSTATUS (16)     */        ULONG cbInput,  /* Undefined                          */        PVOID pInput,   /* Undefined                          */        ULONG cbOutput, /* Undefined                          */        PVOID pOutput   /* Undefined                          */     );
 * The Query VRAM Status request is issued by the PM Session Manager during screen-switches back to PM. It indicates whether or not any intermediate full-screen switches to DOS sessions might possibly have invalidated PM's last video image. If no invalidation occurred, then certain expensive PM application repaints are avoided.

Returns:

NO_ERROR ERROR_INVALID_HANDLE ERROR_INVALID_SCREEN_GROUP ERROR_INVALID_FUNCTION    (iFunc is invalid.) ERROR_INVALID_DATA        (Video memory has been invalidated.) Success indicates that PM's memory image is intact; failure means that the image may or may not be intact.

Other Virtual Video Device Driver Services
A virtual video device driver provides many VDHRequestVDD services for other virtual video device drivers. Some of the common services provided are listed below: VDHRequestVDD (       HVDD  hvddVideo,        HVDM  hvdm,        INT   iFunc,    /* VVDDEVREQ_DEVACCEPT (5)            */        PVOID pReqIn,   /* Undefined                          */        PVOID pReqOut   /* Undefined                          */     );                 /* Returns TRUE                       */

VDHRequestVDD (       HVDD  hvddVideo,        HVDM  hvdm,        INT   iFunc,    /* VVDDEVREQ_DEVRELEASE (6)           */        PVOID pReqIn,   /* Undefined                          */        PVOID pReqOut   /* Undefined                          */     );                 /* Returns TRUE                       */ VDHRequestVDD (       HVDD  hvddVideo,        HVDM  hvdm,        INT   iFunc,    /* VVDDEVREQ_DSPACCEPT (7)            */        PVOID pReqIn,   /* Undefined                          */        PVOID pReqOut   /* Undefined                          */     );                 /* Returns TRUE                       */

VDHRequestVDD (       HVDD  hvddVideo,        HVDM  hvdm,        INT   iFunc,    /* VVDDEVREQ_DSPRELEASE (8)           */        PVOID pReqIn,   /* Undefined                          */        PVOID pReqOut   /* Undefined                          */     );                 /* Returns TRUE                       */

VDHRequestVDD (       HVDD  hvddVideo,        HVDM  hvdm,        INT   iFunc,    /* VVDDEVREQ_POSTEVENT (9)            */        PVVPOST pvvp,   /* Pointer to event structure         */        PVOID pReqOut   /* Undefined                          */     );                 /* Returns TRUE                       */ Any virtual video device driver receiving a DEVRELEASE request that owns its respective device should release ownership (that is, uninstall all associated I/O hooks, page-fault hooks, page mappings, and so forth), so that an accompanying virtual device driver can manage the device in its stead.

This support is provided for multiple virtual video device drivers installed for the same device, but virtualizing different aspects of the hardware (for example, standard VGA and Super VGA virtual video device drivers for a single Super VGA adapter). A virtual video device driver that is not currently the owner must silently pass on any DosRequestVDD and VDHRequestVDD requests that it receives, using the VDDREQ_PASS return code.

Similarly, any virtual video device driver receiving a DEVACCEPT request that does not already own its respective device and can currently accept ownership should take it (that is, install appropriate I/O hooks, page- fault hooks, page mappings, and so forth).

The DSPACCEPT and DSPRELEASE requests are similar to the preceding requests but much more restricted in scope. They are generally intended to determine which virtual video device driver (for one or more adapters) is managing the image currently displayed. For example, on VGA and 8514/A single- display systems, the display owner is the virtual video device driver that responds to certain system requests (that is, QUERYMODE to COPYBITMAP) and virtual mouse device driver drawing requests.

The Post Event request also passes the following structure: /*    ** Input for POSTEVENT request */

typedef struct vvp_s {       LONG   iEvent;  /* See the VVDEVENT_* constants       */ PVOID pEvent;  /* Event data (varies from one event  */                        /* to another)                        */ ULONG flEvent; /* Event posting flags                */ /*  (See POSTEVENT_*                                   /*    constants)           */ } VVPOST;

#define VVDEVENT_NONE       0 /* No change              */ #define VVDEVENT_MODE       1 /* Change in VDM's mode   */ #define VVDEVENT_PALETTE    2 /* Change in VDM's palette*/ #define VVDEVENT_LVB        3 /* Change in VDM's LVB    */ #define VVDEVENT_SCROLL     4 /* Scroll of VDM's LVB    */ #define VVDEVENT_STRING     5 /* String output          */ #define VVDEVENT_CURSOR     6 /* Cursor position/type   */ /* change                */ #define VVDEVENT_INPUT      7 /* DOS session is checking*/ /* for input data        */ #define VVDEVENT_ENDPASTE   8 /* DOS session has        */ /* cancelled pasting     */ #define VVDEVENT_PASTE      9 /* DOS session is ready   */ /* for additional pasting */ #define VVDEVENT_SWITCHERROR 10 /* DOS session cannot be */ /* switched foreground  */ #define VVDEVENT_TITLECHANGE 11 /* DOS session title has */ /* changed              */ #define VVDEVENT_DDE          12 /* Set/Clear DDE flag  */ #define POSTEVENT_ADD     0x0001 /* Add given event. */    #define POSTEVENT_FLUSH    0x0002 /* Flush given (or     */                                       /* existing) event     */ #define POSTEVENT_DELETE  0x0004 /* delete existing event*/ This gives a virtual video device driver (for example, 8514/A) that is operating cooperatively with another virtual video device driver (for example, CGA/EGA/VGA) the ability to post events to the DOS Session Window Manager without having to duplicate the event management.

Super VGA Virtual Video Device Driver Support
This section describes how to add support for a new chip set with Super VGA capability. The source code used is compiled conditionally to produce all the virtual video device drivers; care should be taken to ensure that additions are inserted into the appropriate driver.

Overview
The first goal of virtual video device driver support is to maintain the integrity of the operating system, and then to maintain the integrity of the DOS session. A DOS session has almost total access to the video hardware when running full-screen (foreground) and can put it into a state that prevents successful return to the desktop. An application can program registers into any state and use on-chip hardware-assist or coprocessed capabilities. A DOS session with full access to the video hardware can make use of all the capabilities provided.

While the DOS session remains full-screen, none of this is a problem. However, when a user wants to switch to another session, the adapter state must be saved and then restored accurately when it is brought into the foreground again. (Requirements for the application to continue to execute in the background will be addressed later in this chapter.) Assume that if the DOS session application is operating in an enhanced mode (above standard VGA), it is put into a suspended state, that is, it is not permitted to execute while in the background.

A virtual video device driver works hardest when switching from background to foreground, or the reverse. At these times, the entire state of the adapter, register, and video memory contents must be saved and restored.

In addition, if the base video subsystem is not adapter- or chip set-aware, the adapter must be placed (by default) into a clean state. A problem could occur if the new foreground session, after leaving an enhanced-mode DOS session, is a protect-mode session and no base video support exists for protect mode. Notice that the desktop is just another protect mode session that also might be running in an enhanced mode. This enhanced-mode support might be localized to the desktop display driver. Do not confuse this with protect-mode support.
 * CAUTION :Anytime a virtual video device driver requires register access to determine chip revisions,or for whatever reason, that process can occur in the background. All registers read from or written to should be restored, including their indexes, if appropriate.

Initial Considerations
The existing virtual video device driver, which forms the base for the new support, is aware of all VGA registers. Therefore, the first consideration is to identify the ranges of port addresses that are not part of the register set. All extended registers must be shadowed when a DOS session is in the background and saved/restored, including extensions to indexed registers already in the VGA range and non-indexed registers.

Currently, most chip sets have some means of mapping the video buffer into the A000-BFFF address range, or alternatively, access to video memory through port I/O. If the buffer is memory-mapped into some other region below 1MB, that part of the DOS session address space must be reserved by the virtual video device driver to handle the page faults generated as a result of access to those addresses by the DOS session.

Support for coprocessed chip sets requires even further consideration. A DOS session can switch from foreground to background at any time. If a DOS session application has initiated a coprocessor operation that has not completed when the virtual video device driver receives control to perform a switch to the background, some strategy must be adopted to ensure that, for instance, no data is lost by the DOS session. Obviously, this is relevant only if data is required from the application in a system memory-to-video memory transfer, or the reverse. Foreground and background switches are further described later in this chapter.

Initialization
During the creation of a DOS session, the virtual video device driver is called to perform certain tasks before the DOS session is permitted to execute.

Chip Set Identification
Before creating the first DOS session the chip set on which the device driver is running should be identified to ensure that virtual video support is provided for that chip set. (This task must be done only once and is not required for subsequent DOS sessions.)

Process PMI File
If this method is employed, the file must be read at this time. This is a once-only operation. Again, this cannot be performed during virtual video device driver initialization because the virtual device helper (VDH) services required to read the file are available only at DOS session task time.

The sections of the file required by the virtual video device driver are AdapterType, ChipSet, TrapRegs, Cleanup, and Lock and UnLock. A check against the adapter/chip set entries is used to confirm that the file is valid for the current configuration.

The list of entries in the TrapRegs section specifies the I/O port addresses and indexed ports that are to be saved and restored by the virtual video device driver. A bit mask for indexed registers is created and used for this purpose.

The Cleanup, Lock, and UnLock sections literally are used to perform the specified functions. Cleanup is required to put the adapter into a default clean state.

Install I/O Hooks
If the chip set uses port addresses that are not in the VGA range, I/O handlers must be installed to handle access to these ports when the DOS session is in the background. Otherwise, any Read or Write will be passed directly to the hardware or to a default handler. Hooks must be provided to take care of the accesses.

Registers with addresses outside the VGA range require individual treatment. Two arrays-ahleFgnd when the DOS session is foreground, and ahleBgnd when the DOS session is background-use a list of ports and their associated functions to handle Reads and Writes to the specified ports.

Initialize Shadow Register Data
The virtual video device driver retains sets of data on a per-DOS session basis. Copies of the contents of all the adapter registers should be stored in this area. All this data must be initialized, including data for extended registers. If the DOS session creation occurs while the DOS session is in the background, the same processing occurs as that for foreground, except that I/O port Reads and Writes are shadowed to and from instance data.

The first video-related operation is a BIOS call to set the initial video mode of the DOS session. If the BIOS expects certain configuration registers to contain information that is required when setting a mode, the shadow data must reflect this; therefore, before the DOS session executes, this shadow data must be set to some defaults - usually a simple case of reading the contents of all registers into the shadow data. This could occur while the hardware is set up in any particular mode; however, mode- specific data should be irrelevant.

Foreground/Background Processing
There are two main functions to be performed here: saving and restoring the contents of registers and video memory. All the information necessary to be able to restore a DOS session to the state at which it last executed should be available.

The ability to save and restore registers is dependent on two arrays of variable length - apleAll and apleNoTrap, which contain port addresses and pointers to data areas for each indexed and non-indexed port. apleNoTrap has entries for I/O ports not trapped when the DOS session is foreground. For example, if a write-only port address is always trapped, even when the DOS session is foreground, this permits its value to be restored from shadow data that is already valid; there is no need (or, in this case, possibility) to read the hardware. These entries in apleNoTrap, then, are for ports that must be read from the hardware. In contrast, the apleAll array contains all port addresses and is used to restore the hardware state.

New port addresses that have not already been handled must be added to these array lists. Registers are restored in the order specified in the array. If there is some dependency as to the order of the programming registers on a restore, the array entries must reflect this dependency.

A number of flags are available when reading or writing registers, which is performed by a non-preemptible routine. One of the flags permits the Sequencer to be reset around the operation. This flag should be used where appropriate.

In any of the enhanced video modes, a shadow video buffer is required also to store all or part of video memory. The decision as to whether to save the entire contents of video memory, or only what is deemed to be in use, depends on two factors: what is known about the video mode in effect, or the default memory organization for that particular mode.

An additional problem that can be encountered when an enhanced mode is set and the DOS session is foreground is that there is no way to determine how much video memory the application has actually used. The only way to accurately determine this is to invalidate the address region occupied by video memory, trap bank selected registers, and handle page faults when this region is touched, invalidating the region with each change in bank. This constitutes background virtualization and is too costly for a foreground DOS session in terms of performance.

Saving all of the video memory all of the time could introduce a significant performance penalty: 1MB of shadow buffer must be kept somewhere and, with multiple DOS sessions in enhanced modes, this could become significant. Currently, a viable compromise is to save as much video memory as is calculated to be in use, using the mode data. (Mode data is determined by inspecting register values to get the display resolution. If this is not reflected in standard VGA registers, special handling is required.)

Upon notification that the DOS session is going into the background, that is, the DOS session is currently full-screen and has full hardware access, the DOS session is frozen to ensure that no further execution takes place. A snapshot of all the registers is thus saved by reading the hardware. As described previously, the apleNoTrap array triggers the saving of appropriate registers. Any special-case processing required to save register states should be a part of this process.

The video buffer contents are then saved in one of two ways: The method used depends on the hardware capabilities. Some registers might need to be placed in a specific state before the video-memory transfer takes place to ensure that the memory organization does not interfere with what is saved. This shadow buffer will be used to create a bit map for the desktop, on request, if the DOS session becomes windowed.
 * Linear modes are handled as straight transfers, 64KB at a time, by setting the appropriate bank and copying from video memory to the shadow buffer.
 * Planar modes are copied, one plane at a time, and the 8514/A uses the graphics engine for the transfer.

Bringing a DOS session to the foreground is almost the reverse process. Registers first are restored to the saved state, and then video memory is restored, followed by another restore of the registers. Part of the memory transfer process involves setting registers to an appropriate state for transfer and could destroy the restored state.

Another important part of this foreground-background processing is the requirement to update data with only a best guess as to the current state of the DOS session. If the DOS session was permitted to run while in the background, its state could have changed from a text mode to graphics mode, or the type of graphics mode may have changed. It is important to be aware of this in order to successfully restore the state of the DOS session. VGA modes indicate their state through use of standard GDC, CRTC, or Sequencer registers, but such might not be the case for a particular chip set. Enhanced mode support could be enabled by the programming of some extended register. Awareness of this functionality must be included as part of updating the state information.

The situation that can arise when switching a DOS session that is using a graphics coprocessor to the background was described previously. The coprocessor could be in the process of accepting data from or passing data to the DOS session application. If, at this point, the DOS session is put into a suspended state, the coprocessor cannot complete the operation, and the DOS session will lose data. Any further attempt to use the DOS session will probably result in an error. The virtual video device driver could complete the operation on behalf of the application, but this might be too complex, unpredictable, or frankly impossible.

The most secure solution is to permit the DOS session to continue to execute until the coprocessor operation has completed. At that stage, before the DOS session is frozen, it is still going to be given an execution time slice. Therefore, you can block the virtual video device driver with a semaphore, effectively pausing the Set Background process until the DOS session has completed its operation. One method of being notified that the operation is complete is to install I/O hooks for all ports and use them to clear the semaphore that blocked the virtual video device driver. Any subsequent port access then will permit the virtual video device driver to regain control to complete the background switch. Any number of hook types can be employed by the virtual video device driver. A coprocessor interrupt could be used, but that requires the use of a physical device driver and a communication mechanism between it and the virtual video device driver.

VGA Virtualization
In order for a DOS session to continue executing in the background while an enhanced video mode is set, some form of hardware emulation for that mode is required, if the hardware is not available. This might not always be possible. In the case of a coprocessed chip, some register accesses might be allowed, such as setting parameters for an impending coprocessor operation. The DOS session can be permitted to continue while this is the case; but if an operation is initiated requiring the coprocessor, DOS session execution must be suspended until the DOS session is brought to the foreground.

Dumb-frame buffer chip sets are easier to emulate in enhanced modes, particularly linear (packed-pel or 256-color) modes. Generally, any planar mode requires use of the hardware to achieve acceptable performance. VGA virtualization utilizes this when off-screen video memory is available. Linear modes can be virtualized as long as no hardware-assist functions are required. If the application restricts its operations to simply updating video memory by selecting banks and reading or writing data, it can continue to execute. All that is required in this case is to map the appropriate portion of the shadow video buffer to the expected part of the DOS session address space, usually the A000 region. Some level of support to achieve this already exists.

It is also possible that two or more distinct pieces of video hardware are available. If the desktop used one chip and a DOS session required use of a secondary chip, this would be possible. Multiple chip set scenarios such as this have many possibilities-beyond the scope of this document. If non- overlapping registers are used for each chip set, two distinct virtual video device drivers can be used; otherwise, the solution is more complex.

Chip Set-Specific Code
Although the PMI File attempts to encapsulate as much chip set-specific data as possible, some chip set-specific code is still required. Two elements, one to get or set the current video memory bank and another to determine the lock state of extended registers, are required.

The main function required is the ability to select banks of video memory for Save, Restore, and Memory-Management operations, requiring two routines: one to set a given bank, another to get the current bank. These routines must be operable from both the current hardware register state and shadow data, depending on whether called in a foreground or background context.

A similar problem involves determining the state of registers used to lock extended functionality, if applicable. The PMI File contains a sequence of I/O operations to be used to lock or unlock extended registers, but the current state of these register also must be determined. Often there is no direct mapping of what is written to these registers to lock or unlock them and what is read back when in either state. A necessary part of the save/restore process is to retain the lock state.

Summary and Suggestions
The following is a guideline and list of files, with a brief summary of points as to what functionality, as described previously, is required in each.

vvuser.c
 * Chip identification, PMI-File processing.
 * Reserve the address space for mapping into other than A000-BFFF range.

vvstate.c
 * Chip-specific Restore/UpdateSVGAIOState, for example, Trident old and new register definitions that cannot be handled by way of PMI entries.
 * Update memory state. If chip uses enhanced modes, use extended registers to determine if it is in enhanced mode.
 * Check for greater than 16-color mode determination.
 * Mode data structure setup, determining the number of horizontal and vertical scanlines and number of colors for current mode.
 * Video memory state detection, 16-color, 256-color, or other modes.
 * Restoring I/O state. Check if register ordering is important. Is Sequencer reset required around extended register update?

vvsvga.c
 * Code routines for getting the register lock state.
 * Code get and set bank routines.
 * Ensure vvMaxBanks routine returns appropriate data for allocating and saving the shadow video buffer.

vvdata.c
 * Add entries to ahleFgnd, ahlBgnd, apleAll, apleNoTrap.
 * Add get/set bank routine entries to apfnGetBank and apfnSetBank.

vvmode.c
 * Cleanups, anything not handled by PMI-File cleandata.

vvpmi.c
 * Add new token entries for PMI-File parsing.

vvport.c
 * Install I/O hooks.

vvsvgaio.asm
 * Routines to be called for new ports hooked in background.

vvsvgaid.asm
 * Chip Set/Board identification code.

vvdp.h
 * Create definitions for new adapter type and chip set.
 * Add function prototypes for new functions defined.