📄 vmm.inc
字号:
;
; 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
;==============================================================================
; 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 <loop>
loopde EQU <loope>
loopdne EQU <loopne>
loopdz EQU <loopz>
loopdnz EQU <loopnz>
;******************************************************************************
; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -