📄 hal_mllc.c
字号:
mbpt->size = size;
mbpt->free = FALSE;
#ifdef _DEBUG
sprintf(str, "seVmemAlloc(%08lX) > %08lX", size, mbpt->address);
_seVmemDump(str);
#endif
return mbpt->address;
}
}
}
#ifdef _DEBUG
sprintf(str, "seVmemAlloc(%08lX) FAILED", size);
_seVmemDump(str);
#endif
#ifdef INTEL_DOS
return -1;
#else
return 0;
#endif
}
/*-----------------------------------------------------------------------------
//
// Free a video memory block. Block must have been previously allocated
// by a call to one of the following:
//
// seVmemAlloc
// seVmemAllocCursor
// seVmemAllocOverlay
// seVmemAllocDualPanelBuffer
//
// It is legal to free a free block.
//
//---------------------------------------------------------------------------*/
BOOL seVmemFree(DWORD address)
{
_MEMBLOCKST *mbpt;
#ifdef _DEBUG
char str[50];
#endif
for (mbpt = &gMB; mbpt != NULL; mbpt = mbpt->next)
{
if ((mbpt->address == address) && (mbpt->free == FALSE))
{
mbpt->free = TRUE;
seVmemBlocksMerge();
#ifdef _DEBUG
sprintf(str, "seVmemFree(%08lX) passed", address);
_seVmemDump(str);
#endif
return TRUE;
}
}
#ifdef _DEBUG
sprintf(str, "seVmemFree(%08lX) FAILED", address);
_seVmemDump(str);
#endif
return FALSE;
}
/*-----------------------------------------------------------------------------
//
// Allocate and link block B behind block A.
//
//---------------------------------------------------------------------------*/
static _MEMBLOCKST *seNewBlockAppend(_MEMBLOCKST *mbpta)
{
_MEMBLOCKST *mbptb;
mbptb = (_MEMBLOCKST*)malloc(sizeof(_MEMBLOCKST));
if (mbptb != NULL)
{
mbptb->next = mbpta->next;
if (mbptb->next)
mbptb->next->prev = mbptb;
mbptb->prev = mbpta;
mbpta->next = mbptb;
}
return mbptb;
}
/*-----------------------------------------------------------------------------
//
// Allocate a chunk of memory. (bottommost)
//
// Arguments:
// DWORD size: size of the requested memory block in bytes
// DWORD alignement: initial address alignement. Mostly meant for
// hardware cursors, where the bottommost address needs
// to be aligned at 1k boundary, any other at 8k
// boundary.
//---------------------------------------------------------------------------*/
static DWORD seBackAlloc(DWORD size, DWORD alignment)
{
_MEMBLOCKST *mbpt;
mbpt = seGetLastBlock();
// We traverse the blocks backwards.
// At this time, we are pointing to the very last block.
// The cursor at this position needs to be on 1024 byte boundary.
do
{
if (mbpt->free == TRUE)
{
DWORD lastOffset, alignedOffset, oldsize;
// Check if the block is big enough. Beware we need address
// that meets our alignment needs.
lastOffset = mbpt->address - _DispLinearAddress + mbpt->size;
alignedOffset = (mbpt->address - _DispLinearAddress) & ~(alignment-1);
if ((alignedOffset+size) <= lastOffset)
{
// We fit in.
// Carve the memory from the end of the block
_MEMBLOCKST *cursorblock = seNewBlockAppend(mbpt);
#ifdef INTEL_DOS
if (cursorblock == NULL)
return -1;
#else
if (cursorblock == NULL)
return 0;
#endif
// Calculate the biggest possible aligned address
// within the free block.
lastOffset = mbpt->address - _DispLinearAddress + mbpt->size;
alignedOffset = (lastOffset - size) & ~(alignment-1);
// The original free block will be truncated.
oldsize = mbpt->size;
mbpt->size = (alignedOffset + _DispLinearAddress - mbpt->address);
cursorblock->size = oldsize - mbpt->size;
cursorblock->address = alignedOffset + _DispLinearAddress;
cursorblock->free = FALSE;
// Since we assume alignment >= needed memory size, to preserve
// some memory, we split the new block again. (We don't want
// to allocate 8k for one cursor. We need 1k on 8k alignment)
if (cursorblock->size > size)
{
// Append the new block.
_MEMBLOCKST *spareblock = seNewBlockAppend(cursorblock);
#ifdef INTEL_DOS
if (spareblock == NULL)
return -1;
#else
if (spareblock == NULL)
return 0;
#endif
// The original cursor block will be truncated.
oldsize = cursorblock->size;
cursorblock->size = size;
spareblock->size = oldsize-size;
spareblock->address = cursorblock->address+size;
spareblock->free = TRUE;
}
return cursorblock->address;
}
}
alignment = 8192;
mbpt = mbpt->prev;
} while (mbpt != NULL);
#ifdef INTEL_DOS
return -1;
#else
return 0;
#endif
}
/*-----------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------*/
static _MEMBLOCKST *seGetLastBlock(void)
{
_MEMBLOCKST *mbpt;
for (mbpt = &gMB; mbpt != NULL; mbpt = mbpt->next)
{
if (mbpt->next == NULL) //the last block
break;
}
return mbpt;
}
/*-----------------------------------------------------------------------------
//
// Merge neighbouring free video memory blocks into one big free block.
//
//---------------------------------------------------------------------------*/
static void seVmemBlocksMerge(void)
{
int change;
_MEMBLOCKST *mbpt,*next;
do
{
change = FALSE;
for (mbpt = &gMB; mbpt != NULL; mbpt = mbpt->next)
{
if (mbpt->free == TRUE && ((next = mbpt->next) != NULL))
{
if (next->free == TRUE)
{
mbpt->size += next->size;
mbpt->next = next->next;
if (mbpt->next)
mbpt->next->prev = mbpt;
free(next);
change = TRUE;
break;
}
}
}
} while (change == TRUE);
}
/*-----------------------------------------------------------------------------
//
// Dump video memory blocks.
//
//---------------------------------------------------------------------------*/
void _seVmemDump(char *str)
{
// _MEMBLOCKST *mbpt;
DWORD totalFree,totalUsed,total;
if (str != NULL)
printf("%s\n", str);
// printf("Forward chain:\n");
totalFree = totalUsed = total = 0;
/*
for (mbpt = &gMB; mbpt != NULL; mbpt = mbpt->next)
{
if (mbpt->free)
totalFree += mbpt->size;
else
totalUsed += mbpt->size;
printf("block %8xh: address: %08xh size: %8xh free: %d\n",
mbpt,mbpt->address,mbpt->size, mbpt->free);
}
total = totalFree+totalUsed;
printf("Total Free: %8xh Total Used :%8xh Total: %8xh\n",
totalFree,totalUsed,total);
*/
/*
printf("Backwords chain:\n");
totalFree = totalUsed = total = 0;
for (mbpt = seGetLastBlock(); mbpt != NULL; mbpt = mbpt->prev)
{
if (mbpt->free)
totalFree += mbpt->size;
else
totalUsed += mbpt->size;
printf("block %8xh: address: %08xh size: %8xh free: %d\n",
mbpt,mbpt->address,mbpt->size, mbpt->free);
}
total = totalFree+totalUsed;
printf("Total Free: %8xh Total Used :%8xh Total: %8xh\n",
totalFree,totalUsed,total);
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -