Begin_Control_Dispatch

include vmm.inc

Begin_Control_Dispatch DeviceName
 

Builds a table for dispatching messages passed to the control procedure for the specified virtual device. This macro is used in conjunction with the Control_Dispatch and End_Control_Dispatch macros.

DeviceName
Name of the virtual device. The macro uses this parameter to construct the label for the control procedure (appends _Control to the end of this name). This control procedure label must also be specified in the Declare_Virtual_Device macro.

The Control_Dispatch macro can be used without Begin_Control_Dispatch, but then it the programmer's responsibility to declare a procedure in locked code (VxD_LOCKED_CODE_SEG), and clear the carry flag for any unprocessed messages. The advantage in using Begin_Control_Dispatch macro is when a large number of messages are processed by a device. The macro builds a jump table which usually requires less code than the sequence of compare and jump instructions that are generated when Control_Dispatch is used alone.

The following example builds a complete dispatch table for the virtual device named MyDevice:

Begin_Control_Dispatch MyDevice
Control_Dispatch  Device_Init, MyDeviceInitProcedure
Control_Dispatch  Sys_VM_Init, MyDeviceSysInitProcedure
Control_Dispatch  Create_VM,   MyDeviceCreateVMProcedure
End_Control_Dispatch MyDevice
 

An alternative method for writing the control procedure is as follows:

BeginProc MyDevice_Control
Control_Dispatch  Device_Init, MyDeviceInitProcedure
Control_Dispatch  Sys_VM_Init, MyDeviceSysInitProcedure
Control_Dispatch  Create_VM,   MyDeviceCreateVMProcedure
clc                                              ; Don't forget
ret                                              ; these two lines!
EndProc MyDevice_Control
 

If you use the CallType variant of the Control_Dispatch macro, you may not use the Begin_Control_Dispatch macro; you must use this alternative method.

NOTE  Do not combine Begin_Control_Dispatch with private system control codes. The following code snippet causes the assembler to appear to hang:

    Begin_Control_Dispatch VDEVICE

    ; <other Control_Dispatch macros go here>
    Control_Dispatch BEGIN_RESERVED_PRIVATE_SYSTEM_CONTROL OnPrivateSysCtrl

    End_Control_Dispatch VDEVICE
 

Cause

=====

When you use the Begin_Control_Dispatch and End_Control_Dispatch macros, the vmm.inc header file builds a jump table to perform the dispatch. Since BEGIN_RESERVED_PRIVATE_SYSTEM_CONTROL has numerical value 70000000h, the vmm.inc header file attempts to build a jump table with over 1.8 billion entries. This causes the assembler to appear to hang.

Workaround

Replace Begin_Control_Dispatch with a BeginProc and End_Control_Dispatch with clc / ret / EndProc. The above code snippet would be transformed as follows:

    BeginProc VDEVICE_Control, LOCKED

    ; <other Control_Dispatch macros go here>
    Control_Dispatch BEGIN_RESERVED_PRIVATE_SYSTEM_CONTROL OnPrivateSysCtrl

    clc
    ret
    EndProc VDEVICE_Control
 

See Also

Control_Dispatch, Declare_Virtual_Device, End_Control_Dispatch