KM_FF_RESCHED	EQU	000000FFH   
KM_FF_GCTXH	EQU	00000100H   
KM_FF_ATTENDSWAP	EQU	00000200H   
KM_FF_SIGPEND	EQU	00000400H   
KM_FF_EVAPALL	EQU	00000800H   
KM_FF_FREECOMPDFS	EQU	00001000H   
KM_FF_HYBERNATE	EQU	00002000H   
KM_GLOBAL_CONTEXT    equ   -1 

ifdef   KMSTRICT
BAD_SIGNATURE	EQU	53444142H 
kmAssertDef macro t
&t&_sig dd  ?
   endm

kmAssertCreate macro t, p
   mov   [p].&t&_sig,&t&_SIGNATURE
   endm

kmAssertP   macro t, p
   local l1,l2
   or p,p            
   jz short l1
   cmp   [p].&t&_sig,&t&_SIGNATURE  
   je short l2
l1:   Panic <"kmAssertP">
l2:
   endm

kmAssertDestroy macro t, p
   mov   [p].&t&_sig,BAD_SIGNATURE
   endm

else
kmAssertDef    macro t
   endm
kmAssertCreate    macro t, p
   endm
kmAssertDestroy      macro t, p
   endm
kmAssertP      macro t, p
   endm

endif

dll_s	STRUC
dll_pdllNext	DD	?
dll_pdllPrev	DD	?
dll_s	ENDS

PDLL struc
	dd ?
PDLL ends

DLL_UNLINKED	EQU	(NULL)      

hook_s	STRUC
hook_dll	DB	SIZE dll_s DUP (?)
hook_phookOwner	DD	?
hook_ptcbOwner	DD	?
hook_pfn	DD	?
hook_offRefData	DB	?
hook_iType	DB	?
hook_pad	DB	2 DUP (?)
ifdef   KMSTRICT
HOOK_sig	DD	?
endif
hook_s	ENDS

PHOOK struc
	dd ?
PHOOK ends

HOOKHEAD struc
db size dll_s dup(?)
HOOKHEAD ends

PHOOKHEAD struc
	dd ?
PHOOKHEAD ends

.errnz (size hook_s and 011b)    
.errnz (size hook_s gt 255)      

HOOK_SIGNATURE	EQU	4b4f4f48H   
KM_GLOBAL_HOOK       equ   -1

KMInitHookHead macro phookhead
   mov   [phookhead].dll_pdllNext,phookhead
   mov   [phookhead].dll_pdllPrev,phookhead
   endm

KMMarkHookUnlinked   macro phook
   mov   [phook].hook_dll.dll_pdllNext,DLL_UNLINKED
   mov   [phook].hook_dll.dll_pdllPrev,DLL_UNLINKED
   endm

KMIsHookLinked macro phook
   cmp   [phook].hook_dll.dll_pdllNext,DLL_UNLINKED
   endm

KMQueryHookData macro   p,phook
   local qhd10
ifdef KMSTRICT
   mov   p,-1
   cmp   [phook].hook_offRefData,0
   je short qhd10
endif
   movzx p,[phook].hook_offRefData
   add   p,phook
qhd10:
   endm

KMQueryHookType   macro ulType,phook
   movzx ulType,[phook].hook_iType
   endm

KMNextHookLink macro phookNext,phook
   mov   phookNext,[phook].hook_dll.dll_pdllNext
   endm

KMCallHook  macro phook,param
   PCall [phook].hook_pfn, <param>
   endm

KMDeleteHook macro phook,reg1,reg2
   mov   reg1,[phook].hook_dll.dll_pdllNext
   mov   reg2,[phook].hook_dll.dll_pdllPrev
   mov   [reg2].hook_dll.dll_pdllNext,reg1
   mov   reg1,[phook].hook_dll.dll_pdllPrev
   mov   reg2,[phook].hook_dll.dll_pdllNext
   mov   [reg2].hook_dll.dll_pdllPrev,reg1
   KMMarkHookUnlinked phook
   endm

KM_RIP_INVALID	EQU	0001H    
KM_RIP_INVALID_SET	EQU	0002H    
KM_RIP_WORD	EQU	0004H    
KM_RIP_TSD_RELATIVE	EQU	0008H    
KM_RIP_C32	EQU	0010H    
KM_REG_DS         equ   offset cri_ds
KM_REG_ES         equ   offset cri_es
KM_REG_SS         equ   offset cri_ss
KM_REG_CS         equ   offset cri_cs
KM_REG_GS         equ   offset cri_gs
KM_REG_FS         equ   offset cri_fs
KM_REG_EAX        equ   offset cri_eax
KM_REG_EBX        equ   offset cri_ebx
KM_REG_ECX        equ   offset cri_ecx
KM_REG_EDX        equ   offset cri_edx
KM_REG_EBP        equ   offset cri_ebp
KM_REG_ESP        equ   offset cri_esp
KM_REG_ESI        equ   offset cri_esi
KM_REG_EDI        equ   offset cri_edi
KM_REG_EIP        equ   offset cri_eip
KM_REG_EFLAG         equ   offset cri_eflag
KM_REG_CBARGS        equ   offset cri_cbargs
KM_REG_TRAPNUM       equ   offset cri_trapnum
KM_REG_ERRCODE       equ   offset cri_errcode
KM_REG_MAX        equ   offset cri_errcode
KM_REG_RETURN        equ   <KM_REG_EIP>
KM_REG_TOP        equ   offset cri_ulSize


kmreg_s	STRUC
kmreg_eax	DD	?
kmreg_ebx	DD	?
kmreg_ecx	DD	?
kmreg_edx	DD	?
kmreg_ebp	DD	?
kmreg_esi	DD	?
kmreg_edi	DD	?
kmreg_ds	DD	?
kmreg_es	DD	?
kmreg_fs	DD	?
kmreg_gs	DD	?
kmreg_cs	DD	?
kmreg_eip	DD	?
kmreg_eflag	DD	?
kmreg_ss	DD	?
kmreg_esp	DD	?
kmreg_s	ENDS

PKMREG struc
	dd ?
PKMREG ends


rip_s	STRUC
rip_flags	DW	?
rip_offset	DW	?
rip_s	ENDS

PRIP struc
	dd ?
PRIP ends


cri_s	STRUC
cri_ulSize	DD	?
cri_eax	DB	SIZE rip_s DUP (?)
cri_ebx	DB	SIZE rip_s DUP (?)
cri_ecx	DB	SIZE rip_s DUP (?)
cri_edx	DB	SIZE rip_s DUP (?)
cri_ebp	DB	SIZE rip_s DUP (?)
cri_esi	DB	SIZE rip_s DUP (?)
cri_edi	DB	SIZE rip_s DUP (?)
cri_ds	DB	SIZE rip_s DUP (?)
cri_es	DB	SIZE rip_s DUP (?)
cri_fs	DB	SIZE rip_s DUP (?)
cri_gs	DB	SIZE rip_s DUP (?)
cri_cs	DB	SIZE rip_s DUP (?)
cri_eip	DB	SIZE rip_s DUP (?)
cri_eflag	DB	SIZE rip_s DUP (?)
cri_ss	DB	SIZE rip_s DUP (?)
cri_esp	DB	SIZE rip_s DUP (?)
cri_cbargs	DB	SIZE rip_s DUP (?)
cri_trapnum	DB	SIZE rip_s DUP (?)
cri_errcode	DB	SIZE rip_s DUP (?)
cri_pfnRebuild    dd ?
cri_pafpfnKernelExit dd ?

cri_s	ENDS

PCRI struc
	dd ?
PCRI ends

ISF_STACK_PAD	EQU	8 

isf_s	STRUC
isf_CurrIntLevel	DD	?
isf_gs	DW	?
isf_padgs	DW	?
isf_fs	DW	?
isf_padfs	DW	?
isf_es	DW	?
isf_pades	DW	?
isf_ds	DW	?
isf_padds	DW	?
isf_edi	DD	?
isf_esi	DD	?
isf_ebp	DD	?
isf_padesp	DD	?
isf_ebx	DD	?
isf_edx	DD	?
isf_ecx	DD	?
isf_eax	DD	?
isf_pad	DB	ISF_STACK_PAD DUP (?)
isf_eip	DD	?
isf_cs	DW	?
isf_padcs	DW	?
isf_eflag	DD	?
isf_esp	DD	?
isf_ss	DW	?
isf_padss	DW	?
isf_s	ENDS

PISF struc
	dd ?
PISF ends

ISF_VSF_START	EQU	isf_edi
ISF_SIZE	EQU	(SIZE          isf_s )

tsf_s	STRUC
tsf_edi	DD	?
tsf_esi	DD	?
tsf_ebp	DD	?
tsf_padesp	DD	?
tsf_ebx	DD	?
tsf_edx	DD	?
tsf_ecx	DD	?
tsf_eax	DD	?
tsf_gs	DW	?
tsf_padgs	DW	?
tsf_fs	DW	?
tsf_padfs	DW	?
tsf_es	DW	?
tsf_pades	DW	?
tsf_ds	DW	?
tsf_padds	DW	?
tsf_trapnum	DD	?
tsf_errcode	DD	?
tsf_eip	DD	?
tsf_cs	DW	?
tsf_padcs	DW	?
tsf_eflag	DD	?
tsf_esp	DD	?
tsf_ss	DW	?
tsf_padss	DW	?
tsf_s	ENDS

PTSF struc
	dd ?
PTSF ends

TSF_SIZE	EQU	(SIZE          tsf_s )
tsf_cseip   equ   <fword ptr tsf_eip>
tsf_ssesp   equ   <fword ptr tsf_esp>


ksf_s	STRUC
ksf_edi	DD	?
ksf_esi	DD	?
ksf_ebp	DD	?
ksf_padesp	DD	?
ksf_ebx	DD	?
ksf_edx	DD	?
ksf_ecx	DD	?
ksf_eax	DD	?
ksf_gs	DW	?
ksf_padgs	DW	?
ksf_fs	DW	?
ksf_padfs	DW	?
ksf_es	DW	?
ksf_pades	DW	?
ksf_ds	DW	?
ksf_padds	DW	?
ksf_trapnum	DD	?
ksf_errcode	DD	?
ksf_eip	DD	?
ksf_cs	DW	?
ksf_padcs	DW	?
ksf_eflag	DD	?
ksf_s	ENDS

PKSF struc
	dd ?
PKSF ends

KSF_SIZE	EQU	(SIZE          ksf_s )
ksf_cseip   equ   <fword ptr ksf_eip>
ksf_tos     equ   <dword ptr (KSF_SIZE)>


vsf_s	STRUC
vsf_edi	DD	?
vsf_esi	DD	?
vsf_ebp	DD	?
vsf_padesp	DD	?
vsf_ebx	DD	?
vsf_edx	DD	?
vsf_ecx	DD	?
vsf_eax	DD	?
vsf_trapnum	DD	?
vsf_errcode	DD	?
vsf_eip	DD	?
vsf_cs	DW	?
vsf_padcs	DW	?
vsf_eflag	DD	?
vsf_esp	DD	?
vsf_ss	DW	?
vsf_padss	DW	?
vsf_es	DW	?
vsf_pades	DW	?
vsf_ds	DW	?
vsf_padds	DW	?
vsf_fs	DW	?
vsf_padfs	DW	?
vsf_gs	DW	?
vsf_padgs	DW	?
vsf_alteip	DD	?
vsf_altcs	DW	?
vsf_altpadcs	DW	?
vsf_alteflag	DD	?
vsf_altesp	DD	?
vsf_altss	DW	?
vsf_altpadss	DW	?
vsf_altes	DW	?
vsf_altpades	DW	?
vsf_altds	DW	?
vsf_altpadds	DW	?
vsf_altfs	DW	?
vsf_altpadfs	DW	?
vsf_altgs	DW	?
vsf_altpadgs	DW	?
vsf_s	ENDS

PVSF struc
	dd ?
PVSF ends

VSF_SIZE	EQU	(SIZE          vsf_s )
vsf_ax         equ   (word ptr vsf_eax)
vsf_al         equ   (byte ptr vsf_eax)
vsf_ah         equ   (byte ptr (vsf_eax+1))
vsf_bx         equ   (word ptr vsf_ebx)
vsf_bl         equ   (byte ptr vsf_ebx)
vsf_bh         equ   (byte ptr (vsf_ebx+1))
vsf_cx         equ   (word ptr vsf_ecx)
vsf_cl         equ   (byte ptr vsf_ecx)
vsf_ch         equ   (byte ptr (vsf_ecx+1))
vsf_dx         equ   (word ptr vsf_edx)
vsf_dl         equ   (byte ptr vsf_edx)
vsf_dh         equ   (byte ptr (vsf_edx+1))
vsf_si         equ   (word ptr vsf_esi)
vsf_di         equ   (word ptr vsf_edi)
vsf_bp         equ   (word ptr vsf_ebp)
vsf_sp         equ   (word ptr vsf_esp)
vsf_ip         equ   (word ptr vsf_eip)
vsf_flag    equ   (word ptr vsf_eflag)



VSF_COPY_START    equ   (vsf_eip)
VSF_ALT_START     equ   (vsf_alteip)
VSF_ALT_SIZE      equ   (VSF_SIZE - vsf_alteip)



VSF_ESP0_ADJUST      equ   (vsf_padgs - vsf_padss)


sef_s	STRUC
sef_edi	DD	?
sef_esi	DD	?
sef_ebp	DD	?
sef_padesp	DD	?
sef_ebx	DD	?
sef_edx	DD	?
sef_ecx	DD	?
sef_eax	DD	?
sef_gs	DW	?
sef_padgs	DW	?
sef_fs	DW	?
sef_padfs	DW	?
sef_es	DW	?
sef_pades	DW	?
sef_ds	DW	?
sef_padds	DW	?
sef_retaddr	DD	?
sef_cbargs	DD	?
sef_eflag	DD	?
sef_eip	DD	?
sef_cs	DW	?
sef_padcs	DW	?
sef_s	ENDS

PSEF struc
	dd ?
PSEF ends

SEF_SIZE	EQU	(SIZE          sef_s )

thunksef_s	STRUC
thunksef_sef	DB	SIZE sef_s DUP (?)
thunksef_ulret	DD	?
thunksef_s	ENDS

PTHUNKSEF struc
	dd ?
PTHUNKSEF ends

THUNKSEF_SIZE	EQU	(SIZE          thunksef_s )

ssf_s	STRUC
ssf_edi	DD	?
ssf_esi	DD	?
ssf_ebp	DD	?
ssf_padesp	DD	?
ssf_ebx	DD	?
ssf_edx	DD	?
ssf_ecx	DD	?
ssf_eax	DD	?
ssf_gs	DW	?
ssf_padgs	DW	?
ssf_fs	DW	?
ssf_padfs	DW	?
ssf_es	DW	?
ssf_pades	DW	?
ssf_ds	DW	?
ssf_padds	DW	?
ssf_thopadr	DW	?
ssf_cbargs	DD	?
ssf_sciret	DW	?
ssf_eflag	DD	?
ssf_eip	DD	?
ssf_cs	DW	?
ssf_padcs	DW	?
ssf_s	ENDS

PSSF struc
	dd ?
PSSF ends

SSF_SIZE	EQU	(SIZE          ssf_s )
_16B_Gate	EQU	80000000H   

dhf_s	STRUC
dhf_edi	DD	?
dhf_esi	DD	?
dhf_ebp	DD	?
dhf_padesp	DD	?
dhf_ebx	DD	?
dhf_edx	DD	?
dhf_ecx	DD	?
dhf_eax	DD	?
dhf_gs	DW	?
dhf_padgs	DW	?
dhf_fs	DW	?
dhf_padfs	DW	?
dhf_es	DW	?
dhf_pades	DW	?
dhf_ds	DW	?
dhf_padds	DW	?
dhf_eflag	DD	?
dhf_scratch	DD	?
dhf_eip	DD	?
dhf_cs	DW	?
dhf_padcs	DW	?
dhf_s	ENDS

PDHF struc
	dd ?
PDHF ends

DHF_SIZE	EQU	(SIZE          dhf_s )

tf_s	STRUC
tf_trapnum	DD	?
tf_errcode	DD	?
tf_eip	DD	?
tf_cs	DW	?
tf_padcs	DW	?
tf_eflags	DD	?
tf_esp	DD	?
tf_ss	DW	?
tf_padss	DW	?
tf_s	ENDS

PTF struc
	dd ?
PTF ends














KMQueryStackFrameSize   macro reg, pcri
   mov   reg,[(pcri).cri_ulSize]
   endm


















KMEnterExitKmodeInt macro
   local exk10,exk20,exk30,exk40,exk50,exk55,exk60
   ReferFlat _criISF,dword,ifundef
   ReferFlat _criVSF,dword,ifundef
   ReferFlat _TKSSBase,dword,ifundef
   ReferFlat _pTCBCur,dword,ifundef
if RAS
   ReferFlat _pbDYNResetPoint,dword,ifundef
   ReferFlat _DYNNullResetPoint,dword,ifundef
endif
if2
ifndef   KMExitKmodeEvents
   extrn KMExitKmodeEvents:near
endif
endif
ifdef INFOSTRICT        
ifndef   _PGVerifyInfoSegs
   extrn _PGVerifyInfoSegs:near
endif
   testb [esp].isf_eflag,F_VM
   jnz   short exk10    
   testb [esp].isf_cs,RPL_MASK   
   jz short exk20    
exk10:   call  _PGVerifyInfoSegs 
exk20:
endif
   kmCheckEvents        
   jz exk60       

   testb [esp].isf_eflag,F_VM
   jnz   short exk40    

   testb [esp].isf_cs,RPL_MASK   
   jz exk60       

IF RAS
   cmp   [_pbDYNResetPoint],offset FLAT:_DYNNullResetPoint
   jne   exk60       
ENDIF
   cmp   ss:[TKOPTDA.ptda_ProcType],PT_VDM
   je short exk30    

   mov   ebx,esp        
   SSToDS   ebx         
   mov   esi,[_pTCBCur]    
   mov   [esi].TCB_pcriFrameType,offset FLAT:_criISF
   mov   [esi].TCB_pFrameBase,ebx
   jmp   short exk50

exk30:   mov   eax,dword ptr [esp].isf_ds
   mov   dword ptr [esp].ISF_VSF_START.vsf_ds,eax
   mov   eax,dword ptr [esp].isf_es
   mov   dword ptr [esp].ISF_VSF_START.vsf_es,eax
   mov   eax,dword ptr [esp].isf_fs
   mov   dword ptr [esp].ISF_VSF_START.vsf_fs,eax
   mov   eax,dword ptr [esp].isf_gs
   mov   dword ptr [esp].ISF_VSF_START.vsf_gs,eax




exk40:   mov   esi,[_pTCBCur]    
exk50:   mov   [esi].TCBMiscFlags,0 
   mov   byte ptr [_cInDos],1 
   sti            
   cld            
   call  KMExitKmodeEvents
   kmExitKmode
   testb [esp].isf_eflag,F_VM
   jz    short exk55    

   xor   eax,eax                       
   mov   dword ptr [esp].isf_ds,eax
   mov   dword ptr [esp].isf_es,eax
   mov   dword ptr [esp].isf_fs,eax
   mov   dword ptr [esp].isf_gs,eax
   jmp   short exk60    

exk55:
   cmp   ss:[TKOPTDA.ptda_ProcType],PT_VDM
   jne   short exk60    

   mov   eax,dword ptr [esp].ISF_VSF_START.vsf_ds
   mov   dword ptr [esp].isf_ds,eax
   mov   eax,dword ptr [esp].ISF_VSF_START.vsf_es
   mov   dword ptr [esp].isf_es,eax
   mov   eax,dword ptr [esp].ISF_VSF_START.vsf_fs
   mov   dword ptr [esp].isf_fs,eax
   mov   eax,dword ptr [esp].ISF_VSF_START.vsf_gs
   mov   dword ptr [esp].isf_gs,eax
exk60:
   endm

.errnz   isf_eax - (ISF_VSF_START + vsf_eax)
.errnz   isf_ebx - (ISF_VSF_START + vsf_ebx)
.errnz   isf_ecx - (ISF_VSF_START + vsf_ecx)
.errnz   isf_edx - (ISF_VSF_START + vsf_edx)
.errnz   isf_ebp - (ISF_VSF_START + vsf_ebp)
.errnz   isf_esi - (ISF_VSF_START + vsf_esi)
.errnz   isf_edi - (ISF_VSF_START + vsf_edi)
.errnz   isf_padesp - (ISF_VSF_START + vsf_padesp)
.errnz   isf_pad - (ISF_VSF_START + vsf_trapnum)
.errnz   isf_eip - (ISF_VSF_START + vsf_eip)
.errnz   isf_cs - (ISF_VSF_START + vsf_cs)
.errnz   isf_eflag - (ISF_VSF_START + vsf_eflag)
.errnz   isf_esp - (ISF_VSF_START + vsf_esp)
.errnz   isf_ss - (ISF_VSF_START + vsf_ss)

























KMEnterKmodeVDM macro mode,fsreg,trap
   ReferFlat _criVSF,dword,ifundef
   cld            
   pushad
ifidni   <mode>,<vpm>
   mov   dword ptr [esp].vsf_ds,ds
   mov   dword ptr [esp].vsf_es,es
   mov   dword ptr [esp].vsf_fs,fs
   mov   dword ptr [esp].vsf_gs,gs
ifidni   <fsreg>,<nothing>
   NullContext <gs>,ebx
else
   NullContext <fs,gs>,ebx
endif
else
ifdifi   <mode>,<v86>
   %out  KMEnterKmodeVDM - bad parameter: mode
endif
endif



ifidni   <fsreg>,<flatcontext>
   FlatContext <ds,es,fs>,ebx
else
ifb   <trap>
   FlatContext <ds,es>,ebx
else
   db 0B9h        
   dw (seg FLAT:DGROUP),0  
   mov   ds,ecx         
   mov   es,ecx
   assume   ds:FLAT,es:FLAT
endif
endif
ifb   <trap>
   mov   ebx,[_pTCBCur]    
   mov   [ebx].TCBMiscFlags,0 
endif
   mov   ebx,[_pvsfFrameBase] 
   mov   byte ptr [_cInDos],1 
   sti            
   endm


























KMExitKmodeVDM macro mode,exitflag,debug
   local exk10,exk20,exk30,exk40,exk50,nbChk,normal
   normal = 0
   .386p
if2
 ifndef KMExitKmodeEvents
   extrn KMExitKmodeEvents:near
 endif
endif

ifidni   <exitflag>,<noreturn>
   CCALL32  KMExitKmodeEvents,,<noalignesp>
endif

ifdifi   <exitflag>,<restore>
 ifdifi  <exitflag>,<noreturn>
   nbChk = $
   normal = 1
   cli            
   db MI_SEGDS    
   kmCheckEvents        
  ifidni  <mode>,<v86>
   public   KMCHECKEVENTSIZE
   KMCHECKEVENTSIZE = $-nbChk
  endif
   jnz   short exk40    
 endif
endif

    exk10:
   kmExitKmode       

ifidni   <mode>,<v86orvpm>
   testb [esp].vsf_eflag,F_VM
 if normal ne 0
   jz short exk50    
 else
   jnz   short exk20
   mov   gs,dword ptr [esp].vsf_gs 
   mov   fs,dword ptr [esp].vsf_fs 
   mov   es,dword ptr [esp].vsf_es
   mov   ds,dword ptr [esp].vsf_ds
 endif
elseifidni  <mode>,<vpm>
   mov   gs,dword ptr [esp].vsf_gs 
   mov   fs,dword ptr [esp].vsf_fs 
   mov   es,dword ptr [esp].vsf_es
   mov   ds,dword ptr [esp].vsf_ds
elseifdifi  <mode>,<v86>
   %out  KMExitKmodeVDM - bad exit type parameter: mode
endif

    exk20:
   popad          

ifnb  <debug>
 ifdef   PMDEBUG
   movzx esp,sp         
   cmp   [esp].tf_trapnum,EXCPG  
   jne   short exk30
   testb [esp].tf_eflags,F_TRACE 
   jz short exk30
   mov   [esp].tf_trapnum,EXCSSI 
   JMP16 _Debug_Trap32     
    exk30:
 endif
endif

ifdifi   <exitflag>,<restore>
 ifdifi  <exitflag>,<noreturn>
   add   esp,8       
   iretd          

    exk40:
   CCALL32 KMExitKmodeEvents,,<noalignesp>
   jmp   short exk10

  ifidni  <mode>,<v86orvpm>
    exk50:
   mov   gs,dword ptr [esp].vsf_gs 
   mov   fs,dword ptr [esp].vsf_fs 
   mov   es,dword ptr [esp].vsf_es
   mov   ds,dword ptr [esp].vsf_ds
   jmp   exk20
  endif
 endif
endif

   endm













KMEnterKmodeTrap macro
   ReferFlat _criTSF,dword,ifundef
   PUSHD ds
   PUSHD es
   PUSHD fs
   PUSHD gs
   pushad
   NullContext <fs,gs>,esi
   kmEnterKmode <offset FLAT:_criTSF>,,nocheck
   endm





















KMExitKmodeTrap macro exitflag,debug
   local exk10,exk15,exk20
if2
ifndef   KMExitKmodeEvents
   extrn KMExitKmodeEvents:near
endif
endif
ifidni   <exitflag>,<noreturn>
   CCALL32  KMExitKmodeEvents,,<noalignesp>
endif
ifdifi   <exitflag>,<restore>
ifdifi   <exitflag>,<noreturn>
   cli            
   kmCheckEvents
   jnz   short exk20    
endif
endif
exk10:   kmExitKmode
ifnb  <debug>
ifdef PMDEBUG
   mov   esi,[_pPTDACur]
   cmp   [esi].ptda_flDbgEnabled,0
endif
endif
   popad          
   POPD  gs
   POPD  fs
   POPD  es
   POPD  ds
ifnb  <debug>
ifdef PMDEBUG
   jne   short exk15
   cmp   [esp].tf_trapnum,EXCPG  
   jne   short exk15
   testb [esp].tf_eflags,F_TRACE 
   jz short exk15
   mov   [esp].tf_trapnum,EXCSSI 
   JMP16 _Debug_Trap32     
exk15:
endif
endif
ifdifi   <exitflag>,<restore>
ifdifi   <exitflag>,<noreturn>
   add   esp,8       
   iretd          

exk20:   CCALL32  KMExitKmodeEvents,,<noalignesp>
   jmp   short exk10
endif
endif
   endm















KMEnterKernelTrap macro
   PUSHD ds       
   PUSHD es
   PUSHD fs
   PUSHD gs
   pushad
   NullContext <fs,gs>,esi
   FlatContext <ds,es>,esi    
   cld            
   mov   ebx,esp        
   SSToDS   ebx         
   endm















KMEnterKernelTrap_PS macro
   PUSHD ds       
   PUSHD es                                                       
   PUSHD fs                                                       
   PUSHD gs                                                       
   pushad                                                         
   NullContext <fs,gs>,esi                                        
   FlatContext <ds,es>,esi    
   cld            
   mov   ebx,esp        
   SSToDS_PS ebx        
   endm                                                           





















KMExitKernelTrap macro exitflag,debug
   local exk10
   popad          
   POPD  gs
   POPD  fs
   POPD  es
   POPD  ds
ifnb  <debug>
ifdef PMDEBUG
   cmp   [esp].tf_trapnum,EXCPG  
   jne   short exk10
   testb [esp].tf_eflags,F_TRACE 
   jz short exk10
   mov   [esp].tf_trapnum,EXCSSI 
   JMP16 _Debug_Trap32     
exk10:
endif
endif
ifdifi   <exitflag>,<restore>
ifdifi   <exitflag>,<noreturn>
   add   esp,8       
   iretd          
endif
endif
   endm














KMEnterKmodeAPI32 macro cbargs,pascal,nothunk
    .386p
ifnb <pascal>
ifdif <pascal>,<PASCAL>
   %out KMEnterKmodeAPI32 - the PASCAL keyword must be upper case
   .err
endif
ifb <nothunk>
   %out KMEnterKmodeAPI32 - can't have PASCAL without NOTHUNK
   .err
endif
endif
   pushfd
   PUSHD <cbargs>
ifb <nothunk>
if2
ifndef   KMEnterKmodeThunk&pascal&SEF
   extrn KMEnterKmodeThunk&pascal&SEF:near
endif
endif
   CCALL32  KMEnterKmodeThunk&pascal&SEF,,<nocheck,nocall,noalignesp>
else
if2
ifndef   KMEnterKmode&pascal&SEF
   extrn KMEnterKmode&pascal&SEF:near
endif
endif
   CCALL32  KMEnterKmode&pascal&SEF,,<nocheck,nocall,noalignesp>
endif
    CpuMode reset
   endm












KMExitKmodeAPI32 macro  cbargs,pascal,nothunk
    .386p
ifnb <pascal>
ifdif <pascal>,<PASCAL>
   %out KMExitKmodeAPI32 - the PASCAL keyword must be upper case
   .err
endif
ifb <nothunk>
   %out KMExitKmodeAPI32 - can't have PASCAL without NOTHUNK
   .err
endif
endif
   ?JumpSEFExit %&((cbargs+3) AND (NOT 3)),pascal
    CpuMode reset
   endm












?JumpSEFExit macro cbargs,pascal
    .386p
if2
ifndef   KMExitKmode&pascal&SEF&cbargs
   EXTRN32  KMExitKmode&pascal&SEF&cbargs
endif
endif
if (?cstype eq ?CS_32bit)
   jmp   KMExitKmode&pascal&SEF&cbargs
else
   JMP32 KMExitKmode&pascal&SEF&cbargs
endif
endm

















KMEnterKmodeCallGate macro cbargs,enterflag,pascal
   ReferFlat _cri&pascal&SEF,dword,ifundef
    .386p
ifidni   <enterflag>,<noinline>
   KMEnterKmodeAPI32 <cbargs>,<pascal>,nothunk
else
   pushfd
   PUSHD <cbargs>
   PUSHD 0     
   PUSHD ds
   PUSHD es
   PUSHD fs
   PUSHD gs
   pushad
   NullContext <fs,gs>,esi
   kmEnterKmode <offset FLAT:_cri&pascal&SEF>,<enterflag>
endif
    CpuMode reset
   endm
















KMExitKmodeCallGate macro cbargs,enterflag,pascal,nocheck
   local exk10,exk20,exk30,exk40
   .386p
ifidni   <enterflag>,<noinline>
   KMExitKmodeAPI32 <cbargs>,<pascal>,nothunk
else
if2
ifndef   KMExitKmodeEvents
   extrn KMExitKmodeEvents:near
endif
endif
ifdifi   <enterflag>,<noretval>
   mov   [esp].sef_eax,eax 
endif
   kmCheckEvents
   jnz   short exk20    

exk10:   kmExitKmode







if cbargs
ifb <pascal>
if (cbargs AND 3)
   %out Argument count not dword aligned for a 32-bit C call.
   .err
endif
   sub   dword ptr [esp]+SEF_SIZE+cbargs,cbargs
endif
endif
ifb   <nocheck>
   kmChkStack1 exk40    
exk30:               
endif
   popad          
   POPD  gs
   POPD  fs
   POPD  es
   POPD  ds
   add   esp,8       
   popfd          
   RETFD <(cbargs+3) AND (NOT 3)>

exk20:   CCALL32  KMExitKmodeEvents,,<noalignesp>
   jmp   exk10

ifb   <nocheck>
exk40:   kmChkStack2 exk30    
endif
endif
    CpuMode reset
   endm






















KMEnterKmodeSCI macro
   local   eksci
   ReferFlat _criSSF,dword,ifundef
    .386p
   PUSHD ds
   PUSHD es
   PUSHD fs
   PUSHD gs
   pushad
   mov     bx,fs                 
   mov     si,gs
   or      si,bx
   jz      short eksci
   NullContext <fs,gs>,esi
eksci:
   kmEnterKmode <offset FLAT:_criSSF>
    CpuMode reset
   endm










KMExitKmodeSCI macro
   local exk10,exk20,exk30,exk40
    .386p
if2
ifndef   KMExitKmodeEvents
   extrn KMExitKmodeEvents:near
endif
endif
   ifdef ?sci_ds
      if ?sci_ds eq ?SCI_UNKNOWN
         FlatContext <ds>,si
      endif
      ?sci_ds = ?SCI_FLAT
      ?sci_es = ?SCI_UNKNOWN
   else
      FlatContext <ds,es>,si
   endif
   kmCheckEvents
   jnz   short exk20    
exk10:   kmExitKmode
   kmChkStack1 <short exk40>    
exk30:
   popad          
   POPD  gs
   POPD  fs
   POPD  es
   POPD  ds
   add   esp,(size ssf_thopadr + size ssf_cbargs)
   ret

exk20:
   ifdef ?sci_es
      FlatContext <es>
      ?sci_es = ?SCI_FLAT
   endif
   CCALL32  KMExitKmodeEvents,,<noalignesp>
   jmp   exk10
exk40:
   kmChkStack2 exk30
   CpuMode reset
   endm









KMEnterKmodeDH macro
   ReferFlat _criDHF,dword,ifundef
    .386p
   pushfd
   PUSHD ds
   PUSHD es
   PUSHD fs
   PUSHD gs
   pushad
   NullContext <fs,gs>,esi
   kmEnterKmode <offset FLAT:_criDHF>,,nocheck



   mov   es,[ebx].dhf_es
   mov   esi,[ebx].dhf_esi
   push  [ebx].dhf_eflag
   push  [ebx].dhf_ebx
   push  [ebx].dhf_ds
   pop   ds
   pop   ebx
   popfd
    CpuMode reset
   endm









KMExitKmodeDH macro
   local exk10
    .386p
if2
ifndef   KMExitKmodeEvents
   extrn KMExitKmodeEvents:near
endif
endif
   pushfd
   pop   [esp].dhf_eflag
   mov   [esp].dhf_es,es
   mov   [esp].dhf_ds,ds
   mov   [esp].dhf_eax,eax
   mov   [esp].dhf_ebx,ebx
   mov   [esp].dhf_ecx,ecx
   mov   [esp].dhf_edx,edx
   mov   [esp].dhf_edi,edi
   mov   [esp].dhf_esi,esi
   FlatContext <ds,es>,si
   kmCheckEvents
   jz short exk10    
   CCALL32  KMExitKmodeEvents,,<noalignesp>
exk10:   kmExitKmode
   popad          
   POPD  gs
   POPD  fs
   POPD  es
   POPD  ds
   popfd
    CpuMode reset
   endm

















KMEnterKmodeRebuild macro
   ReferFlat _cInDos,byte,ifundef
   ReferFlat _pTCBCur,dword,ifundef
    .386p
   mov   byte ptr [_cInDos],1 
   mov   esi,[_pTCBCur]    
   mov   [esi].TCBMiscFlags,0 
   sti            
    CpuMode reset
   endm

















kmEnterKmode   macro sftype,enterflag,checkflag
   local enk10
   ReferFlat _cInDos,byte,ifundef
   ReferFlat _pTCBCur,dword,ifundef
    .386p
   cli            
   cld            
   ifdef ?sci_ds
      FlatContext <ds>,esi
      ?sci_ds = ?SCI_FLAT
      ?sci_es = ?SCI_UNKNOWN
   else
      FlatContext <ds,es>,esi
   endif
   mov   ebx,esp        
   SSToDS   ebx         
   mov   esi,[_pTCBCur]    
   mov   [esi].TCBMiscFlags,0 
   mov   [esi].TCB_pcriFrameType,sftype
   mov   [esi].TCB_pFrameBase,ebx
   mov   byte ptr [_cInDos],1 
ifb   <checkflag>
   kmCheckEntry         
endif
ifdifi   <enterflag>,<nosti>
   sti            
endif
   endm










kmExitKmode macro
   ReferFlat _cInDos,byte,ifundef
ifdef INFOSTRICT
   ifndef   _PGVerifyInfoSegs
      extrn _PGVerifyInfoSegs:near
   endif
   ifdef ?sci_es
      FlatContext <es>
      ?sci_es = ?SCI_FLAT
   endif
   CCALL32  _PGVerifyInfoSegs,,<nofar32,noalignesp> 
endif
    .386p
   mov   byte ptr [_cInDos],0 
   endm










kmCheckEvents macro
   ReferFlat _flGlobalActions,dword,ifundef
   ReferFlat _pTCBCur,dword,ifundef
   ReferFlat _pPTDACur,dword,ifundef
    .386p
   mov   eax,[_flGlobalActions]  
   mov   esi,[_pTCBCur]    
   or eax,[esi].TCBForcedActions 
   mov   esi,[_pPTDACur]      
   or eax,[esi].ptda_ForcedActions  
    CpuMode reset
   endm










kmChkStack1 macro checklabel
ifndef   _pTSDCur
   ReferFlat _pTSDCur,DWORD
endif
    .386p
   mov   eax,[_pTSDCur]
   test  byte ptr [eax].TSDUserSS,1 
   jz checklabel        
   endm














kmChkStack2 macro jmpback
   local kcs10
    .386p
   mov   edx,[eax].TSDUserESP    
   test  byte ptr [eax].TSDUserSS,SEL_LDTBIT 
   jz short kcs10           

   movzx edx,dx            
   movzx eax,[eax].TSDUserSS     

   shl   eax,SEL_LADDR_SHIFT     
   and   eax,SEL_LADDR_MASK
   add   edx,eax
kcs10:   mov   al,byte ptr [edx-1]     
   jmp   short jmpback        
   endm








kmCheckEntry   macro
   local lpf10
if (?cstype eq ?CS_32bit)
if2
ifndef   KMEnterKmodeEvents
   EXTRN32  KMEnterKmodeEvents
endif
endif
else
if2
ifndef   g_KMEnterKmodeEvents
   EXTRNF32 KMEnterKmodeEvents
endif
endif
endif
   cmp   [esi].TCBEntryActions,0
   jz short lpf10
   ifdef ?sci_es
      if ?sci_es eq ?SCI_UNKNOWN
         FlatContext <es>
         ?sci_es = ?SCI_FLAT
      endif
   endif
   CCALL32  KMEnterKmodeEvents,,<noalignesp>
lpf10:
   endm

ifndef   INCL_NOREFERS
   ReferFlat _flGlobalActions,dword
   ReferFlat _pPTDACur,dword
   ReferFlat _pTCBCur,dword
   ReferFlat _cInDos,byte
   ReferFlat _pvsfFrameBase,dword
   if2
       EXTRNF32 KMExitKmodeEvents
   endif
endif

