1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
/*++ BUILD Version: 0001
Copyright (c) 1990 Microsoft Corporation
Module Name:
VINT.H
Abstract:
This module contains macro support for manipulating virtual
interrupt bit from v86 mode and 16bit protect mode. FCLI/FST/FIRET
result in exact behavior of these instructions on the chip without
trapping.
Author:
Sudeepb 08-Dec-1992 Created
Revision History:
sudeepb 16-Mar-1993 added FIRET
--*/
/*
See \nt\private\inc\vdm.h for a complete list
of the NTVDM state flag bit definitions
INTERRUPT_PENDING_BIT - set if interrupts pending
VIRTUAL_INTERRUPT_BIT - This bit always correctly reflects the interrupt
disbale/enable state of the vDM while in 16bit land.
MIPS_BIT_MASK - tells whether VDM is running on x86/mips
EXEC_BIT_MASK - tells if DOS is in int21/exec operation.
*/
#define INTERRUPT_PENDING_BIT 0x0003
#define VIRTUAL_INTERRUPT_BIT 0x0200
#define MIPS_BIT_MASK 0x400
#define EXEC_BIT_MASK 0x800
#define RM_BIT_MASK 0x1000
#define RI_BIT_MASK 0x2000
#define FIXED_NTVDMSTATE_SEGMENT 0x70
#define FIXED_NTVDMSTATE_OFFSET 0x14
#define FIXED_NTVDMSTATE_LINEAR ((FIXED_NTVDMSTATE_SEGMENT << 4) + FIXED_NTVDMSTATE_OFFSET)
#define FIXED_NTVDMSTATE_REL40 0x314
#define FIXED_NTVDMSTATE_SIZE 4
#define NTIO_LOAD_SEGMENT 0x70
#define NTIO_LOAD_OFFSET 0
#define pNtVDMState ((PULONG)FIXED_NTVDMSTATE_LINEAR)
#define VDM_TIMECHANGE 0x00400000
/* ASM
; FCLI macro should be used in v86mode/16bit preotect mode code to replace
; costly cli's. Please note that this macro could destroy the Overflow
; bit in the flag.
FCLI macro
local a,b,c
push ds
push ax
mov ax,40h
mov ds,ax
lahf
test word ptr ds:FIXED_NTVDMSTATE_REL40, MIPS_BIT_MASK OR RI_BIT_MASK
jnz short b
lock and word ptr ds:FIXED_NTVDMSTATE_REL40,NOT VIRTUAL_INTERRUPT_BIT
a:
sahf
pop ax
pop ds
jmp short c
b:
cli
jmp short a
c:
endm
;
; FSTI macro should be used in v86mode or 16bit protectmode code to replace
; costly sti's. Please note that this macro could destroy the Overflow bit
; in the flag.
FSTI macro
local a,b,c
push ds
push ax
mov ax,40h
mov ds,ax
lahf
test word ptr ds:FIXED_NTVDMSTATE_REL40, INTERRUPT_PENDING_BIT
jnz short b
test word ptr ds:FIXED_NTVDMSTATE_REL40, MIPS_BIT_MASK OR RI_BIT_MASK
jnz short b
lock or word ptr ds:FIXED_NTVDMSTATE_REL40, VIRTUAL_INTERRUPT_BIT
a:
sahf
pop ax
pop ds
jmp short c
b:
sti
jmp short a
c:
endm
FIRET MACRO
local a,b,d,e,f,g,i,j,k
push ds
push ax
;; Do real IRET on MIPS or if interrupts are pending
mov ax,40h
mov ds,ax
test word ptr ds:FIXED_NTVDMSTATE_REL40, MIPS_BIT_MASK OR RI_BIT_MASK
jnz short b
;; running on x86 can assume 386 or above instructions
push bp
mov bp,sp
mov ax,[bp+10] ; get flags
pop bp
test ax,100h ; test if trap flag is set
jnz short b ; if so, do iret
test ax,200h ; test if interrupt flag is set
jz short i ; ZR -> flag image has IF not set
lock or word ptr ds:FIXED_NTVDMSTATE_REL40, VIRTUAL_INTERRUPT_BIT
test word ptr ds:FIXED_NTVDMSTATE_REL40, INTERRUPT_PENDING_BIT
jnz short b
j:
xchg ah,al ; AH=low byte AL=high byte
cld
test al,4 ; check direction flag
jnz short d ;
e:
test al,8 ; check overflow flag
jnz short f ; go to f if flag image has OF set
jo short k ; go to k to reset OF
g:
sahf ; set low byte of flags from ah
pop ax
pop ds
retf 2 ; IRET and discard flags
i:
lock and word ptr ds:FIXED_NTVDMSTATE_REL40,NOT VIRTUAL_INTERRUPT_BIT
jmp short j
f:
jo short g ; all OK if OF bit set in real flag
; set the overflow bit in real flag
push ax
mov al,127
add al,2 ; will set OF
pop ax
jmp short g
k:
; reset the OF
push ax
xor al,al ; will reset OF
pop ax
jmp short g
d:
std
jmp short e
b:
pop ax
pop ds
iret
endm
*/
|