;****************************************************************************** ; ; (C) Copyright MICROSOFT Corp., 1988-1990 ; ; Title: VMM.INC - Include file for Virtual Machine Manager ; ; Version: 1.00 ; ; Date: 05-May-1988 ; ; Author: RAL ; ;------------------------------------------------------------------------------ ; ; Change log: ; ; DATE REV DESCRIPTION ; ----------- --- ----------------------------------------------------------- ; 05-May-1988 RAL Original ; ;============================================================================== ; NON Windows/386 Virtual Device sources can include this file to get some ; useful equates by declaring the symbol "Not_VxD" If this symbol is defined, ; then everything that has to do with the specifics of the 32 bit environment ; for virtual devices is removed. Useful equates include: device ID's, pushad ; structure, BeginDoc/EndDoc/BeginMsg/EndMsg equates, page table equates, etc. False EQU 0 True EQU NOT False ; ; These null macros are recognized by a utility program that produces ; documentation files. ; BeginDoc EQU <> EndDoc EQU <> BeginMsg EQU <> EndMsg EQU <> BeginDoc ;****************************************************************************** ; ; EQUATES FOR REQUIRED DEVICES ; ; Device ID formulation note: ; ; Device ID's are a combination of OEM # and device # in the form: ; ; xOOOOOOOOOODDDDD ; ; The high bit of the device ID is reserved for future use. The next ; 10 bits are the OEM # which is assigned by Microsoft. The last 5 bits ; are the device #. This allows each OEM to create 32 unique devices. ; If an OEM is creating a replacement for a standard device, then it ; should re-use the standard ID listed below. Microsoft reserves the ; first 16 OEM #'s (0 thru 0Fh) ; ;============================================================================== Undefined_Device_ID EQU 00000h VMM_Device_ID EQU 00001h ; Used for dynalink table Debug_Device_ID EQU 00002h VPICD_Device_ID EQU 00003h VDMAD_Device_ID EQU 00004h VTD_Device_ID EQU 00005h V86MMGR_Device_ID EQU 00006h PageSwap_Device_ID EQU 00007h Parity_Device_ID EQU 00008h Reboot_Device_ID EQU 00009h VDD_Device_ID EQU 0000Ah VSD_Device_ID EQU 0000Bh VMD_Device_ID EQU 0000Ch VKD_Device_ID EQU 0000Dh VCD_Device_ID EQU 0000Eh VPD_Device_ID EQU 0000Fh VHD_Device_ID EQU 00010h VMCPD_Device_ID EQU 00011h EBIOS_Device_ID EQU 00012h BIOSXlat_Device_ID EQU 00013h VNETBIOS_Device_ID EQU 00014h DOSMGR_Device_ID EQU 00015h WINLOAD_Device_ID EQU 00016h SHELL_Device_ID EQU 00017h VMPoll_Device_ID EQU 00018h VPROD_Device_ID EQU 00019h DOSNET_Device_ID EQU 0001Ah VFD_Device_ID EQU 0001Bh VDD2_Device_ID EQU 0001Ch ; Secondary display adapter WINDEBUG_Device_ID EQU 0001Dh TSRLoad_Device_ID EQU 0001Eh ; TSR instance utility ID ; ; Initialization order equates. Devices are initialized in order from ; LOWEST to HIGHEST. If 2 or more devices have the same initialization ; order value, then they are initialized in order of occurance, so a ; specific order is not guaranteed. Holes have been left to allow maximum ; flexibility in ordering devices. ; VMM_Init_Order EQU 000000000h Debug_Init_Order EQU 004000000h VPROD_Init_Order EQU 008000000h VPICD_Init_Order EQU 00C000000h VTD_Init_Order EQU 014000000h PageSwap_Init_Order EQU 01C000000h Parity_Init_Order EQU 020000000h Reboot_Init_Order EQU 024000000h EBIOS_Init_Order EQU 026000000h VDD_Init_Order EQU 028000000h VSD_Init_Order EQU 02C000000h VCD_Init_Order EQU 030000000h VMD_Init_Order EQU 034000000h VKD_Init_Order EQU 038000000h VPD_Init_Order EQU 03C000000h VHD_Init_Order EQU 040000000h VFD_Init_Order EQU 044000000h VMCPD_Init_Order EQU 048000000h BIOSXlat_Init_Order EQU 050000000h VNETBIOS_Init_Order EQU 054000000h DOSMGR_Init_Order EQU 058000000h DOSNET_Init_Order EQU 05C000000h WINLOAD_Init_Order EQU 060000000h VMPoll_Init_Order EQU 064000000h Undefined_Init_Order EQU 080000000h WINDEBUG_Init_Order EQU 081000000h VDMAD_Init_Order EQU 090000000h V86MMGR_Init_Order EQU 0A0000000h SHELL_Init_Order EQU 0B0000000h EndDoc ;****************************************************************************** ; ; Macro to cause a delay in between I/O accesses to the same device. ; ;------------------------------------------------------------------------------ IO_Delay macro jmp $+2 ENDM Pushad_Struc STRUC Pushad_EDI dd ? ; Client's EDI Pushad_ESI dd ? ; Client's ESI Pushad_EBP dd ? ; Client's EBP Pushad_ESP dd ? ; ESP at pushall Pushad_EBX dd ? ; Client's EBX Pushad_EDX dd ? ; Client's EDX Pushad_ECX dd ? ; Client's ECX Pushad_EAX dd ? ; Client's EAX Pushad_Struc ENDS IFNDEF Not_VxD ??_CUR_CODE_SEG = 0 ??_CODE = 1 ??_ICODE = 2 ??_LCODE = 3 ??_RCODE = 4 ?_CODE equ <(??_CUR_CODE_SEG MOD 8) - ??_CODE> ?_ICODE equ <(??_CUR_CODE_SEG MOD 8) - ??_ICODE> ?_LCODE equ <(??_CUR_CODE_SEG MOD 8) - ??_LCODE> ?_RCODE equ <(??_CUR_CODE_SEG MOD 8) - ??_RCODE> ; ; SEGMENT definitions and order ; ;* 32 Bit locked code _LTEXT SEGMENT DWORD USE32 PUBLIC 'CODE' _LTEXT ENDS ;* 32 Bit code _TEXT SEGMENT DWORD USE32 PUBLIC 'PCODE' _TEXT ENDS ;* 32 Bit initialization code _ITEXT SEGMENT DWORD USE32 PUBLIC 'ICODE' _ITEXT ENDS ;* Contains 32 Bit locked data _LDATA SEGMENT DWORD PUBLIC 'CODE' _LDATA ENDS ;* Contains 32 Bit data _DATA SEGMENT DWORD PUBLIC 'PCODE' _DATA ENDS ;* Contains 32 Bit initialization data _IDATA SEGMENT DWORD PUBLIC 'ICODE' _IDATA ENDS ;* Real Mode initialization code/data for devices _RCODE SEGMENT WORD USE16 PUBLIC 'RCODE' _RCODE ENDS _LGROUP GROUP _LTEXT, _LDATA _PGROUP GROUP _TEXT, _DATA _IGROUP GROUP _ITEXT, _IDATA ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:FLAT OFFSET32 EQU BeginDoc ;============================================================================== ; The following macros are used in defining the routines ; in a VxD which are going to be registered with VMM as callable entry ; points. Once registered, the entry points can be called by any other ; devices via the "VxDCall" macro, defined below. In the comments below, ; replace "VxD" with the appropriate device name. ; ;******* ; In the VxD.INC file, put the following lines, replacing ; with an appropriate name describing the function of the routine. ; ; Begin_Service_Table VxD[,] ; VxD_Service [,] ; VxD_Service [,] ; . . . ; VxD_Service [,] ; End_Service_Table VxD[,] ; ; Note that is an optional argument and, if specified, the ; table is put in the segment defined by the macro "yyy_Data_Seg", ; where yyy=segname. Otherwise the segment is defined by the ; "VxD_Data_Seg" macro, defined below. ; Note that is an optional argument and, if specified, ; the procedure's segment is defined by the macro "zzz_Code_Seg", ; where zzz=segname. Otherwise the segment is defined by the ; "VxD_Code_Seg" macro, defined below. ; ;******* ; One VxD module should have the following in order to define the entry points: ;Create_VxD_Service_Table = 1 ; Only in module where table is ; INCLUDE VxD.INC ; Include the table definition ; ;******* ; All modules that want to call the services defined in the table should include ; VxD.INC, but not define the label "Create_VxD_Service_Table". This ; will define the service names to be used with the VxDCall macro. ; EndDoc Begin_Service_Table MACRO Device_Name, Def_Segment IFB BST2 Device_Name, VxD ELSE BST2 Device_Name, Def_Segment ENDIF ENDM BST2 MACRO Device_Name, Def_Segment Num_&Device_Name&_Services = 0 IFDEF Create_&Device_Name&_Service_Table Def_Segment&_LOCKED_DATA_SEG Device_Name&_Service_Table LABEL DWORD Device_Name&_Service MACRO Procedure, Local_Seg PUBLIC $&&Procedure IF1 $&&Procedure LABEL DWORD ENDIF IFDIFI , IFNB Local_Seg&&_SEG ELSE Def_Segment&_CODE_SEG ENDIF EXTRN @&&Procedure:NEAR IFNB Local_Seg&&_ENDS ELSE Def_Segment&_CODE_ENDS ENDIF ENDIF dd OFFSET32 @&&Procedure Procedure = (Device_Name&_Device_ID SHL 16) + Num_&Device_Name&_Services Num_&Device_Name&_Services = Num_&Device_Name&_Services + 1 ENDM ELSE Device_Name&_Service MACRO Procedure Procedure = (Device_Name&_Device_ID SHL 16) + Num_&Device_Name&_Services Num_&Device_Name&_Services = Num_&Device_Name&_Services + 1 ENDM ENDIF ENDM ;------------------------------------------------------------------------------ End_Service_Table MACRO Device_Name, Def_Segment PURGE Device_Name&_Service IFDEF Create_&Device_Name&_Service_Table IFB VxD_LOCKED_DATA_ENDS ELSE Def_Segment&_LOCKED_DATA_ENDS ENDIF ENDIF ENDM ;****************************************************************************** ; ; Dword_Align -- Aligns code to dword boundry by inserting nops ; ;------------------------------------------------------------------------------ Dword_Align MACRO Seg_Name LOCAL segn IFNB segn equ Seg_Name ELSE IFE ?_CODE segn equ <_TEXT> ELSE IFE ?_ICODE segn equ <_ITEXT> ELSE IFE ?_LCODE segn equ <_LTEXT> ELSE .err Dword_Align not supported ENDIF ENDIF ENDIF ENDIF IF (($-OFFSET segn:0) MOD 4) db 4 - (($-OFFSET segn:0) MOD 4) DUP (90h) ENDIF ENDM BeginDoc ;****************************************************************************** ; ; Fatal_Error ; ; DESCRIPTION: ; This macro is used to crash Windows/386 when an unrecoverable error ; is detected. If Msg_Ptr is ommitted then no error message will be ; displayed, otherwise Msg_Ptr is the address ; when the ; ; PARAMETERS: ; Msg_Ptr (OPTIONAL) - Points to an ASCIIZ string to display. ; ; EXIT: ; To DOS (hopefully). This macro never returns. ; ;============================================================================== EndDoc Fatal_Error MACRO Msg_Ptr, Exit_Flags pushad IFB xor esi, esi ELSE mov esi, Msg_Ptr IFB xor eax, eax ELSE mov eax, Exit_Flags ENDIF ENDIF VMMcall Fatal_Error_Handler ENDM EF_Hang_On_Exit EQU 1h ;****************************************************************************** ;============================================================================== ;------------------------------------------------------------------------------ BeginDoc ;****************************************************************************** ; The following are control block offsets of items that can be of interest ; to VxDs. ;******* ; VM status indicates globally interesting VM states CB_VM_Status EQU DWORD PTR 00h VMStat_Exclusive EQU 000000000000000000001b ; VM is exclusive mode VMStat_Exclusive_Bit EQU 0 VMStat_Background EQU 000000000000000000010b ; VM runs in background VMStat_Background_Bit EQU 1 VMStat_Creating EQU 000000000000000000100b ; In process of creating VMStat_Creating_Bit EQU 2 VMStat_Suspended EQU 000000000000000001000b ; VM not scheduled VMStat_Suspended_Bit EQU 3 VMStat_Not_Executeable EQU 000000000000000010000b ; VM partially destroyed VMStat_Not_Executeable_Bit EQU 4 VMStat_PM_Exec EQU 000000000000000100000b ; Currently in PM app VMStat_PM_Exec_Bit EQU 5 VMStat_PM_App EQU 000000000000001000000b ; PM app present in VM VMStat_PM_App_Bit EQU 6 VMStat_PM_Use32 EQU 000000000000010000000b ; PM app is 32-bit VMStat_PM_Use32_Bit EQU 7 VMStat_VxD_Exec EQU 000000000000100000000b ; Call from VxD VMStat_VxD_Exec_Bit EQU 8 VMStat_High_Pri_Back EQU 000000000001000000000b ; High pri background VMStat_High_Pri_Back_Bit EQU 9 VMStat_Blocked EQU 000000000010000000000b ; Blocked on semaphore VMStat_Blocked_Bit EQU 0Ah VMStat_Awakening EQU 000000000100000000000b ; Woke up after blocked VMStat_Awakening_Bit EQU 0Bh VMStat_PageableV86 EQU 000000001000000000000b ; part of V86 is pageable (PM app) VMStat_PageableV86Bit EQU 0Ch VMStat_V86IntsLocked EQU 000000010000000000000b ; Rest of V86 is locked VMStat_V86IntsLockedBit EQU 0Dh ; regardless of pager type VMStat_TS_Sched EQU 000000100000000000000b ; Scheduled by time-slicer VMStat_TS_Sched_Bit EQU 0Eh VMStat_Idle EQU 000001000000000000000b ; VM has released time VMStat_Idle_Bit EQU 0Fh ; slice VMStat_Use32_Mask EQU VMStat_PM_Use32 OR VMStat_VxD_Exec ;******* ; Add this value to a V86 linear address to get address of VM's memory in ; the VMM linear address space CB_High_Linear EQU DWORD PTR 04h ;******* CB_Client_Pointer EQU DWORD PTR 08h CB_VMID EQU DWORD PTR 0Ch ; ; Equates for protected mode application control blocks ; PMCB_Flags EQU DWORD PTR 00h PMCB_Parent EQU DWORD PTR 04h EndDoc ;****************************************************************************** ; V M M S E R V I C E S ;****************************************************************************** Begin_Service_Table VMM, VMM VMM_Service Get_VMM_Version, LOCAL ; MUST REMAIN SERVICE 0! VMM_Service Get_Cur_VM_Handle VMM_Service Test_Cur_VM_Handle VMM_Service Get_Sys_VM_Handle VMM_Service Test_Sys_VM_Handle VMM_Service Validate_VM_Handle VMM_Service Get_VMM_Reenter_Count, LOCAL VMM_Service Begin_Reentrant_Execution, LOCAL VMM_Service End_Reentrant_Execution, LOCAL VMM_Service Install_V86_Break_Point VMM_Service Remove_V86_Break_Point VMM_Service Allocate_V86_Call_Back VMM_Service Allocate_PM_Call_Back VMM_Service Call_When_VM_Returns VMM_Service Schedule_Global_Event VMM_Service Schedule_VM_Event VMM_Service Call_Global_Event VMM_Service Call_VM_Event VMM_Service Cancel_Global_Event VMM_Service Cancel_VM_Event VMM_Service Call_Priority_VM_Event VMM_Service Cancel_Priority_VM_Event VMM_Service Get_NMI_Handler_Addr, LOCAL VMM_Service Set_NMI_Handler_Addr, LOCAL VMM_Service Hook_NMI_Event VMM_Service Call_When_VM_Ints_Enabled VMM_Service Enable_VM_Ints VMM_Service Disable_VM_Ints VMM_Service Map_Flat VMM_Service Map_Lin_To_VM_Addr ; ; Scheduler services ; VMM_Service Adjust_Exec_Priority VMM_Service Begin_Critical_Section VMM_Service End_Critical_Section VMM_Service End_Crit_And_Suspend VMM_Service Claim_Critical_Section VMM_Service Release_Critical_Section VMM_Service Call_When_Not_Critical VMM_Service Create_Semaphore VMM_Service Destroy_Semaphore VMM_Service Wait_Semaphore VMM_Service Signal_Semaphore VMM_Service Get_Crit_Section_Status VMM_Service Call_When_Task_Switched VMM_Service Suspend_VM VMM_Service Resume_VM VMM_Service No_Fail_Resume_VM VMM_Service Nuke_VM VMM_Service Crash_Cur_VM VMM_Service Get_Execution_Focus VMM_Service Set_Execution_Focus VMM_Service Get_Time_Slice_Priority VMM_Service Set_Time_Slice_Priority VMM_Service Get_Time_Slice_Granularity VMM_Service Set_Time_Slice_Granularity VMM_Service Get_Time_Slice_Info VMM_Service Adjust_Execution_Time VMM_Service Release_Time_Slice VMM_Service Wake_Up_VM VMM_Service Call_When_Idle VMM_Service Get_Next_VM_Handle ; ; Time-out and system timer services ; VMM_Service Set_Global_Time_Out VMM_Service Set_VM_Time_Out VMM_Service Cancel_Time_Out VMM_Service Get_System_Time VMM_Service Get_VM_Exec_Time VMM_Service Hook_V86_Int_Chain VMM_Service Get_V86_Int_Vector VMM_Service Set_V86_Int_Vector VMM_Service Get_PM_Int_Vector VMM_Service Set_PM_Int_Vector VMM_Service Simulate_Int VMM_Service Simulate_Iret VMM_Service Simulate_Far_Call VMM_Service Simulate_Far_Jmp VMM_Service Simulate_Far_Ret VMM_Service Simulate_Far_Ret_N VMM_Service Build_Int_Stack_Frame VMM_Service Simulate_Push VMM_Service Simulate_Pop ; ; Heap Manager ; VMM_Service _HeapAllocate VMM_Service _HeapReAllocate VMM_Service _HeapFree VMM_Service _HeapGetSize ; --------------------------------------------------- ; ; Flags for heap allocator calls ; ; --------------------------------------------------- HeapZeroInit equ 00000000000000000000000000000001B HeapZeroReInit equ 00000000000000000000000000000010B HeapNoCopy equ 00000000000000000000000000000100B ; NOTE: HIGH 8 BITS (bits 24-31) are reserved ; ; Page Manager ; VMM_Service _PageAllocate VMM_Service _PageReAllocate VMM_Service _PageFree VMM_Service _PageLock VMM_Service _PageUnLock VMM_Service _PageGetSizeAddr VMM_Service _PageGetAllocInfo VMM_Service _GetFreePageCount VMM_Service _GetSysPageCount VMM_Service _GetVMPgCount VMM_Service _MapIntoV86 VMM_Service _PhysIntoV86 VMM_Service _TestGlobalV86Mem VMM_Service _ModifyPageBits VMM_Service _CopyPageTable VMM_Service _LinMapIntoV86 VMM_Service _LinPageLock VMM_Service _LinPageUnLock VMM_Service _SetResetV86Pageable VMM_Service _GetV86PageableArray VMM_Service _PageCheckLinRange VMM_Service _PageOutDirtyPages VMM_Service _PageDiscardPages ; --------------------------------------------------- ; ; Flags for other page allocator calls ; ; --------------------------------------------------- PageZeroInit equ 00000000000000000000000000000001B PageUseAlign equ 00000000000000000000000000000010B PageContig equ 00000000000000000000000000000100B PageFixed equ 00000000000000000000000000001000B PageDEBUGNulFault equ 00000000000000000000000000010000B PageZeroReInit equ 00000000000000000000000000100000B PageNoCopy equ 00000000000000000000000001000000B PageLocked equ 00000000000000000000000010000000B PageLockedIfDP equ 00000000000000000000000100000000B PageSetV86Pageable equ 00000000000000000000001000000000B PageClearV86Pageable equ 00000000000000000000010000000000B PageSetV86IntsLocked equ 00000000000000000000100000000000B PageClearV86IntsLocked equ 00000000000000000001000000000000B PageMarkPageOut equ 00000000000000000010000000000000B PagePDPSetBase equ 00000000000000000100000000000000B PagePDPClearBase equ 00000000000000001000000000000000B PageDiscard equ 00000000000000010000000000000000B PagePDPQueryDirty equ 00000000000000100000000000000000B ; NOTE: HIGH 8 BITS (bits 24-31) are reserved ; ; Informational services ; VMM_Service _GetNulPageHandle VMM_Service _GetFirstV86Page VMM_Service _MapPhysToLinear VMM_Service _GetAppFlatDSAlias VMM_Service _SelectorMapFlat VMM_Service _GetDemandPageInfo ; ; Data structure for _GetDemandPageInfo ; DemandInfoStruc struc DILin_Total_Count dd ? ; # pages in linear address space DIPhys_Count dd ? ; Count of phys pages DIFree_Count dd ? ; Count of free phys pages DIUnlock_Count dd ? ; Count of unlocked Phys Pages DILinear_Base_Addr dd ? ; Base of pageable address space DILin_Total_Free dd ? ; Total Count of free linear pages DIReserved dd 10 dup (?) ; Resvd for expansion DemandInfoStruc ends VMM_Service _GetSetPageOutCount ; ; Flags bits for _GetSetPageOutCount ; GSPOC_F_Get equ 00000000000000000000000000000001B ; ; Device VM page manager ; VMM_Service Hook_V86_Page VMM_Service _Assign_Device_V86_Pages VMM_Service _DeAssign_Device_V86_Pages VMM_Service _Get_Device_V86_Pages_Array VMM_Service MMGR_SetNULPageAddr ; ; GDT/LDT management ; VMM_Service _Allocate_GDT_Selector VMM_Service _Free_GDT_Selector VMM_Service _Allocate_LDT_Selector VMM_Service _Free_LDT_Selector VMM_Service _BuildDescriptorDWORDs ; ; Flag equates for _BuildDescriptorDWORDs ; BDDExplicitDPL EQU 00000000000000000000000000000001B ; ; Flag equates for _Allocate_LDT_Selector ; ALDTSpecSel EQU 00000000000000000000000000000001B VMM_Service _GetDescriptor VMM_Service _SetDescriptor VMM_Service _MMGR_Toggle_HMA ; ; Flag equates for _MMGR_Toggle_HMA ; MMGRHMAPhysical EQU 00000000000000000000000000000001B MMGRHMAEnable EQU 00000000000000000000000000000010B MMGRHMADisable EQU 00000000000000000000000000000100B MMGRHMAQuery EQU 00000000000000000000000000001000B VMM_Service Get_Fault_Hook_Addrs, LOCAL VMM_Service Hook_V86_Fault, LOCAL VMM_Service Hook_PM_Fault, LOCAL VMM_Service Hook_VMM_Fault, LOCAL VMM_Service Begin_Nest_V86_Exec VMM_Service Begin_Nest_Exec VMM_Service Exec_Int VMM_Service Resume_Exec VMM_Service End_Nest_Exec VMM_Service Allocate_PM_App_CB_Area, VMM_ICODE VMM_Service Get_Cur_PM_App_CB VMM_Service Set_V86_Exec_Mode VMM_Service Set_PM_Exec_Mode VMM_Service Begin_Use_Locked_PM_Stack VMM_Service End_Use_Locked_PM_Stack VMM_Service Save_Client_State VMM_Service Restore_Client_State VMM_Service Exec_VxD_Int VMM_Service Hook_Device_Service, LOCAL VMM_Service Hook_Device_V86_API VMM_Service Hook_Device_PM_API VMM_Service System_Control ; ; I/O and software interrupt hooks ; VMM_Service Simulate_IO VMM_Service Install_Mult_IO_Handlers VMM_Service Install_IO_Handler VMM_Service Enable_Global_Trapping VMM_Service Enable_Local_Trapping VMM_Service Disable_Global_Trapping VMM_Service Disable_Local_Trapping ; ; Linked List Abstract Data Type Services ; VMM_Service List_Create VMM_Service List_Destroy VMM_Service List_Allocate VMM_Service List_Attach VMM_Service List_Attach_Tail VMM_Service List_Insert VMM_Service List_Remove VMM_Service List_Deallocate VMM_Service List_Get_First VMM_Service List_Get_Next VMM_Service List_Remove_First ; ; Flags used by List_Create ; LF_Async EQU 00000001b LF_Async_Bit EQU 0 LF_Use_Heap EQU 00000010b LF_Use_Heap_Bit EQU 1 LF_Alloc_Error EQU 00000100b LF_Alloc_Error_Bit EQU 2 ;============================================================================== ; I N I T I A L I Z A T I O N P R O C E D U R E S ;------------------------------------------------------------------------------ ; ; Instance data manager ; VMM_Service _AddInstanceItem ; ; Data structure for _AddInstanceItem ; InstDataStruc struc InstLinkF dd 0 ; RESERVED SET TO 0 InstLinkB dd 0 ; RESERVED SET TO 0 InstLinAddr dd ? ; Linear address of start of block InstSize dd ? ; Size of block in bytes InstType dd ? ; Type of block InstDataStruc ends ; ; Values for InstType ; INDOS_Field equ 100h ; Bit indicating INDOS switch requirements ALWAYS_Field equ 200h ; Bit indicating ALWAYS switch requirements ; ; System structure data manager ; VMM_Service _Allocate_Device_CB_Area, VMM_ICODE VMM_Service _Allocate_Global_V86_Data_Area, VMM_ICODE VMM_Service _Allocate_Temp_V86_Data_Area, VMM_ICODE VMM_Service _Free_Temp_V86_Data_Area, VMM_ICODE ; ; Flag bits for _Allocate_Global_VM_Data_Area ; GVDAWordAlign EQU 00000000000000000000000000000001B GVDADWordAlign EQU 00000000000000000000000000000010B GVDAParaAlign EQU 00000000000000000000000000000100B GVDAPageAlign EQU 00000000000000000000000000001000B GVDAInstance EQU 00000000000000000000000100000000B GVDAZeroInit EQU 00000000000000000000001000000000B GVDAReclaim EQU 00000000000000000000010000000000B ; ; Initialization information calls (win.ini and environment parameters) ; VMM_Service Get_Profile_Decimal_Int, VMM_ICODE VMM_Service Convert_Decimal_String, VMM_ICODE VMM_Service Get_Profile_Fixed_Point, VMM_ICODE VMM_Service Convert_Fixed_Point_String, VMM_ICODE VMM_Service Get_Profile_Hex_Int, VMM_ICODE VMM_Service Convert_Hex_String, VMM_ICODE VMM_Service Get_Profile_Boolean, VMM_ICODE VMM_Service Convert_Boolean_String, VMM_ICODE VMM_Service Get_Profile_String, VMM_ICODE VMM_Service Get_Next_Profile_String, VMM_ICODE VMM_Service Get_Environment_String, VMM_ICODE VMM_Service Get_Exec_Path, VMM_ICODE VMM_Service Get_Config_Directory, VMM_ICODE VMM_Service OpenFile, VMM_ICODE VMM_Service Get_PSP_Segment, VMM_ICODE VMM_Service GetDOSVectors, VMM_ICODE VMM_Service Get_Machine_Info GMIF_80486 EQU 00010000h GMIF_80486_Bit EQU 10h GMIF_PCXT EQU 00020000h GMIF_PCXT_Bit EQU 11h GMIF_MCA EQU 00040000h GMIF_MCA_Bit EQU 12h GMIF_EISA EQU 00080000h GMIF_EISA_Bit EQU 13h ; ; Following service is not restricted to initialization ; VMM_Service GetSet_HMA_Info VMM_Service Set_System_Exit_Code VMM_Service Fatal_Error_Handler VMM_Service Fatal_Memory_Error ; ; Called by VTD only ; VMM_Service Update_System_Clock ;============================================================================== ; D E B U G G I N G E X T E R N S ;============================================================================== VMM_Service Test_Debug_Installed ; Valid call in retail also VMM_Service Out_Debug_String ; Valid in DEBLEVEL=1 VMM_Service Out_Debug_Chr VMM_Service In_Debug_Chr VMM_Service Debug_Convert_Hex_Binary VMM_Service Debug_Convert_Hex_Decimal VMM_Service Debug_Test_Valid_Handle VMM_Service Validate_Client_Ptr VMM_Service Test_Reenter VMM_Service Queue_Debug_String VMM_Service Log_Proc_Call VMM_Service Debug_Test_Cur_VM .errnz Debug_Test_Cur_VM - 100CCh ; VMM service table changed above this service VMM_Service Get_PM_Int_Type VMM_Service Set_PM_Int_Type VMM_Service Get_Last_Updated_System_Time VMM_Service Get_Last_Updated_VM_Exec_Time End_Service_Table VMM, VMM ;****************************************************************************** IFDEF DEBUG DebFar EQU NEAR PTR ELSE DebFar EQU SHORT ENDIF BeginDoc ;****************************************************************************** ; ; EQUATES FOR SYSTEM_CONTROL CALLS ; ;============================================================================== ; ; Sys_Critical_Init is a device init call. Devices that have a critical ; function that needs initializing before interrupts are enabled should ; do it at Sys_Critical_Init. Devices which REQUIRE a certain range of ; V86 pages to operate (such as the VDD video memory) should claim them ; at Sys_Critical_Init. SYS VM Simulate_Int, Exec_Int ACTIVITY IS NOT ; ALLOWED. Returning carry aborts device load only. ; Sys_Critical_Init EQU 0000h ; Devices required for virt mode ; ; Device init is where most devices do the bulk of their initialization. ; SYS VM Simulate_Int, Exec_Int activity is allowed. Returning carry ; aborts device load only. ; Device_Init EQU 0001h ; All other devices init ; ; Init_Complete is the final phase of device init called just before the ; WIN386 INIT pages are released and the Instance snapshot is taken. ; Devices which wish to search for a region of V86 pages >= A0h to use ; should do it at Init_Complete. ; SYS VM Simulate_Int, Exec_Int activity is allowed. Returning carry ; aborts device load only. ; Init_Complete EQU 0002h ; All devices have initialized ;----------------- INITIALIZATION CODE AND DATA DISCARDED --------------------- ; ; Same as VM_Init, except for SYS VM. ; Sys_VM_Init EQU 0003h ; Execute the system VM (Win86) ; ; Same as VM_Terminate, except for SYS VM (Normal WIN386 exit ONLY, on a crash ; exit this call is not made). SYS VM Simulate_Int, Exec_Int activity is ; allowed. ; Sys_VM_Terminate EQU 0004h ; System VM terminted (exiting) ;------------------------------------------------------------------------------ ; ; System_Exit call is made when WIN386 is exiting either normally or via ; a crash. INTERRUPS ARE ENABLED. Instance snapshot has been restored. ; SYS VM Simulate_Int, Exec_Int ACTIVITY IS NOT ALLOWED. ; System_Exit EQU 0005h ; Devices prepare to exit ; ; System_Exit call is made when WIN386 is exiting either normally or via ; a crash. INTERRUPS ARE DISABLED. SYS VM Simulate_Int, Exec_Int ACTIVITY ; IS NOT ALLOWED. ; Sys_Critical_Exit EQU 0006h ; System critical devices reset ; ; Create_VM creates a new VM. EBX = VM handle of new VM. Returning Carry will ; fail the Create_VM. ; Create_VM EQU 0007h ; ; Second phase of Create_VM. EBX = VM handle of new VM. Returning Carry will ; cause the VM to go Not_Executeable, then be destroyed. VM Simulate_Int, ; Exec_Int activity is NOT allowed. ; VM_Critical_Init EQU 0008h ; ; Third phase of Create_VM. EBX = VM handle of new VM. Returning Carry will ; cause the VM to go Not_Executeable, then be destroyed. VM Simulate_Int, ; Exec_Int activity is allowed. ; VM_Init EQU 0009h ; ; NORMAL (First phase) of Destroy_VM. EBX = VM Hanlde. This occurs on normal ; termination of the VM. Call cannot be failed. VM Simulate_Int, Exec_Int ; activity is allowed. ; VM_Terminate EQU 000Ah ; Still in VM -- About to die ; ; Second phase of Destroy_VM. EBX = VM Handle, EDX = Flags (see below). Note ; that in the case of destroying a running VM, this is the first call made ; (VM_Terminate call does not occur). Call cannot be failed. VM Simulate_Int, ; Exec_Int activity is NOT allowed. ; VM_Not_Executeable EQU 000Bh ; Most devices die (except VDD) ; ; Final phase of Destroy_VM. EBX = VM Handle. Note that considerable time ; can elaps between the VM_Not_Executeable call and this call. Call cannot ; be failed. VM Simulate_Int, Exec_Int activity is NOT allowed. ; Destroy_VM EQU 000Ch ; VM's control block about to go ; ; Flags for VM_Not_Executeable control call (passed in EDX) ; VNE_Crashed EQU 0000000000000000000000001b VNE_Crashed_Bit EQU 0 ; VM was crashed VNE_Nuked EQU 0000000000000000000000010b VNE_Nuked_Bit EQU 1 ; VM was destroyed while active VNE_CreateFail EQU 0000000000000000000000100b VNE_CreateFail_Bit EQU 2 ; Some device failed Create_VM VNE_CrInitFail EQU 0000000000000000000001000b VNE_CrInitFail_Bit EQU 3 ; Some device failed VM_Critical_Init VNE_InitFail EQU 0000000000000000000010000b VNE_InitFail_Bit EQU 4 ; Some device failed VM_Init ;------------------------------------------------------------------------------ ; ; EBX = VM Handle. Call cannot be failed. ; VM_Suspend EQU 000Dh ; VM not runnable until resume ; ; EBX = VM Handle. Returning carry fails and backs out the resume. ; VM_Resume EQU 000Eh ; VM is leaving suspended state ;------------------------------------------------------------------------------ ; ; EBX = VM Handle to set device focus to. EDX = Device ID if device specific ; setfocus. == 0 if device critical setfocus (all devices). THIS CALL CANNOT ; BE FAILED. ; ; NOTE: In case where EDX == 0, ESI is a FLAG word that indicates special ; functions. Currently Bit 0 being set indicates that this Device ; critical set focus is also "VM critical". It means that we do not ; want some other VM to take the focus from this app now. This is ; primarily used when doing a device critical set focus to Windows ; (the SYS VM) it is interpreted by the SHELL to mean "if an old app ; currently has the Windows activation, set the activation to the ; Windows Shell, not back to the old app". ALSO in the case where ; Bit 0 is set, EDI = The VM handle of the VM that is "having trouble". ; Set this to 0 if there is no specific VM associated with the problem. ; Set_Device_Focus EQU 000Fh ;------------------------------------------------------------------------------ ; ; EBX = VM Handle going into message mode. THIS CALL CANNOT BE FAILED. ; Begin_Message_Mode EQU 0010h ; ; EBX = VM Handle leaving message mode. THIS CALL CANNOT BE FAILED. ; End_Message_Mode EQU 0011h ;------------------------- SPECIAL CONTROL CALLS ------------------------------ ; ; Request for reboot. Call cannot be failed. ; Reboot_Processor EQU 0012h ; Request a machine reboot ; ; Query_Destroy is an information call made by the SHELL device before an ; attempt is made to initiate a destroy VM sequence on a running VM which ; has not exited normally. EBX = VM Handle. Returning carry indicates that ; a device "has a problem" with allowing this. THE DESTROY SEQUENCE CANNOT ; BE ABORTED HOWEVER, this decision is up to the user. All this does is ; indicate that there is a "problem" with allowing the destroy. The device ; which returns carry should call the SHELL_Message service to post an ; informational dialog about the reason for the problem. ; Query_Destroy EQU 0013h ; OK to destroy running VM? ;------------------------- DEBUGGING CONTROL CALL ----------------------------- ; ; Special call for device specific DEBUG information display and activity. ; Debug_Query EQU 0014h ;---------- CALLS FOR BEGIN/END OF PROTECTED MODE VM EXECUTION ---------------- ; ; About to run a protected mode application. ; EBX = Current VM handle. ; EDX = Flags ; EDI -> Application Control Block ; Returning with carry set fails the call. ; Begin_PM_App EQU 0015h ; ; Flags for Begin_PM_App (passed in EDX) ; BPA_32_Bit EQU 00000001b BPA_32_Bit_Flag EQU 1 ; ; Protected mode application is terminating. ; EBX = Current VM handle. THIS CALL CAN NOT FAIL. ; EDI -> Application Control Block ; End_PM_App EQU 0016h EndDoc BeginDoc ;****************************************************************************** ; BeginProc is a macro for defining entry points to routines in VMM and in the ; VxDs. It correctly defines the procedure name for VxD services(it prepends ; a "@" to the procedure name), DWORD aligns the procedure, takes care of ; public declaration and does some calling verification for debug versions ; of the software. EndProc is a macro which defines the end of the procedure. ; ; Valid parameters to the BeginProc macro are: ; PUBLIC ; Routine used outside this module ; HIGH_FREQ ; DWORD align procedure ; SERVICE ; Routine is called via VxDCall ; ASYNC_SERVICE ; Same as "SERVICE" plus routine can ; ; be called under interrupt. ; After the routine header in which the routine entry conditions, exit ; conditions, side affects and functionality are specified, the BeginProc ; macro should be used to define the routine's entry point. It has up to ; four parameters as specified below. For example: ; ;BeginProc ,PUBLIC, HIGH_FREQ, ASYNC_SERVICE ; ; ; ;EndProc ;============================================================================== EndDoc BeginProc MACRO Name, P1, P2, P3, P4 LOCAL Profile_Data, Skip_Data IF ?_RCODE Process_Param MACRO P IFNB

IFIDNI

, Dword_Align ELSE IFIDNI

, ??_SERVICE = 1 ELSE IFIDNI

, ??_ASYNC_SERVICE = 1 IF ?_LCODE %OUT ERROR: ASYNC_SERVICE's must be in LOCKED code ;;.err ENDIF ELSE IFIDNI

, ??_NO_LOG = 1 ELSE IFDIFI

, %OUT ERROR: Bad para "&P" to BeginProc .ERR ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDM ??_SERVICE = 0 ??_ASYNC_SERVICE = 0 ??_NO_LOG = 0 Process_Param P1 Process_Param P2 Process_Param P3 Process_Param P4 IFE ??_SERVICE + ??_ASYNC_SERVICE PUBLIC Name Name PROC NEAR IFDEF DEBUG IFE ??_NO_LOG IFNDEF VMMSYS VMMcall Log_Proc_Call ENDIF ENDIF ENDIF ELSE IFDEF DEBUG jmp SHORT Skip_Data Profile_Data LABEL DWORD dd 0 Skip_Data: ENDIF PUBLIC @&Name @&Name PROC NEAR IFDEF DEBUG IFE ??_NO_LOG ;;;;IFNDEF VMMSYS VMMcall Log_Proc_Call ;;;;ENDIF ENDIF pushfd inc [Profile_Data] IFE ??_ASYNC_SERVICE VMMcall Test_Reenter ENDIF popfd ENDIF ENDIF ELSE IFIDNI , PUBLIC Name ENDIF Name PROC NEAR ENDIF ENDM EndProc MACRO Name IFDEF @&Name @&Name ENDP ELSE IFDEF Name Name ENDP ELSE .ERR %OUT EndProc for &Name does not match BeginProc ENDIF ENDIF ENDM ;****************************************************************************** ; S C H E D U L E R B O O S T V A L U E S ;============================================================================== Reserved_Low_Boost EQU 00000000000000000000000000000001b Cur_Run_VM_Boost EQU 00000000000000000000000000000100b Low_Pri_Device_Boost EQU 00000000000000000000000000010000b High_Pri_Device_Boost EQU 00000000000000000001000000000000b Critical_Section_Boost EQU 00000000000100000000000000000000b Time_Critical_Boost EQU 00000000010000000000000000000000b Reserved_High_Boost EQU 01000000000000000000000000000000b ;****************************************************************************** ; F L A G S F O R C A L L _ P R I O R I T Y _ V M _ E V E N T ;============================================================================== PEF_Wait_For_STI EQU 0000001b PEF_Wait_For_STI_Bit EQU 0 PEF_Wait_Not_Crit EQU 0000010b PEF_Wait_Not_Crit_Bit EQU 1 PEF_Dont_Unboost EQU 0000100b PEF_Dont_Unboost_Bit EQU 2 PEF_Always_Sched EQU 0001000b PEF_Always_Sched_Bit EQU 3 ;****************************************************************************** ; F L A G S F O R B E G I N _ C R I T I C A L _ S E C T I O N ; A N D W A I T _ S E M A P H O R E ;============================================================================== Block_Svc_Ints EQU 0000001b Block_Svc_Ints_Bit EQU 0 Block_Svc_If_Ints_Locked EQU 0000010b Block_Svc_If_Ints_Locked_Bit EQU 1 Block_Enable_Ints EQU 0000100b Block_Enable_Ints_Bit EQU 2 BeginDoc ;****************************************************************************** ; The following structures are pointed to by EBP when VxD routines are entered, ; both for VxD control calls and traps(I/O traps, software INT traps, etc.). ; The first structure as DWORD values, the second WORD values and the last ; has BYTE values. ; Client_Reg_Struc struc Client_EDI dd ? ; Client's EDI Client_ESI dd ? ; Client's ESI Client_EBP dd ? ; Client's EBP dd ? ; ESP at pushall Client_EBX dd ? ; Client's EBX Client_EDX dd ? ; Client's EDX Client_ECX dd ? ; Client's ECX Client_EAX dd ? ; Client's EAX Client_Error dd ? ; Dword error code Client_EIP dd ? ; EIP Client_CS dw ? ; CS dw ? ; (padding) Client_EFlags dd ? ; EFLAGS Client_ESP dd ? ; ESP Client_SS dw ? ; SS dw ? ; (padding) Client_ES dw ? ; ES dw ? ; (padding) Client_DS dw ? ; DS dw ? ; (padding) Client_FS dw ? ; FS dw ? ; (padding) Client_GS dw ? ; GS dw ? ; (padding) Client_Alt_EIP dd ? Client_Alt_CS dw ? dw ? Client_Alt_EFlags dd ? Client_Alt_ESP dd ? Client_Alt_SS dw ? dw ? Client_Alt_ES dw ? dw ? Client_Alt_DS dw ? dw ? Client_Alt_FS dw ? dw ? Client_Alt_GS dw ? dw ? Client_Reg_Struc ends Client_Word_Reg_Struc struc Client_DI dw ? ; Client's DI dw ? ; (padding) Client_SI dw ? ; Client's SI dw ? ; (padding) Client_BP dw ? ; Client's BP dw ? ; (padding) dd ? ; ESP at pushall Client_BX dw ? ; Client's BX dw ? ; (padding) Client_DX dw ? ; Client's DX dw ? ; (padding) Client_CX dw ? ; Client's CX dw ? ; (padding) Client_AX dw ? ; Client's AX dw ? ; (padding) dd ? ; Dword error code Client_IP dw ? ; Client's IP dw ? ; (padding) dd ? ; CS Client_Flags dw ? ; Client's flags (low) dw ? ; (padding) Client_SP dw ? ; SP dw ? dd 5 dup (?) Client_Alt_IP dw ? dw ? dd ? Client_Alt_Flags dw ? dw ? Client_Alt_SP dw ? Client_Word_Reg_Struc ends Client_Byte_Reg_Struc struc dd 4 dup (?) ; EDI, ESI, EBP, ESP at pushall Client_BL db ? ; Client's BL Client_BH db ? ; Client's BH dw ? ; (padding) Client_DL db ? ; Client's DL Client_DH db ? ; Client's DH dw ? ; (padding) Client_CL db ? ; Client's CL Client_CH db ? ; Client's CH dw ? ; (padding) Client_AL db ? ; Client's AL Client_AH db ? ; Client's AH Client_Byte_Reg_Struc ends ;============================================================================== EndDoc .ERRNZ Client_SP - Client_ESP .ERRNZ Client_AL - Client_EAX PushCParams MACRO P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 IRP Param, IFNB push Param ENDIF ENDM ENDM ClearCParams MACRO Count, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 IFNB ClearCParams %(Count+1), , , , , , , , , ELSE IF Count add esp, Count*4 ENDIF ENDIF ENDM Dyna_Link_Int EQU 20h ; ; BeginDoc ;****************************************************************************** ; The VMMCall and VxDCall macros provide a dynamic link to the VMM and VxD ; service routines. For example: ; ; VMMCall Enable_VM_Ints ; Equivalent to STI in VM code ; ; mov eax,[My_IRQ_Handle] ; VxDCall VPICD_Set_Int_Request ; Set IRQ for my device's interrupt ; ; Note that Enable_VM_Ints is defined in VMM.INC and VPICD_Set_Int_Request is ; defined in VPICD.INC ; ;============================================================================== EndDoc BeginDoc ;****************************************************************************** ; VxDCall ;============================================================================== EndDoc VxDcall MACRO P, Param PushCParams Param int Dyna_Link_Int dd P ClearCParams 0, Param ENDM VxDjmp MACRO P, Param IFNB %OUT ERROR: Parameters may not be passed to VxDjmp or VMMjmp macros .ERR ENDIF int Dyna_Link_Int IFDEF DEBUG dd P ret ELSE dd P OR DL_Jmp_Mask ENDIF ENDM DL_Jmp_Mask EQU 8000h DL_Jmp_Bit EQU 0Fh VMMcall MACRO P, Param .ERRNZ (P SHR 16) - VMM_Device_ID VxDcall

, ENDM VMMjmp MACRO P, Param .ERRNZ (P SHR 16) - VMM_Device_ID VxDjmp

, ENDM cCall MACRO P, Param PushCParams Param call P ClearCParams 0, Param ENDM BeginDoc ;****************************************************************************** ; Segment definition macros ; ; The segment definition macros are a convenience used in defining the ; segments used by the device driver. They are: ;VxD_ICODE_SEG defines start of initialization code segment ;VxD_ICODE_ENDS defines end of initialization code segment ;VxD_IDATA_SEG defines start of initialization data segment ;VxD_IDATA_ENDS defines end of initialization data segment ;VxD_CODE_SEG defines start of always present code segment ;VxD_CODE_ENDS defines end of always present code segment ;VxD_DATA_SEG defines start of always present data segment ;VxD_DATA_ENDS defines end of always present data segment ;============================================================================== EndDoc ; Protected mode code VxD_CODE_SEG EQU VxD_CODE_ENDS EQU VxD_LOCKED_CODE_SEG MACRO _LTEXT SEGMENT ??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_LCODE ASSUME cs:FLAT, ds:FLAT, es:FLAT, ss:FLAT ENDM VxD_LOCKED_CODE_ENDS MACRO ??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3 _LTEXT ENDS ENDM ; Protected mode initialization code VxD_ICODE_SEG MACRO _ITEXT SEGMENT ??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_ICODE ASSUME cs:FLAT, ds:FLAT, es:FLAT, ss:FLAT ENDM VxD_ICODE_ENDS MACRO ??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3 _ITEXT ENDS ENDM ; Protected mode data VxD_DATA_SEG EQU VxD_DATA_ENDS EQU VxD_LOCKED_DATA_SEG MACRO NO_ALIGN _LDATA SEGMENT IFB ALIGN 4 ENDIF ENDM VxD_LOCKED_DATA_ENDS MACRO _LDATA ENDS ENDM ; Protected mode initialization data VxD_IDATA_SEG MACRO _IDATA SEGMENT ENDM VxD_IDATA_ENDS MACRO _IDATA ENDS ENDM VxD_REAL_INIT_SEG MACRO _RCODE SEGMENT ASSUME CS:_RCODE, DS:_RCODE, ES:_RCODE, SS:_RCODE ??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_RCODE ENDM VxD_REAL_INIT_ENDS MACRO ??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3 _RCODE ENDS ENDM ENDIF DDK_Version equ 300h VxD_Desc_Block STRUC DDB_Next dd ? ; VMM RESERVED FIELD DDB_SDK_Version dw DDK_Version ; VMM RESERVED FIELD DDB_Req_Device_Number dw Undefined_Device_ID ; Required device number DDB_Dev_Major_Version db 0 ; Major device number DDB_Dev_Minor_Version db 0 ; Minor device number DDB_Flags dw 0 ; Flags for init calls complete DDB_Name db " " ; Device name DDB_Init_Order dd Undefined_Init_Order; Initialization Order DDB_Control_Proc dd ? ; Offset of control procedure DDB_V86_API_Proc dd 0 ; Offset of API procedure (or 0) DDB_PM_API_Proc dd 0 ; Offset of API procedure (or 0) DDB_V86_API_CSIP dd 0 ; CS:IP of API entry point DDB_PM_API_CSIP dd 0 ; CS:IP of API entry point DDB_Reference_Data dd ? ; Reference data from real mode DDB_Service_Table_Ptr dd 0 ; Pointer to service table DDB_Service_Table_Size dd 0 ; Number of services VxD_Desc_Block ENDS IFNDEF Not_VxD ; flag values for DDB_Flags DDB_Sys_Crit_Init_Done EQU 00000001b DDB_Sys_Crit_Init_Done_Bit EQU 0 DDB_Device_Init_Done EQU 00000010b DDB_Device_Init_Done_Bit EQU 1 BeginDoc ;****************************************************************************** ; ; Declare_Virtual_Device macro ; ; ???? Write something here ???? ; ;============================================================================== EndDoc Declare_Virtual_Device MACRO Name, Major_Ver, Minor_Ver, Ctrl_Proc, Device_Num, Init_Order, V86_Proc, PM_Proc LOCAL V86_API_Offset, PM_API_Offset, Serv_Tab_Offset, Serv_Tab_Len dev_id_err MACRO %OUT Device ID required when providing services .ERR ENDM IFB V86_API_Offset EQU 0 ELSE IFB dev_id_err ENDIF V86_API_Offset EQU ENDIF IFB PM_API_Offset EQU 0 ELSE IFB dev_id_err ENDIF PM_API_Offset EQU ENDIF IFDEF Name&_Service_Table IFB dev_id_err ELSE IFE Device_Num - Undefined_Device_ID dev_id_err ENDIF ENDIF Serv_Tab_Offset EQU Serv_Tab_Len EQU Num_&Name&_Services ELSE Serv_Tab_Offset EQU 0 Serv_Tab_Len EQU 0 ENDIF VxD_LOCKED_DATA_SEG PUBLIC Name&_DDB Name&_DDB VxD_Desc_Block <,,Device_Num,Major_Ver,Minor_Ver,,"&Name",Init_Order,\ OFFSET32 Ctrl_Proc, V86_API_Offset, PM_API_Offset, \ ,,,Serv_Tab_Offset, Serv_Tab_Len> VxD_LOCKED_DATA_ENDS ENDM BeginDoc ;****************************************************************************** ; The Begin_Control_Dispatch macro is used for building a table for dispatching ; messages passed to the VxD_Control procedure. It is used with ; Control_Dispatch and End_Control_Dispatch. The only parameter is used to ; contruct the procedure label by adding "_Control" to the end (normally the ; device name is used i.e. VKD results in creating the procedure VKD_Control, ; this created procedure label must be included in Declare_Virtual_Device) ; ; An example of building a complete dispatch table: ; ; Begin_Control_Dispatch MyDevice ; Control_Dispatch Device_Init, MyDeviceInitProcedure ; Control_Dispatch Sys_VM_Init, MyDeviceSysInitProcedure ; Control_Dispatch Create_VM, MyDeviceCreateVMProcedure ; End_Control_Dispatch MyDevice ; ; (NOTE: Control_Dispatch can be used without Begin_Control_Dispatch, but ; then it is the programmer's responsibility for declaring a procedure ; in locked code (VxD_LOCKED_CODE_SEG) and returning Carry clear for ; any messages not processed. The advantage in using ; Begin_Control_Dispatch is when a large # of messages are processed by ; a device, because a jump table is built which will usually require ; less code space then the compares and jumps that are done when ; Control_Dispatch is used alone. ; ;============================================================================== EndDoc Begin_Control_Dispatch MACRO VxD_Name ??_cd_low = 0FFFFFFFFh ??_cd_high = 0 BeginProc VxD_Name&_Control ENDM End_Control_Dispatch MACRO VxD_Name LOCAL ignore, table jmpproc MACRO num jmp ??_cd_&&num ENDM procoff MACRO num IFDEF ??_cd_&&num dd OFFSET32 ??_cd_&&num ELSE dd OFFSET32 ignore ENDIF ENDM IF ??_cd_low EQ ??_cd_high cmp eax, ??_cd_low jne short ignore jmpproc %(??_cd_low) ignore: clc ret ELSE cmp eax, ??_cd_high ja short ignore sub eax, ??_cd_low jb short ignore jmp cs:[eax*4+table] ignore: clc ret table label dword REPT ??_cd_high - ??_cd_low + 1 procoff %(??_cd_low) ??_cd_low = ??_cd_low + 1 ENDM ENDIF EndProc VxD_Name&_Control PURGE jmpproc PURGE procoff PURGE Begin_Control_Dispatch PURGE Control_Dispatch PURGE End_Control_Dispatch ENDM BeginDoc ;****************************************************************************** ; The Control_Dispatch macro is used for dispatching based on message ; passed to the VxD_Control procedure. E.G.: ; ; Control_Dispatch Device_Init, MyDeviceInitProcedure ; ; (NOTE: Control_Dispatch can be used with Begin_Control_Dispatch and ; End_Control_Dispatch to create a jump table for dispatching messages, ; when a large # of messages are processed.) ; ;============================================================================== EndDoc Control_Dispatch MACRO Service, Procedure LOCAL Skip_Interseg_Jump IFE ?_lcode IFDEF ??_cd_low Equate_Service MACRO Serv ??_cd_&&Serv equ Procedure ENDM Equate_Service %(Service) IF Service LT ??_cd_low ??_cd_low = Service ENDIF IF Service GT ??_cd_high ??_cd_high = Service ENDIF PURGE Equate_Service ELSE cmp eax, Service jne SHORT Skip_Interseg_Jump jmp Procedure Skip_Interseg_Jump: ENDIF ELSE %OUT ERROR: The Control proc should be in LOCKED code. %OUT Control_Dispatch can only be used inside of VxD_LOCKED_CODE_SEG. .err ENDIF ENDM BeginDoc ;****************************************************************************** ; The following are the definitions for the "type of I/O" parameter passed ; to a I/O trap routine Byte_Input EQU 000h Byte_Output EQU 004h Word_Input EQU 008h Word_Output EQU 00Ch Dword_Input EQU 010h Dword_Output EQU 014h Output EQU 0000000000000100b Output_Bit EQU 2 Word_IO EQU 0000000000001000b Word_IO_Bit EQU 3 Dword_IO EQU 0000000000010000b Dword_IO_Bit EQU 4 String_IO EQU 00000020h String_IO_Bit EQU 5 Rep_IO EQU 00000040h Rep_IO_Bit EQU 6 Addr_32_IO EQU 00000080h Addr_32_IO_Bit EQU 7 Reverse_IO EQU 00000100h Reverse_IO_Bit EQU 8 IO_Seg_Mask EQU 0FFFF0000h ; Use these bits to get segment IO_Seg_Shift EQU 10h ; Must shift right this many ;============================================================================== EndDoc BeginDoc ;****************************************************************************** ; ; Dispatch_Byte_IO macro ; ; Dispatch_Byte_IO Byte_In_Proc, Byte_Out_Proc ;============================================================================== EndDoc Dispatch_Byte_IO MACRO In_Proc, Out_Proc LOCAL Byte_IO cmp ecx, Byte_Output jbe SHORT Byte_IO VMMjmp Simulate_IO Byte_IO: IFIDNI , je Out_Proc ELSE IFIDNI , jb In_Proc ELSE je Out_Proc jmp In_Proc ENDIF ENDIF ENDM BeginDoc ;****************************************************************************** ; ; Emulate_Non_Byte_IO ; ; Emulate_Non_Byte_IO ; ;============================================================================== EndDoc Emulate_Non_Byte_IO MACRO LOCAL Byte_IO cmp ecx, Byte_Output jbe SHORT Byte_IO VMMjmp Simulate_IO Byte_IO: ENDM VxD_IOT_Hdr STRUC VxD_IO_Ports dw ? VxD_IOT_Hdr ENDS VxD_IO_Struc STRUC VxD_IO_Port dw ? VxD_IO_Proc dd ? VxD_IO_Struc ENDS BeginDoc ;****************************************************************************** ; ; Begin_VxD_IO_Table ; ; Example: ; Begin_VxD_IO_Table MyTableName ; ;============================================================================== EndDoc .ERRNZ SIZE VxD_IOT_Hdr - 2 ; Begin_VxD_IO_Table creates a 1 word count hdr Begin_VxD_IO_Table MACRO Table_Name PUBLIC Table_Name Table_Name LABEL WORD IF2 IFNDEF Table_Name&_Entries %OUT ERROR: No End_VxD_IO_Table for &Table_Name .ERR ENDIF dw Table_Name&_Entries ELSE dw ? ENDIF ENDM .ERRNZ SIZE VxD_IO_Struc - 6 ; VxD_IO creates 6 byte I/O port entries VxD_IO MACRO Port, Proc_Name dw Port dd OFFSET32 Proc_Name ENDM End_VxD_IO_Table MACRO Table_Name IFNDEF Table_Name %OUT ERROR: No Begin_VxD_IO_Table for &Table_Name .ERR ELSE Table_Name&_Entries EQU (($-Table_Name)-2) / (SIZE VxD_IO_Struc) IF Table_Name&_Entries LE 0 %OUT ERROR: Invalid number of port traps in &Table_Name .ERR ENDIF ENDIF ENDM ;****************************************************************************** ;****************************************************************************** Push_Client_State MACRO sub esp, SIZE Client_Reg_Struc push edi lea edi, [esp+4] VMMcall Save_Client_State pop edi ENDM Pop_Client_State MACRO push esi lea esi, [esp+4] VMMcall Restore_Client_State pop esi add esp, SIZE Client_Reg_Struc ENDM BeginDoc ;****************************************************************************** ; ; CallRet -- Call procedure and return. For debugging purposes only. ; If compiled with debugging then this will generate a call ; followed by a return. If non-debugging version then the ; specified label will be jumped to. ; ; PARAMETERS: ; Label_Name = Procedure to be called ; ; EXIT: ; Return from current procedure ; ;------------------------------------------------------------------------------ EndDoc CallRet MACRO P1, P2 IFDEF DEBUG IFIDNI , call P2 ELSE call P1 ENDIF ret ELSE jmp P1 P2 ENDIF ENDM ; ebp offsets to segments pushed by PMode_Fault in Fault_Dispatch PClient_DS equ WORD PTR -4 PClient_ES equ WORD PTR -8 PClient_FS equ WORD PTR -12 PClient_GS equ WORD PTR -16 Client_Ptr_Flat MACRO Reg_32, Cli_Seg, Cli_Off IFDIFI , push eax ENDIF IFB mov ax, (Client_&Cli_Seg * 100h) + 0FFh ELSE mov ax, (Client_&Cli_Seg * 100h) + Client_&Cli_Off ENDIF VMMcall Map_Flat IFDIFI , mov Reg_32, eax pop eax ENDIF ENDM ;------------------------------------------------------------------------------ VxDint MACRO Int_Number push DWORD PTR Int_Number VMMcall Exec_VxD_Int ENDM ENDIF ; Not_VxD BeginDoc ;****************************************************************************** ; ; The following equates are for flags sent to the real mode ; initialization portion of a device driver: ; Duplicate_Device_ID equ 0000000000000001b ; duplicate device ID already Duplicate_Device_ID_Bit equ 0 ; loaded Duplicate_From_INT2F equ 0000000000000010b ; duplicate device ID already Duplicate_From_INT2F_Bit equ 1 ; loaded as part of INT 2F ; device list Loading_From_INT2F equ 0000000000000100b ; this device was specified Loading_From_INT2F_Bit equ 2 ; in the INT 2F device list EndDoc BeginDoc ;****************************************************************************** ; ; The following equates are used to indicate the result of the real mode ; initialization portion of a device driver: ; Device_Load_Ok equ 0 ; protected mode portion of device ; should be loaded Abort_Device_Load equ 1 ; don't load any protected mode portion ; of this device, but continue loading ; the rest of the devices Abort_Win386_Load equ 2 ; fatal-error: abort the load of Win386 No_Fail_Message equ 8000h ; The high bit is set in the return No_Fail_Message_Bit equ 15 ; code, if the loader should not print ; any message for results ; Abort_Device_Load or Abort_Win386_Load ;============================================================================== EndDoc ;============================================================================== ; CR0 bit assignments PE_Mask EQU 0001h ; 1 = Protected Mode PE_Bit EQU 0 MP_Mask EQU 0002h ; 1 = Monitor Coprocessor MP_Bit EQU 1 EM_Mask EQU 0004h ; 1 = Emulate Math Coprocessor EM_Bit EQU 2 TS_Mask EQU 0008h ; 1 = Task Switch occured TS_Bit EQU 3 ET_Mask EQU 0010h ; 1 = 387 present, 0 = 287 present ET_Bit EQU 4 PG_Mask EQU 80000000h ; 1 = paging enabled, 0 = paging disabled PG_Bit EQU 31 ; EFLAGs bit assignments CF_Mask EQU 000000000000000001b ; Carry flag CF_Bit EQU 0 PF_Mask EQU 000000000000000100b ; Parity flag PF_Bit EQU 2 AF_Mask EQU 000000000000010000b ; Aux flag AF_Bit EQU 4 ZF_Mask EQU 000000000001000000b ; Zero flag ZF_Bit EQU 6 SF_Mask EQU 000000000010000000b ; Sign flag SF_Bit EQU 7 TF_Mask EQU 000000000100000000b ; Trace flag TF_Bit EQU 8 IF_Mask EQU 000000001000000000b ; Int flag IF_Bit EQU 9 DF_Mask EQU 000000010000000000b ; Direction flag DB_Bit EQU 10 OF_Mask EQU 000000100000000000b ; Overflow flag OF_Bit EQU 11 IOPL_Mask EQU 000011000000000000b ; IOPL flags IOPL_Bit0 EQU 12 IOPL_Bit1 EQU 13 NT_Mask EQU 000100000000000000b ; Nested task flag NT_Bit EQU 14 RF_Mask EQU 010000000000000000b ; Resume flag RF_Bit EQU 16 VM_Mask EQU 100000000000000000b ; Virtual Mode flag VM_Bit EQU 17 ;------------------------------------------------------------------------------ ; ; Temporary MASM macros (to be removed when supported by MASM) ; ;------------------------------------------------------------------------------ loopd EQU loopde EQU loopdne EQU loopdz EQU loopdnz EQU ;****************************************************************************** ; PAGE TABLE EQUATES ;****************************************************************************** P_SIZE equ 1000h ; page size ; --------------------------------------------------- ; ; Page table entry bits ; ; --------------------------------------------------- P_PRES equ 01h ; page present bit P_WRITE equ 02h ; write access bit P_USER equ 04h ; access bit for User mode P_ACC equ 20h ; page accessed bit P_DIRTY equ 40h ; page dirty bit P_AVAIL equ (P_PRES+P_WRITE+P_USER) ; avail to everyone & present ; --------------------------------------------------- ; ; Page types - definition of the OS reserved bits in the page table ; entry. ; --------------------------------------------------- PG_TYPE equ 0E00h ; TYPE bits in PTE ; --------------------------------------------------- ; ; Page types for page allocator calls ; ; --------------------------------------------------- PG_VM equ 0 PG_SYS equ 1 PG_RESERVED1 equ 2 PG_PRIVATE equ 3 PG_RESERVED2 equ 4 PG_RELOCK equ 5 ; PRIVATE to MMGR PG_INSTANCE equ 6 PG_HOOKED equ 7 PG_IGNORE equ 0FFFFFFFFh ; --------------------------------------------------- ; ; Types for page table entries ; ; --------------------------------------------------- PgT_VM equ PG_VM SHL 9 PgT_SYS equ PG_SYS SHL 9 PgT_RESERVED1 equ PG_RESERVED1 SHL 9 PgT_PRIVATE equ PG_PRIVATE SHL 9 PgT_RESERVED2 equ PG_RESERVED2 SHL 9 PgT_RELOCK equ PG_RELOCK SHL 9 PgT_INSTANCE equ PG_INSTANCE SHL 9 PgT_HOOKED equ PG_HOOKED SHL 9 ;****************************************************************************** ; --------------------------------------------------- ; ; Definitions for the access byte in a descriptor ; ; --------------------------------------------------- ; Following fields are common to segment and control descriptors D_PRES equ 080h ; present in memory D_NOTPRES equ 0 ; not present in memory D_DPL0 equ 0 ; Ring 0 D_DPL1 equ 020h ; Ring 1 D_DPL2 equ 040h ; Ring 2 D_DPL3 equ 060h ; Ring 3 D_SEG equ 010h ; Segment descriptor D_CTRL equ 0 ; Control descriptor D_GRAN_BYTE equ 000h ; Segment length is byte granular D_GRAN_PAGE equ 080h ; Segment length is page granular D_DEF16 equ 000h ; Default operation size is 16 bits D_DEF32 equ 040h ; Default operation size is 32 bits ; Following fields are specific to segment descriptors D_CODE equ 08h ; code D_DATA equ 0 ; data D_RX equ 02h ; if code, readable D_X equ 0 ; if code, exec only D_W equ 02h ; if data, writable D_R equ 0 ; if data, read only D_ACCESSED equ 1 ; segment accessed bit ; Useful combination access rights bytes RW_Data_Type equ (D_PRES+D_SEG+D_DATA+D_W) R_Data_Type equ (D_PRES+D_SEG+D_DATA+D_R) Code_Type equ (D_PRES+D_SEG+D_CODE+D_RX) D_PAGE32 equ (D_GRAN_PAGE+D_DEF32) ; 32 bit Page granular ; Masks for selector fields SELECTOR_MASK equ 0fff8h ; selector index SEL_LOW_MASK equ 0f8h ; mask for low byte of sel indx TABLE_MASK equ 04h ; table bit RPL_MASK equ 03h ; privilige bits RPL_CLR equ not 03h ; clear ring bits