VDD_Register_Virtual_Port

Call With

CL contains the equate WORD_LENGTHED or BYTE_LENGTHED depending on how wide the port is. See the following for instructions on registering doubleword length ports. EDX contains the port number to register

Return Values

Uses EDX and ESI. No data is returned to the caller.

Remarks

This function can only be called up to and including the Init_Complete phase of VxD initialization. It will cause a fatal page fault if called after Init_Complete.

Many modern display cards have hardware BLTers in them that are accessed via I/O ports that are not just extensions to VGA ports. For example, the S3 hardware uses many I/O ports such as BEE8h, 9AE8h etc. to draw onto the display hardware. Many display operations (such as drawing a rectangle) are accomplished on the hardware by the display driver setting values into these I/O ports. The shared memory aperture (such as that at A000:0) is never touched.

When virtualizing a VGA 4 plane graphics application in a window, the VDD changes the MemC state (that is, how the CPU sees the card's Video RAM) from the packed pixel state that the card is running in to a 4 plane state. It then uses off-screen memory as a "pseudo 4 plane VGA" and draws into it in order to take advantage of the VGA's rudimentary BLT engine (such as the latches, SetReset registers, and write modes). The VDD then maps some of this off-screen memory to the VM's A000:0h address. Applications may write to address A000:0h but it is actually writing to a piece of off-screen memory that the VDD has virtually mapped. As a result of this process, the VDD must determine whether to set the MemC state to the packed pixel state that Windows is running in, or the "pseudo planar" state that the VGA 4 plane application is running in.

If the display driver and the VGA 4 plane application were both using the memory aperture at A000:0h as their only method of talking to the video hardware, the VDD's determination of which MemC state to set into the hardware would be easy. If this was the case, when the VGA 4 plane application first touched memory at A000:0h, it would cause a page fault that the VDD would intercept. The Main VDD would then set the MemC state to the "pseudo 4 plane" mode and unmap all of the pages that the Windows VM owned at A000:0h. Then, when the Windows display driver touched memory at A000:0h, it would cause a page fault to the VDD. The VDD would then set the MemC state back to the packed pixel state and unmap all of the 4 plane VGA application pages. This would continue and each VM (the Windows VM where the display driver was running and the MS-DOS VM where the 4 plane VGA application was running) would alternate MemC states and each VM would talk to the video hardware in the correct way.

However, modern display hardware may draw within the Windows VM by setting I/O ports to the correct values and using a hardware BLTer, and never touch address A000:0h. So, the VDD needs an alternate method to know when to switch back to the Windows MemC state. To accomplish this task, the VDD traps the BLTer registers that the display driver may talk to in order to draw to the screen. When the VDD sets the VGA 4 plane MemC state, it also notifies the mini-VDD to enable trapping on the BLTer registers which have been registered via VDD_Register_Virtual_Port. Subsequently, when the Windows display driver next touches one of the ports, the VDD automatically sets the MemC state back to Windows.

Any non-VGA port that your display driver touches during its drawing routines should be registered using VDD_Register_Virtual_Port. If your display card's BLTer registers are extensions to the standard VGA registers, they will be taken care of without calling this service.

So, a mini-VDD must register each port, telling the Main VDD whether it is word lengthed or byte lengthed (by passing the equated flag from MINIVDD.INC in CL) and then hook the ENABLE_TRAPS and DISABLE_TRAPS services to enable and disable trapping for each port that has been registered using VDD_Register_Virtual_Port. Within your ENABLE_TRAPS and DISABLE_TRAPS routines, you must call Enable_Global_Trapping or Disable_Global_Trapping once for each port. If you have a word lengthed port (such as BEE8h), you must call Enable_Global_Trapping for both BEE8h and BEE9h.

There is no support for doubleword lengthed ports. Therefore, if you have a 32 bit wide port, you should call VDD_Register_Virtual_Port twice, once for each half of the doubleword lengthed port registering each half as WORD_LENGTHED.

See the S3 or ATI sample mini-VDD 's for examples of how this BLTer port trapping works .