An application program can use either of two methods to test for the existence of the Expanded Memory Manager:
Issue an open request (Int 21H Function 3DH) using the guaranteed device name of the EMM driver: EMMXXXX0. If the open function succeeds, either the driver is present or a file with the same name coincidentally exists on the default disk drive. To rule out the latter, the application can use IOCTL (Int 21H Function 44H) subfunctions 00H and 07H to ensure that EMM is present. In either case, the application should then use Int 21H Function 3EH to close the handle that was obtained from the open function, so that the handle can be reused for another file or device.
Use the address that is found in the Int 67H vector to inspect the device header of the presumed EMM. Interrupt handlers and device drivers must use this method. If the EMM is present, the name field at offset 0AH of the device header contains the string EMMXXXX0. This approach is nearly foolproof and avoids the relatively high overhead of an MS-DOS open function. However, it is somewhat less well behaved because it involves inspection of memory that does not belong to the application.
These two methods of testing for the existence of the Expanded Memory Manager are illustrated in Figures 11-4 and 11-5.
.
.
.
; attempt to "open" EMM...
mov dx,seg emm_name ; DS:DX = address of name
mov ds,dx ; of Expanded Memory Manager
mov dx,offset emm_name
mov ax,3d00h ; function 3dh, mode = 00h
; = open, read only
int 21h ; transfer to MS-DOS
jc error ; jump if open failed
; open succeeded, be sure
; it was not a file...
mov bx,ax ; BX = handle from open
mov ax,4400h ; function 44h subfunction 00h
; = IOCTL get device information
int 21h ; transfer to MS-DOS
jc error ; jump if IOCTL call failed
and dx,80h ; bit 7 = 1 if character device
jz error ; jump if it was a file
; EMM is present, be sure
; it is available...
; (BX still contains handle)
mov ax,4407h ; function 44h subfunction 07h
; = IOCTL get output status
int 21h ; transfer to MS-DOS
jc error ; jump if IOCTL call failed
or al,al ; test device status
jz error ; if AL = 0 EMM is not available
; now close handle ...
; (BX still contains handle)
mov ah,3eh ; function 3eh = close
int 21h ; transfer to MS-DOS
jc error ; jump if close failed
.
.
.
emm_name db 'EMMXXXX0',0 ; guaranteed device name for
; Expanded Memory Manager
Figure 11-4. Testing for the Expanded Memory Manager by means of the MS-DOS open and IOCTL functions.
emm_int equ 67h ; Expanded Memory Manager
; software interrupt
.
.
.
; first fetch contents of
; EMM interrupt vector...
mov al,emm_int ; AL = EMM int number
mov ah,35h ; function 35h = get vector
int 21h ; transfer to MS-DOS
; now ES:BX = handler address
; assume ES:0000 points
; to base of the EMM...
mov di,10 ; ES:DI = address of name
; field in device header
; DS:SI = EMM driver name
mov si,seg emm_name
mov ds,si
mov si,offset emm_name
mov cx,8 ; length of name field
cld
repz cmpsb ; compare names...
jnz error ; jump if driver absent
.
.
.
emm_name db 'EMMXXXX0' ; guaranteed device name for
; Expanded Memory Manager
Figure 11-5. Testing for the Expanded Memory Manager by inspection of the name field in the driver's device header.