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.
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
Control_Dispatch, Declare_Virtual_Device, End_Control_Dispatch