|
|
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
|