📄 hal_mllc.c
字号:
/*-------------------------------------------------------------------------
//
// Copyright (c) 2000, 2001 Epson Research and Development, Inc.
// All Rights Reserved.
//
//-----------------------------------------------------------------------*/
#include "hal.h"
/*
** Because malloc.h redefines NULL, undefine NULL here first.
*/
#undef NULL
#include <stdio.h>
#include "nonsefns.h"
#include <malloc.h>
#ifdef INTEL_W32
#pragma warning(disable:4001) // Disable the 'single line comment' warning.
#pragma warning(disable:4115) // ignore "named type definition in parentheses" warning
#pragma warning(disable:4514) // ignore "unreferenced inline function has been removed" warning
#pragma warning(disable:4201) // Disable the 'nonstandard extension used : nameless struct/union'
#pragma warning(disable:4214) // Disable the 'single line comment' warning.
#pragma warning(disable:4702) // Disable the 'unreachable code' warning.
#endif
/*-----------------------------------------------------------------------------
//
// Static function prototypes
//
//---------------------------------------------------------------------------*/
static void seVmemBlocksMerge(void);
//static _MEMBLOCKST *seGetLastBlock(void);
static _MEMBLOCKST *seNewBlockAppend(_MEMBLOCKST *mbpta);
/*-----------------------------------------------------------------------------
//
// Global data.
//
//---------------------------------------------------------------------------*/
static _MEMBLOCKST gMB;
/*-----------------------------------------------------------------------------
//
// Claim the whole video memory as one free block.
// This function MUST be called as part of the HAL init sequence
// before any video memory allocations calls.
//
// Arguments:
// DWORD size : total amount of video memory installed (bytes)
//
//---------------------------------------------------------------------------*/
void _seVmemInit(DWORD size)
{
gMB.next = gMB.prev = NULL;
gMB.size = size;
gMB.free = TRUE;
gMB.address = _DispLinearAddress;
#ifdef _DEBUG
printf("_seVmemInit(%08lX)\n", size);
#endif
}
/*-----------------------------------------------------------------------------
//
// Allocate a block of video memory.
//
// Arguments:
// DWORD size : amount of video memory (bytes) to allocate
//
//---------------------------------------------------------------------------*/
DWORD seVmemAlloc(DWORD size)
{
_MEMBLOCKST *mbpt;
#ifdef _DEBUG
char str[50];
#endif
// round up to the next 1k boundary
size += 1023;
size &= ~1023;
for (mbpt = &gMB; mbpt != NULL; mbpt = mbpt->next)
{
if (mbpt->free == TRUE)
{
// is the block big enough?
if (mbpt->size == size)
{
// Snug fit. Just claim the block not free.
mbpt->free = FALSE;
#ifdef _DEBUG
sprintf(str, "seVmemAlloc(%08lX) > %08lX", size, mbpt->address);
_seVmemDump(str);
#endif
return mbpt->address;
}
else if (mbpt->size > size)
{
// Split the free block.
_MEMBLOCKST *newblock = seNewBlockAppend(mbpt);
if (newblock == NULL)
{
#ifdef _DEBUG
sprintf(str, "seVmemAlloc(%08lX) FAILED", size);
_seVmemDump(str);
#endif
return 0;
}
newblock->size = mbpt->size-size;
newblock->address = mbpt->address + size;
newblock->free = TRUE;
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 LINEAR_ADDRESSES_SUPPORTED
return 0;
#else
return -1;
#endif
}
/*-----------------------------------------------------------------------------
//
// Free a video memory block. Block must have been previously allocated
// by a call to one of the following:
//
// seVmemAlloc
//
// 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;
}
/*-----------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------*/
//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 + -