summaryrefslogtreecommitdiffstats
path: root/private/mvdm/inc/vint.h
blob: 460374aee60ee0d4e476817428129e0315775ea9 (plain) (blame)
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

 */