426 lines
9.9 KiB
NASM
426 lines
9.9 KiB
NASM
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
|