📄 lim40specification.txt
字号:
o Applications should always return expanded memory pages
to the expanded memory manager upon termination. These
pages will be made available for other applications. If
unneeded pages are not returned to the expanded memory
manager, the system could "run out" of expanded memory
pages or expanded memory handles.
o Terminate and stay resident programs (TSR's) should
ALWAYS save the state of the map registers before
changing them. Since TSR's may interrupt other programs
Writing Programs That Use Expanded Memory 12
which may be using expanded memory, they must not change
the state of the page mapping registers without first
saving them. Before exiting, TSR's must restore the
state of the map registers.
The following sections describe the three ways to save
and restore the state of the map registers.
1. Save Page Map and Restore Page Map (Functions 8 and
9). This is the simplest of the three methods. The
EMM saves the map register contents in its own data
structures -- the application does not need to
provide extra storage locations for the mapping
context. The last mapping context to be saved,
under a particular handle, will be restored when a
call to Restore Page Map is issued with the same
handle. This method is limited to one mapping
context for each handle and saves the context for
only LIM standard 64K-byte page frames.
2. Get/Set Page Map (Function 15). This method
requires the application to allocate space for the
storage array. The EMM saves the mapping context in
an array whose address is passed to the EMM. When
restoring the mapping context with this method, an
application passes the address of an array which
contains a previously stored mapping context.
This method is preferable if an application needs to
do more than one save before a restore. It provides
a mechanism for switching between more than one
mapping context.
3. Get/Set Partial Page Map (Function 16). This method
provides a way for saving a partial mapping context.
It should be used when the application does not need
to save the context of all mappable memory. This
function also requires that the storage array be
part of the application's data.
o All functions using pointers to data structures must
have those data structures in memory which will not be
mapped out. Functions 22 and 23 (Alter Map & Call and
Alter Map & Jump) are the only exceptions.
Writing Programs That Use Expanded Memory 13
Examples
This section lists four example programs that demonstrate
the use of expanded memory.
Example 1
This program was written using the Microsoft C compiler
Version 3.0. EMM function calls are made with the int86
function found in the dos.h library. To create an ex-
ecutable program use the following compile command line:
msc /Gs /Oat /Ml program,,program;
#include
#include
#define EMM_INT 0x67 /* EMM interrupt number */
#define GET_PAGE_FRAME 0x41 /* EMM get page frame */
/* function number */
#define GET_UNALLOC_PAGE_COUNT 0x42 /* EMM get unallocated */
/* page count */
/* function number */
#define ALLOCATE_PAGES 0x43 /* EMM allocate pages */
/* function number */
#define MAP_PAGES 0x44 /* EMM map pages */
/* function number */
#define DEALLOCATE_PAGES 0x45 /* EMM deallocate pages */
/* function number */
#define DEVICE_NAME_LENGTH 8 /* length of a device */
/* name string */
#define TRUE 1
#define FALSE 0
union REGS input_regs, output_regs;
struct SREGS segment_regs;
int pf_addr;
/*------------------------------------------------------------*/
/* Routine to convert a segment:offset pair to a far ptr. */
/*------------------------------------------------------------*/
char *build_ptr (segment, offset)
unsigned int segment;
unsigned int offset;
{
char *ptr;
ptr = (char *)(((unsigned long)segment << 16) + offset);
return (ptr);
}
Writing Programs That Use Expanded Memory 14
/*------------------------------------------------------------*/
/* Function which determines whether EMM device driver */
/* is installed. */
/*------------------------------------------------------------*/
char emm_installed()
{
char *EMM_device_name = "EMMXXXX0";
char *int_67_device_name_ptr;
/*--------------------------------------------------------*/
/* AH = DOS get interrupt vector function. */
/*--------------------------------------------------------*/
input_regs.h.ah = 0x35;
/*--------------------------------------------------------*/
/* AL = EMM interrupt vector number. */
/*--------------------------------------------------------*/
input_regs.h.al = EMM_INT;
intdosx (&input_regs, &output_regs, &segment_regs);
/*--------------------------------------------------------*/
/* Upon return ES:0Ah points to location where */
/* device name should be. */
/*--------------------------------------------------------*/
int_67_device_name_ptr = build_ptr (segment_regs.es, 0x0A);
/*--------------------------------------------------------*/
/* Compare memory with EMM device name. */
/*--------------------------------------------------------*/
if (memcmp (EMM_device_name, int_67_device_name_ptr,
DEVICE_NAME_LENGTH) == 0)
return (TRUE);
else
return (FALSE);
}
/*------------------------------------------------------------*/
/* Function which determines if there are enough unallocated */
/* expanded memory pages for the application. */
/*------------------------------------------------------------*/
char enough_unallocated_pages (pages_needed)
int pages_needed;
{
input_regs.h.ah = GET_UNALLOCATED_PAGE_COUNT;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah != 0 || pages_needed > output_regs.x.bx)
return (FALSE);
else
return (TRUE);
}
Writing Programs That Use Expanded Memory 15
/*------------------------------------------------------------*/
/* Function which allocates expanded memory pages and passes */
/* back to the main EMM handle. */
/*------------------------------------------------------------*/
char allocate_expanded_memory_pages (pages_needed,emm_handle_ptr)
int pages_needed;
unsigned int *emm_handle_ptr;
{
input_regs.h.ah = ALLOCATE_PAGES;
input_regs.x.bx = pages_needed;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah == 0) {
*emm_handle_ptr = output_regs.x.dx;
return (TRUE);
}
else
return (FALSE);
}
/*------------------------------------------------------------*/
/* Routine to map a logical page to a physical page. */
/*------------------------------------------------------------*/
char map_expanded_memory_pages (emm_handle, physical_page,
logical_page)
unsigned int emm_handle;
int physical_page;
int logical_page;
{
input_regs.h.ah = MAP_PAGES;
input_regs.h.al = physical_page;
input_regs.x.bx = logical_page;
input_regs.x.dx = emm_handle;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah == 0)
return (TRUE);
else
return (FALSE);
}
Writing Programs That Use Expanded Memory 16
/*------------------------------------------------------------*/
/* Routine which gets the page frame base address from EMM. */
/*------------------------------------------------------------*/
char get_page_frame_address (pf_ptr)
char **pf_ptr;
{
input_regs.h.ah = GET_PAGE_FRAME;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah != 0) /* check EMM status */
return (FALSE);
else
*pf_ptr = build_ptr (output_regs.x.bx, 0);
return (TRUE);
}
/*------------------------------------------------------------*/
/* Routine to release all expanded memory pages allocated */
/* by an EMM handle. */
/*------------------------------------------------------------*/
char deallocate_expanded_memory_pages (emm_handle)
unsigned int emm_handle;
{
input_regs.h.ah = DEALLOCATE_PAGES;
input_regs.x.dx = emm_handle;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah == 0)
return (TRUE);
else
return (FALSE);
}
main()
{
unsigned int emm_handle;
char *pf_addr;
int pages_needed;
int physical_page;
int logical_page;
int index;
/*--------------------------------------------------------*/
/* Determine if EMM is installed. */
/*--------------------------------------------------------*/
if (!emm_installed())
exit(1);
Writing Programs That Use Expanded Memory 17
/*--------------------------------------------------------*/
/* Determine if enough expanded memory pages exist for */
/* application. */
/*--------------------------------------------------------*/
pages_needed = 1;
if (!enough_unallocated_pages (pages_needed))
exit(1);
/*--------------------------------------------------------*/
/* Allocate expanded memory pages. */
/*--------------------------------------------------------*/
if (!allocate_expanded_memory_pages (pages_needed,
&emm_handle))
exit(1);
/*--------------------------------------------------------*/
/* Map in the required pages. */
/*--------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -