windows-nt/Source/XPSP1/NT/base/mvdm/dpmi/dxemm.asm

426 lines
9.9 KiB
NASM
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
PAGE ,132
TITLE DXEMM.ASM -- Dos Extender MEMM Disable Code
; Copyright (c) Microsoft Corporation 1989-1991. All Rights Reserved.
;***********************************************************************
;
; DXEMM.ASM -- Dos Extender MEMM Disable Code
;
;-----------------------------------------------------------------------
;
; This module provides routines that attempt to disable MEMM/CEMM/EMM386
; drivers. DOSX tries to disable MEMM when starting up, and enables MEMM
; when terminating.
;
; NOTE: All the code in this module is consider initialization, and
; is discarded before going operational. This includes code
; segment variables. The MEMM enable code is not in this file
; since that cannot be discarded.
;
;-----------------------------------------------------------------------
;
; 12/08/89 jimmat Minor changes so enable code could be finished.
; 07/14/89 jimmat Original version - but largely taken from Windows/386
; code from ArronR
;
;***********************************************************************
.286p
; -------------------------------------------------------
; INCLUDE FILE DEFINITIONS
; -------------------------------------------------------
.xlist
.sall
include segdefs.inc
include gendefs.inc
IFDEF ROM
include dxrom.inc
ENDIF
.list
if NOT VCPI
; -------------------------------------------------------
; GENERAL SYMBOL DEFINITIONS
; -------------------------------------------------------
EMM_OK equ 0
; Device driver header for Microsoft 386 EMM drivers
;
emm_hdr STRUC
;
DW ? ;Null segment address
DW ? ;Null offset address
DW ? ;Attribute - Char
DW ? ;Strategy routine entry
DW ? ;Interrupt routine entry
DB 'EMMXXXX0' ;Character device name
;
; GENERAL FUNCTIONS ENTRY POINT
; ELIM_Entry is a entry point for executing general MEMM
; functions. (e.g. ON, OFF function).
;
ELIM_Entry_off dw ? ; general entry point
;
; MEMM signature
;
emmsig db ? ; MEMM signature
emm_hdr ENDS
; -------------------------------------------------------
; EXTERNAL SYMBOL DEFINITIONS
; -------------------------------------------------------
; -------------------------------------------------------
; DATA SEGMENT DEFINITIONS
; -------------------------------------------------------
DXDATA segment
extrn MEMM_State:BYTE ; initial on/off/auto state
extrn MEMM_Call:DWORD ; far call address into MEMM driver
extrn fMEMM_Disabled:BYTE ; NZ if MEMM was disabled
DXDATA ends
; -------------------------------------------------------
; CODE SEGMENT VARIABLES
; -------------------------------------------------------
DXCODE segment
IFNDEF ROM
extrn segDXData:WORD
ENDIF
EMMDevNameRM DB "EMMXXXX0" ;Character device name
MEMMsig db 'MICROSOFT EXPANDED MEMORY MANAGER 386'
MEMMsiglen equ $ - MEMMsig
CEMMsig db 'COMPAQ EXPANDED MEMORY MANAGER 386'
CEMMsiglen equ $ - CEMMsig
DXCODE ends
DXPMCODE segment
DXPMCODE ends
; -------------------------------------------------------
subttl MEMM/CEMM/EMM386 Disable Routines
page
; -------------------------------------------------------
; MEMM/CEMM/EMM386 DISABLE ROUTINES
; -------------------------------------------------------
DXCODE segment
assume cs:DXCODE
; -------------------------------------------------------
; EMMDisable -- This routine attempts to disable any installed
; MEMM/CEMM/EMM386 driver.
;
; Input: none
; Output: CY off - EMM driver disabled (or not installed)
; CY set - EMM installed, and can't disable
; Errors:
; Uses: All registers preserved
assume ds:DGROUP,es:NOTHING,ss:NOTHING
public EMMDisable
EMMDisable proc near
pusha
push ds
push es
call Check_for_EMM_Driver ;is there and EMM driver?
jc emmd_ok ; no, then we're already done
call MEMM_Inst_chk ;is it one we know about?
jc emmd_bad ; no, then we can't disable it
; Get the current EMM driver state before checking for open handles. The
; process of checking for handles may change the driver from AUTO to ON.
xor ax,ax ; get & save current emm state
call [MEMM_Call] ; returns ah = 0 - on, 1 - off,
mov MEMM_state,ah ; 2 - auto & off, 3 - auto & on
call AnyMEMMHandles ;does it have any handles allocated?
jc emmd_bad ; yes, then we can't disable it
call TurnMEMMOff ;try to disable it
jc emmd_bad
mov fMEMM_Disabled,1 ;remember that we disabled MEMM
emmd_ok:
clc ;indicate disabled (or not installed)
emmd_ret:
pop es
pop ds
popa
ret
emmd_bad:
stc ;can't disable!
jmp short emmd_ret
EMMDisable endp
; -------------------------------------------------------
; Windows/386 EMM Disable Code
; -------------------------------------------------------
assume ds:NOTHING,es:NOTHING,ss:NOTHING
BeginProc macro name
name proc near
endm
EndProc macro name
name endp
endm
;--------------------------------------------------------
;******************************************************************************
;
; MEMM_Inst_chk - Check to see if MEMM/CEMM is already installed
;
; ENTRY:
; Know there is an EMM driver so INT 67 vector points to something
;
; EXIT:
; Carry set
; No MEMM/CEMM driver
; Carry Clear
; [entry_seg] = segment of driver header
; [entry_off] = offset of status routine in MEMM
;
; USES: AX,CX,SI,DI,FLAGS
;
;******************************************************************************
assume ds:NOTHING, es:NOTHING
BeginProc MEMM_Inst_chk
push ds
push es
xor ax,ax
mov ds,ax
mov ax,word ptr ds:[(67h * 4)+2] ; get segment pointed to by int 67
mov ds,ax
mov si,emmsig
cld ; strings foward
mov di,offset MEMMsig
push cs
pop es
mov cx,MEMMsiglen
cld
repe cmpsb ; q: is the MEMM signature out there?
je short found_sig ; y: return one
mov si,emmsig
mov di,offset CEMMsig
mov cx,CEMMsiglen
cld
repe cmpsb ; q: is the CEMM signature out there?
jne short Not_Found ; n: done, not found
found_sig:
IFDEF ROM
GetRMDataSeg
mov es,ax
ELSE
mov es,segDXData
ENDIF
xor si,si
mov word ptr es:[MEMM_Call+2],ds ; save segment for far call
mov cx,ds:[si.ELIM_Entry_off]
mov word ptr es:[MEMM_Call],cx ; Offset for far call
clc
MEMM_Inst_Done:
pop es
pop ds
ret
Not_Found:
stc
jmp short MEMM_Inst_Done
EndProc MEMM_Inst_chk
;******************************************************************************
;
; TurnMEMMOff
;
; Turn MEMM off (CEMM, IEFF, MEMM)
;
; ENTRY:
; entry_seg entry_off set to CEMM/MEMM enable disable routine
;
; EXIT:
; Carry Set
; Could not disable EMM
; Carry Clear
; MEMM CEMM EMM turned off
;
; USES: EAX,FLAGS
;
;******************************************************************************
assume ds:DGROUP, es:NOTHING
BeginProc TurnMEMMOff
cmp MEMM_state,1 ; MEMM already off?
jz short memm_off ; yes, nothing to do
mov AX,0101h ; no, turn it OFF
call [MEMM_Call]
jc short memm_err
memm_off:
clc
memm_done:
ret
memm_err:
stc ; Error, set carry
jmp short memm_done
EndProc TurnMEMMOff
;******************************************************************************
;
; AnyMEMMHandles/Check_For_EMM_Handles
;
; Are there any open MEMM handles
;
; ENTRY:
; entry_seg entry_off set to CEMM/MEMM enable disable routine
;
; EXIT:
; Carry Set
; There are open handles
; Carry Clear
; There are no open handles
;
; USES: EAX,EBX,ECX,FLAGS
;
;******************************************************************************
assume ds:DGROUP, es:NOTHING
BeginProc AnyMEMMHandles
mov ax,4600h
int 67h
cmp ah,EMM_OK
jne short memm_is_off
mov cx,ax
mov ax,4B00h
int 67h
cmp ah,EMM_OK
jne short memm_is_off
cmp cl,40h
jb short Check_Cnt
or bx,bx ; Don't dec through 0!!!
jz short Check_Cnt
dec bx ; Do not include handle 0 on 4.0 drivers
Check_Cnt:
cmp bx,0
stc
jne short HaveHandles
memm_is_off:
clc
HaveHandles:
ret
EndProc AnyMEMMHandles
;******************************************************************************
;
; Check_For_EMM_Driver
;
; See if an EMM driver is around
;
; ENTRY:
; None
;
; EXIT:
; Carry Set
; No EMM driver around
; Carry Clear
; EMM driver is around
;
; USES: AX,CX,SI,DI,FLAGS
;
;******************************************************************************
assume ds:NOTHING,es:NOTHING
BeginProc Check_For_EMM_Driver
push ds
push es
; Note, DS:SI & ES:DI used to be swapped, but on at least one system where
; Int 67h pointed to F000 and there was not ram or rom at F000:000A (rom
; started at F0000:8000), bus noise made the compare work when it shouldn't
; have. Swapping ES:DI / DS:SI corrected this.
xor ax,ax
mov es,ax
mov ax,word ptr es:[(67h * 4)+2] ; get segment pointed to by int 67
mov es,ax
mov di,000Ah ; Offset of device name
mov si,offset EMMDevNameRM
push cs
pop ds
mov cx,8
cld
repe cmpsb
jne short NoEMM_Seen
clc
EMMTstDone:
pop es
pop ds
ret
NoEMM_Seen:
stc
jmp short EMMTstDone
EndProc Check_For_EMM_Driver
; -------------------------------------------------------
DXCODE ends
;****************************************************************
endif ; NOT VCPI
end