⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_mllc.c

📁 epson 13506 driver code
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-------------------------------------------------------------------------
//
// Copyright (c) 1997, 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 DWORD seBackAlloc(DWORD size,DWORD alignment);
static void seVmemBlocksMerge(void);
static _MEMBLOCKST *seGetLastBlock(void);
static _MEMBLOCKST *seNewBlockAppend(_MEMBLOCKST *mbpta);

/*-----------------------------------------------------------------------------
//
// Global data.
//
//---------------------------------------------------------------------------*/

static _MEMBLOCKST gMB;
static DWORD gDualPanelBuffer;
static DWORD DualPanelBufferSize = 0;

/*-----------------------------------------------------------------------------
//
//  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;
    gDualPanelBuffer = 0;
    gMB.address = _DispLinearAddress;

    DualPanelBufferSize = 0;
    _AutoAllocDualPanelBufferAddr = 0;

#ifdef _DEBUG
    printf("_seVmemInit(%08lX)\n", size);
#endif
    }

/*-----------------------------------------------------------------------------
//
//  Allocate a block of memory for HW ink layer.
//  It is any address on an 8k boundary.
//
//  Arguments: 
//        DWORD overlaysize : amount of video memory (bytes) to allocate
//
//---------------------------------------------------------------------------*/

DWORD seVmemAllocInk(DWORD overlaysize)
    {
    DWORD addr;
#ifdef _DEBUG
    char str[50];
#endif

    addr = seBackAlloc(overlaysize,8192);

#ifdef _DEBUG
    sprintf(str, "seVmemAllocInk(%08lX) > %08lX", overlaysize, addr);
    _seVmemDump(str);
#endif

    return addr;
    }        

/*-----------------------------------------------------------------------------
//
//  Allocate a block of memory for HW cursor.
//  It is either the very last 1k of video memory
//  or any address on an 8k boundary.
//
//---------------------------------------------------------------------------*/

DWORD seVmemAllocCursor(void)
    {
    DWORD addr;
#ifdef _DEBUG
    char str[50];
#endif

    addr = seBackAlloc(1024,1024);


#ifdef _DEBUG
    sprintf(str, "seVmemAllocCursor(%08lX) > %08lX", (DWORD) 1024, addr);
    _seVmemDump(str);
#endif
    return addr;
    }

/*-----------------------------------------------------------------------------
//
//  Allocate a block of memory for Dual Panel Buffer.
//  This function must be called whenever the dual panel buffer is needed.
//
//  Arguments: 
//        DWORD size : amount of video memory (bytes) to allocate
//
//---------------------------------------------------------------------------*/

DWORD seVmemAllocDualPanelBuffer(DWORD size)
    {
    _MEMBLOCKST *mbpt;
    int forever = 1;
#ifdef _DEBUG
    char str[50];
#endif

    // If a dual panel buffer is allocated, free it first
    seVmemFreeDualPanelBuffer();

    // Carve the block at the end of the video memory.
    // If the block is not free, free it first.
    
    do
        {
        mbpt = seGetLastBlock();
        if (mbpt->size >= size) 
            {
            // block big enough. We'll split it into two blocks.
            // The first one will be free, the last one used (our 
            // dual panel buffer)

            _MEMBLOCKST *newblock = seNewBlockAppend(mbpt);
            if (newblock == NULL)
               {
#ifdef _DEBUG
                sprintf(str, "seVmemAllocDualPanelBuffer(%08lX) FAILED", size);
               _seVmemDump(str);
#endif

#ifdef INTEL_DOS
               return -1;
#else
               return 0;
#endif
               }

            // Truncate the original block.
            mbpt->size = mbpt->size - size;

            newblock->size = size;
            newblock->free = FALSE;
            newblock->address = mbpt->address+mbpt->size;

            // Free the original block (to force blocks merge)
            mbpt->free = FALSE;
            seVmemFree(mbpt->address);
            gDualPanelBuffer = newblock->address;
#ifdef _DEBUG
            sprintf(str, "seVmemAllocDualPanelBuffer(%08lX) > %08lX", size, newblock->address);
            _seVmemDump(str);
#endif
            DualPanelBufferSize = size;
            return newblock->address;
            }
        else
            {
            // block too small. Merge the last two blocks 
            // and start all over again.

            if (mbpt->prev == NULL)
               {
#ifdef _DEBUG
                sprintf(str, "seVmemAllocDualPanelBuffer(%08lX) FAILED", size);
               _seVmemDump(str);
#endif

#ifdef INTEL_DOS
               return -1;
#else
               return 0;
#endif
               }

            seVmemFree(mbpt->prev->address);
            seVmemFree(mbpt->address);
            }
        } while (forever);

#ifdef INTEL_DOS
    return -1;
#else
    return 0;
#endif
    }        

/*-----------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------*/

void seVmemFreeDualPanelBuffer(void)
    {
    if (gDualPanelBuffer)
        {
        seVmemFree(gDualPanelBuffer);
        gDualPanelBuffer = 0;
        DualPanelBufferSize = 0;
        }
    }

/*-----------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------*/

DWORD seVmemGetDualPanelBufferSize(void)
    {
    return DualPanelBufferSize;
    }

/*-----------------------------------------------------------------------------
//
//  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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -