home *** CD-ROM | disk | FTP | other *** search
- COMMENT ~
- /*-------------------------------------------------------------------------+
- | Module: EMS.ASM |
- | Project: TOOLS |
- | Author: Paul A. Penrose |
- | (c) 1992, 4D Interactive Systems, Inc. All rights reserved. |
- | Start Date: 01 Nov 92 |
- | Last Revised: 29 Nov 92 |
- | Purpose: |
- | This module contains the EMS support code. The functions provided are |
- | C callable and provide complete linkage to the EMS services supported. |
- +-------------------------------------------------------------------------*/ ~
-
- IDEAL
-
- MODEL HUGE,C
-
- P286N
-
- DATASEG
- ;
- ; Define the equates here
- ;
-
- ;
- ; Define structures here
- ;
- STRUC physical_map
- segment_sel DW ?
- page_num DW ?
- ENDS
-
- STRUC handle_size_map
- handle DW ?
- num_pages DW ?
- ENDS
-
- STRUC handle_name_map
- handle DW ?
- handle_name DB 8 DUP(?)
- ENDS
-
- STRUC handle_directory
- handle DW ?
- num_pages DW ?
- handle_name DB 9 DUP(?)
- ENDS
-
- ;
- ; Declare module level data here
- ;
- ALIGN 2
- ems_pageframe DW 0
- ems_errnum DB 0
- ems_function DB 0
- ems_version DB 0
- ASCII_device_name DB 'EMMXXXX0', 0
- map_buffer DB 2550 DUP(0)
- name_buffer DB 8 DUP(0)
- temp DW ?
- copyright DB 'EMS functions (c) 1992, 4D Interactive Systems, Inc. '
- DB 'All rights reserved'
-
- PUBLIC ems_errnum, ems_function, ems_version, ems_pageframe
-
- CODESEG
-
- ;
- ; This function initializes the EMS package. TRUE is returned if the
- ; initialization is sucessfull, otherwise FALSE is returned.
- ;
- PROC ems_init
- ;
- ; First check to see if there is an EMS driver loaded
- ;
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- mov [ems_function],0
- mov ax,3D00H ;Open file, read only
- mov dx,offset ASCII_device_name
- int 21H
- jc ei_no_driver ;If not found, report no driver
- mov bx,ax
- push bx
- mov [ems_function],1
- mov ax,4400H ;Get device info
- int 21H
- pop bx
- jc ei_no_driver2
- test dx,0080H ;Is it a device?
- jz ei_no_driver2
- push bx
- mov ax,4407H ;Is the device ready?
- int 21H
- pop bx
- or al,al
- jz ei_no_driver2
- mov ax,3E00H ;Close the driver
- int 21H
- ;
- ; Get the EMS version and store it for later reference
- ;
- mov ah,46H
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah
- mov [ems_version],al
- or ah,ah
- jnz ei_error
- ;
- ; Next get the pageframe and store it for later reference
- ;
- mov ah,41H
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah
- mov [ems_pageframe],bx
- or ah,ah
- jnz ei_error
- mov ax,1 ;Return TRUE
- jmp ei_exit
- ei_no_driver2:
- mov ax,3E00H ;Close the driver
- int 21H
- ei_no_driver:
- ei_error:
- xor ax,ax ;Return FALSE
- ei_exit:
- pop ds
- ret
- ENDP
- PUBLIC ems_init
-
- ;
- ; This function returns the number of free (available) EMS pages
- ;
- PROC ems_num_free_pages
- ARG true_size:WORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- test [true_size],0FFFFH ;Report true size?
- jz nfp_001
- mov bx,4444H ;Put signature "DDDD" in BX:DX
- mov dx,4444H
- nfp_001:
- mov ah,42H
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah
- mov ax,bx
- pop ds
- ret
- ENDP
- PUBLIC ems_num_free_pages
-
- ;
- ; This function is used to allocate a number of EMS pages. It returns a
- ; handle that is used to identify these pages to other EMS functions. If
- ; a handle of -1 is returned, an error occured. An optional name of up to
- ; 8 characters can be passed that is used to name the handle. This name is
- ; ignored for EMS driver versions less than 4.0.
- ;
- PROC ems_alloc
- ARG num_pages:WORD
- ARG handle_name:DWORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- push si
- push di
- mov ah,43H
- mov [ems_function],ah
- mov bx,[num_pages]
- int 67H
- mov [ems_errnum],ah
- or ah,ah
- jz ea_good
- mov dx,0FFFFH ;Return -1 if error
- ea_good:
- push dx
- cmp [ems_version],40H ;Check if we can name it
- jb ea_exit ; exit if version < 4.0
- les si,[handle_name] ;Check the name ptr (NULL = none)
- mov ax,es
- or ax,si
- jz ea_exit
- mov ax,es ;Zero out name_buffer
- push ds ; first swap DS and ES
- pop es
- mov ds,ax
- xor ax,ax ; now set up the loop
- mov cx,4
- mov di,offset name_buffer ; and zero out the buffer
- ea_loop1:
- stosw
- loop ea_loop1
- mov di,offset name_buffer ;Copy the name into the buffer
- mov cx,8 ; but only the first 8 chars
- ea_loop2:
- lodsb
- or al,al
- jz ea_endcopy ;Exit if end of string
- stosb
- loop ea_loop2
- ea_endcopy:
- push es ;Restore DS
- pop ds
- mov ax,5301H ;Set name
- pop dx ;Get handle
- push dx ; and save it again
- mov si,offset name_buffer
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah
- ea_exit:
- pop ax ;Recover handle
- pop di
- pop si
- pop ds
- ret
- ENDP
- PUBLIC ems_alloc
-
- ;
- ; This function is used to free up EMS pages previously allocated using the
- ; ems_alloc function.
- ;
- PROC ems_free
- ARG handle:WORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- mov ah,45H
- mov [ems_function],ah
- mov dx,[handle]
- int 67H
- mov [ems_errnum],ah
- mov al,ah
- mov al,0
- pop ds
- ret
- ENDP
- PUBLIC ems_free
-
- ;
- ; This function is used to map a logical page that was previously allocated
- ; using the ems_alloc function to a physical page. A non-zero return value
- ; indicates an error occured.
- ;
- PROC ems_map_page
- ARG handle:WORD
- ARG logical_page:WORD
- ARG physical_page:WORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- mov bx,[logical_page]
- mov ax,[physical_page]
- mov dx,[handle]
- mov ah,44H
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah
- mov al,ah
- xor ah,ah
- pop ds
- ret
- ENDP
- PUBLIC ems_map_page
-
- ;
- ; This function is used to unmap logical page that is currently mapped to
- ; a physical page. A non-zero return value indicates an error occured.
- ;
- PROC ems_unmap_page
- ARG handle:WORD
- ARG physical_page:WORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- mov ax,[physical_page]
- mov dx,[handle]
- mov bx,0FFFFH
- mov ah,44H
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah
- mov al,ah
- xor ah,ah
- pop ds
- ret
- ENDP
- PUBLIC ems_unmap_page
-
- ;
- ; This function returns the number of physical pages available in the EMS
- ; page frame.
- ;
- PROC ems_num_physical_pages
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- cmp [ems_version],40H ;Is it ver 4.0 or greater?
- jae enpp_001
- mov ax,4 ;Return 4 pages if ver < 4.0
- pop ds
- ret
- enpp_001:
- push si
- push di
- mov ax,seg map_buffer ;Get a map of all mappable physical
- mov es,ax ; pages in the system
- mov di,offset map_buffer
- mov ax,5800H
- mov [ems_function],ah
- int 67H
- or ah,ah
- jz enpp_002
- mov [ems_errnum],ah ;Return error
- xor ax,ax
- pop ds
- ret
- enpp_002:
- mov si,offset map_buffer ;Search through the map
- mov dx,0 ;highest page found
- enpp_003:
- mov ax,[(physical_map PTR si).page_num]
- cmp ax,3 ;Skip this one if it's > 3
- ja enpp_004
- cmp ax,dx ;Skip if < highest
- jb enpp_004
- mov dx,ax ;This is the highest < 4
- enpp_004:
- add si,4
- loop enpp_003
- mov ax,dx ;Get the highest page < 4
- inc ax ;Return number of pages
- pop di
- pop si
- pop ds
- ret
- ENDP
- PUBLIC ems_num_physical_pages
-
- ;
- ; This function returns the number of open EMS handles
- ;
- PROC ems_num_open_handles
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- mov ah,4BH
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah ;Return error
- mov ax,bx
- pop ds
- ret
- ENDP
- PUBLIC ems_num_open_handles
-
- ;
- ; This function will fill in an EMS directory map structure with the current
- ; status of all open EMS handles. Returns 0 if no error, else error code.
- ;
- PROC ems_get_handle_directory
- ARG handle_dir:DWORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- push si
- push di
- push ds ;Get map showing number of pages for
- pop es ; each handle
- mov di,offset map_buffer
- mov ah,4DH
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah ;Return error
- or ah,ah
- jnz eghd_exit
- mov cx,bx
- mov si,offset map_buffer ;Search through the returned data and
- les di,[handle_dir] ; post it to the hande dir
- eghd_loop1:
- mov ax,[(handle_size_map PTR si).handle]
- mov [es:(handle_directory PTR di).handle],ax
- mov ax,[(handle_size_map PTR si).num_pages]
- mov [es:(handle_directory PTR di).num_pages],ax
- mov [es:(handle_directory PTR di).handle_name],0
- add di,13
- add si,4
- loop eghd_loop1
-
- cmp [ems_version],40H ;Exit if ems_version < 4.0
- jb eghd_exit
- push ds ;Get map of name for each handle
- pop es
- mov di,offset map_buffer
- mov ax,5400H
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah ;Return error
- or ah,ah
- jnz eghd_exit
- mov cx,ax
- mov [temp],cx
- mov si,offset map_buffer ;Search through the returned data and
- les di,[handle_dir] ; post it to the handle dir
- eghd_loop2:
- mov ax,[(handle_name_map PTR si).handle]
- push di ;Find the same handle in the dir
- push cx ; (don't assume that the handles are
- mov cx,[temp] ; in the same order as the previous
- eghd_loop3: ; call)
- cmp ax,[es:(handle_directory PTR di).handle]
- je eghd_handle_found
- add di,13
- loop eghd_loop3
- jmp eghd_next_handle
- eghd_handle_found:
- push si ;Copy the name into the directory
- add si,2 ;Point to name field
- add di,4 ;ditto
- mov cx,4
- rep movsw ;copy the name
- xor al,al
- stosb ;make sure string is terminated
- pop si
- eghd_next_handle:
- pop cx ;Process the next entry
- pop di
- add si,10
- loop eghd_loop2
- xor ah,ah
- eghd_exit:
- xor al,al
- pop di
- pop si
- pop ds
- ret
- ENDP
- PUBLIC ems_get_handle_directory
-
- ;
- ; This function will find the handle for any named EMS memory block and return
- ; it to the caller. If the name can't be found, 0xFFFF is returned.
- ;
- PROC ems_find_handle
- ARG handle_name:DWORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- push si
- push di
- les si,[handle_name] ;Check the name ptr (NULL = none)
- mov ax,es
- or ax,si
- jz efh_exit
- mov ax,es ;Zero out name_buffer
- push ds ; first swap DS and ES
- pop es
- mov ds,ax
- xor ax,ax ; now set up the loop
- mov cx,4
- mov di,offset name_buffer ; and zero out the buffer
- efh_loop1:
- stosw
- loop efh_loop1
- mov di,offset name_buffer ;Copy the name into the buffer
- mov cx,8 ; but only the first 8 chars
- efh_loop2:
- lodsb
- or al,al
- jz efh_endcopy ;Exit if end of string
- stosb
- loop efh_loop2
- efh_endcopy:
- push es ;Restore DS
- pop ds
- mov ax,5401H ;Find Name
- mov si,offset name_buffer
- mov [ems_function],ah
- int 67H
- mov [ems_errnum],ah
- or ah,ah
- jz efh_exit
- mov dx,0FFFFH
- efh_exit:
- mov ax,dx ;Return handle
- pop di
- pop si
- pop ds
- ret
- ENDP
- PUBLIC ems_find_handle
-
- ;
- ; This function will save the current EMS Page Frame mapping context.
- ;
- PROC ems_save_mapping_context
- ARG handle:WORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- mov ah,47H
- mov [ems_function],ah
- mov dx,[handle]
- int 67H
- mov [ems_errnum],ah ;Return error
- xor al,al
- pop ds
- ret
- ENDP
- PUBLIC ems_save_mapping_context
-
- ;
- ; This function will restore the current EMS Page Frame mapping context.
- ;
- PROC ems_restore_mapping_context
- ARG handle:WORD
-
- push ds ;Perform entry setup
- mov ax,seg ems_function
- mov ds,ax
- mov ah,48H
- mov [ems_function],ah
- mov dx,[handle]
- int 67H
- mov [ems_errnum],ah ;Return error
- xor al,al
- pop ds
- ret
- ENDP
- PUBLIC ems_restore_mapping_context
-
- END