Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

425 lines
9.9 KiB

  1. PAGE ,132
  2. TITLE DXEMM.ASM -- Dos Extender MEMM Disable Code
  3. ; Copyright (c) Microsoft Corporation 1989-1991. All Rights Reserved.
  4. ;***********************************************************************
  5. ;
  6. ; DXEMM.ASM -- Dos Extender MEMM Disable Code
  7. ;
  8. ;-----------------------------------------------------------------------
  9. ;
  10. ; This module provides routines that attempt to disable MEMM/CEMM/EMM386
  11. ; drivers. DOSX tries to disable MEMM when starting up, and enables MEMM
  12. ; when terminating.
  13. ;
  14. ; NOTE: All the code in this module is consider initialization, and
  15. ; is discarded before going operational. This includes code
  16. ; segment variables. The MEMM enable code is not in this file
  17. ; since that cannot be discarded.
  18. ;
  19. ;-----------------------------------------------------------------------
  20. ;
  21. ; 12/08/89 jimmat Minor changes so enable code could be finished.
  22. ; 07/14/89 jimmat Original version - but largely taken from Windows/386
  23. ; code from ArronR
  24. ;
  25. ;***********************************************************************
  26. .286p
  27. ; -------------------------------------------------------
  28. ; INCLUDE FILE DEFINITIONS
  29. ; -------------------------------------------------------
  30. .xlist
  31. .sall
  32. include segdefs.inc
  33. include gendefs.inc
  34. IFDEF ROM
  35. include dxrom.inc
  36. ENDIF
  37. .list
  38. if NOT VCPI
  39. ; -------------------------------------------------------
  40. ; GENERAL SYMBOL DEFINITIONS
  41. ; -------------------------------------------------------
  42. EMM_OK equ 0
  43. ; Device driver header for Microsoft 386 EMM drivers
  44. ;
  45. emm_hdr STRUC
  46. ;
  47. DW ? ;Null segment address
  48. DW ? ;Null offset address
  49. DW ? ;Attribute - Char
  50. DW ? ;Strategy routine entry
  51. DW ? ;Interrupt routine entry
  52. DB 'EMMXXXX0' ;Character device name
  53. ;
  54. ; GENERAL FUNCTIONS ENTRY POINT
  55. ; ELIM_Entry is a entry point for executing general MEMM
  56. ; functions. (e.g. ON, OFF function).
  57. ;
  58. ELIM_Entry_off dw ? ; general entry point
  59. ;
  60. ; MEMM signature
  61. ;
  62. emmsig db ? ; MEMM signature
  63. emm_hdr ENDS
  64. ; -------------------------------------------------------
  65. ; EXTERNAL SYMBOL DEFINITIONS
  66. ; -------------------------------------------------------
  67. ; -------------------------------------------------------
  68. ; DATA SEGMENT DEFINITIONS
  69. ; -------------------------------------------------------
  70. DXDATA segment
  71. extrn MEMM_State:BYTE ; initial on/off/auto state
  72. extrn MEMM_Call:DWORD ; far call address into MEMM driver
  73. extrn fMEMM_Disabled:BYTE ; NZ if MEMM was disabled
  74. DXDATA ends
  75. ; -------------------------------------------------------
  76. ; CODE SEGMENT VARIABLES
  77. ; -------------------------------------------------------
  78. DXCODE segment
  79. IFNDEF ROM
  80. extrn segDXData:WORD
  81. ENDIF
  82. EMMDevNameRM DB "EMMXXXX0" ;Character device name
  83. MEMMsig db 'MICROSOFT EXPANDED MEMORY MANAGER 386'
  84. MEMMsiglen equ $ - MEMMsig
  85. CEMMsig db 'COMPAQ EXPANDED MEMORY MANAGER 386'
  86. CEMMsiglen equ $ - CEMMsig
  87. DXCODE ends
  88. DXPMCODE segment
  89. DXPMCODE ends
  90. ; -------------------------------------------------------
  91. subttl MEMM/CEMM/EMM386 Disable Routines
  92. page
  93. ; -------------------------------------------------------
  94. ; MEMM/CEMM/EMM386 DISABLE ROUTINES
  95. ; -------------------------------------------------------
  96. DXCODE segment
  97. assume cs:DXCODE
  98. ; -------------------------------------------------------
  99. ; EMMDisable -- This routine attempts to disable any installed
  100. ; MEMM/CEMM/EMM386 driver.
  101. ;
  102. ; Input: none
  103. ; Output: CY off - EMM driver disabled (or not installed)
  104. ; CY set - EMM installed, and can't disable
  105. ; Errors:
  106. ; Uses: All registers preserved
  107. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  108. public EMMDisable
  109. EMMDisable proc near
  110. pusha
  111. push ds
  112. push es
  113. call Check_for_EMM_Driver ;is there and EMM driver?
  114. jc emmd_ok ; no, then we're already done
  115. call MEMM_Inst_chk ;is it one we know about?
  116. jc emmd_bad ; no, then we can't disable it
  117. ; Get the current EMM driver state before checking for open handles. The
  118. ; process of checking for handles may change the driver from AUTO to ON.
  119. xor ax,ax ; get & save current emm state
  120. call [MEMM_Call] ; returns ah = 0 - on, 1 - off,
  121. mov MEMM_state,ah ; 2 - auto & off, 3 - auto & on
  122. call AnyMEMMHandles ;does it have any handles allocated?
  123. jc emmd_bad ; yes, then we can't disable it
  124. call TurnMEMMOff ;try to disable it
  125. jc emmd_bad
  126. mov fMEMM_Disabled,1 ;remember that we disabled MEMM
  127. emmd_ok:
  128. clc ;indicate disabled (or not installed)
  129. emmd_ret:
  130. pop es
  131. pop ds
  132. popa
  133. ret
  134. emmd_bad:
  135. stc ;can't disable!
  136. jmp short emmd_ret
  137. EMMDisable endp
  138. ; -------------------------------------------------------
  139. ; Windows/386 EMM Disable Code
  140. ; -------------------------------------------------------
  141. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  142. BeginProc macro name
  143. name proc near
  144. endm
  145. EndProc macro name
  146. name endp
  147. endm
  148. ;--------------------------------------------------------
  149. ;******************************************************************************
  150. ;
  151. ; MEMM_Inst_chk - Check to see if MEMM/CEMM is already installed
  152. ;
  153. ; ENTRY:
  154. ; Know there is an EMM driver so INT 67 vector points to something
  155. ;
  156. ; EXIT:
  157. ; Carry set
  158. ; No MEMM/CEMM driver
  159. ; Carry Clear
  160. ; [entry_seg] = segment of driver header
  161. ; [entry_off] = offset of status routine in MEMM
  162. ;
  163. ; USES: AX,CX,SI,DI,FLAGS
  164. ;
  165. ;******************************************************************************
  166. assume ds:NOTHING, es:NOTHING
  167. BeginProc MEMM_Inst_chk
  168. push ds
  169. push es
  170. xor ax,ax
  171. mov ds,ax
  172. mov ax,word ptr ds:[(67h * 4)+2] ; get segment pointed to by int 67
  173. mov ds,ax
  174. mov si,emmsig
  175. cld ; strings foward
  176. mov di,offset MEMMsig
  177. push cs
  178. pop es
  179. mov cx,MEMMsiglen
  180. cld
  181. repe cmpsb ; q: is the MEMM signature out there?
  182. je short found_sig ; y: return one
  183. mov si,emmsig
  184. mov di,offset CEMMsig
  185. mov cx,CEMMsiglen
  186. cld
  187. repe cmpsb ; q: is the CEMM signature out there?
  188. jne short Not_Found ; n: done, not found
  189. found_sig:
  190. IFDEF ROM
  191. GetRMDataSeg
  192. mov es,ax
  193. ELSE
  194. mov es,segDXData
  195. ENDIF
  196. xor si,si
  197. mov word ptr es:[MEMM_Call+2],ds ; save segment for far call
  198. mov cx,ds:[si.ELIM_Entry_off]
  199. mov word ptr es:[MEMM_Call],cx ; Offset for far call
  200. clc
  201. MEMM_Inst_Done:
  202. pop es
  203. pop ds
  204. ret
  205. Not_Found:
  206. stc
  207. jmp short MEMM_Inst_Done
  208. EndProc MEMM_Inst_chk
  209. ;******************************************************************************
  210. ;
  211. ; TurnMEMMOff
  212. ;
  213. ; Turn MEMM off (CEMM, IEFF, MEMM)
  214. ;
  215. ; ENTRY:
  216. ; entry_seg entry_off set to CEMM/MEMM enable disable routine
  217. ;
  218. ; EXIT:
  219. ; Carry Set
  220. ; Could not disable EMM
  221. ; Carry Clear
  222. ; MEMM CEMM EMM turned off
  223. ;
  224. ; USES: EAX,FLAGS
  225. ;
  226. ;******************************************************************************
  227. assume ds:DGROUP, es:NOTHING
  228. BeginProc TurnMEMMOff
  229. cmp MEMM_state,1 ; MEMM already off?
  230. jz short memm_off ; yes, nothing to do
  231. mov AX,0101h ; no, turn it OFF
  232. call [MEMM_Call]
  233. jc short memm_err
  234. memm_off:
  235. clc
  236. memm_done:
  237. ret
  238. memm_err:
  239. stc ; Error, set carry
  240. jmp short memm_done
  241. EndProc TurnMEMMOff
  242. ;******************************************************************************
  243. ;
  244. ; AnyMEMMHandles/Check_For_EMM_Handles
  245. ;
  246. ; Are there any open MEMM handles
  247. ;
  248. ; ENTRY:
  249. ; entry_seg entry_off set to CEMM/MEMM enable disable routine
  250. ;
  251. ; EXIT:
  252. ; Carry Set
  253. ; There are open handles
  254. ; Carry Clear
  255. ; There are no open handles
  256. ;
  257. ; USES: EAX,EBX,ECX,FLAGS
  258. ;
  259. ;******************************************************************************
  260. assume ds:DGROUP, es:NOTHING
  261. BeginProc AnyMEMMHandles
  262. mov ax,4600h
  263. int 67h
  264. cmp ah,EMM_OK
  265. jne short memm_is_off
  266. mov cx,ax
  267. mov ax,4B00h
  268. int 67h
  269. cmp ah,EMM_OK
  270. jne short memm_is_off
  271. cmp cl,40h
  272. jb short Check_Cnt
  273. or bx,bx ; Don't dec through 0!!!
  274. jz short Check_Cnt
  275. dec bx ; Do not include handle 0 on 4.0 drivers
  276. Check_Cnt:
  277. cmp bx,0
  278. stc
  279. jne short HaveHandles
  280. memm_is_off:
  281. clc
  282. HaveHandles:
  283. ret
  284. EndProc AnyMEMMHandles
  285. ;******************************************************************************
  286. ;
  287. ; Check_For_EMM_Driver
  288. ;
  289. ; See if an EMM driver is around
  290. ;
  291. ; ENTRY:
  292. ; None
  293. ;
  294. ; EXIT:
  295. ; Carry Set
  296. ; No EMM driver around
  297. ; Carry Clear
  298. ; EMM driver is around
  299. ;
  300. ; USES: AX,CX,SI,DI,FLAGS
  301. ;
  302. ;******************************************************************************
  303. assume ds:NOTHING,es:NOTHING
  304. BeginProc Check_For_EMM_Driver
  305. push ds
  306. push es
  307. ; Note, DS:SI & ES:DI used to be swapped, but on at least one system where
  308. ; Int 67h pointed to F000 and there was not ram or rom at F000:000A (rom
  309. ; started at F0000:8000), bus noise made the compare work when it shouldn't
  310. ; have. Swapping ES:DI / DS:SI corrected this.
  311. xor ax,ax
  312. mov es,ax
  313. mov ax,word ptr es:[(67h * 4)+2] ; get segment pointed to by int 67
  314. mov es,ax
  315. mov di,000Ah ; Offset of device name
  316. mov si,offset EMMDevNameRM
  317. push cs
  318. pop ds
  319. mov cx,8
  320. cld
  321. repe cmpsb
  322. jne short NoEMM_Seen
  323. clc
  324. EMMTstDone:
  325. pop es
  326. pop ds
  327. ret
  328. NoEMM_Seen:
  329. stc
  330. jmp short EMMTstDone
  331. EndProc Check_For_EMM_Driver
  332. ; -------------------------------------------------------
  333. DXCODE ends
  334. ;****************************************************************
  335. endif ; NOT VCPI
  336. end