📄 vmm.inc
字号:
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_Proc>
V86_API_Offset EQU 0
ELSE
IFB <Device_Num>
dev_id_err
ENDIF
V86_API_Offset EQU <OFFSET32 V86_Proc>
ENDIF
IFB <PM_Proc>
PM_API_Offset EQU 0
ELSE
IFB <Device_Num>
dev_id_err
ENDIF
PM_API_Offset EQU <OFFSET32 PM_Proc>
ENDIF
IFDEF Name&_Service_Table
IFB <Device_Num>
dev_id_err
ELSE
IFE Device_Num - Undefined_Device_ID
dev_id_err
ENDIF
ENDIF
Serv_Tab_Offset EQU <OFFSET32 Name&_Service_Table>
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 <In_Proc>, <Fall_Through>
je Out_Proc
ELSE
IFIDNI <Out_Proc>, <Fall_Through>
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 <P1>, <SHORT>
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 <Reg_32>, <EAX>
push eax
ENDIF
IFB <Cli_Off>
mov ax, (Client_&Cli_Seg * 100h) + 0FFh
ELSE
mov ax, (Client_&Cli_Seg * 100h) + Client_&Cli_Off
ENDIF
VMMcall Map_Flat
IFDIFI <Reg_32>, <EAX>
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
;=====================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -