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 + -
显示快捷键?