⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmm.inc

📁 [随书类]Dos6.0源代码
💻 INC
📖 第 1 页 / 共 4 页
字号:
;
; 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 + -