windpmi.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 566 行 · 第 1/2 页
C
566 行
}
DPMISetSegmentLimit( sel, len );
} /* setLimitAndAddr */
/*
* DPMIGet32 - get a 32-bit segment
*/
WORD DPMIGet32( DWORD _FAR *addr_data, DWORD len )
{
int rc;
long adata[2];
/*
* the return codes 4 and 5 are the same as WINMEM32.DLL's return
* codes. Hysterical raisins.
*/
/*
* get memory region
*/
#ifdef DLL32
rc = _fDPMIAllocateMemoryBlock( adata, len );
#else
rc = DPMIAllocateMemoryBlock( adata, len );
#endif
if( rc ) {
return( 5 );
}
addr_data[0] = adata[0];
addr_data[1] = adata[1];
return( 0 );
} /* DPMIGet32 */
/*
* InitFlatAddrSpace - initialize flat address space
*/
WORD InitFlatAddrSpace( DWORD baseaddr, DWORD len )
{
long rc;
WORD sel;
descriptor desc;
hugeIncrement = DPMIGetNextSelectorIncrementValue();
/*
* get a code selector pointing to the memory
*/
rc = DPMIAllocateLDTDescriptors( 1 );
if( rc < 0L ) {
return( 4 );
}
sel = (WORD) rc;
CodeEntry.seg = sel;
setLimitAndAddr( sel, baseaddr, len, ACCESS_CODE );
CodeSelectorBase = baseaddr;
/*
* get a data and stack selector pointing to the memory
*/
rc = DPMIAllocateLDTDescriptors( 2 );
if( rc < 0L ) {
DPMIFreeLDTDescriptor( sel );
return( 4 );
}
sel = (WORD) rc;
DataSelector = sel;
setLimitAndAddr( sel, baseaddr, len, ACCESS_DATA );
StackSelector = sel + hugeIncrement;
// setLimitAndAddr( StackSelector, baseaddr, StackSize, ACCESS_DATA );
// The code generator sometimes uses EBP as general purpose
// register for accessing data that is not in the STACK segment
// so we must access the same space as DS
setLimitAndAddr( StackSelector, baseaddr, len, ACCESS_DATA );
WrapAround = FALSE;
if( DPMIGetDescriptor( DataSelector, &desc ) == 0 ) {
if( desc.lim_16_19 == 0x0F && desc.lim_0_15 == 0xFFFF ) {
WrapAround = TRUE;
} else {
WrapAround = FALSE;
}
}
return( 0 );
} /* InitFlatAddrSpace */
/*
* DPMIFree32 - free a 32-bit handle
*/
void DPMIFree32( DWORD handle )
{
DPMIFreeLDTDescriptor( DataSelector );
DPMIFreeLDTDescriptor( StackSelector );
DPMIFreeLDTDescriptor( CodeEntry.seg );
DPMIFreeMemoryBlock( handle );
} /* DPMIFree32 */
/*
* __DPMIAlloc - allocate a new block of memory
*/
DWORD FAR PASCAL __DPMIAlloc( DWORD size )
{
int rc;
DWORD adata[2];
memblk *p;
for(;;) {
rc = DPMIGet32( adata, size );
if( rc != 0 ) {
adata[0] = DataSelectorBase; // cause NULL to be returned
break;
}
p = (memblk *)LocalAlloc( LMEM_FIXED, sizeof(memblk) );
if( p == NULL ) {
DPMIFreeMemoryBlock( adata[1] );
adata[0] = DataSelectorBase; // cause NULL to be returned
break;
}
p->next = MemBlkList;
p->handle = adata[1];
p->addr = adata[0];
p->size = size;
MemBlkList = p;
if( WrapAround || adata[0] >= DataSelectorBase ) break;
// if we are on NT or OS/2, try again until we get a memory
// block with address higher than our DataSelectorBase 05-jul-95
}
if( (! WrapAround) && MemBlkList != NULL ) {
/* free up any memory allocated that is below DataSelectorBase */
for(;;) {
p = MemBlkList->next;
if( p == NULL ) break;
if( p->addr >= DataSelectorBase ) break;
DPMIFreeMemoryBlock( p->handle );
MemBlkList->next = p->next;
LocalFree( (HLOCAL)p );
}
p = MemBlkList;
if( p->addr < DataSelectorBase ) {
DPMIFreeMemoryBlock( p->handle );
MemBlkList = p->next;
LocalFree( (HLOCAL)p );
}
}
return( adata[0] - DataSelectorBase ); // return address of memory block
}
/*
* __DPMIFree - free a block of memory allocated by __DPMIAlloc 17-jan-95
*/
WORD FAR PASCAL __DPMIFree( DWORD addr )
{
memblk *p;
memblk *prev;
addr += DataSelectorBase; // add base address
prev = NULL;
for( p = MemBlkList; p != NULL; p = p->next ) {
if( p->addr == addr ) {
DPMIFreeMemoryBlock( p->handle );
if( prev == NULL ) {
MemBlkList = p->next;
} else {
prev->next = p->next;
}
LocalFree( (HLOCAL)p );
return( 0 ); // indicate success
}
prev = p;
}
return( -1 ); // indicate error
}
void FreeDPMIMemBlocks( void )
{
memblk *p;
for(;;) {
p = MemBlkList;
if( p == NULL ) break;
MemBlkList = p->next;
DPMIFreeMemoryBlock( p->handle );
LocalFree( (HLOCAL)p );
}
}
/*
* GetDataSelectorInfo - collect data about current 32-bit data segment
*/
void GetDataSelectorInfo( void )
{
DataSelectorBase = DPMIGetSegmentBaseAddress( DataSelector );
} /* GetDataSelectorInfo */
/*
* InitSelectorCache - allocate the selector cache
*/
int InitSelectorCache( void )
{
long rc;
int i;
WORD sel;
rc = DPMIAllocateLDTDescriptors( MAX_CACHE + 2 );
if( rc < 0L ) {
return( rc );
}
firstCacheSel = (WORD) rc;
sel = (WORD) rc;
for( i=0; i < MAX_CACHE + 2; i++ ) {
if( i < MAX_CACHE ) {
aliasCache[i].sel = sel;
aliasCache[i].limit = 0xFFFF;
aliasCache[i].base = 0L;
aliasCache[i].in_use = FALSE;
lastCacheSel = sel;
}
DPMISetDescriptorAccessRights( sel, DPL+ACCESS_DATA16 );
DPMISetSegmentLimit( sel, 0xFFFF );
sel += hugeIncrement;
}
StackCacheSel = lastCacheSel + hugeIncrement;
Int21Selector = StackCacheSel + hugeIncrement;
StackBase = 0;
if( SaveSP > 0x10000 ) {
StackBase = SaveSP - 0x10000;
}
StackBase_64K = SaveSP;
DPMISetSegmentBaseAddress( StackCacheSel, DataSelectorBase + StackBase );
return( 0 );
} /* InitSelectorCache */
/*
* FiniSelectorCache - clean up the selector cache
*/
void FiniSelectorCache( void )
{
int i;
for( i=0;i< MAX_CACHE; i++ ) {
if( aliasCache[i].sel != NULL ) {
DPMIFreeLDTDescriptor( aliasCache[i].sel );
}
}
DPMIFreeLDTDescriptor( StackCacheSel );
DPMIFreeLDTDescriptor( Int21Selector ); // 20-sep-94
} /* FiniSelectorCache */
/*
* FiniSelList - free selector list array
*/
void FiniSelList( void )
{
int i;
int j;
WORD sel;
unsigned char mask;
i = currSelCount;
j = 0;
while( i > 0 ) {
if( SelBitArray[j] != 0 ) {
mask = SelBitArray[j];
sel = (j << (3+3)) | (firstCacheSel & 7);
while( mask != 0 ) {
if( mask & 1 ) {
DPMIFreeLDTDescriptor( sel );
--i;
if( i == 0 ) return;
}
sel += 8;
mask = mask >> 1;
}
}
++j;
}
} /* FiniSelList */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?