Some applications require the ability to allocate memory in the real mode addressable 1 megabyte region. These services allow protected mode applications to allocate and free memory that is directly addressable by real mode software such as networks and DOS device drivers. Often, this memory is used in conjunction with the API translation services to call real mode software that is not directly supported by DPMI.
This function will allocate a block of memory from the DOS free memory pool. It returns both the real mode segment and one or more descriptors that can be used by protected mode applications to access the block.
To Call
AX = 0100h
BX = Number of paragraphs (16 byte blocks) desired
Returns
If function was successful:
Carry flag is clear.
AX = Initial real mode segment of allocated block
DX = Selector for allocated block
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as
requested
1Fh no more selectors available (DOS/4G(W) specific)
BX = Size of largest available block in paragraphs
Programmer's Notes
The following function allocates some DOS memory and
returns a C pointer to the memory.
It compiles with Watcom C/C++ version 11.0 or later,
and Microsoft Visual C/C++ version 4.0 or later,
and should compile with 16-bit C/C++ compilers:
// allocate DOS space from DPMI
// return error code, 0 if successful
void *dpmiAllocateDOSMemoryBlock(
long nbytes, // number of bytes requested
unsigned short *pPMsel) // (returned) protected-mode selector
{
short failed = 0; // non-zero if int 31h fails
unsigned short numpara; // number of paragraphs
unsigned short rmseg = 0; // real mode segment
unsigned short pmsel = 0; // protected-mode selector
// can't allocate 0 or negative bytes
if (nbytes <= 0)
return 0;
// fail if we ask for 1MB (or more)
if (nbytes >= (1024L * 1024)
return 0;
// convert bytes to paragraphs
numpara = (unsigned short) ((nbytes | 15) >> 4);
// switch to assembly to call DPMI host
__asm {
mov bx, numpara // put number of paragraphs into bx
mov ax, 0x100 // call dpmi host
int 0x31
mov rmseg, ax // collect results to C variables
mov pmsel, dx
sbb ax, ax // carry code to ax
mov failed, ax // and then to result
}
// if we didn't succeed, return null
if (failed)
return 0;
// set output results
*pPMsel = pmsel;
// return real-mode segment converted to linear address
return (void *) (((unsigned long) rmseg) << 4);
}
The following function returns the size in bytes of
the largest available DOS memory block.
It compiles with Watcom C/C++ version 11.0 or later,
and Microsoft Visual C/C++ version 4.0 or later,
and should compile with 16-bit C/C++ compilers:
// return size of largest available DOS block in bytes
unsigned long dpmiGetMaxDOSMemory(void)
{
unsigned short largest=0; // size of largest available block in paragraphs
// switch to assembly to call DPMI host
__asm {
mov bx, 0xffff // maximum request can never be satisfied
mov ax, 0x100 // DOS memory allocate/report
int 0x31
mov largest, bx // get largest available block
}
return ((unsigned long) largest) << 4;
}
This function frees memory that was allocated through the Allocate DOS Memory Block function.
To Call
AX = 0101h
DX = Selector of block to free
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
09h incorrect memory segment specified
Programmer's Notes
This function is used to grow or shrink a memory block that was allocated through the Allocate DOS Memory Block function.
To Call
AX = 0102h
BX = New block size in paragraphs
DX = Selector of block to modify
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as
requested
09h incorrect memory segment specified
BX = Maximum block size possible in paragraphs
Programmer's Notes