pm.c

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

C
1,460
字号
}

/****************************************************************************
REMARKS:
Allocate a block of real mode memory
****************************************************************************/
void * PMAPI PM_allocRealSeg(
    uint size,
    uint *r_seg,
    uint *r_off)
{
    /* We do not support dynamically allocating real mode memory buffers
     * from Win32 programs (we need a 16-bit DLL for this, and Windows
     * 9x becomes very unstable if you free the memory blocks out of order).
     */
    (void)size;
    (void)r_seg;
    (void)r_off;
    return NULL;
}

/****************************************************************************
REMARKS:
Free a block of real mode memory.
****************************************************************************/
void PMAPI PM_freeRealSeg(
    void *mem)
{
    /* Not supported in Windows */
    (void)mem;
}

/****************************************************************************
REMARKS:
Issue a real mode interrupt (parameters in DPMI compatible structure)
****************************************************************************/
void PMAPI DPMI_int86(
    int intno,
    DPMI_regs *regs)
{
    DWORD   inBuf[2];   /* Buffer to send data to VxD       */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = intno;
    inBuf[1] = (ulong)regs;
    CHECK_FOR_PMHELP();
    DeviceIoControl(_PM_hDevice, PMHELP_DPMIINT8632, inBuf, sizeof(inBuf),
	NULL, 0, &count, NULL);
}

/****************************************************************************
REMARKS:
Issue a real mode interrupt.
****************************************************************************/
int PMAPI PM_int86(
    int intno,
    RMREGS *in,
    RMREGS *out)
{
    DWORD   inBuf[3];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = intno;
    inBuf[1] = (ulong)in;
    inBuf[2] = (ulong)out;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_INT8632, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return outBuf[0];
    return 0;
}

/****************************************************************************
REMARKS:
Issue a real mode interrupt.
****************************************************************************/
int PMAPI PM_int86x(
    int intno,
    RMREGS *in,
    RMREGS *out,
    RMSREGS *sregs)
{
    DWORD   inBuf[4];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = intno;
    inBuf[1] = (ulong)in;
    inBuf[2] = (ulong)out;
    inBuf[3] = (ulong)sregs;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_INT86X32, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return outBuf[0];
    return 0;
}

/****************************************************************************
REMARKS:
Call a real mode far function.
****************************************************************************/
void PMAPI PM_callRealMode(
    uint seg,
    uint off,
    RMREGS *in,
    RMSREGS *sregs)
{
    DWORD   inBuf[4];   /* Buffer to send data to VxD       */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = seg;
    inBuf[1] = off;
    inBuf[2] = (ulong)in;
    inBuf[3] = (ulong)sregs;
    CHECK_FOR_PMHELP();
    DeviceIoControl(_PM_hDevice, PMHELP_CALLREALMODE32, inBuf, sizeof(inBuf),
	NULL, 0, &count, NULL);
}

/****************************************************************************
REMARKS:
Return the amount of available memory.
****************************************************************************/
void PMAPI PM_availableMemory(
    ulong *physical,
    ulong *total)
{
    /* We don't support this under Win32 at the moment */
    *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)
{
    DWORD   inBuf[4];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = size;
    inBuf[1] = (ulong)physAddr;
    inBuf[2] = (ulong)contiguous;
    inBuf[3] = (ulong)below16M;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_ALLOCLOCKED32, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return (void*)outBuf[0];
    return NULL;
}

/****************************************************************************
REMARKS:
Free a block of locked physical memory.
****************************************************************************/
void PMAPI PM_freeLockedMem(
    void *p,
    uint size,
    ibool contiguous)
{
    DWORD   inBuf[3];   /* Buffer to send data to VxD       */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = (ulong)p;
    inBuf[1] = size;
    inBuf[2] = contiguous;
    CHECK_FOR_PMHELP();
    DeviceIoControl(_PM_hDevice, PMHELP_FREELOCKED32, inBuf, sizeof(inBuf),
	NULL, 0, &count, NULL);
}

/****************************************************************************
REMARKS:
Allocates a page aligned and page sized block of memory
****************************************************************************/
void * PMAPI PM_allocPage(
    ibool locked)
{
    DWORD   inBuf[2];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = locked;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_ALLOCPAGE32, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return (void*)outBuf[0];
    return NULL;
}

/****************************************************************************
REMARKS:
Free a page aligned and page sized block of memory
****************************************************************************/
void PMAPI PM_freePage(
    void *p)
{
    DWORD   inBuf[1];   /* Buffer to send data to VxD       */
    DWORD   count;      /* Count of bytes returned from VxD */

    if (!inited)
	PM_init();
    inBuf[0] = (ulong)p;
    CHECK_FOR_PMHELP();
    DeviceIoControl(_PM_hDevice, PMHELP_FREEPAGE32, inBuf, sizeof(inBuf),
	NULL, 0, &count, NULL);
}

/****************************************************************************
REMARKS:
Lock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_lockDataPages(void *p,uint len,PM_lockHandle *lh)
{
    DWORD   inBuf[2];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    inBuf[0] = (ulong)p;
    inBuf[1] = len;
    inBuf[2] = (ulong)lh;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_LOCKDATAPAGES32, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return outBuf[0];
    return 0;
}

/****************************************************************************
REMARKS:
Unlock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh)
{
    DWORD   inBuf[2];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    inBuf[0] = (ulong)p;
    inBuf[1] = len;
    inBuf[2] = (ulong)lh;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_UNLOCKDATAPAGES32, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return outBuf[0];
    return 0;
}

/****************************************************************************
REMARKS:
Lock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
{
    DWORD   inBuf[2];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    inBuf[0] = (ulong)p;
    inBuf[1] = len;
    inBuf[2] = (ulong)lh;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_LOCKCODEPAGES32, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return outBuf[0];
    return 0;
}

/****************************************************************************
REMARKS:
Unlock linear memory so it won't be paged.
****************************************************************************/
int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
{
    DWORD   inBuf[2];   /* Buffer to send data to VxD       */
    DWORD   outBuf[1];  /* Buffer to receive data from VxD  */
    DWORD   count;      /* Count of bytes returned from VxD */

    inBuf[0] = (ulong)p;
    inBuf[1] = len;
    inBuf[2] = (ulong)lh;
    CHECK_FOR_PMHELP();
    if (DeviceIoControl(_PM_hDevice, PMHELP_UNLOCKCODEPAGES32, inBuf, sizeof(inBuf),
	    outBuf, sizeof(outBuf), &count, NULL))
	return outBuf[0];
    return 0;
}

/****************************************************************************
REMARKS:
Call the VBE/Core software interrupt to change display banks.
****************************************************************************/
void PMAPI PM_setBankA(
    int bank)
{
    RMREGS  regs;
    regs.x.ax = 0x4F05;
    regs.x.bx = 0x0000;
    regs.x.dx = bank;
    PM_int86(0x10,&regs,&regs);
}

/****************************************************************************
REMARKS:
Call the VBE/Core software interrupt to change display banks.
****************************************************************************/
void PMAPI PM_setBankAB(
    int bank)
{
    RMREGS  regs;
    regs.x.ax = 0x4F05;
    regs.x.bx = 0x0000;
    regs.x.dx = bank;
    PM_int86(0x10,&regs,&regs);
    regs.x.ax = 0x4F05;
    regs.x.bx = 0x0001;
    regs.x.dx = bank;
    PM_int86(0x10,&regs,&regs);
}

/****************************************************************************
REMARKS:
Call the VBE/Core software interrupt to change display start address.
****************************************************************************/
void PMAPI PM_setCRTStart(
    int x,
    int y,
    int waitVRT)
{
    RMREGS  regs;
    regs.x.ax = 0x4F07;
    regs.x.bx = waitVRT;
    regs.x.cx = x;
    regs.x.dx = y;
    PM_int86(0x10,&regs,&regs);
}

/****************************************************************************
REMARKS:
Enable write combining for the memory region.
****************************************************************************/
ibool PMAPI PM_enableWriteCombine(
    ulong base,
    ulong length,
    uint type)

⌨️ 快捷键说明

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