summaryrefslogblamecommitdiffstats
path: root/private/mvdm/inc/vint.h
blob: 460374aee60ee0d4e476817428129e0315775ea9 (plain) (tree)
















































































































































































                                                                                               
/*++ 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

 */