pm.c

来自「适合KS8695X」· C语言 代码 · 共 1,995 行 · 第 1/5 页

C
1,995
字号
		break;
	    case 0x4F02:
		rmregs.pB[0].bBufferType = INPUT_BUFFER;
		rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es);
		rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi);
		rmregs.pB[0].pAddress = RMBuf;
		rmregs.pB[0].ulSize = 256;
		break;
	    case 0x4F09:
		rmregs.pB[0].bBufferType = INPUT_BUFFER;
		rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es);
		rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi);
		rmregs.pB[0].pAddress = RMBuf;
		rmregs.pB[0].ulSize = 1024;
		break;
	    case 0x4F0A:
		/* Due to bugs in the mini-VDM in OS/2, the 0x4F0A protected
		 * mode interface functions will not work (we never get any
		 * selectors returned), so we fail this function here. The
		 * rest of the VBE/Core driver will work properly if this
		 * function is failed, because the VBE 2.0 and 3.0 specs
		 * allow for this.
		 */
		regs->eax = 0x014F;
		return;
	    }
	}
    if (useVPMI)
	PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,NULL,&rmregs);
    else {
	DosSysCtl(6, &rmregs);
	}

    OUTDPMI(eax); OUTDPMI(ebx); OUTDPMI(ecx); OUTDPMI(edx); OUTDPMI(esi); OUTDPMI(edi);
    if (((regs->eax & 0xFFFF) == 0x004F) && ((eax & 0xFFFF) == 0x4F00)) {
	/* Hack to fix up the missing 'VESA' string for mini-VDM */
	memcpy(RMBuf,"VESA",4);
	}
    regs->ds = rmregs.aCRF.reg_ds;
    regs->es = rmregs.aCRF.reg_es;
    regs->flags = rmregs.aCRF.reg_eflag;
}

#define IN(reg)     rmregs.reg = in->e.reg
#define OUT(reg)    out->e.reg = rmregs.reg

/****************************************************************************
REMARKS:
Issue a real mode interrupt.
****************************************************************************/
int PMAPI PM_int86(
    int intno,
    RMREGS *in,
    RMREGS *out)
{
    DPMI_regs   rmregs;

    memset(&rmregs, 0, sizeof(rmregs));
    IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);
    DPMI_int86(intno,&rmregs);
    OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);
    out->x.cflag = rmregs.flags & 0x1;
    return out->x.ax;
}

/****************************************************************************
REMARKS:
Issue a real mode interrupt.
****************************************************************************/
int PMAPI PM_int86x(
    int intno,
    RMREGS *in,
    RMREGS *out,
    RMSREGS *sregs)
{
    DPMI_regs   rmregs;

    memset(&rmregs, 0, sizeof(rmregs));
    IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);
    rmregs.es = sregs->es;
    rmregs.ds = sregs->ds;
    DPMI_int86(intno,&rmregs);
    OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);
    sregs->es = rmregs.es;
    sregs->cs = rmregs.cs;
    sregs->ss = rmregs.ss;
    sregs->ds = rmregs.ds;
    out->x.cflag = rmregs.flags & 0x1;
    return out->x.ax;
}

/****************************************************************************
REMARKS:
Call a real mode far function.
****************************************************************************/
void PMAPI PM_callRealMode(
    uint seg,
    uint off,
    RMREGS *in,
    RMSREGS *sregs)
{
    PM_fatalError("PM_callRealMode not supported on OS/2!");
}

/****************************************************************************
REMARKS:
Return the amount of available memory.
****************************************************************************/
void PMAPI PM_availableMemory(
    ulong *physical,
    ulong *total)
{
    /* Unable to get reliable values from OS/2 for this */
    *physical = *total = 0;
}

/****************************************************************************
REMARKS:
Allocate a block of locked, physical memory for DMA operations.
****************************************************************************/
void * PMAPI PM_allocLockedMem(
    uint size,
    ulong *physAddr,
    ibool contiguous,
    ibool below16M)
{
    parmsIn[0] = size;
    parmsIn[1] = contiguous;
    parmsIn[2] = below16M;
    CallSDDHelp(PMHELP_ALLOCLOCKED);
    *physAddr = parmsOut[1];
    return (void*)parmsOut[0];
}

/****************************************************************************
REMARKS:
Free a block of locked physical memory.
****************************************************************************/
void PMAPI PM_freeLockedMem(
    void *p,
    uint size,
    ibool contiguous)
{
    parmsIn[0] = (ulong)p;
    CallSDDHelp(PMHELP_FREELOCKED);
}

/****************************************************************************
REMARKS:
Allocates a new block of pages for the page block manager.
****************************************************************************/
static pageblock *PM_addNewPageBlock(void)
{
    int         i;
    pageblock   *newBlock;
    char        *p,*next;

    /* Allocate memory for the new page block, and add to head of list */
    if (DosAllocSharedMem((void**)&newBlock,NULL,PAGE_BLOCK_SIZE,OBJ_GETTABLE | PAG_READ | PAG_WRITE | PAG_COMMIT))
	return NULL;
    if (!PM_lockDataPages(newBlock,PAGE_BLOCK_SIZE,&newBlock->lockHandle))
	return NULL;
    newBlock->prev = NULL;
    newBlock->next = pageBlocks;
    if (pageBlocks)
	pageBlocks->prev = newBlock;
    pageBlocks = newBlock;

    /* Initialise the page aligned free list for the page block */
    newBlock->freeCount = PAGES_PER_BLOCK;
    newBlock->freeList = p = (char*)(((ulong)(newBlock + 1) + (PM_PAGE_SIZE-1)) & ~(PM_PAGE_SIZE-1));
    newBlock->freeListStart = newBlock->freeList;
    newBlock->freeListEnd = p + (PAGES_PER_BLOCK-1) * PM_PAGE_SIZE;
    for (i = 0; i < PAGES_PER_BLOCK; i++,p = next)
	FREELIST_NEXT(p) = next = p + PM_PAGE_SIZE;
    FREELIST_NEXT(p - PM_PAGE_SIZE) = NULL;
    return newBlock;
}

/****************************************************************************
REMARKS:
Allocates a page aligned and page sized block of memory
****************************************************************************/
void * PMAPI PM_allocPage(
    ibool locked)
{
    pageblock   *block;
    void        *p;

    /* Scan the block list looking for any free blocks. Allocate a new
     * page block if no free blocks are found.
     */
    for (block = pageBlocks; block != NULL; block = block->next) {
	if (block->freeCount)
	    break;
	}
    if (block == NULL && (block = PM_addNewPageBlock()) == NULL)
	return NULL;
    block->freeCount--;
    p = block->freeList;
    block->freeList = FREELIST_NEXT(p);
    (void)locked;
    return p;
}

/****************************************************************************
REMARKS:
Free a page aligned and page sized block of memory
****************************************************************************/
void PMAPI PM_freePage(
    void *p)
{
    pageblock   *block;

    /* First find the page block that this page belongs to */
    for (block = pageBlocks; block != NULL; block = block->next) {
	if (p >= block->freeListStart && p <= block->freeListEnd)
	    break;
	}
    CHECK(block != NULL);

    /* Now free the block by adding it to the free list */
    FREELIST_NEXT(p) = block->freeList;
    block->freeList = p;
    if (++block->freeCount == PAGES_PER_BLOCK) {
	/* If all pages in the page block are now free, free the entire
	 * page block itself.
	 */
	if (block == pageBlocks) {
	    /* Delete from head */
	    pageBlocks = block->next;
	    if (block->next)
		block->next->prev = NULL;
	    }
	else {
	    /* Delete from middle of list */
	    CHECK(block->prev != NULL);
	    block->prev->next = block->next;
	    if (block->next)
		block->next->prev = block->prev;
	    }

	/* Unlock the memory and free it */
	PM_unlockDataPages(block,PAGE_BLOCK_SIZE,&block->lockHandle);
	DosFreeMem(block);
	}
}

/****************************************************************************
REMARKS:
Map in all the shared memory blocks for managing the memory pages above.
****************************************************************************/
void PMAPI PM_mapSharedPages(void)
{
    pageblock   *block;

    /* Map all the page blocks above into the shared memory for process */
    for (block = pageBlocks; block != NULL; block = block->next) {
	DosGetSharedMem(block, PAG_READ | PAG_WRITE);
	}
}

/****************************************************************************
REMARKS:
Lock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_lockDataPages(
    void *p,
    uint len,
    PM_lockHandle *lockHandle)
{
    parmsIn[0] = (ulong)p;
    parmsIn[1] = len;
    CallSDDHelp(PMHELP_LOCKPAGES);
    lockHandle->h[0] = parmsOut[1];
    lockHandle->h[1] = parmsOut[2];
    lockHandle->h[2] = parmsOut[3];
    return parmsOut[0];
}

/****************************************************************************
REMARKS:
Unlock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_unlockDataPages(
    void *p,
    uint len,
    PM_lockHandle *lockHandle)
{
    parmsIn[0] = lockHandle->h[0];
    parmsIn[1] = lockHandle->h[1];
    parmsIn[2] = lockHandle->h[2];
    return CallSDDHelp(PMHELP_UNLOCKPAGES);
}

/****************************************************************************
REMARKS:
Lock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_lockCodePages(
    void (*p)(),
    uint len,
    PM_lockHandle *lockHandle)
{
    parmsIn[0] = (ulong)p;
    parmsIn[1] = len;
    CallSDDHelp(PMHELP_LOCKPAGES);
    lockHandle->h[0] = parmsOut[1];
    lockHandle->h[1] = parmsOut[2];
    lockHandle->h[2] = parmsOut[3];
    return parmsOut[0];
}

/****************************************************************************
REMARKS:
Unlock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_unlockCodePages(
    void (*p)(),
    uint len,
    PM_lockHandle *lockHandle)
{
    parmsIn[0] = lockHandle->h[0];
    parmsIn[1] = lockHandle->h[1];
    parmsIn[2] = lockHandle->h[2];
    return CallSDDHelp(PMHELP_UNLOCKPAGES);
}

/****************************************************************************
REMARKS:
Call the VBE/Core software interrupt to change display banks.
****************************************************************************/
void PMAPI PM_setBankA(
    int bank)
{
    INTCRF  rmregs;

    if (!InitInt10())
	return;
    memset(&rmregs, 0, sizeof(rmregs));
    rmregs.ulBIOSIntNo = 0x10;
    rmregs.aCRF.reg_eax = 0x4F05;
    rmregs.aCRF.reg_ebx = 0x0000;
    rmregs.aCRF.reg_edx = bank;
    PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
}

/****************************************************************************
REMARKS:
Call the VBE/Core software interrupt to change display banks.
****************************************************************************/
void PMAPI PM_setBankAB(
    int bank)
{
    INTCRF  rmregs;

    if (!InitInt10())
	return;
    memset(&rmregs, 0, sizeof(rmregs));
    rmregs.ulBIOSIntNo = 0x10;
    rmregs.aCRF.reg_eax = 0x4F05;
    rmregs.aCRF.reg_ebx = 0x0000;
    rmregs.aCRF.reg_edx = bank;
    PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
    rmregs.ulBIOSIntNo = 0x10;
    rmregs.aCRF.reg_eax = 0x4F05;
    rmregs.aCRF.reg_ebx = 0x0001;
    rmregs.aCRF.reg_edx = bank;
    PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
}

/****************************************************************************
REMARKS:
Call the VBE/Core software interrupt to change display start address.
****************************************************************************/
void PMAPI PM_setCRTStart(
    int x,
    int y,
    int waitVRT)
{
    INTCRF  rmregs;

    if (!InitInt10())
	return;
    memset(&rmregs, 0, sizeof(rmregs));
    rmregs.ulBIOSIntNo = 0x10;
    rmregs.aCRF.reg_eax = 0x4F07;
    rmregs.aCRF.reg_ebx = waitVRT;
    rmregs.aCRF.reg_ecx = x;
    rmregs.aCRF.reg_edx = y;
    PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
}

/****************************************************************************
REMARKS:
Execute the POST on the secondary BIOS for a controller.
****************************************************************************/
ibool PMAPI PM_doBIOSPOST(
    ushort axVal,

⌨️ 快捷键说明

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