home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
4DEMS.ZIP
/
EMS.ASM
next >
Wrap
Assembly Source File
|
1993-11-13
|
16KB
|
548 lines
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